BUUCTF 刮开有奖(特别详细了,尽自己全力理解所写)


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,不仅仅是为了自己以后复习所用,更是为了帮助别人,一起进步吧。

继续加油。

  • 95
    点赞
  • 49
    收藏
    觉得还不错? 一键收藏
  • 48
    评论
评论 48
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值