crackMe

已知用户名:welcomebeijing,要我们查密码。运行看看:

有头目但不多

这道题目是反编译的一个了解吧(个人认为),还是能学到了很多的。

查壳:

32位,进IDA:

先重命名变量,方便看,然后一个个分析:

密码和用户名的循环,可以看到循环条件都是一样的,也就是说,用户名能过循环,那么密码就一定也能过循环 --> 这两循环没啥太大用处

sub_401090(name);对用户名进行函数操作,决定byte_416050里的内容。也就是说用户名如果不对,那么byte_416050里面的值会出错,这里一定要保证byte_416050的值是正确的不然会影响后边的结果

最后是两个if,第一个if对name和password进行函数操作,除此之外(密码循环那层忽略掉,没用)我们没能看到任何对password的操作,那么逆推password只能从这下手。跟进sub_401830(name, password):

我们能看到password -> v8,v8 -> v9, v9 ->v15,由上述思路可以知道,v15的十六进制表达式就是密码,而在逆推v15的时候我们又限制于byte_416050,和v16的值,两者都知晓后才能根据异或运算逆推出v15的值,由此可知byte_416050值不能出错,也就是name不能错误,对于byte_416050的值我们后边可以通过调试拿到,所以我们把目标看到v16的值上:sub_401710(v16, a1, v5++);和sub_401470(v16, &v13);前者我们跟进发现对于v16没有任何影响,那么只能看后者:

我们能看到v16进入函数后就成了a2,那么根据函数分析我们能得到v16:dbappsec,有人可能会问为什么不是dbappfec,因为f是在反调试下选取的,反调试,也就说程序正常运行的时候选的是s,当我们用dbg或者ida去调试的时候选择的就是f,至此,我们就结束了v16值的寻找,接下来是对byte_416050值的调试拿取。

我们能知道,这两个反调试的函数会影响到byte_416050的值,那么我们要对它进行修改:一:直接nop掉;二:将条件反转;两者都行,我选的是第二种:红框的是被修改过后的,原来是:jz short loc_401B6E,保存动调(dbug;ida都可以)

动调拿取byte_416050的值(IDA):

在此下断点:输入name:welcomebeijing,密码随便输入

ecx的值就是byte_416050的值,f9弄出来完得到:2A,D7,92,E9,53,E2,C4,CD

动调拿取byte_416050的值(dbug):

观察xor eax, ecx所在的地址:00401B3E,由于计算机原因,所以在dbug上地址是不同的,但是偏移地址是一样的,也就是说在dbug上的xxxx1B3E上就是我们要设断点的xor eax, ecx;看看:

同理动调f9,一样拿到2A,D7,92,E9,53,E2,C4,CD,可以写脚本解题了:

import hashlib
Des = 'dbappsec'
des = [0x2A, 0xD7, 0x92, 0xE9, 0x53, 0xE2, 0xC4, 0xCD]
flag = ''
for i in range(len(des)):
    flag += hex(ord(Des[i]) ^ des[i])[2:]
md5 = hashlib.md5()
md5.update(flag.encode())
value = md5.hexdigest()
print(value)

得到flag{d2be2981b84f2a905669995873d6a36c}

posted @ 2023-09-05 17:34  TFOREVERY  阅读(27)  评论(0编辑  收藏  举报