2020-12-22

逆向练习#12

BUUCTF-[2019红帽杯]easyRE

1.信息收集:无加壳,64位文件

2.IDA64位,搜索关键代码,如下

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
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
signed __int64 sub_4009C6()
{
char *v0; // rsi
char *v1; // rdi
__int64 v2; // rax
signed __int64 result; // rax
unsigned __int64 v4; // rax
__int64 v5; // rax
__int64 v6; // ST10_8
__int64 v7; // ST18_8
__int64 v8; // ST20_8
__int64 v9; // ST28_8
__int64 v10; // ST30_8
__int64 v11; // ST38_8
__int64 v12; // ST40_8
__int64 v13; // ST48_8
__int64 v14; // ST50_8
__int64 v15; // ST58_8
int i; // [rsp+Ch] [rbp-114h]
char v17; // [rsp+60h] [rbp-C0h]
char v18; // [rsp+61h] [rbp-BFh]
char v19; // [rsp+62h] [rbp-BEh]
char v20; // [rsp+63h] [rbp-BDh]
char v21; // [rsp+64h] [rbp-BCh]
char v22; // [rsp+65h] [rbp-BBh]
char v23; // [rsp+66h] [rbp-BAh]
char v24; // [rsp+67h] [rbp-B9h]
char v25; // [rsp+68h] [rbp-B8h]
char v26; // [rsp+69h] [rbp-B7h]
char v27; // [rsp+6Ah] [rbp-B6h]
char v28; // [rsp+6Bh] [rbp-B5h]
char v29; // [rsp+6Ch] [rbp-B4h]
char v30; // [rsp+6Dh] [rbp-B3h]
char v31; // [rsp+6Eh] [rbp-B2h]
char v32; // [rsp+6Fh] [rbp-B1h]
char v33; // [rsp+70h] [rbp-B0h]
char v34; // [rsp+71h] [rbp-AFh]
char v35; // [rsp+72h] [rbp-AEh]
char v36; // [rsp+73h] [rbp-ADh]
char v37; // [rsp+74h] [rbp-ACh]
char v38; // [rsp+75h] [rbp-ABh]
char v39; // [rsp+76h] [rbp-AAh]
char v40; // [rsp+77h] [rbp-A9h]
char v41; // [rsp+78h] [rbp-A8h]
char v42; // [rsp+79h] [rbp-A7h]
char v43; // [rsp+7Ah] [rbp-A6h]
char v44; // [rsp+7Bh] [rbp-A5h]
char v45; // [rsp+7Ch] [rbp-A4h]
char v46; // [rsp+7Dh] [rbp-A3h]
char v47; // [rsp+7Eh] [rbp-A2h]
char v48; // [rsp+7Fh] [rbp-A1h]
char v49; // [rsp+80h] [rbp-A0h]
char v50; // [rsp+81h] [rbp-9Fh]
char v51; // [rsp+82h] [rbp-9Eh]
char v52; // [rsp+83h] [rbp-9Dh]
char v53[32]; // [rsp+90h] [rbp-90h]
int v54; // [rsp+B0h] [rbp-70h]
char v55; // [rsp+B4h] [rbp-6Ch]
char v56; // [rsp+C0h] [rbp-60h]
char v57; // [rsp+E7h] [rbp-39h]
char v58; // [rsp+100h] [rbp-20h]
unsigned __int64 v59; // [rsp+108h] [rbp-18h]

v59 = __readfsqword(0x28u);
v17 = 73;
v18 = 111;
v19 = 100;
v20 = 'l';
v21 = '>';
v22 = 'Q';
v23 = 'n';
v24 = 'b';
v25 = '(';
v26 = 'o';
v27 = 'c';
v28 = 'y';
v29 = '';
v30 = 'y';
v31 = '.';
v32 = 'i';
v33 = '';
v34 = 'd';
v35 = '`';
v36 = '3';
v37 = 'w';
v38 = '}';
v39 = 'w';
v40 = 'e';
v41 = 'k';
v42 = '9';
v43 = '{';
v44 = 'i';
v45 = 'y';
v46 = '=';
v47 = '~';
v48 = 'y';
v49 = 'L';
v50 = '@';
v51 = 'E';
v52 = 'C';
memset(v53, 0, sizeof(v53)); //输入1
v54 = 0;
v55 = 0;
v0 = v53;
sub_4406E0(0LL, v53, 37LL);
v55 = 0;
v1 = v53; //v1获取输入1
LODWORD(v2) = sub_424BA0((const __m128i *)v53);
if ( v2 == 36 )
{
for ( i = 0; ; ++i )//猜测是遍历每一位
{
v1 = v53;
LODWORD(v4) = sub_424BA0((const __m128i *)v53);
if ( i >= v4 )
break;
if ( (unsigned __int8)(v53[i] ^ i) != *(&v17 + i) ) //输入每一位与对应位置数异或,与保存的数据对应位置进行比较
{
result = 4294967294LL;
goto LABEL_13;
}
}
sub_410CC0("continue!");
memset(&v56, 0, 0x40uLL);//输入2
v58 = 0;
v0 = &v56;
sub_4406E0(0LL, &v56, 64LL);
v57 = 0;
v1 = &v56;//置入输入2
LODWORD(v5) = sub_424BA0((const __m128i *)&v56);
if ( v5 == 39 )
{
v6 = sub_400E44(&v56);//base64加密10次
v7 = sub_400E44(v6);
v8 = sub_400E44(v7);
v9 = sub_400E44(v8);
v10 = sub_400E44(v9);
v11 = sub_400E44(v10);
v12 = sub_400E44(v11);
v13 = sub_400E44(v12);
v14 = sub_400E44(v13);
v15 = sub_400E44(v14);
v0 = off_6CC090;
v1 = (char *)v15;
if ( !(unsigned int)sub_400360(v15, off_6CC090) )//进行比较
{
sub_410CC0("You found me!!!");
v1 = "bye bye~";
sub_410CC0("bye bye~");
}
result = 0LL;
}
else
{
result = 4294967293LL;
}
}
else
{
result = 0xFFFFFFFFLL;
}
LABEL_13:
if ( __readfsqword(0x28u) != v59 )
sub_444020(v1, v0);
return result;
}

所有分析在注释当中

首先我们再异或得出保存的数据的意思,简单得出:Info:The first four chars are flag

再看sub_400E44,点开里面可以发现有一个方法保存的字符串是ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/

即可明白这是base64加密,还进行了10次加密。

然后把加密后的结果与off_6CC090中保存的字符串比较。

解密过后得:https://bbs.pediy.com/thread-254172.htm,查询发现被耍了。

实际上在off_6CC090里,下面还有一节字符串

image-20201222194819480

跟进它的地址,就是解密过程(这一段蛮难的)

image-20201222194910295

24行中,byte_6CC0A0就是存储的字符串,byte_6CC0A3 也就是byte_6CC0A0[3]

HIBYTE(v8)=HIBYTE(v4)=(*((_BYTE)&(V4)+1)) 属于未知

解密过程为byte_6CC0A0与v8对应位(四位一循环)异或

由于flag开头是flag,我们明白前四位与byte_6CC0A0异或后等于”flag”

存储的字符串要与v8对应位进行异或,v8要四位进行循环遍历,可根据开头flag得出v8.

于是就可以再异或得出flag了

于是写脚本:

1
2
3
4
5
6
7
8
9
10
11
12
s = [0x40, 0x35, 0x20, 0x56, 0x5D, 0x18, 0x22, 0x45, 0x17, 0x2F, 0x24, 0x6E, 0x62, 0x3C, 0x27, 0x54, 0x48, 0x6C, 0x24, 0x6E, 0x72, 0x3C, 0x32, 0x45, 0x5B]
s1 = 'flag'
flag = ''
key = ''

for i in range(4):
key += chr(s[i] ^ ord(s1[i]))

for i in range(len(s)):
flag += chr(s[i] ^ ord(key[i % 4]))

print(flag)

得flag{Act1ve_Defen5e_Test}

搞定!

红帽杯的题还蛮难的

经验:memset与输入有关

byte_6CC0A3 也就是byte_6CC0A0[3]

HIBYTE(v8)=HIBYTE(v4)=(*((_BYTE)&(V4)+1))

一般从最后面看起,明白最终结果是什么,再逆着推导,更好理清逻辑,明白关键代码。