RE | BUUCTF 刮开有奖1

本文详细解析了如何通过分析C函数和字符串操作来解密BUUCTF比赛中的一个挑战,包括理解魔改函数、构造满足条件的字符串(flag),以及应用Base64解码技术。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目:BUUCTF 刮开有奖1
参考:
BUUCTF 刮开有奖(特别详细了,尽自己全力理解所写)(这是主参考,写得很详细
BUUCTF_刮开有奖(主参考的参考,思路很清晰

我是大菜鸡…尽力写自己的理解了,哪里有不对的希望指正


主函数分析

首先查壳无壳32位,ida32打开,看字符串
有一个疑似u get it的东东
在这里插入图片描述点进去,看这个DialogFunc函数(好眼熟的函数名
在这里插入图片描述
分析一下
首先获取了一个string,并且string长度为8
一系列的赋值,后面是不知道干嘛的函数,疑似对v7这一串进行了魔改,而且v7以及后面一串赋值都在char范围内,后边又传参v7,怀疑是(隔开放的?)char数组
在这里插入图片描述然后把string的一部分赋给v18,然后v4、v5由v8魔改而来
在这里插入图片描述最后对string和v7进行一系列比较,对v4、v5加限制,条件全部满足就输出u get it
在这里插入图片描述现在就比较明朗了,我们要构造一个string满足最后的所有条件,就是flag(大概吧


把魔改后的v7搞出来

我一看这种函数就头疼…看不懂一点…看别人的题解才发觉,其实不用看懂啊,你c语言复现一下不就行了!!

注意点:

  1. v7 int数组改char,删掉所有DWORD
  2. *(a1 + 4 * i)这种要改成a1[i],因为ida中定义的是int数组,int占四个字节,而我们改成char数组了,char只占一个字节,还用*(a1 + 4 * i)就会变成a1[4*i]
  3. 见代码注释,有一个*(a1 + v5)要改成a1[v5 / 4](其实好像和i还是有关联的但是我懒得看了
#include <vector>
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;

typedef long long ll;
const int N = 1e5 + 5;

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 = 4 * i;
    v6 = a1[i];
    //v6 = i[a1];
    if ( a2 < result && i < result )
    {
      do
      {
        if ( v6 > a1[result] )
        {
          if ( i >= result )
            break;
          ++i;
          //特别注意这里,写a1[i] = a1[result]是不行的,因为v5和现在的i*4已经不相等了
          a1[v5 / 4] = a1[result];
          if ( i >= result )
            break;
          while ( a1[i] <= v6 )
          {
            if ( ++i >= result )
              goto LABEL_13;
          }
          if ( i >= result )
            break;
          v5 = 4 * 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 v7[] = {90,74,83,69,67,97,78,72,51,110, 103};
	
    sub_4010F0(v7, 0, 10);
    cout << v7 << endl;
	return 0;
}

得到3CEHJNSZagn
在这里插入图片描述


拼出flag

(把string改名flag了)已知:

在这里插入图片描述前几行只涉及flag和v7数组,我们已经知道了,可以直接得到flag前几位
在之前求v7的代码后边加上几行:

str[0] = v7[0] + 34;
str[1] = v7[4];
str[2] = (char)((int)(3 * v7[2] + 141) / 4);
str[3] = 2 * (v7[7] / 9) * 4;
cout << str << endl;

得到flag[0-3] = UJWP在这里插入图片描述后两行要求v4=ak1w,v5=V1Ax
再看前面,v4v5都是从flag中截取一部分,再经过sub_401000函数得到
在这里插入图片描述看看这个函数
在这里插入图片描述看看这个byte_407830,char数组,大小写字幕数字和=
在这里插入图片描述再加上v4v5原本长度是4,处理完确只用了三个
合理怀疑是base64(?
找个网站解码
在这里插入图片描述得到

v4:ak1w <- jMp
v5:V1Ax <- WP1

再根据v18和flag的对应关系

//v18: jMp
v18[0] = flag[5];
v18[2] = flag[7];
v18[1] = flag[6];
//v18: WP1
v18[1] = flag[3];
v18[0] = flag[2];
v18[2] = flag[4];

得出flag[5-7] = jMpflag[2-4] = WP1
最终flag数组就是UJWP1jMp
(话说这里解出flag的2-7,跟前面与v7比较得到的flag0-3有重合啊怎么回事,虽然是一样的)

过了
在这里插入图片描述


感觉学会了很多又好像没学会…

### BUUCTF Reserve 刮开有奖 活动详情 BUUCTF 是一项专注于网络安全技术的在线竞赛平台,其目标是通过各种挑战来提升参赛者的技能水平。其中,“reserve 刮开有奖”活动属于一种特定类型的解密或逆向工程题目设计。 #### 关于刮开有奖的核心机制 在提到的“刮开有奖”活动中,通常会涉及一些基础编码技巧以及字符串处理相关内容。例如,在某些情况下,可能需要解析隐藏数据或者理解程序内部逻辑以获取最终答案。这里提到了一个 flag 的形式 `flag{1999902069a45792d233ac}`[^1],这表明该活动的结果是以标准 CTF Flag 格式呈现出来的。 另外还提及了一个关于字符数组的重要知识点:当使用 strlen 函数测量长度时如果未正确终止零(`\0`)则可能导致不可预测的行为[^2]。这种特性可以被利用作为谜题的一部分, 参赛者需仔细分析源码并找出潜在漏洞才能成功完成任务。 #### 技术细节说明 对于此类CTF题目解答过程中的关键技术点如下: - **Flag格式识别**: 认识到最终提交的答案遵循`flag{...}`这样的结构化模式是非常重要的第一步。 - **C语言基础知识应用**: 掌握像`strlen()`这样常见库函数的工作原理及其局限性有助于快速定位问题所在之处。 - **逆向思维能力培养**: 学习如何从已知现象反推出背后运行机理也是解决这类复杂难题的关键要素之一。 ```c #include <stdio.h> #include <string.h> int main() { char arr[] = {'a','b','c','d','e'}; // No '\0' printf("%lu\n", strlen(arr)); // Output is undefined behavior. } ``` 上述代码片段展示了如果没有给定适当结束符`\0`,调用`strlen()`将会产生不确定行为的情况。 ### 结论 综上所述,“BUUCTF reserve 刮开有奖”的具体实现方式可能会围绕着对字符串操作的理解展开,特别是针对那些容易忽视却至关重要的细节部分——比如忘记添加串尾标记所引发的一系列连锁反应等问题。希望以上信息能够帮助您更好地准备参加这项有趣的赛事!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值