2020-11-13

逆向练习#11

Buuctf-CrackRTF

1.

惯例exeinfo查看信息,放进ida后搜索字符串进入关键函数

2.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
int main_0()
{
DWORD v0; // eax
DWORD v1; // eax
CHAR String; // [esp+4Ch] [ebp-310h]
int v4; // [esp+150h] [ebp-20Ch]
CHAR String1; // [esp+154h] [ebp-208h]
BYTE pbData; // [esp+258h] [ebp-104h]

memset(&pbData, 0, 0x104u);
memset(&String1, 0, 0x104u);
v4 = 0;
printf("pls input the first passwd(1): ");
scanf("%s", &pbData);
if ( strlen((const char *)&pbData) != 6 ) //长度等于6位
{
printf("Must be 6 characters!\n");
ExitProcess(0);
}
v4 = atoi((const char *)&pbData); //转换为字符串形式
if ( v4 < 100000 )
ExitProcess(0);
strcat((char *)&pbData, "@DBApp"); //在输入后面加入@DBApp
v0 = strlen((const char *)&pbData);
sub_40100A(&pbData, v0, &String1); //加密函数
if ( !_strcmpi(&String1, "6E32D0943418C2C33385BC35A1470250DD8923A9") )
{
printf("continue...\n\n");
printf("pls input the first passwd(2): "); //第二次输入
memset(&String, 0, 0x104u);
scanf("%s", &String);
if ( strlen(&String) != 6 )
{
printf("Must be 6 characters!\n");
ExitProcess(0);
}
strcat(&String, (const char *)&pbData);
memset(&String1, 0, 0x104u);
v1 = strlen(&String);
sub_401019((BYTE *)&String, v1, &String1);
if ( !_strcmpi("27019e688a4e62a649fd99cadaafdb4e", &String1) )
{
if ( !(unsigned __int8)sub_40100F(&String) )
{
printf("Error!!\n");
ExitProcess(0);
}
printf("bye ~~\n");
}
}
return 0;
}

能发现sub_40100A是对输入进行加密处理的函数,且使结果等于6E32D0943418C2C33385BC35A1470250DD8923A9

进入sub_40100A

image-20201113094531546

百度能明白,这是用系统自带的hash加密算法。0x8004u是加密标识码,表示加密方式。

查询便可得知是sh1加密。于是写脚本把密码爆破。

1
2
3
4
5
6
7
import hashlib
flag2='@DBApp'
for i in range(100000,999999):
h2 = hashlib.sha1((str(i)+flag2).encode("utf-8"))
flags = h2.hexdigest()
if "6e32d0943418c2c33385bc35a1470250dd8923a9" == flags:
print (str(i)+flag2)

网上的wp脚本python版本都不同了,好在这个很容易写😉

得出结果: 123321@DBApp

接下来看下面,有第二次输入

过程类似,进入第二次加密函数sub_401019

image-20201113101213702

这次换了加密方式,查询得是MD5加密,然而并没有更多的提示了,得不出结果。

3.

在下面的比较中,还有个sub_40100F函数,这是这题的重点。

进入后

image-20201113103600853

大意为:从AAA中取出数据与我们的输入进行处理,生成一个dbapp.rtf的文件

这里还有个sub_401005函数,进入后可以知道是将AAA与我们的输入进行异或

image-20201113104417413

a2代表AAA中的首部指针,v5是字符串的长度

麻烦的是,还需要用工具 ResourceHacker 去查看文件中的AAA

由于生成了一个rtf文件,则搜索rtf文件头:{\rtfl

且由于我们知道密码是六位的

于是我们拿rtf文件前六位,正好就是文件头,与AAA文件中的前六位进行异或(此为反操作)

1
2
3
4
5
6
7
8
9
s = "{\\rtf1"

a = [0x05,0x7D,0x41,0x15,0x26,0x01]

flag = ""
for i in range(0,len(s)):
x = ord(s[i]) ^ a[i]
flag += chr(x)
print(flag)

得到结果:~!3a@0

于是运行程序,输入密码,正确,生成了flag文件

Flag{N0_M0re_Free_Bugs} 搞定!