-
-
[原创]BUUCTF逆向题:[WUSTCTF2020]level3
-
发表于: 2022-3-24 23:13 9984
-
64位,无壳,ELF文件
函数的逻辑很清晰,v6接受输入,但却是随缘进入if判断因为它的进入条件是随机生成的而随机的种子是系统时间,假设进入了if里面,会将输入作为参数调用一个函数(看名字是base64编码),但是编码完后就直接输出,也不进行判断,奇奇怪怪的,这里看一下下方提示:
对不起,我想它还没有准备好....
我从程序中得到一个奇怪的字符串,它不同于标准的base64:
先去在线网站将这个base64编码的字串解密看一下:
发现解码失败,根据上面的提示它说这个字符串不同于标准的base64,这里猜测base64_encode()
这个函数可能不是正常的base64,应该魔改了。
这个函数就是这个程序的base64编码函数,先去看一下它的码表有没有问题:
可以看到码表没什么问题,那就看一下,base64的编码过程有没有问题了。
这里贴一下base64加密的原理:(以“ABC”为例):
修饰后的伪代码:
怎么说呢,这个代码不能说十分正常,只能说是一点毛病没有,到这里我就卡壳了,去百度后发现,这个程序还是换了码表但是它是在运行时动态更换的所以我们在看码表的数据时看不出什么毛病。我们点击码表看他的交叉引用:
可以看到除了base64_encode()
,O_OLookAtYou()
也调用了码表,这时候确实有点无语这个函数名这么奇怪做题时一点没发现,先到O_OLookAtYou()
函数那去看看,因为main函数是没有调用这个函数的,那这个函数是如何做到修改码表的呢?,还是看它的交叉引用:
可以看到函数其实是在init,也就是初始化函数里被调用,我们知道函数的最开始并不是从main开始,start才是函数的真正入口点,这个知识点可以去看程序员的自我修养那本书,对这些东西分析得很透彻。init和start一样都是编译器加进去的,init函数主要负责设置包、初始化变量或其他要在程序运行前优先完成的引导工作。
这里选择直接动调看码表改完后是个啥样:
这里随便下个断点,没啥影响:
直接双击查看码表:
TSRQPONMLKJIHGFEDCBAUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/
上面这一串就是修改后的码表,然后利用新表解base64就行:
wctf2020{Base64_is_the_start_of_reverse}
提交时记得是flag包裹
int
__cdecl main(
int
argc, const char
*
*
argv, const char
*
*
envp)
{
const char
*
v3;
/
/
rax
char v5;
/
/
[rsp
+
Fh] [rbp
-
41h
]
char v6[
56
];
/
/
[rsp
+
10h
] [rbp
-
40h
] BYREF
unsigned __int64 v7;
/
/
[rsp
+
48h
] [rbp
-
8h
]
v7
=
__readfsqword(
0x28u
);
printf(
"Try my base64 program?.....\n>"
);
__isoc99_scanf(
"%20s"
, v6);
v5
=
time(
0LL
);
srand(v5);
if
( (rand() &
1
) !
=
0
)
{
v3
=
(const char
*
)base64_encode(v6);
puts(v3);
puts(
"Is there something wrong?"
);
}
else
{
puts(
"Sorry I think it's not prepared yet...."
);
puts(
"And I get a strange string from my program which is different from the standard base64:"
);
puts(
"d2G0ZjLwHjS7DmOzZAY0X2lzX3CoZV9zdNOydO9vZl9yZXZlcnGlfD=="
);
puts(
"What's wrong??"
);
}
return
0
;
}
int
__cdecl main(
int
argc, const char
*
*
argv, const char
*
*
envp)
{
const char
*
v3;
/
/
rax
char v5;
/
/
[rsp
+
Fh] [rbp
-
41h
]
char v6[
56
];
/
/
[rsp
+
10h
] [rbp
-
40h
] BYREF
unsigned __int64 v7;
/
/
[rsp
+
48h
] [rbp
-
8h
]
v7
=
__readfsqword(
0x28u
);
printf(
"Try my base64 program?.....\n>"
);
__isoc99_scanf(
"%20s"
, v6);
v5
=
time(
0LL
);
srand(v5);
if
( (rand() &
1
) !
=
0
)
{
v3
=
(const char
*
)base64_encode(v6);
puts(v3);
puts(
"Is there something wrong?"
);
}
else
{
puts(
"Sorry I think it's not prepared yet...."
);
puts(
"And I get a strange string from my program which is different from the standard base64:"
);
puts(
"d2G0ZjLwHjS7DmOzZAY0X2lzX3CoZV9zdNOydO9vZl9yZXZlcnGlfD=="
);
puts(
"What's wrong??"
);
}
return
0
;
}
char
*
__fastcall base64_encode(char
*
a1)
{
int
v1;
/
/
eax
int
v2;
/
/
eax
int
v4;
/
/
[rsp
+
1Ch
] [rbp
-
54h
]
int
v5;
/
/
[rsp
+
20h
] [rbp
-
50h
]
int
v6;
/
/
[rsp
+
24h
] [rbp
-
4Ch
]
int
v7;
/
/
[rsp
+
28h
] [rbp
-
48h
]
int
v8;
/
/
[rsp
+
2Ch
] [rbp
-
44h
]
char src[
56
];
/
/
[rsp
+
30h
] [rbp
-
40h
] BYREF
unsigned __int64 v10;
/
/
[rsp
+
68h
] [rbp
-
8h
]
v10
=
__readfsqword(
0x28u
);
v1
=
strlen(a1);
v8
=
v1
%
3
;
v7
=
v1
/
3
;
memset(src,
0
,
0x30uLL
);
v6
=
0
;
v4
=
0
;
v5
=
0
;
while
( v4 < v7 )
{
src[v6]
=
base64_table[a1[v5] >>
2
];
src[v6
+
1
]
=
base64_table[(
16
*
(a1[v5] &
3
)) | (a1[v5
+
1
] >>
4
)];
src[v6
+
2
]
=
base64_table[(
4
*
(a1[v5
+
1
] &
0xF
)) | (a1[v5
+
2
] >>
6
)];
v2
=
v6
+
3
;
v6
+
=
4
;
src[v2]
=
base64_table[a1[v5
+
2
] &
0x3F
];
v5
+
=
3
;
+
+
v4;
}
if
( v8
=
=
1
)
{
src[v6]
=
base64_table[a1[v5] >>
2
];
src[v6
+
1
]
=
base64_table[
16
*
(a1[v5] &
3
)];
strcat(src,
"=="
);
}
else
if
( v8
=
=
2
)
{
src[v6]
=
base64_table[a1[v5] >>
2
];
src[v6
+
1
]
=
base64_table[(
16
*
(a1[v5] &
3
)) | (a1[v5
+
1
] >>
4
)];
src[v6
+
2
]
=
base64_table[
4
*
(a1[v5
+
1
] &
0xF
)];
src[v6
+
3
]
=
61
;
}
strcpy(a1, src);
return
a1;
}
char
*
__fastcall base64_encode(char
*
a1)
{
int
v1;
/
/
eax
int
v2;
/
/
eax
int
v4;
/
/
[rsp
+
1Ch
] [rbp
-
54h
]
int
v5;
/
/
[rsp
+
20h
] [rbp
-
50h
]
int
v6;
/
/
[rsp
+
24h
] [rbp
-
4Ch
]
int
v7;
/
/
[rsp
+
28h
] [rbp
-
48h
]
int
v8;
/
/
[rsp
+
2Ch
] [rbp
-
44h
]
char src[
56
];
/
/
[rsp
+
30h
] [rbp
-
40h
] BYREF
unsigned __int64 v10;
/
/
[rsp
+
68h
] [rbp
-
8h
]
v10
=
__readfsqword(
0x28u
);
v1
=
strlen(a1);
v8
=
v1
%
3
;
v7
=
v1
/
3
;
memset(src,
0
,
0x30uLL
);
v6
=
0
;
v4
=
0
;
v5
=
0
;
while
( v4 < v7 )
{
src[v6]
=
base64_table[a1[v5] >>
2
];
src[v6
+
1
]
=
base64_table[(
16
*
(a1[v5] &
3
)) | (a1[v5
+
1
] >>
4
)];
src[v6
+
2
]
=
base64_table[(
4
*
(a1[v5
+
1
] &
0xF
)) | (a1[v5
+
2
] >>
6
)];
v2
=
v6
+
3
;
v6
+
=
4
;
src[v2]
=
base64_table[a1[v5
+
2
] &
0x3F
];
v5
+
=
3
;
+
+
v4;
}
if
( v8
=
=
1
)
{
src[v6]
=
base64_table[a1[v5] >>
2
];
src[v6
+
1
]
=
base64_table[
16
*
(a1[v5] &
3
)];
strcat(src,
"=="
);
}
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!
赞赏
- 关于迷宫题的一些求解思路 11224
- [原创]攻防世界PWN新手区:int_overflow 7860
- [原创]攻防世界PWN新手区:guess_num 11574
- [原创]攻防世界PWN新手区:level2 11850
- [原创]攻防世界PWN新手区:level0 6145