0x00 查壳
上来先查壳,无壳。并且可以看到是ELF文件,这里就直接用IDA64打开就好。
0x01 IDA分析
打开之后可以看到main函数,直接转过去分析:
这里的逻辑清晰可见,v5就是我们的输入,只要函数sub_400917返回真值,if条件语句成立即可输出flag。所以我们转到函数里面分析:
一个数独游戏,这里的两个if语句则是判断行和列有无重复值,数独的数据则保存在unk_601060里面,所以根据这个规则直接把它解出来,得到一个数列。然后返回main函数继续分析,依次向上分析函数,发现sub_400881实现了v7往unk_601060里面赋值的操作,赋值的位置恰好是空的位置(既 ‘#’ 号的位置)
所以继续往上看,就看到v7来自v3,v3来自v5,两次都是递归算法(两张拼在一起):
递归算法由于其空间复杂,不便于手动分析逆算。所以先放着,整体分析完最后解决。然后就是最上面的if语句里的函数,是对输入的v5的一个效验函数:
效验函数很简单,先判断长度是否等于10,再判断每一个字符是否超出了0~4的范围。分析到这里,我们的基本思路以及捋清楚了。
所以我们只需要解决两次递归变序的问题就好。硬分析不如动调来的简单,把文件甩进虚拟机,用ida直接动态调试,我们输入0123456789然后在sub_400881函数下断查看即可。这样就得到变序处理后的顺序,再还原回去就OK。
0x02 动态调试
在如图的地方的设置断点,然后在下面jz跳转的时候使起不跳转进入后面的两个递归函数即可。
成功找到变序之后的数列:
0x03 exp
最后一步就很简单了,可以直接手推回去或者写个exp。附上exp:
inputs = "0421421430"
listindex = [7,3,8,1,9,4,0,5,2,6]
F = [0]*10
for i in range(10):
F[listindex[i]] = inputs[i]
flag = ''.join(F)
print(flag)
#1134240024
检验: