查壳,64位
找main函数,F5查看伪代码,简单分析一下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
int
__cdecl main(
int
argc,
const
char
**argv,
const
char
**envp)
{
int
v4;
// [rsp+24h] [rbp-44h] BYREF
void
*Buf1;
// [rsp+28h] [rbp-40h] BYREF
char
v6[56];
// [rsp+30h] [rbp-38h] BYREF
sub_401770(argc, argv, envp);
printf
(
"please input the flag:"
);
scanf
(
"%s"
, v6);
// v6是flag
Buf1 = 0i64;
// 初始化Buf1
sub_401570(v6, &Buf1, &v4);
// v6进行base64编码,但是不是根据A-Z,...,而是根据这串字符编码qvEJAfHmUYjBac+u8Ph5n9Od17FrICL/X0gVtM4Qk6T2z3wNSsyoebilxWKGZpRD
if
( !
memcmp
(Buf1, a5mc58bphliax7j, v4) )
// 对这串字符串"5Mc58bPHLiAx7J8ocJIlaVUxaJvMcoYMaoPMaOfg15c475tscHfM/8=="进行微改变的base64解码,即得flag
printf
(
"\nsuccess!"
);
else
printf
(
"\nfailed!"
);
if
( Buf1 )
free
(Buf1);
return
0;
}
|
v6是flag,经过sub_401570函数加密,得到a5mc58bphliax7j
对应的加密后的值,即加密后的flag值
这里的重点就是sub_401570函数,我们需要了解经过怎么样的加密,接下来我们点进去看看
sub_401570函数
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
|
__int64
__fastcall sub_401570(
const
char
*a1, _QWORD *a2,
int
*a3)
{
int
v6;
// r15d
int
v7;
// r12d
int
v8;
// r13d
__int64
v9;
// r14
_BYTE *v10;
// rax
_BYTE *v11;
// r9
__int64
v12;
// r8
char
v13;
// cl
char
v14;
// r11
char
v15;
// r10
__int64
result;
// rax
v6 =
strlen
(a1);
v7 = v6 % 3;
if
( v6 % 3 )
{
v8 = 4 * (v6 / 3) + 4;
v9 = v8;
v10 =
malloc
(v8 + 1i64);
v10[v8] = 0;
if
( v6 <= 0 )
goto
LABEL_5;
}
else
{
v8 = 4 * (v6 / 3);
v9 = v8;
v10 =
malloc
(v8 + 1i64);
v10[v8] = 0;
if
( v6 <= 0 )
goto
LABEL_8;
}
v11 = v10;
v12 = 0i64;
do
{
v11 += 4;
v13 = a1[v12];
*(v11 - 4) = aQvejafhmuyjbac[v13 >> 2];
v14 = a1[v12 + 1];
*(v11 - 3) = aQvejafhmuyjbac[(v14 >> 4) | (16 * v13) & 0x30];
v15 = a1[v12 + 2];
v12 += 3i64;
*(v11 - 2) = aQvejafhmuyjbac[(v15 >> 6) | (4 * v14) & 0x3C];
*(v11 - 1) = aQvejafhmuyjbac[v15 & 0x3F];
}
while
( v6 > (
int
)v12 );
LABEL_5:
if
( v7 == 1 )
{
v10[v9 - 2] = 61;
v10[v9 - 1] = 61;
}
else
if
( v7 == 2 )
{
v10[v9 - 1] = 61;
}
LABEL_8:
*a2 = v10;
result = 0i64;
*a3 = v8;
return
result;
}
|
看不懂不要紧,为了这个,我专门用一天时间消化base64编码与解码的原理,链接如下:
看完,就能对base64原理了解的八九不离十了
这段代码一看移位运算,或运算,与运算,与base64编码一样,只不过base64是根据ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/
编码,而这里修改为aQvejafhmuyjbac
对应的字符串
双击进入,知道这个base64是根据这串字符串编码的qvEJAfHmUYjBac+u8Ph5n9Od17FrICL/X0gVtM4Qk6T2z3wNSsyoebilxWKGZpRD
,而不是ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/
知道原理了,返回main函数
简单捋一下,就是将flag进行变异的base64编码,编码结果为a5mc58bphliax7j
对应的数据,即5Mc58bPHLiAx7J8ocJIlaVUxaJvMcoYMaoPMaOfg15c475tscHfM/8==
写出源码
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
|
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
char
base64CharsArr[] =
"qvEJAfHmUYjBac+u8Ph5n9Od17FrICL/X0gVtM4Qk6T2z3wNSsyoebilxWKGZpRD"
;
void
base64decode(
char
str[]) {
int
length =
strlen
(str);
int
padding = 0;
// 计算填充字符数量
if
(str[length - 1] ==
'='
) {
padding++;
if
(str[length - 2] ==
'='
)
padding++;
}
// 计算解码后的字符数量
int
decodedLength = (length * 3) / 4 - padding;
// 分配存储解码结果的内存
char
* decodedStr = (
char
*)
malloc
(decodedLength + 1);
int
outIndex = 0;
for
(
int
i = 0; i < length; i += 4) {
char
char1 = -1, char2 = -1, char3 = -1, char4 = -1;
// 查找每个字符在Base64字符集中的索引
for
(
int
j = 0; j < 64; j++) {
if
(base64CharsArr[j] == str[i]) {
char1 = j;
break
;
}
}
for
(
int
j = 0; j < 64; j++) {
if
(base64CharsArr[j] == str[i + 1]) {
char2 = j;
break
;
}
}
for
(
int
j = 0; j < 64; j++) {
if
(base64CharsArr[j] == str[i + 2]) {
char3 = j;
break
;
}
}
for
(
int
j = 0; j < 64; j++) {
if
(base64CharsArr[j] == str[i + 3]) {
char4 = j;
break
;
}
}
// 解码并存储结果
decodedStr[outIndex++] = (char1 << 2) | ((char2 & 0x30) >> 4);
if
(char3 != -1)
decodedStr[outIndex++] = ((char2 & 0xf) << 4) | ((char3 & 0x3c) >> 2);
if
(char4 != -1)
decodedStr[outIndex++] = ((char3 & 0x3) << 6) | char4;
}
// 添加字符串结束符
decodedStr[decodedLength] =
'\0'
;
printf
(
"Decoded string: %s\n"
, decodedStr);
// 释放内存
free
(decodedStr);
}
int
main() {
char
str[100]=
"5Mc58bPHLiAx7J8ocJIlaVUxaJvMcoYMaoPMaOfg15c475tscHfM/8=="
;
// Example base64 encoded string
base64decode(str);
return
0;
}
|
flag:NSSCTF{a8d4347722800e72e34e1aba3fe914ae}
更多【[HUBUCTF 2022 新生赛]simple_RE】相关视频教程:www.yxfzedu.com