ADWORLD [REV] HW_RE1

HW_RE1

第一眼看到HW还以为和华为有什么关系,是我想多了。。。

IDA Pro打开:

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
__int64 __fastcall main(int a1, char **a2, char **a3)
{
__int64 *v3; // rbx
char *v4; // rbp
void *v5; // rax
char *v6; // rsi
const char *v7; // r13
int v8; // ebp
char *v9; // rsi
__int64 v11; // [rsp+0h] [rbp-B8h] BYREF
void *dest; // [rsp+8h] [rbp-B0h]
const char *v13; // [rsp+10h] [rbp-A8h]
__int64 v14; // [rsp+18h] [rbp-A0h]
char buf[6]; // [rsp+20h] [rbp-98h] BYREF
char s[98]; // [rsp+26h] [rbp-92h] BYREF
unsigned __int64 v17; // [rsp+88h] [rbp-30h]

v17 = __readfsqword(0x28u);
read(0, buf, 0x20uLL);
s[26] = 0;
if ( memcmp("CISCN{", buf, 6uLL) )
return 0xFFFFFFFFLL;
v3 = &v11;
v4 = (char *)&v11;
do
{
v5 = malloc(0x20uLL);
*(_QWORD *)v4 = v5;
if ( !v5 )
return 0xFFFFFFFFLL;
v4 += 8;
}
while ( buf != v4 );
v6 = strtok(s, "_");
if ( !v6 )
return 0xFFFFFFFFLL;
v7 = (const char *)dest;
memcpy(dest, v6, strlen(v6));
v8 = 1;
do
{
++v8;
v9 = strtok(0LL, "_");
if ( !v9 )
return 0xFFFFFFFFLL;
memcpy((void *)v3[2], v9, strlen(v9));
++v3;
}
while ( v8 != 3 );
if ( (unsigned int)sub_4012DE(v7) )
return 0xFFFFFFFFLL;
if ( (unsigned int)sub_401411(v13) )
return 0xFFFFFFFFLL;
if ( (unsigned int)sub_401562(v14) )
return 0xFFFFFFFFLL;
puts("Congratulations!");
_IO_getc(stdin);
return 0LL;
}

main函数使用strtok将输入的字符串以_分割成三部分。每部分作为参数传递给不同的1三个函数:

第一个函数:

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
__int64 __fastcall sub_4012DE(const char *a1)
{
unsigned __int64 i; // rsi
char v2; // cl
unsigned int v4[24]; // [rsp+0h] [rbp-A8h] BYREF
__int64 v5[2]; // [rsp+60h] [rbp-48h] BYREF
char v6[40]; // [rsp+70h] [rbp-38h] BYREF
unsigned __int64 v7; // [rsp+98h] [rbp-10h]

v7 = __readfsqword(0x28u);
sub_400876(v4);
sub_4008A0(v4);
sub_40108B(v4, (char *)a1, strlen(a1));
sub_401170(v4, (__int64)v5);
sub_401285(v6, v5, 16LL);
qword_603640 = v5[0];
qword_603648 = v5[1];
for ( i = 0LL; i < strlen(v6); ++i )
{
v2 = v6[i];
if ( (unsigned __int8)(v2 - 65) <= 5u )
v6[i] = (int)i % 10 + v2;
}
return (unsigned int)-(memcmp("9F925J9341B490FKJ3J4C4ED3G0J1NF2", v6, 0x20uLL) != 0);
}

使用动调,发现执行完 sub_4008A0(v4);后,v4里存储了MD5的标准幻数。那么剩下的肯定就是MD5加密算法了,直接跳到for循环。for循环对MD5加密后的结果进行微调;最终与字符串9F925J9341B490FKJ3J4C4ED3G0J1NF2比对。