ps:学习了一下大家写文章的方式,以后就都这么写了,之前的第一篇就懒得改了,参考了网上师傅的wp
题目链接:7d3K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6T1N6i4g2G2K9W2)9J5k6h3y4F1i4K6u0r3j5$3S2S2L8r3I4W2L8X3N6W2M7#2)9J5x3$3y4J5j5h3y4C8e0h3f1`.

通过题目内容可以了解到,用户名是welcomebeijing,密码MD5的小写哈希就是我们的flag。点开程序,可以看到关键字符串,大致的思路就是通过这个字符串可以定位到关键函数,再进行进一步分析。
先用查壳软件看一下程序情况

是一个无壳的32位PE文件,用IDA32打开,定位到主函数
对于一些不是很重要的函数的作用我都直接在上面的函数注明了,比较重要的,我会在下文着重分析。
这个函数就是对user进行了一系列操作,最后把值赋给了byte_416050这个数组,我看着很像RC4加密,后面可以直接动调出来
一下子就能看见有好几个反调试的语句,第一个while循环里的意思就是将输入的密码,例如123456,按0x12,0x34,0x56这样两位切割,然后放在v14数组里面。接下来重点就是第二个循环,我们先来看这个sub_401710函数
在上面这个函数中 v4是user用户名的长度,a3是两位一组后的密码分组个数计数,v4是永远大于a3的。else if里面的操作就是把V6和用户名异或再把值存放在v16里,为了区别,这里将新的v16记作v16'。然后就是sub_401470,我们通过return语句可以推出,v13 == 0xAB94,通过这个我们就可以推出v16'的值。
这里面的a2就是v16',只要v16'的每一位值能等于这里面if判断语句的每一个值就会输出v13 == 0xAB94,所以v16'=dbappfsec。然后我们就可以通过v16'和用户名异或得出v16,再把v16和byte_416050数组异或就可以得出我们要的两位一组分割后的密码,最后拼起来就行。现在我们唯一缺的就是byte_416050数组,这里可以通过动态调试得出
动态调试之前需要先将前面的反调试语句处理一下,将下图处的jz改为jmp就行了

然后我们再去看一下关键位置的汇编代码


可以看见我们只需要观察ecx的值就可以得出byte_416050数组的值,动调得出值为0x2A, 0xD7, 0x92, 0xE9, 0x53, 0xE2, 0xC4, 0xCD。ps:这里动调的值,不知道是程序原因还是什么原因,动调出来的值跟网上动调出来的值不一样,最后搬的网上师傅动调出来的值,有师傅知道的可以在评论区指点一手。
奇怪的是这个结果程序是可以通过的,但是提交到Buuctf没通过,网上的一些wp的结果提交到Buuctf是可以的,但是通不过程序的检验,不知道是不是Buuctf的flag错了。网上其他wp的结果是4eb5f3992391a1ae,大家可以自己试一下。

int
wmain()
{
FILE
*
v0;
/
/
eax
FILE
*
v1;
/
/
eax
char v3;
/
/
[esp
+
3h
] [ebp
-
405h
]
char v4;
/
/
[esp
+
4h
] [ebp
-
404h
] BYREF
char v5[
255
];
/
/
[esp
+
5h
] [ebp
-
403h
] BYREF
char
Format
;
/
/
[esp
+
104h
] [ebp
-
304h
] BYREF
char v7[
255
];
/
/
[esp
+
105h
] [ebp
-
303h
] BYREF
char v8;
/
/
[esp
+
204h
] [ebp
-
204h
] BYREF
char v9[
255
];
/
/
[esp
+
205h
] [ebp
-
203h
] BYREF
char v10;
/
/
[esp
+
304h
] [ebp
-
104h
] BYREF
char v11[
255
];
/
/
[esp
+
305h
] [ebp
-
103h
] BYREF
printf(
"Come one! Crack Me~~~\n"
);
v10
=
0
;
memset(v11,
0
, sizeof(v11));
v8
=
0
;
memset(v9,
0
, sizeof(v9));
while
(
1
)
{
do
{
do
{
printf(
"user(6-16 letters or numbers):"
);
scanf(
"%s"
, &v10);
v0
=
(
FILE
*
)sub_4024BE();
fflush(v0);
}
while
( !(unsigned __int8)sub_401000(&v10) );
printf(
"password(6-16 letters or numbers):"
);
scanf(
"%s"
, &v8);
v1
=
(
FILE
*
)sub_4024BE();
fflush(v1);
}
while
( !(unsigned __int8)sub_401000(&v8) );
sub_401090(&v10);
Format
=
0
;
memset(v7,
0
, sizeof(v7));
v4
=
0
;
memset(v5,
0
, sizeof(v5));
v3
=
((
int
(__cdecl
*
)(char
*
, char
*
))loc_4011A0)(&
Format
, &v4);
if
( (unsigned __int8)sub_401830(&v10, &v8) )
{
if
( v3 )
break
;
}
printf(&v4);
}
printf(&
Format
);
return
0
;
}
int
wmain()
{
FILE
*
v0;
/
/
eax
FILE
*
v1;
/
/
eax
char v3;
/
/
[esp
+
3h
] [ebp
-
405h
]
char v4;
/
/
[esp
+
4h
] [ebp
-
404h
] BYREF
char v5[
255
];
/
/
[esp
+
5h
] [ebp
-
403h
] BYREF
char
Format
;
/
/
[esp
+
104h
] [ebp
-
304h
] BYREF
char v7[
255
];
/
/
[esp
+
105h
] [ebp
-
303h
] BYREF
char v8;
/
/
[esp
+
204h
] [ebp
-
204h
] BYREF
char v9[
255
];
/
/
[esp
+
205h
] [ebp
-
203h
] BYREF
char v10;
/
/
[esp
+
304h
] [ebp
-
104h
] BYREF
char v11[
255
];
/
/
[esp
+
305h
] [ebp
-
103h
] BYREF
printf(
"Come one! Crack Me~~~\n"
);
v10
=
0
;
memset(v11,
0
, sizeof(v11));
v8
=
0
;
memset(v9,
0
, sizeof(v9));
while
(
1
)
{
do
{
do
{
printf(
"user(6-16 letters or numbers):"
);
scanf(
"%s"
, &v10);
v0
=
(
FILE
*
)sub_4024BE();
fflush(v0);
}
while
( !(unsigned __int8)sub_401000(&v10) );
printf(
"password(6-16 letters or numbers):"
);
scanf(
"%s"
, &v8);
v1
=
(
FILE
*
)sub_4024BE();
fflush(v1);
}
while
( !(unsigned __int8)sub_401000(&v8) );
sub_401090(&v10);
Format
=
0
;
memset(v7,
0
, sizeof(v7));
v4
=
0
;
memset(v5,
0
, sizeof(v5));
v3
=
((
int
(__cdecl
*
)(char
*
, char
*
))loc_4011A0)(&
Format
, &v4);
if
( (unsigned __int8)sub_401830(&v10, &v8) )
{
if
( v3 )
break
;
}
printf(&v4);
}
printf(&
Format
);
return
0
;
}
_BYTE
*
__cdecl sub_401090(_BYTE
*
a1)
{
_BYTE
*
result;
/
/
eax
int
v2;
/
/
[esp
+
Ch] [ebp
-
18h
]
int
v3;
/
/
[esp
+
10h
] [ebp
-
14h
]
_BYTE
*
v4;
/
/
[esp
+
14h
] [ebp
-
10h
]
int
i;
/
/
[esp
+
18h
] [ebp
-
Ch]
char v7;
/
/
[esp
+
20h
] [ebp
-
4h
]
char v8;
/
/
[esp
+
22h
] [ebp
-
2h
]
unsigned __int8 v9;
/
/
[esp
+
23h
] [ebp
-
1h
]
for
( i
=
0
; i <
256
;
+
+
i )
byte_416050[i]
=
i;
v2
=
0
;
v9
=
0
;
v3
=
0
;
result
=
a1;
v4
=
a1;
do
LOBYTE(result)
=
*
v4;
while
(
*
v4
+
+
);
while
( v2 <
256
)
{
v8
=
byte_416050[v2];
v9
+
=
v8
+
a1[v3];
v7
=
byte_416050[v9];
+
+
v3;
byte_416050[v9]
=
v8;
byte_416050[v2]
=
v7;
result
=
(_BYTE
*
)v3;
if
( v3 >
=
v4
-
(a1
+
1
) )
v3
=
0
;
+
+
v2;
}
return
result;
}
_BYTE
*
__cdecl sub_401090(_BYTE
*
a1)
{
_BYTE
*
result;
/
/
eax
int
v2;
/
/
[esp
+
Ch] [ebp
-
18h
]
int
v3;
/
/
[esp
+
10h
] [ebp
-
14h
]
_BYTE
*
v4;
/
/
[esp
+
14h
] [ebp
-
10h
]
int
i;
/
/
[esp
+
18h
] [ebp
-
Ch]
char v7;
/
/
[esp
+
20h
] [ebp
-
4h
]
char v8;
/
/
[esp
+
22h
] [ebp
-
2h
]
unsigned __int8 v9;
/
/
[esp
+
23h
] [ebp
-
1h
]
for
( i
=
0
; i <
256
;
+
+
i )
byte_416050[i]
=
i;
v2
=
0
;
v9
=
0
;
v3
=
0
;
result
=
a1;
v4
=
a1;
do
LOBYTE(result)
=
*
v4;
while
(
*
v4
+
+
);
while
( v2 <
256
)
{
v8
=
byte_416050[v2];
v9
+
=
v8
+
a1[v3];
v7
=
byte_416050[v9];
+
+
v3;
byte_416050[v9]
=
v8;
byte_416050[v2]
=
v7;
result
=
(_BYTE
*
)v3;
if
( v3 >
=
v4
-
(a1
+
1
) )
v3
=
0
;
+
+
v2;
}
return
result;
}
bool
__cdecl sub_401830(
int
a1, const char
*
a2)
{
int
v3;
/
/
[esp
+
18h
] [ebp
-
22Ch
]
int
v4;
/
/
[esp
+
1Ch
] [ebp
-
228h
]
int
v5;
/
/
[esp
+
28h
] [ebp
-
21Ch
]
unsigned
int
v6;
/
/
[esp
+
30h
] [ebp
-
214h
]
char v7;
/
/
[esp
+
36h
] [ebp
-
20Eh
]
char v8;
/
/
[esp
+
37h
] [ebp
-
20Dh
]
char v9;
/
/
[esp
+
38h
] [ebp
-
20Ch
]
unsigned __int8 v10;
/
/
[esp
+
39h
] [ebp
-
20Bh
]
unsigned __int8 v11;
/
/
[esp
+
3Ah
] [ebp
-
20Ah
]
char v12;
/
/
[esp
+
3Bh
] [ebp
-
209h
]
int
v13;
/
/
[esp
+
3Ch
] [ebp
-
208h
] BYREF
char v14;
/
/
[esp
+
40h
] [ebp
-
204h
] BYREF
char v15[
255
];
/
/
[esp
+
41h
] [ebp
-
203h
] BYREF
char v16;
/
/
[esp
+
140h
] [ebp
-
104h
] BYREF
char v17[
255
];
/
/
[esp
+
141h
] [ebp
-
103h
] BYREF
v4
=
0
;
v5
=
0
;
v11
=
0
;
v10
=
0
;
v16
=
0
;
memset(v17,
0
, sizeof(v17));
v14
=
0
;
memset(v15,
0
, sizeof(v15));
v9
=
0
;
v6
=
0
;
v3
=
0
;
while
( v6 < strlen(a2) )
{
if
( isdigit(a2[v6]) )
{
v8
=
a2[v6]
-
48
;
}
else
if
( isxdigit(a2[v6]) )
{
if
(
*
((_DWORD
*
)NtCurrentPeb()
-
>SubSystemData
+
3
) !
=
2
)
a2[v6]
=
34
;
v8
=
(a2[v6] |
0x20
)
-
87
;
}
else
{
v8
=
((a2[v6] |
0x20
)
-
97
)
%
6
+
10
;
}
__rdtsc();
__rdtsc();
v9
=
v8
+
16
*
v9;
if
( !((
int
)(v6
+
1
)
%
2
) )
{
*
(&v14
+
v3
+
+
)
=
v9;
v9
=
0
;
}
+
+
v6;
}
while
( v5 <
8
)
{
v10
+
=
byte_416050[
+
+
v11];
v12
=
byte_416050[v11];
v7
=
byte_416050[v10];
byte_416050[v10]
=
v12;
byte_416050[v11]
=
v7;
if
( ((
int
)NtCurrentPeb()
-
>UnicodeCaseTableData &
0x70
) !
=
0
)
v12
=
v10
+
v11;
*
(&v16
+
v5)
=
byte_416050[(unsigned __int8)(v7
+
v12)] ^
*
(&v14
+
v4);
if
( (unsigned __int8)
*
(_DWORD
*
)&NtCurrentPeb()
-
>BeingDebugged )
{
v10
=
-
83
;
v11
=
43
;
}
sub_401710(&v16, a1, v5
+
+
);
v4
=
v5;
if
( v5 >
=
(unsigned
int
)(&v14
+
strlen(&v14)
+
1
-
v15) )
v4
=
0
;
}
v13
=
0
;
sub_401470(&v16, &v13);
return
v13
=
=
0xAB94
;
}
bool
__cdecl sub_401830(
int
a1, const char
*
a2)
{
int
v3;
/
/
[esp
+
18h
] [ebp
-
22Ch
]
int
v4;
/
/
[esp
+
1Ch
] [ebp
-
228h
]
int
v5;
/
/
[esp
+
28h
] [ebp
-
21Ch
]
unsigned
int
v6;
/
/
[esp
+
30h
] [ebp
-
214h
]
char v7;
/
/
[esp
+
36h
] [ebp
-
20Eh
]
char v8;
/
/
[esp
+
37h
] [ebp
-
20Dh
]
char v9;
/
/
[esp
+
38h
] [ebp
-
20Ch
]
unsigned __int8 v10;
/
/
[esp
+
39h
] [ebp
-
20Bh
]
unsigned __int8 v11;
/
/
[esp
+
3Ah
] [ebp
-
20Ah
]
char v12;
/
/
[esp
+
3Bh
] [ebp
-
209h
]
int
v13;
/
/
[esp
+
3Ch
] [ebp
-
208h
] BYREF
char v14;
/
/
[esp
+
40h
] [ebp
-
204h
] BYREF
char v15[
255
];
/
/
[esp
+
41h
] [ebp
-
203h
] BYREF
char v16;
/
/
[esp
+
140h
] [ebp
-
104h
] BYREF
char v17[
255
];
/
/
[esp
+
141h
] [ebp
-
103h
] BYREF
v4
=
0
;
v5
=
0
;
v11
=
0
;
v10
=
0
;
v16
=
0
;
memset(v17,
0
, sizeof(v17));
v14
=
0
;
memset(v15,
0
, sizeof(v15));
v9
=
0
;
v6
=
0
;
v3
=
0
;
while
( v6 < strlen(a2) )
{
if
( isdigit(a2[v6]) )
{
v8
=
a2[v6]
-
48
;
}
else
if
( isxdigit(a2[v6]) )
{
if
(
*
((_DWORD
*
)NtCurrentPeb()
-
>SubSystemData
+
3
) !
=
2
)
a2[v6]
=
34
;
v8
=
(a2[v6] |
0x20
)
-
87
;
}
else
{
v8
=
((a2[v6] |
0x20
)
-
97
)
%
6
+
10
;
}
__rdtsc();
__rdtsc();
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课