BUUCTF crackMe

[BUUCTF] crackMe

本题用于熟悉动调和对于反调试的练习

image-20220808215802075

找到主函数,user已有题目给给出,为welcomebeijing,只需逆向密码即可。

除去两个验证性的函数,只剩decode1和decode2

decode1

image-20220808215953599

decode1里面是由输入的user来生成一个key数组,由于输入已给出,key数组结果相当于已知

decode2

decode2函数开头一段是对输入的密码进行转换

image-20220808220232175

并且根据判断

1
2
3
4
5
6
7
v10 = v9 + 16 * v10;                        // 一位一位的去读取数据,计入v9
if ( !((int)(v7 + 1) % 2) )
{
password[v4++ - 1] = v10; // 两位char组成一个16进制的数,存入v15
a1 = v4;
v10 = 0;
}

可以得知,将输入的密码两位为一组看作一个16进制数,所以密码本身应该是16进制的

第二部分是对于密码的再次处理

image-20220808220537892

首先对key数组进行二次处理,然后再和密码进行异或

对于key数组的处理受到两个反调试的影响,动调前要先绕过

异或的结果放入sub_11470函数并且当v14 == 0xAB94时才返回1

sub_11470函数

image-20220808220802338

注意5号位,若是动调时结果为f,没有被调试为s,所以和key数组异或后的结果的为dbappsec

然后对程序进行动调来得出key数组的值

image-20220808221037685

最后这个值会被移到ecx寄存器里面和密码进行异或,直接读取ecx的值

image-20220808221420834

写出脚本,注意输出要用16进制输出

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include<iostream>
using namespace std;
int main()
{
string key = "dbappsec";
int flag[] = {0x2a, 0xd7, 0x92, 0xe9, 0x53, 0xe2, 0xc4, 0xcd};
for(int i = 0 ; i < 8; i++)
{
int num = (int)key[i];
int ans = num ^ (int)flag[i];
cout << hex << ans;
}

return 0;
}
//flag:4eb5f3992391a1ae

最后md5加密取32位小写

1
flag{d2be2981b84f2a905669995873d6a36c}