攻防世界BABYRE逆向
拿到题目,查壳如下:
拖拽IDA Pro7.5打开,查看main函数,代码如下:
可以看到:
(*(unsigned int (__fastcall **)(char *))judge)(s),
再一看上面的judge是一个数组的形式,心想:这是哪门子的写法,,,。强制转换unsigned int????这不是函数返回结果才能这么写嘛,再看到后面的**__fastcall**猜测是函数的动态生成。。。写法高档,作者🐂就完事了。。。查看judge汇编代码,按下C(编码),P(创建函数),变红,无效,如下图:
吓得我连续按了两次Ctrl+Z撤销,怎么说呢,失败呗,那没办法了,动调,你还不现出原形?
打开我们的kali,将IDA pro目录下dbgsrv目录里的linux_server64文件拖动到kali里,给执行权限,然后执行,然后在IDA里Debugger >> select a debugger,悬崖边则Remote Linux debugger,然后Debugger >> proccess option输入kali的hostname(ip地址)和密码。完成上述步骤后,去IF语句上F2下个断点,看看这个judge为何方妖孽,按下F9直接起飞。断点如下:
起飞过后别忘了去kali里输入字符串让它断下,这里的字符串输入14位,因为断点处cmp [rbp+var_8],0Eh,而0Eh就是十进制的14,输入完后回车我们开始分析,发现猜想果然没错,这妖孽就是个函数,我们F7单步步入下图所示的call:
咳咳,发现14个mov,一看就是声明一个数组,然后,,,,这些数就是我们要的密文:
继续往下分析,看看这个函数到底干了啥,分析发现流程为:
cmp dword ptr [rbp-4], 0Dh
jle short loc_600B49
就是比较[rbp-4]和0Dh(十进制:13),小于等于13则跳转,其实就是做了14次判断,分析图如下:
来分析一下这个判断跳转后都做了些啥事,复制出来分析:(分析过程不是很官方)
.data:0000000000600B49 loc_600B49: ; CODE XREF: .data:0000000000600B75↓j
.data:0000000000600B49 mov eax, [rbp-4] //eax赋值0
.data:0000000000600B4C movsxd rdx, eax //rdx赋值0
.data:0000000000600B4F mov rax, [rbp-28h] //取出数组给rax
.data:0000000000600B53 add rax, rdx //rax=rax+rdx,也就是数组[1]
.data:0000000000600B56 mov edx, [rbp-4] //edx赋值0
.data:0000000000600B59 movsxd rcx, edx //rcx赋值edx,也就是是0
.data:0000000000600B5C mov rdx, [rbp-28h] //取出数组给rdx
.data:0000000000600B60 add rdx, rcx //rdx=rdx+rcx也就是数组[0]
.data:0000000000600B63 movzx edx, byte ptr [rdx] //edx=[rdx],也就是edx为数组[0]
.data:0000000000600B66 mov ecx, [rbp-4] //ecx=[rbp-4],也就是ecx为0
.data:0000000000600B69 xor edx, ecx //edx=edx^ecx,也就是数组[0]^0
.data:0000000000600B6B mov [rax], dl //[rax]这里应该是保存异或后的结果
.data:0000000000600B6D add dword ptr [rbp-4], 1 //[rbp-4]+=1,这里就是循环的变量
好了,分析完毕,其实前八行都是没用的,有用的是第九行以后,现在取处我们要的内容,也就是 数组[i]^i,i+=1,写代码如下:
a=[0x66,0x6D,0x63,0x64,0x7F,0x6B,0x37,0x64,0x3B,0x56,0x60,0x3B,0x6E,0x70]
for i in range(14):
print(chr(a[i]^i),end='')
输出如下:
flag{n1c3_j0b}
总结:这个题其实很简单,但是碰到了这个题叭,我觉得很有必要记录一下这个思路,感谢阅读!