楚慧杯PWN、RE、Crypto与Misc部分题解
字数 3902
更新时间 2026-03-18 13:50:38

CTF逆向工程与漏洞利用(PWN)基础与实例教学文档

——基于“楚慧杯”赛题解析的实战分析

一、 文档来源

本教学文档内容基于“楚慧杯PWN、RE、Crypto与Misc部分题解”技术文章(发布于先知社区,2026年3月12日)进行归纳、提炼与系统化整理,旨在提供一套结构化的攻防技术学习路径。

二、 前言与背景

本文档面向具备一定计算机安全基础的学习者。所涉及的CTF(Capture The Flag)竞赛题目涵盖了二进制漏洞利用(PWN)、逆向工程(RE)、密码学(Crypto)与杂项(Misc)四大常见方向。通过剖析具体赛题的解题思路,我们将深入理解相关漏洞原理、逆向分析方法和自动化利用脚本的编写。


三、 二进制漏洞利用(PWN)篇

3.1 题目:house_1

  • 目标程序概况:保护全开(Canary, NX, PIE等),使用libc 2.31。
  • 漏洞类型:格式化字符串漏洞(Format String Vulnerability)。
  • 核心利用思路
    1. 信息泄露:利用格式化字符串漏洞泄露出栈上的libc地址与程序基址。解题脚本通过%21$p%26$p两个格式化参数分别获取了关键地址。
    2. 计算关键地址:根据泄露的地址,计算出libc_base(libc基址)、程序base(程序基址)以及目标hook函数__malloc_hook的地址。
    3. 定位one_gadget:在libc中寻找一个能直接启动shell的代码片段(one_gadget),其地址为libc_base + 0xe3b01
    4. 覆盖hook函数:利用格式化字符串写(fmtstr_payload)能力,分步(因每次写入2字节)将__malloc_hook函数的地址覆盖为one_gadget的地址。
    5. 触发执行:通过调用触发malloc的函数(题目中发送选项b'1')来执行__malloc_hook,进而执行one_gadget获取shell。
  • 替代方案(ROP):文档提及还可通过read函数中的全局变量漏洞构造ROP链进行利用,该方法更为简单。
  • 关键脚本函数
    • fmtstr_payload(offset, writes, write_size='short'):生成格式化字符串攻击载荷。
    • fmt_write(addr, value):自定义函数,用于向指定地址写入指定值。

四、 逆向工程(RE)篇

4.1 题目:眼见为虚_1

  • 初步分析:遇到此类题目,逆向手应优先考虑TLS回调或代码自修改(SMC)技术。本题检查TLS回调未发现逻辑。
  • 核心逻辑
    1. 主函数分析:主函数逻辑简单,关键在key_create部分。
    2. C++虚表调用:程序通过构造C++类的虚表(vtable),动态调用加密函数。这是一个典型的利用C++多态性进行代码混淆的例子。
    3. 双阶段加密
      • 阶段一(sub_402A18):一个魔改的TEA加密算法。与标准TEA的区别在于,本轮的delta(或s)是累加的(s = s + 0xDEADBEEF),而非使用固定的0x9E3779B9常数轮换。加密对象是输入的statev0, v1)。
      • 阶段二(sub_402AFC):将第一阶段产生的state(作为Mask)与输入数据进行异或处理。
  • 逆向解密步骤
    1. 逆向实现魔改TEA算法,使用相同的key和初始v0v1,运行32轮,得到Mask
    2. Mask与密文(题目中硬编码的10个dword常量)进行异或,得到原始flag
  • 关键Python还原代码:文档提供了完整的逆向解密脚本,核心是模拟加密过程的反向运算。

4.2 题目:eazy_code-new

  • 文件类型:PowerShell脚本,经过深度混淆。
  • 混淆分析
    1. 变量名混淆:使用特殊字符和数字作为变量名(如${-``}, ${$%}, ${``*%})。
    2. 数字映射:混淆脚本将数字0-9映射到这些特殊变量名。
    3. 字符拼接${$%}被拼接成[char],用于将数字转换为ASCII字符,从而还原出真实的代码逻辑。
  • 核心逻辑还原:去除混淆后,可发现脚本包含一个e()函数,该函数是TEA系列加密算法(可能是XXTEA)。密文是硬编码的数组ans
  • 解密方法:编写逆向的TEA解密函数(decrypt)。算法使用固定的DELTAKEY,对密文ans进行解密,将得到的4个uint32按小端序拼接成字节串,即可得到flag明文:yOUar3g0oD@tPw5H

五、 密码学(Crypto)篇

5.1 题目:Flip

  • 问题模型:一个类DSA的签名方案,但在模p下运算。已知多组签名对(r_i, s_i),以及flag的每个字节y_m取值范围很小(0-7),目标是恢复flag
  • 攻击方法格基规约攻击(Lattice Reduction Attack)
  • 攻击步骤
    1. 消元:利用第一组签名(r0, s0)的方程,将未知的私钥d表示为另一个未知数k0的函数,从而在后续方程中消去d
    2. 建立线性关系:将关于k_ik_0的模方程转化为整数域上的方程,并引入小误差变量z_m= y_m - 3,将取值范围[0,7]平移到[-3, 4])。
    3. 构造格(Lattice):构建一个包含所有小变量z_i,m和模数进位项的矩阵。这个格中的一个短向量就对应了满足所有方程的正确解。
    4. 规约求解:对构造的格应用LLL算法进行规约,在规约后的基向量中即可找到flag的各个字节y_m,从而拼接出完整flag
  • 关键点:将密码学问题转化为寻找格中短向量的问题,利用y_m值域很小的特点构造可行解。

5.2 题目:GCD,杠上了

  • 问题模型:已知多个数x_i = p * q_i + e_i,其中p是大素数,q_i是大整数,e_i是相对很小的误差。目标是恢复p
  • 攻击方法正交格攻击(Orthogonal Lattice Attack)
  • 攻击原理
    1. 寻找一组整数系数c_i,使得线性组合∑c_i * x_i = 0。由于x_i的表达式,可得 p * ∑c_i * q_i + ∑c_i * e_i = 0
    2. 由于p很大而e_i很小,要使得上式成立,很可能同时满足 ∑c_i * q_i = 0∑c_i * e_i = 0。这意味着系数向量c与向量q正交。
    3. 构造格:构造一个以x_i和放大因子N组成的矩阵,进行LLL规约。规约后得到的前k-1个短向量就近似是所需的c向量。
    4. 恢复q:这些c向量张成的空间与q向量正交。通过计算这些c向量矩阵的右零空间(Right Kernel),其基向量就是q_i向量的倍数。
    5. 恢复p:得到q_0后,计算p = round(x_0 / q_0),即可利用四舍五入消除小误差e_0,得到精确的p

六、 杂项(Misc)篇

6.1 题目:go-gane

  • 文件分析:给定的exe是一个自解压程序,内含另一个可执行文件和一个CAB压缩包。
  • 提取过程
    1. 使用十六进制编辑器(如010 Editor)查找CAB文件头标志MSCF,将其之后的数据提取为payload.cab
    2. 解压CAB文件,得到游戏资源文件。
  • 游戏类型识别:通过文件目录结构(如GraphicsAudio等)和文件后缀(.rvdata2),识别出该游戏由RPG Maker VX Ace引擎制作。
  • .rvdata2文件:本质是Ruby的Marshal序列化格式存储的游戏数据。
    • MapXXX.rvdata2:存储地图事件,可能隐藏提示和逻辑。
    • Scripts.rvdata2:存储游戏脚本,可能包含自定义逻辑。
    • Weapons.rvdata2/Items.rvdata2等:存储游戏数据库,常直接包含字符串信息。
  • 获取Flag
    1. 后半部分:通过实际运行游戏并退出,可直接在游戏界面获得flag的后半段(一个类似UUID的字符串)。
    2. 前半部分
      • 方法一(Fuzzing):使用字符串搜索工具(如strings)或十六进制编辑器直接搜索Data/Weapons.rvdata2等数据文件,发现了flag的前半部分。
      • 方法二(Ruby脚本解析):使用Ruby的Marshal.load函数直接反序列化.rvdata2文件,查看其数据结构,从而定位到flag。
  • 最终Flag:将前后两部分拼接,得到完整的Flag:DASCTF{1168cb17-31ff-43b7--b586-8414d383afce}

文档未详述此点,但基于我所掌握的知识:本文档中涉及的漏洞利用(如格式化字符串)、逆向分析(TEA算法、PowerShell去混淆)、密码学攻击(格基规约、正交格攻击)以及文件格式分析(RPG Maker)均为CTF竞赛和实战安全研究中的经典技能点。深入理解并实践这些案例,对构建二进制安全和密码学分析能力至关重要。建议学习者结合提供的脚本代码,在隔离的实验环境中复现整个流程。

相似文章
相似文章
 全屏