部分RE题目解题过程

148 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第8天,点击查看活动详情

RE

easyre

查壳

UPX壳,脱壳后拉近ida

查看字符串发现有个换过表的base64加密,查看主函数

为了省事不截图了

 _main();
  i = 0;
  puts("Welcome to QLNU!");
  puts("Maybe you like the escape plan, too?");
  strcpy(Str2, "hJqAr3qKq36Cv4SJtKi3snt=");//这里引号里的就是加密字符串
  Str2[25] = 0;
  v6 = 0;
  v7 = 0;
  memset(v8, 0, sizeof(v8));
  puts("Please input string: ");
  scanf("%s", Str);//获取输入,赋值到str
  for ( i = 0; i < strlen(Str); ++i )//这里有个凯撒加密(比赛的时候没太注意这行)
    ++Str[i];
  v12 = Str;
  v11 = strlen(Str);
  v10 = memset_1((const unsigned __int8 *)Str, v11, (unsigned __int8 *)Str1);
  Str1[v10] = 0;
  if ( !strcmp(Str1, Str2) )//这里是比较两个字符串
    printf("Yes!");
  else
    printf("No!");
  return 0;
}

根据对主函数的分析写脚本

import base64
import string
str1 = "hJqAr3qKq36Cv4SJtKi3snt="
string1 = "RSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQ+/"
string2 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
print (base64.b64decode(str1.translate(str.maketrans(string1,string2))))

得到字符串 Cfmjfwfjozpvstfmg

然后解凯撒,主函数里进行了+

所以解的话需要-

target = bytearray(b'Cfmjfwfjozpvstfmg')
for i in range(len(target)):
    target[i] -= 1
print(target)

最后得到flag

 

easy_baby_re

查壳

ASPack壳,没找到脱壳机,手动脱壳

 

 

smali

安卓题,拖进ide查看

找到crakme,发现没法点小咖啡

在雪月三十大神的博客找到别的方法

把apk拖到dex2jar目录然后在命令行运行这个命令

d2j-dex2jar.bat smali.apk

等完成后得到一个

 

把这个jar拖进jad-gui

看到源码

package com.SnowMoon.xyzz;


import android.util.Base64;
import java.io.IOException;


public class Crakme {
    public static String crack() throws IOException {
        char[] cArr = new char[56];
        for (int i = 0; i < 56; i++) {
            cArr[i] = (char) ((char) (new int[]{26, 25, 13, 39, 12, 15, 16, 9, 49, 6, 17, 47, 25, 34, 44, 45, 35, 6, 40, 32, 13, 27, 47, 40, 38, 14, 24, 25, 44, 14, 10, 30, 43, 12, 37, 22, 6, 46, 34, 44, 50, 6, 31, 21, 26, 3, 18, 36, 1, 28, 14, 24, 35, 6, 30, 34}[i] + new int[]{35, 23, 59, 61, 105, 55, 55, 91, 72, 51, 54, 52, 91, 74, 6, 43, 18, 68, 48, 58, 37, 30, 23, 60, 11, 60, 26, 63, 9, 64, 78, 59, 65, 45, 33, 78, 112, 7, 16, 44, 57, 102, 19, 77, 95, 79, 91, 62, 103, 88, 37, 66, 69, 114, 79, 56}[i]));
        }
        return new String(Base64.decode(String.valueOf(new StringBuffer(String.valueOf(cArr)).reverse()), 0));
    }
}

分析一波

数组长度56

两个数组相加,然后12行有个reverse函数,是将数组逆向

逆向完之后转字符串

转完字符串后解base64

分析完写个脚本

import base64
data0 = [26, 25, 13, 39, 12, 15, 16, 9, 49, 6, 17, 47, 25, 34, 44, 45, 35, 6, 40, 32, 13, 27, 47, 40, 38, 14, 24, 25, 44, 14, 10, 30, 43, 12, 37, 22, 6, 46, 34, 44, 50, 6, 31, 21, 26, 3, 18, 36, 1, 28, 14, 24, 35, 6, 30, 34]
data1 = [35, 23, 59, 61, 105, 55, 55, 91, 72, 51, 54, 52, 91, 74, 6, 43, 18, 68, 48, 58, 37, 30, 23, 60, 11, 60, 26, 63, 9, 64, 78, 59, 65, 45, 33, 78, 112, 7, 16, 44, 57, 102, 19, 77, 95, 79, 91, 62, 103, 88, 37, 66, 69, 114, 79, 56]
data2 = []
QLNU=""
for i in range(len(data0)):
    data2.append(data0[i] + data1[i])
print(data2)
a=56
b=0
while a:
    data0[b]=data2[a-1]
    a=a-1
    b=b+1
print(data0)
for i in range(len(data0)):
    QLNU += chr(data0[i])
print(data0)
print(base64.b64decode(QLNU))

得到flag

 

 

 

run

下载查看发现是个蟒蛇

拖进ida查看

有很多py前缀,

可以确定这是python写的程序

接下来将其中的pyc文件给提取出来

先安装必要的一些插件等等

pip install uncompyle(安装uncompyle)

回滚python版本(虚拟机装的3.7.9)

pip install uncompyle6==3.7.4

这样就ok了

 

 

安装python-exe-unpacker-master

安装010(虚拟机)

将文件拖进去

搜索cmd

运行这个命令

python pyinstxtractor.py run.exe

 

会出来个文件夹 run.exe_extracted

进去找到这个run 和srtuct

没有后缀,其实是缺少pyc头的pyc文件

然后用010打开这两个文件

可以看到这个run缺少了一行pyc头

把struct的pyc头复制给run

然后把run文件重命名,改成run.pyc

接着在该目录使用如下命令

uncompyle6 run.pyc

然后能看到源码

把源码沾到下面了

import os


def check(flag):
    try:
        v0 = ord(flag[5])
        v1 = ord(flag[6])
        v2 = ord(flag[7])
        v3 = ord(flag[8])
        v4 = ord(flag[9])
        v5 = ord(flag[10])
        v6 = ord(flag[11])
        v7 = ord(flag[12])
    except IndexError as e:
        try:
            print('长度为14位字符噢')
        finally:
            e = None
            del e


    else:
        if flag[0] == 'Q':
            if flag[1] == 'L':
                if flag[2] == 'N':
                    if flag[3] == 'U':
                        if flag[4] == '{':
                            if flag[13] == '}':
                                if check2(v0, v1, v2, v3, v4, v5, v6, v7):
                                    return 1
                                return 0




def check2(v0, v1, v2, v3, v4, v5, v6, v7):
    return (v1 * v2 - v5 * 72 - v4 * 3 - v3 ^ v1 + (v3 << 2) + v2 * 6 - v7 & v6 - 1000) - 14 == -2296 
and (v5 * 7 + v3 * 3 + v2 + v6 - (v2 >> 2) - v1 ^ v0 + v7 + (v4 ^ v1) + (v4 | v7)) - 801 == 34 
and (v6 * 5 + v2 * 6 - v3 * 7 + v4 | v5 + v4 * 10 + v0 ^ v1 * 3 - v7 + v0 + v1) - 924 == 51 
and v1 * 3 + v5 * 9 + v0 + v2 * 2 + v3 * 5 - v4 * (v6 ^ v7) + 321 - 16 == -2261 
and (v5 * 12 - v0 ^ v6 - v3 * 23 + v4 * 3 + v2 * 8 + v1 - v7 * 2 + v6 * 4 + 1324) + 1 == 1505 
and v3 * 54 - v1 * 3 + v2 * 3 + v4 * 11 - v5 * 2 + v0 + v7 * 3 - v6 - 6298 + 40 == -2932 
and v7 - v6 * v3 + v2 * v2 - v4 * 32 + v5 * (v0 >> 2) - v1 * v1 - 6689 + 41 == -3903 
and (v5 - v3 * 41 + v6 * 41 + v5 ^ (v4 & v6 | v0) - (v7 * 24 | v2) + v1 - 589) - 36 == -4020




flag = input('输入你的flag:')
if check(list(flag)):
    print('成功了')
else:
    print('再想想吧')
os.system('pause')

对源码分析一波

比较容易得到的信息 flag为14位

给了QLNU{},所以需要求剩下八位

可以看到剩下的八位(从v0到v7)作为check2的参数进行运算

运算的式子非常多,

需要所有表达式全部满足,所以考虑z3

弄个z3的脚本

from z3 import *


s = Solver()
v0 = BitVec('v0',32)
v1 = BitVec('v1',32)
v2 = BitVec('v2',32)
v3 = BitVec('v3',32)
v4 = BitVec('v4',32)
v5 = BitVec('v5',32)
v6 = BitVec('v6',32)
v7 = BitVec('v7',32)
s.add((((v1*v2-v5*72-v4*3-v3^v1+(v3<<2)+v2*6-v7&v6-1000)-14)) == -2296)
s.add((((v5*7+v3*3+v2+v6-(v2>>2)-v1^v0+v7+(v4^v1)+(v4|v7))-801)) == 34)
s.add((((v6*5+v2*6-v3*7+v4|v5+v4*10+v0^v1*3-v7+v0+v1)-924)) == 51)
s.add((((v5*12-v0^v6-v3*23+v4*3+v2*8+v1-v7*2+v6*4+1324)+1)) == 1505)
s.add(((v3*54-v1*3+v2*3+v4*11-v5*2+v0+v7*3-v6-6298+40)) == -2932)
s.add(((v7-v6*v3+v2*v2-v4*32+v5*(v0>>2)-v1*v1-6689+41)) == -3903)
s.add((((v5-v3*41+v6*41+v5^(v4&v6|v0)-(v7*24|v2)+v1-589)-36)) == -4020)
s.add(((v1*3+v5*9+v0+v2*2+v3*5-v4*(v6^v7)+321-16)) == -2261)
if(s.check() == sat):
    result = s.model()
print(result)

然后得到v0到v7

这里弄出来是乱序的,需要从v0到v7重新排序

然后写个ASCII转字符串的脚本

data = [122,51,95,49,51,95,101,52]
flag = ''
for i in range(8):
    flag +=chr(data[i])
print(flag)

得到八位字符串

包上壳即可