2020-10-08

逆向练习#4

[BUUCTF-xor]

前言:

认识了简单的伪代码之后,要开始看复杂的了。

1.

在exeinfo中确认信息后,放入ida,找到main函数,f5查看伪代码

image-20201008111053312

直接从网上扒来的图,因为我第一眼真的看不懂啊呜呜

逻辑具体是:首先判断我们的输入v6长度是否为33,不是就进入label_12,下面可以看到就是返回”Failed”。

然后i=1,v6[1]代表从输入的第二位开始,^=表示异或(即xor)。即把两个数据二进制化,对位相同则输出0,不同输出1,再以输出的二进制转换回来。

例子:5和3转为二进制分别为:0101 、0011,异或结果0110,转换为十进制的6,即5^3=6.

但是a^=b是什么操作?应该是把异或好的数据赋值给a。

之后,比较v6global,(33uLL我不明白什么意思,uLL应该是数据类型,unsiged Long Long,33应该就是长度吧,但不知道这里面为什么说的是前31位)

2.

跟进global,里面有一串存储数据aFKWOXZUPFVMDGH,再跟进

1
2
3
__cstring:0000000100000F6E aFKWOXZUPFVMDGH db 'f',0Ah              ; DATA XREF: __data:_global↓o
__cstring:0000000100000F6E db 'k',0Ch,'w&O.@',11h,'x',0Dh,'Z;U',11h,'p',19h,'F',1Fh,'v"M#D',0Eh,'g'
__cstring:0000000100000F6E db 6,'h',0Fh,'G2O',0

既然知道了求得global的原理是异或,那么就反着来求出flag。异或反运算就是再异或一次。

0Ah0ch这些其实是十六进制,其他为字符串。

于是写python脚本,第一位f是不变的,从第二位0Ah开始。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
str1 = ['f', 0x0A, 'k', 0x0C, 'w', '&', 'O', '.', '@', 0x11, 'x', 0x0D, 'Z', ';', 'U', 0x11, 'p', 0x19, 'F', 0x1F, 'v',
'"', 'M', '#', 'D', 0x0E, 'g', 6, 'h', 0x0F, 'G', '2', 'O']

x = 'f'

for i in range(1, len(str1)):
if (isinstance(str1[i], str)):
if (isinstance(str1[i - 1], str)):
x += chr(ord(str1[i]) ^ ord(str1[i - 1]))
else:
x += chr(ord(str1[i]) ^ str1[i - 1])
else:
x += chr(str1[i] ^ ord(str1[i - 1]))

print(x)

首先把我们的数据输入,把16进制的数据写成python能识别的。查看第i位是不是字符串类型,不是就让第二位和第一位异或,输出加在x后面。

ord表示把字符串转化为十进制数字,因为ord()内只能是字符串类型,所以要先isinstance判断。

这个脚本其实有bug,连续两个数字就出错了。改正也很简单,最下面的else内改为

1
2
3
4
if (isinstance(str1[i - 1], str)):
x += chr(str1[i] ^ ord(str1[i - 1]))
else:
x += chr(str1[i] ^ str1[i - 1])

3.

得出结果,flag{QianQiuWanDai_YiTongJiangHu},完事!