胖哈勃杯第十三届CUIT校赛之re150
 
150分的逆向题
0x00 分析
题目相关文件:https://github.com/Reshahar/BlogFile/tree/master/2017-cuit-re150_1
这是linux下的逆向,还是先拖到IDA里看看吧
void start()
{
int v0; // eax@1
int v1; // ecx@1
int v2; // esi@1
v0 = sys_write(1, &unk_80488E2, 9u);
v1 = unk_80488DE;
v2 = 0;
do
{
*((_BYTE *)nullsub_1 + v2) = ((unsigned __int8)(*((_BYTE *)nullsub_1 + v2) ^ 0x42) >> 3) | 32
* (*((_BYTE *)nullsub_1 + v2) ^ 0x42);
++v2;
--v1;
}
while ( v1 );
JUMPOUT(__CS__, nullsub_1);
}
start开始看的有点蒙圈的,后来查看汇编发现其实这是自己实现的一个解密代码,就是将每个字符的异或0x42再将它的底三位和高五位换位
.eh_frame:0804892B loc_804892B:
.eh_frame:0804892B mov bl, 0
.eh_frame:0804892D mov al, [edi+esi]
.eh_frame:08048930 xor al, 42h
.eh_frame:08048932 shl al, 5
.eh_frame:08048935 or bl, al
.eh_frame:08048937 mov al, [edi+esi]
.eh_frame:0804893A xor al, 42h
.eh_frame:0804893C shr al, 3
.eh_frame:0804893F or bl, al
.eh_frame:08048941 mov [edi+esi], bl
.eh_frame:08048944 inc esi
.eh_frame:08048945 loop **loc_804892B**
这里也不用自己解密,直接使用gdb在loop之后下断点,然后单步运行就能到解密后代码的地方,然后使用dump命令将这块代码dump下来,可以使用IDA分析,都是汇编代码,有些地址调用是错的,可读性很差,然后对照着代码,使用gdb分析前期的算法分析出来部分,但是看了一下后面还有狠多,脑袋疼,gdb调试程序,效果并不是很好,后来想起来edb,类似windows下的OD图形的,可以同时观察内存,栈上的数据,很方便,之前的逻辑已经比较清晰了,使用edb调试,下几个断点,很快就分析出了算法
整体算法是这样的:
将输入的字符右移x位,或上,这个字符左移8-x位(和上面解密的算法差不多的),其中x等于当前字符下标与上7,然后在异或上当前字符下标,然后在异或上32 ,最后和内存中0x080499ec地址的值比较
根据上面的算法,直接将0x080499ec地址dump出来,然后写脚本如下:
list = [0x73,0x8d,0xf2,0x4c ,0xc7 ,0xd4 ,0x7b ,0xf7 ,0x18 ,0x32 ,0x71 ,0x0d ,0xcf ,0xdc ,0x67 ,0x4f,0x7f,0x0b ,0x6d]
ret=[]
for i in list:
ret.append(hex(i^32))
k = 0
x = 0
flag = ''
for i in ret:
for j in range(0,256):
x = k & 7
z = ((j>>x)|(j<<(8-x)))
y = z^k
y = y%256
#print y
if y==int(i,16):
flag+=chr(j)
k = k+1
print flag
运行结果如下:
SYC{>>Wh06m1>>R0Ot}
验证一下:
root@kali:~/D/re# ./re150
syclover
SYC{>>Wh06m1>>R0Ot}
right
0x01 总结
工具可以换着用,不要总依赖一个工具
0x02 参考
[1]:http://blog.csdn.net/yasi_xi/article/details/18399731 gdb dump binary memory to file