2019xman个人晋级赛之little-unpack
逆向题有点坑,这道看到后边时间有点紧,看不下去,有点可惜。
题目
一打开数据混乱,应该是加壳了。
直接在seg022段下断点,动态调试。
运行如下代码段。
seg024:000000000060309D cmp rax, rcx
seg024:00000000006030A0 jnz short near ptr loc_6030A4+1
seg024:00000000006030A2 jz short near ptr loc_6030A4+1
发现解密循环判断,判断是否解密完。rax是段的起始地址,也就是0x400850,rcx代表段尾。
解密完之后进入代码段之间还有一个反调试。
libc_2.24.so:00007FBF48D4E344 mov , eax
libc_2.24.so:00007FBF48D4E346 jz short loc_7FBF48D4E354
libc_2.24.so:00007FBF48D4E348 xor edx, edx
libc_2.24.so:00007FBF48D4E34A xor esi, esi
libc_2.24.so:00007FBF48D4E34C mov rdi, r9
libc_2.24.so:00007FBF48D4E34F call near ptr __cxa_atexit
手动修改寄存器的值跳过。
进入核心段之后发现
造成这种原因为因为代码段中插入了很多0xE8数据,手段修改,得到。
虽然还有很多花指令在其中,但已经不影响阅读。
其中还有一些反调试,可以手动去掉、
程序大概流程是输入明文,经过des加密对比、
这是key的赋值
.text:00000000004009FC mov qword ptr , 0
.text:0000000000400A05 mov byte ptr , 31h
.text:0000000000400A0A mov byte ptr , 32h
.text:0000000000400A0F mov byte ptr , 33h
.text:0000000000400A14 mov byte ptr , 34h
.text:0000000000400A19 mov byte ptr , 35h
.text:0000000000400A1E mov byte ptr , 36h
.text:0000000000400A23 mov byte ptr , 37h
.text:0000000000400A28 mov byte ptr , 38h
即key=12345678
加密后,密文的对比方式
.text:0000000000400BE5 loc_400BE5: ; CODE XREF: .text:0000000000400BDF↑j
.text:0000000000400BE5 pop rax
.text:0000000000400BE6 pop rax
.text:0000000000400BE7 mov edx,
.text:0000000000400BEE mov eax,
.text:0000000000400BF5 mov ecx, edx
.text:0000000000400BF7 sub ecx, eax
.text:0000000000400BF9 cmp ecx, 55F8FD5Bh
.text:0000000000400BFF jz loc_400CA6
.text:0000000000400CA6 loc_400CA6: ; CODE XREF: .text:0000000000400BFF↑j
.text:0000000000400CA6 mov ecx,
.text:0000000000400CAD mov esi,
.text:0000000000400CB4 mov edi, ecx
.text:0000000000400CB6 sub edi, esi
.text:0000000000400CB8 cmp edi, 3C763966h
.text:0000000000400CBE jnz loc_400C05
.text:0000000000400CC4 imul rax, rcx
.text:0000000000400CC8 mov rcx, 13069E5EF81C51D0h
.text:0000000000400CD2 cmp rax, rcx
.text:0000000000400CD5 jnz loc_400C05
.text:0000000000400CDB imul rdx, rsi
.text:0000000000400CDF mov rax, 16DE11EA08E740B7h
.text:0000000000400CE9 cmp rdx, rax
.text:0000000000400CEC jnz loc_400C05
.text:0000000000400CF2 jnz short near ptr loc_400CF6+1
.text:0000000000400CF4 jz short near ptr loc_400CF6+1
即
one - tow = 0x55F8FD5B
three - four = 0x3C763966
tow * three = 0x13069E5EF81C51D0
one * four = 0x16DE11EA08E740B7
直接写脚本解
from z3 import *
x = Solver()
flag =
x.add(flag>0)
x.add(flag>0)
x.add(flag>0)
x.add(flag>0)
x.add(flag-flag==0x55F8FD5B)
x.add(flag-flag==0x3C763966)
x.add((flag*flag)==0x13069E5EF81C51D0)
x.add((flag*flag)==0x16DE11EA08E740B7)
print x.check()
print x.model()
得到
[flag1 = 780944752,
flag3 = 741130309,
flag0 = 2223325899,
flag2 = 1755511211]
根据大端小端,得到密文
cb42858470458c2eabf9a26845c02c2c
此时还是解不开。后面发现是字秘钥处理方式被改了。
就是生成16组字秘钥之后,再将每一组以64位操作下循环左移5位。
在标准的des代码中加入
for (count = 0; count < 16; count++)
{
temps = sub_key;
//sub_key = ((temps << 5) & 0xffffffff) | ((temps >> 59) & 0xffffffff);
sub_key = (temps << 5);
}
运行得flag
惭愧。到现在还是看不懂 谢谢楼主提供好工具。 这些楼主分享思路,新人总是需要去尝试,但是没人带只能自己下琢磨 软件真的好用
页:
[1]