CTF-竞赛之re简介(小白手搓版)

CTF-竞赛之re简介(小白手搓版)

 次点击
116 分钟阅读

CTF Reverse(逆向)题目类型全景图:从 🟢 签到 到 ⚫ 地狱

一句话本质:逆向不是"看懂每一行汇编",而是——确认程序类型/保护 → 定位关键逻辑(验证/加密/计算)→ 把它翻译成你能重放的逆运算(或干脆 Patch 跳过它)


🧰 前置准备(先把环境焊死)

类别

工具

什么时候用

查壳/查文件类型

file、Detect It Easy(DIE)、ExeinfoPE

第一件事:什么平台?多少位?有没有壳/混淆?

静态分析主力

IDA Pro(F5伪代码)、Ghidra(免费全能)、Radare2/Cutter

不运行程序,先"看结构/流程/字符串/交叉引用"

动态调试

x64dbg / OllyDbg(Windows)、GDB + pwndbg/gef(Linux)、WinDbg

运行时看寄存器/内存/跳转,验证你的静态猜测

辅助/编辑

010 Editor / HxD、Binwalk、Strings、objdump/readelf

看文件格式、提取嵌在数据段的东西

脚本还原

Python(struct / z3 / cryptography)+ Capstone/Keystone(进阶)

把"正向加密/变换"写成逆向脚本算 flag

动态插桩(中后期)

Frida、QBDI(偏高级)

当静态看不清/反调试恶心时,直接 Hook 取值

新手最短路径:IDA(或Ghidra)静态看伪代码 + x64dbg/GDB动态验证,两个配合就够打到大量入门~中级题。


🟢 Level 1 — 签到 / 信息收集逆向(最快拿分,先做这些)

和 Web 一样,逆向也有"根本不用真·逆向"的送分题:

题型

为什么简单

你该怎么做

字符串里直接藏 flag

flag{...}明文躺在 .rodata/ 资源段

IDA → Shift+F12​ 字符串窗口 → 搜 flag{/ correct/ wrong/ good

无壳、逻辑一眼看完

主函数里就是把输入和固定数组逐字节比对

把数组抄出来 → 按伪代码里的变换(±//xor/位移)逆着算一遍*就行

Patch 过校验(打补丁)

关键跳转 jnz/je决定成败

x64dbg:找到 je/jne→ 改成 jmp(或直接改 ZF)→ 让它走到成功分支,程序自己吐 flag

资源/常量泄漏

flag 编进图标、对话框资源、字符串表、甚至图片资源

ResourceHacker、strings、binwalk 扫一遍

📚 练手平台:Bugku Reverse 新手区 / CTFshow Reverse / 攻防世界「新手 Reverse」/ 简单 crackme on Crackmes.one


🟡 Level 2 — 经典"加密/变换还原"题(新手→初级核心,⭐⭐)

CTF Wiki 与多数 WriteUp 的共识:新手 Reverse 里最大头就是"字符串异或/移位/替换 + 简单算法逆向"

① 异或 / 加减 / 位移 / 查表替换(出现率极高)

典型伪代码模式:

// 正向
enc[i] = (input[i] ^ key[i]) + 3;
// 或
enc[i] = input[i] + key[i];
// 或替换表: out[i] = table[ input[i] ]

你要做的只有一件事:把正向公式写反

模式

逆向操作

enc[i] = input[i] ^ k

input[i] = enc[i] ^ k(xor 自逆)

enc[i] = input[i] + k

input[i] = enc[i] - k

`enc[i] = (input[i] << 1)

(input[i] >> 7)`

替换表

建反查表:orig = inv_table[enc[i]]

关键训练:看到 for+ ^/ +/ <</ 数组下标 → 先假设"逐字节可逆",直接抄目标密文数组 + key 写 Python 还原。

② Base64 / Hex / 自定义编码链

考法

对策

标准 Base64 后再比较

直接 Base64-decode 目标串,再看剩下是什么

魔改 Base64 表

从代码里把 alphabet​ 抄出来,换表解码

多层编码:hex → b64 → xor

顺着伪代码从外往里拆(或从后往前逆)

③ 简单"算法验证":CRC/哈希咆哮、查表校验和

  • 常见到「看起来像 CRC32/简单 Checksum」

  • 先别硬证明:搜常量特征(多项式)或用 angr / z3​ 暴力约束(中级手法,先标记)

📚 靶场:CTFHub 逆向入门 / BUUCTF 搜"reverse 签到/ XOR / easy" / ReversingHero


🟠 Level 3 — 中级:加壳·脱壳·反调试·混淆·跨语言(初级→中级分水岭,⭐⭐⭐)

④ 加壳与脱壳(这里开始"程序不能直接 F5")

第一反应永远一样:DIE/ExeinfoPE 先看壳 → 再决定要不要脱。

壳/压缩

国赛/常规赛出现率

处理方式

UPX(最常见)

⭐ 占大头

直接 upx -d xxx一键脱;失败就用 ESP 定律/内存 dump + IAT修复​ 手动脱

ASPack / FSG

中等(尤其 64 位压轴爱出)

专用脱壳脚本/手动定位 OEP → dump → 修 IAT

VMProtect / Themida(强壳)

偏高分题 / AWD 风格

一般不指望"完美脱壳",更多靠 动态Trace、符号执行、Hook、差分分析​ 抠关键比较值

通用口诀:壳 ≠ 不可做。很多题的"加壳"只是压缩壳(UPX),一脱完里面就是 Level 2 的异或/比对题。

⑤ 反调试 / 反-VM / 花指令

技术

你怎么认出来

怎么对付

IsDebuggerPresent/ PEB.BeingDebugged

调用一目了然

Patch 返回值 AL=0 / 用 ScyllaHide / x64dbg 插件

时间差 rdtsc

连续 rdtsc 差值判断

断点跳过或 nop 掉检测块

硬件断点检测 / 代码校验和

在关键区段扫 hash

找准检测函数 → retn 直接跳过(Patch)

花指令(junk bytes 让反汇编错位)

IDA 里满屏 db ??、控制流碎

手动 C(code)/U(undefined) 修正;更狠的用反混淆脚本/插件

⑥ 控制流平坦化(OLLVM 等)

  • 特征:switch-case 状态机、一大张扁平化 CFG、很难直接读

  • 应对三档:

    1. 先找最终比较/目标数组:有时不需要还原全部 CFG,直接跟踪"最终那个 memcmp 的两个 buffer"就能拿答案

    2. 符号执行轻量用:angr 把路径约束出来取 flag(偏脚本流)

    3. 反混淆插件/IDA d810 之类(进阶)

⑦ 跨语言/跨架构入门

类型

为什么突然变烦

要点

Python 打包(PyInstaller / pyc)

拿到的不是原生 ELF/PE,而是 Python bytecode

pycdc/uncompyle6 反编译 .pyc→ 读源码更直接

Go 二进制

符号多但名字奇怪、runtime 噪音大

r2 -A/ Ghidra 的 Go 辅助脚本;重点搜字符串 + 看 main.*

.NET (C#)

IL 而不是 native asm

dnSpy / ILSpy 直接反编译到 C#(往往是最快的逆向之一)

ARM/ARM64(Android 相关)

指令集变了

先抓:ELF 结构不变,只是汇编是 ARM;重点学 BL/LDR/STR/调用约定

📚 此阶段刷题:BUUCTF Reverse 2~4星 / CTFshow 进阶 / Flare-On(偏真实 malware 风格但极练本事)/ picoCTF Reverse 中高


🔴 Level 4 — 进阶:VM·算法识别·符号约束·移动端(中级→进阶,⭐⭐⭐⭐)

⑧ 自定义 VM(字节码解释器)

题目会写一个小型"虚拟机":自己定义 opcode → fetch-decode-execute 循环。

解法是:

  1. opcode 含义​ 翻译成人类语言(add/sub/xor/load/store…)

  2. bytecode​ 提取出来

  3. 要么:手写解释器正向跑你的输入候选,要么:直接模拟 VM 反推(通常等价"解一个约束系统")

标志:你看到 while(opcode != HALT)+ 一个大 switch+ 一堆 mem[rIP++]— 就高度怀疑 VM。

⑨ 算法识别:TEA/XTEA/RC4/AES/MD5-SHA 变种

场景

识别点

处理

TEA 系

魔数 0x9E3779B9(v0+=...)双变量循环

抄密钥/轮数,写 逆 TEA

RC4

S[i] = i初始化 + swap KSA

如果只做了 KSA+PRGA 输出与 flag 异或:RC4 也自逆(key 未知就另说)

AES

大量查表 / SubBytes/ShiftRows/MixColumns 特征

先确认 key 是不是硬编码;很多题 key 就在 data 段

MD5/SHA 变种

初态常量 0x67452301...

多半是:MD5(input) == target_md5 → 你只需要 识别它是 MD5,然后换思路(爆破/已知明文/长度短)

⑩ 约束求解 / 符号执行(angr / z3)

当你懒得手推公式,但可以精确描述"输入满足条件"时:

  • angr:建模路径(从 start 到 "win" 地址,avoid "lose"),让它帮你找输入

  • z3:把逐字节约束写成 BitVec,让 SAT solver 吐解

注意:angr 不是万能锤,遇到复杂反调试/系统调用交互会翻车;但对"纯计算验证"的题中非常好用。


⚫ Level 5 — 高阶:Android/iOS·强壳·对抗性题目·AWD 逆向(⭐⭐⭐⭐⭐)

类型

关键点

Android Reverse

APK → dex→ jadx/grok smali;native so → IDA 继续;Frida Hook​ 直接截返回值/绕过校验

iOS Reverse

Mach-O、Hopper/IDA、Objective-C msgSend 模式、dyld 共享缓存

强壳 VMProtect/Themida

目标通常不是"完美脱壳",而是:定位关键比较点/输入变换出口,用差分/插桩把 flag 抠出来

AWD 逆向

你既要解(拿 flag),也可能要 快速 Patch 出后门维持访问​ / 修洞防别人打(偏攻防赛制)


🗺️ 通用解题框架(任何 Reverse 题都照这个顺序走)

这个 5 步在多篇 CTF 总结里反复出现,照做就不会乱:

  1. 程序初判file/ DIE — 平台?位数?语言?壳?有什么字符串?

  2. 静态粗定位:IDA/Ghidra → 字符串窗口(Shift+F12)→ 交叉引用(X)→ 追到验证函数

  3. 看伪代码(F5):把主逻辑读成"输入 → 变换A → 变换B → cmp 与 target"

  4. 关键信息提取:target 数组 / key / 表 / 比较函数地址

  5. 脚本还原 OR Patch:Python 逆运算 → 得 flag;或调试器 Patch 跳转直接走成功分支

口诀:一看(工具)二猜(这是什么变换/算法家族)三验证(动态调试确认你的猜测)


📅 推荐刷题路线(按周/月可落地)

阶段

时长(大致)

目标

去哪练

第1~2周

装环境 + 吃透汇编最小集(mov/push/pop/call/ret/cmp/test/jcc)

能把简单 C 程序反汇编后对应回源码逻辑

自己写几个 C 小程序:strcmp校验 / xor / 循环 → 用 IDA 读伪代码

第1个月

Level 1+Level 2 主循环

无壳题能稳定拿:字符串题/异或还原/base64链/Patch跳转

Bugku、CTFshow Reverse、攻防世界新手区、Crackmes.one(easy)

第2~3月

加壳入门 + 动态调试成型

UPX 一键脱壳→再分析;会用 x64dbg/GDB 下断点追关键比较;懂基本反调试 Patch

CTFHub 技能树 Reverse / BUUCTF 搜"UPX/easy_reverse"

第3~6月

Level 3 主体打完

能处理:ASPack类壳/花指令/控制流混乱题/PyInstaller/Go/.NET;开始碰 TEA/RC4/VM-lite

BUUCTF 2~4星 / picoCTF / Flare-On 早期 / CTFtime​ 找 WriteUp 对照

之后

Level 4+

自定义 VM、z3/angr、Android smali+Frida、强混淆对抗

高质量杯赛真题、Flare-On 后半段、看雪/论坛里的深度 WriteUp


🧠 一句老选手经验(比 Payload 更重要)

逆向题 70% 的时间花在"定位与确认",30% 才是"算"。

你最强的习惯应该是:

  • 先看字符串窗口(最少五秒钟)

  • 再看 main → 找 cmp / memcmp / strcmp / 成功/失败分支

  • 把 target bytes 抄准(差一个字节就全错)

  • 能用 Python 逆的就别手算,能 Patch 跳过的就别死磕公式

© 本文著作权归作者所有,未经许可不得转载使用。