title: BUUCTF 刮开有奖 date: 2021年8月13日 15点23分 tags: BUUCTF categories: BUUCTF
自己的心声(痛骂wp抄袭狗)
这道题,其实有点坑,对于目前的我来说,还是有点难度的。
在复盘之前,我想对网上一些直接抄袭别人文章的人说,可真tm不要脸啊。你若跟着别人的wp,把题做出来了,自己跟着软件啥的,实验成功之后,写一篇wp啊,抄袭别人的。主要tm一个字不改,也不说是抄袭的。
本来做题没思路了,做不下去了,想看一篇高质量的wp,跟着大佬学一学,百度一下。
就这几篇,全是一模一样一个字不差,图片也是如此,都不知道原创是谁,观看了一波,在一篇文章下,有师傅问,为什么伪代码里有+4,而在把伪代码写成c语言之后,就没有了,博主没有对此解答。我也是有此疑惑,百度不出来,最后是问了一手工作室的好哥哥,才得以解惑。
你说你要抄袭wp,好歹抄袭一篇高质量的wp,思路清晰的抄袭吧,这nm不明不白的就得到flag的wp,也抄袭,而且抄袭的人还很多,就nm无语。
当然在众多抄袭狗,还是有很多好的wp,本人的思路就来自于某一篇博客。
BUUCTF_刮开有奖_ZYen12138的博客-CSDN博客
不知道这篇文章,博主是不是原创,但是目前好像没发现跟他一样的。在此敬礼,感谢大佬的wp,让小子在毫无头绪的情况下,有点思路,学习了很多。
复盘分析
1、打开EXE文件
下载题目之后,打开题目,发现没有什么用,点击这个界面,也是没有效果。
2、拖入PE查看
发现是32位的。
3、IDApro
(1)shift + F12查看字符串窗口
可以看到一串字符,有点可疑,跟进。
(2)ctrl + x 交叉引用
(3)F5反编译
找到关键的伪代码。
(4)还有一个方法就是直接找到main函数进入
根据之前的经验,这个界面可再熟悉不过,DialogFunc函数,也是看到过多次,直接跟进这个函数便可。
(5)分析伪代码
这里前面的这些代码,是初始化,根据之前的经验,memset函数就是初始化的。
(6)找到字符串加密函数
看到这里,String,应该是我们要的flag,flag = 8.,也就是有8个字符了。
看到这里有10个字符,,但是还有一个函数sub_4010F0,跟进去看看。
很显然,这个函数会把这已知的10个字符,加密成其他的,这里我们直接把伪代码换为C语言代码,运行就能得到新的加密字符是什么。
#include <stdio.h>
int sub_4010F0(char* a1, int a2, int a3)
{
int result; // eax
int i; // esi
int v5; // ecx
int v6; // edx
result = a3;
for ( i = a2; i <= a3; a2 = i )
{
v5 = i;
v6 = i[a1];
if ( a2 < result && i < result )
{
do
{
if ( v6 > a1[result])
{
if ( i >= result )
break;
++i;
a1[v5] = a1[result];
if ( i >= result )
break;
while ( a1[i] <= v6 )
{
if ( ++i >= result )
goto LABEL_13;
}
if ( i >= result )
break;
v5 = i;
a1[result] = a1[i];
}
--result;
}
while ( i < result );
}
LABEL_13:
a1[result] = v6 ;
sub_4010F0(a1, a2, i - 1);
result = a3;
++i;
}
return result;
}
int main()
{
char str[] = "ZJSECaNH3ng";
sub_4010F0(str,0,10);
printf("%s", str);
return 0;
}
(7)解惑,伪代码跟C语言代码
在这里,我相信大家应该都会有一丝疑惑,我们可以看到,在伪代码中,有a1+ 4 * i,a1+4 *result,这样的字符。但是在C语言代码中,为什么没有了。
我也是有疑惑,在百度之后,也是没有效果,最后问了好哥哥,才得以解惑。
int占四个字节,所以需要*4.如果是char类型,就不需要.
在这里,我也是找到一点资料。百度一下数组寻址公式。
从这里,我们知道a1+4*i,也就是a1【i】,a1+4 * result,也就是a1【result】。
将伪代码的寻址方式改为数组寻址,然后将*(_DWORD*) 删掉,因为这是汇编的表示。
所以伪代码变成了C语言代码。
(8)运行c语言代码
3CEHJNSZagn
得到加密之后的字符。继续分析
(9)base64加密
在这里,可以看到,v4,v5 = sub_401000,跟进看看。
发现也是一串代码,但是很复杂,看到这里有一个byte_407830函数,跟进看看。
推测是将,v4 = ak1w,v5 = V1Ax,两个字符串base64加密。
加密之后,v4 = jMp,v5 = WP1.
(10)最后分析if语句,得到flag
最后,我们看到最后的if语句,
第一句:String[0] == v7[0] + 34,这里的v7【0】,就是上面10个字符的第一个字符,我们通过加密函数之后,v7【0】由一开始的Z变成了,v7【0】 = 3.
3的ASCII码是51,51 + 34 = 85,85ASCII码对应的是大写的 U。flag第一个字符得到。
第二句:String[1] == v10,v10在之前没加密的时候,是排第五位,我们看看加密之后的第五位是谁,3CEHJNSZagn,可以看到,加密之后的第五位是 J。flag第二个字符得到。
第三句:4 * String[2] - 141 == 3 * v8,v8在没加密之前,是排第三位,先看看加密之后的第三位是谁,可以看到是E,E的ASCII码是69,所以3*69 + 141 / 4 = 87 ,ASCII为W,flag第三个字符得到。
第四句:String[3] / 4 == 2 * (v13 / 9),看到v13没加密之前排到数第四位,看看加密之后的到数第四位是谁,是Z,Z的ASCII是90,所以2*(90/9)*4 = 80 ,ASCII为P,flag第四个字符得到。
后面四个字符,就是base64加密的那几个,可以看到第三第四字符已经是WP了,说明,WP1在前,jMp在后。
将他们拼接在一起,得到,UJWP1jMp。
带上flag{},得到flag{UJWP1jMp}。
总结
做题的时候,还是要小心小心再小心的观察伪代码,稍微漏了一个函数,就解不出来了。这道题的两个最关键函数,一个是那个对十个字符加密的函数。一个是base64加密的那个函数。一开始分析加密函数的时候,对于伪代码写成C语言代码,还是有点懵的,在观看大佬的wp之后,有了一点思路,特别是伪代码中的那个+ 4,这个东西,一开始直接跟着复制了,没修改,导致加密出来的字符不对。
对base64加密,还没有非常敏锐的直觉,其实在查看字符串窗口的时候,就看到了那一串类似base64加密的字符串,但是没太注意,下次若是再碰见,就可以直接推测一波有base64加密了,便在伪代码中,好好寻找。 写好的wp,不仅仅是为了自己以后复习所用,更是为了帮助别人,一起进步吧。
继续加油。
|