持续创作,加速成长!这是我参与「掘金日新计划 · 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)
得到八位字符串
包上壳即可