打开ida后,看见代码包含了很多个while循环,而且最后量个while循环结束之后都有printf,便想着看看回显了个啥。
于是他便卡在了第一个断点处,看看应该printf啥:
而最后一个printf的字符串为:
所以要做的也就是不触发前一个printf的判断,直接出while循环。
思路已经明确那么现在也就是要保证让两个if条件都不为0(即sub_8C1830与v4不为0)以达到break的效果
进入loc_8C11A0里发现没被声明为函数,先全部选中按p声明下,然后反编译
我反编译出来个什么玩意儿???,但将a1与a2赋值的数字转为字符后,就发现其实就是,上文所说的两个printf输出的字符串,正是因为这两个字符串是在运行时生成的,静态调试无法直接看出。
然后这个函数不管怎样只返回1,所以v4一定不为0。那么现在只要保证sub_5D1830(a1, (int)v8, v7)同样不为0即可。
对于该函数分为两个while循环
第一个说白了也就是对密码字符串进行处理:
对于v14的取值很明显要到sub_731470中寻找,毕竟是将地址作为参数
然后就又是一滩难看的代码
但在最后64行不难看出想要v14 == 43924,那么a2[7] = 0x63是必要条件,在这里形参a2也就是实参v17的值。
v17 = “dbappsec”
而在看下一个while循环时byte_5E6050并没有,猜测为运行时其他函数生成。。。好吧,也不用猜,看看谁引用他不就完了
然后就定位到了这个函数
然后动态调试一下,在最后下个断点,就把这个只拿出来了。这里的byte_746050就是之前的那个byte数据动态调试后他变样了!!
但这里用户名要输入正确,因为这个生成函数以用户名为参数
然后我发觉根据原来的逻辑
我下断点的这句话应该是最关键的一句语句,因为v17已知,byte_746050可以拿出来,而v16是要求的密码。而且涉及到异或操作,然后我就想着去看看汇编,发现点惊喜。
根据之前的静态分析可以知道此处while循环了8次,那就看看eax与ecx的值。试了两组不同的密码,ecx不变但eax值变了,所以ecx为byte数组,eax为密码。然后拿到ecx = [0x7E,0x98,0xC9,0x95,0x10,0x6D,0xF3,0x67],然后写了个脚本跑出来的密码为1afaa8e5601e964,转md5提交不对,然后人傻了。。。
网上的大佬说因为前面的反调试语句导致ida跑不出来正确答案,于是我换了od ,ecx确实得到了另一组数据[0x2a,0xD7,0x92,0xE9,0x53,0xE2,0xC4,0xCD]。
嗯。这波od,yyds
脚本:
a = [0x2a,0xD7,0x92,0xE9,0x53,0xE2,0xC4,0xCD]
b = "dbappsec"
flag = ''
for i in range(8):
flag += hex(a[i]^ord(b[i]))
print(flag.replace('0x', ''), end='')
得到密码:4eb5f3992391a1ae,md5后即为flag
最后吐槽一下:
我flag都交上了,你让我再试一次????