--- name: re-ctf type: gateway description: > CTF 实践网关。编排:题型识别 → 简单题直接 [[re-binary-core]] → 需自动化 [[re-angr]]/[[re-z3]] → 混淆 [[re-deobfuscate]]。 子技能:[[re-angr]] [[re-z3]] [[re-pwn]]、[[re-stego]]。 触发词:CTF、赛题、逆向题、pwn、babyre、自动解题、符号执行、angr、z3、solver、找flag。 capabilities: [constraint-solving, stego-detection, shellcode-analysis] --- # CTF 实践(题型识别 / 自动化解题 / 约束求解) ## 完整工作流 按顺序执行;每步产物(题型结论 / 关键函数地址 / 约束模型 / flag)记录证据路径 + sha256(见 [[re-triage]](能力:`triage`)),供 writeup 引用。 1. **题型识别** —— 先别急着上工具,读题 + 初勘定题型(见坑 1): - 逆向题(rev / babyre):给一个二进制,要求还原算法 / 找输入 / 找 flag —— 按第 2-4 步走 - 加密 / 算法题:给加密函数 / 密文,要求解出明文或逆算法 —— 涉及 [[re-crypto-id]](能力:`crypto-identification`) / [[re-crypto-decrypt]](能力:`crypto-decryption`),约束求解用 [[re-z3]](能力:`constraint-solving`) - 序列号 / 注册类题:校验函数还原 → 注册机(见 [[re-license]](能力:`license-analysis`) / [[re-keygen]](能力:`license-analysis`),硬推比较链用 [[re-z3]](能力:`constraint-solving`)) - pwn / 栈溢出题:入门利用走 [[re-pwn]]([[re-gdb]](能力:`debugging`) / [[re-radare2]](能力:`decompilation`) 动态调试,运行在 [[re-sandbox]](能力:`sandbox-setup`)) - 初勘命令:`file` / `checksec` / 熵 / strings([[re-triage]](能力:`triage`)),识别架构、是否带壳、是否静态链接 2. **简单题直接 [[re-binary-core]](能力:`decompilation`、`debugging`、`memory-dump`、`elf-parser`、`pe-parser`、`macho-parser`)** —— 题不需要自动化时,走通用分析(初勘 → 格式解析 → 反编译 → 调试):[[re-ghidra]](能力:`decompilation`、`debugging`) / [[re-ida]](能力:`decompilation`、`debugging`) / [[re-radare2]](能力:`decompilation`) 反编译主逻辑,人工还原出 flag / 注册算法。**先估算复杂度**:几行比较 / 简单 XOR 的题 15 分钟人工就够,上 angr 反而慢(见坑 2) 3. **需自动化 → [[re-angr]](能力:`symbolic-execution`) / [[re-z3]](能力:`constraint-solving`)**: - 输入在长循环 / 深比较链里逐字节校验(human 逐位逆推费时、容易错)→ **[[re-angr]](能力:`symbolic-execution`)** 符号执行(符号化输入 → find 目标地址 → 求解) - 校验是"一组数学等式 / 比较链"(满足约束即 flag)→ **[[re-z3]](能力:`constraint-solving`)** 建模求解(比 angr 轻、快、稳) - 分派细则见「选择树」 4. **混淆 → [[re-deobfuscate]](能力:`deobfuscation`)** —— 反编译产物有花指令 / 控制流平坦化 / 字符串加密:**先还原再自动化**。直接对混淆函数上 angr 会路径爆炸 / 解不出(见坑 3);[[re-deobfuscate]](能力:`deobfuscation`) 还原后回到第 2/3 步 5. **验证与产出**: - 求解出的输入跑原程序(沙箱内,[[re-analyze/platform-tips]] 最高原则)必须打印 `flag{...}`(见坑 4:flag 格式 / 与求解结果一致性) - 记录:题型、关键函数地址、约束模型、求解脚本、flag、复现命令 —— writeup 与 [[re-ioc]](能力:`threat-intel`) 特征(如自动化解题特征) ## 何时用哪个原子技能(选择树) 按题型特征 / 目标分支: - **刚拿到题,未定题型** → 第 1 步:[[re-triage]](能力:`triage`) 初勘 + 反编译扫一眼主逻辑,先人工判断(大多数简单题人工即可,别急着自动化) - **简单 XOR / 移位 / 查表变换(≤ 一屏伪代码)** → [[re-binary-core]](能力:`decompilation`、`debugging`、`memory-dump`、`elf-parser`、`pe-parser`、`macho-parser`) 人工还原([[re-ghidra]](能力:`decompilation`、`debugging`) / [[re-radare2]](能力:`decompilation`)),或小规模约束直接 [[re-z3]](能力:`constraint-solving`) 建模 - **逐字节 / 逐字符长循环校验(每个字节都要满足条件,人工逆推繁琐)** → [[re-angr]](能力:`symbolic-execution`;符号化输入 + find 校验通过地址) - **"满足一组等式 / 比较链即 flag / 密钥"(无循环或循环已人工展开)** → [[re-z3]](能力:`constraint-solving`;BitVec 建模 + solver 求解) - **输入位置复杂(argv / 文件 / 标准输入 / 网络)** → [[re-angr]](能力:`symbolic-execution`;符号化任意输入点,[[re-z3]](能力:`constraint-solving`) 需人工先定位变量来源) - **花指令 / 平坦化 / 字符串加密可见** → 先 [[re-deobfuscate]](能力:`deobfuscation`) 还原,再按题型走 angr / z3 / 人工(坑 3) - **带壳题**(CTF 少见,常见于"脱壳题")→ 先 [[re-anti-analysis]](能力:`unpack`、`deobfuscation`、`evasion-analysis`;packer-id → unpack-*),脱壳后回本网关 - **加密 / 密码学题**(AES / RSA / 自定义加密 + 密文)→ [[re-crypto-id]](能力:`crypto-identification`) 识别 → [[re-crypto-decrypt]](能力:`crypto-decryption`) 还原;自定义数学关系用 [[re-z3]](能力:`constraint-solving`) 求解 - **pwn 题** → [[re-pwn]](能力:`exploit-development`;漏洞利用入门:栈溢出 / 格式化字符串 / ret2libc)→ [[re-gdb]](能力:`debugging`) / [[re-radare2]](能力:`decompilation`) + [[re-sandbox]](能力:`sandbox-setup`) 动态调试(本网关以逆向题为主,pwn 作为相邻题型移交调试域) - **flag 解出但格式不对** → 检查大小写 / 换行 / 编码(坑 4) ## 跨域联合 - **入口调度**:本网关被 [[re-analyze]] 的 triage「CTF 赛题」路径调用(re-ctf → 题型识别 → re-angr / re-z3 / 反混淆 re-deobfuscate → 底座 re-binary-core) - **CTF 题 = 核心技能应用(规格 2.4 联合场景)**:CTF 题本质是核心技能的组合应用 → 简单题 / 反编译工作台直接走 [[re-binary-core]]([[re-triage]] / [[re-ghidra]] / [[re-ida]] / [[re-radare2]]);[[re-binary-core]] 网关亦声明"CTF 逆向题 → 本网关为底座" - **自动化解题**:[[re-angr]](符号执行)、[[re-z3]](约束求解)—— 本网关的两个原子技能,被本网关工作流第 3 步调度;[[re-deobfuscate]] 工作流第 1 步亦产出可被 angr 消费的干净二进制 - **混淆对抗**:混淆题先 [[re-deobfuscate]] 还原(其「跨域联合」声明 CTF 反混淆题固定引用本网关) - **加密类题**:[[re-crypto-id]] / [[re-crypto-keys]] / [[re-crypto-decrypt]](算法识别、密钥定位、解密还原);密钥推导用 [[re-z3]] 建模 - **序列号类题**:[[re-license]] / [[re-keygen]](校验定位与注册机);比较链硬推用 [[re-z3]] - **pwn / 动态**:[[re-gdb]](调试 / 断点看校验分支)、[[re-radare2]](命令行快攻)、[[re-sandbox]](运行与 flag 验证沙箱,[[re-analyze/platform-tips]] 最高原则) - **产出**:自动化解题脚本特征 / 题型指纹可进 [[re-ioc]] 列表 ## 常见坑与陷阱 - **不审题直接上 angr**:现象——简单 XOR 题 / 明文比较题上了符号执行,求解半天或直接无解;原因——题型误判,自动化工具反而引入路径爆炸 / 建模误差;对策——第 1 步先初勘 + 反编译估算复杂度:一屏内能人工还原的题直接 [[re-binary-core]],自动化留给长循环 / 深比较链 - **盲目人工逆推长循环**:现象——几百次迭代的逐字节校验,人工逆推中途出错、时间失控;原因——低估了机械化计算的规模;对策——按第 3 步分派:逐字节长循环用 [[re-angr]],等式集合用 [[re-z3]];求解脚本边写边验证(小输入先测) - **混淆未还原就自动化**:现象——angr 直接跑平坦化 / 带花指令的函数,路径爆炸跑不完,或求解出的"输入"跑原程序不通过;原因——混淆使约束模型失真、状态空间膨胀;对策——先 [[re-deobfuscate]] 还原(D-810 / 手动),再符号执行或人工分析;angr 上确认符号化函数反编译清晰再跑(见 [[re-angr]] 坑 1) - **flag 格式 / 边界不一致**:现象——求解出看似正确的输入,程序却输出非 flag 内容或报错;原因——flag 有前缀后缀格式(`flag{...}`)、大小写 / 换行符 / 编码(ASCII 与宽字符)不一致,或输入长度固定需对齐;对策——用 [[re-gdb]] 断在打印处看实际输出;求解脚本按程序期望的输入通道(stdin / argv / 文件)与格式原样重放,沙箱内跑原程序验证 - **带壳 / 静态链接漏判**:现象——字符串全乱码、xref 全是壳代码,反编译毫无头绪;原因——题目带壳(脱壳题)或静态链接(无导入表线索);对策——[[re-triage]] 初勘先查壳(熵 / 节名 / EP);带壳走 [[re-anti-analysis]];静态链接题从 main / 入口特征 / 字符串定位逻辑起点([[re-imports]] 的库指纹思路) - **PyInstaller 题:入口脚本无行为 ≠ 解包失败**:现象——解包后 `main.pyc` 只剩 `sys.exit(0)`,题面提示却完全对不上;原因——真实逻辑不在入口脚本:可能藏在 runtime hook、**冻结模块**(`_frozen` 数组,如修改版 `os` 模块)、修改版 Python 运行库(重编译的 python313.dll)、bootloader 前置逻辑或运行时生成的 code object;对策——**竞争假设 + 最小实验**:假设 1=修改的冻结模块、假设 2=bootloader 前置逻辑,先执行成本最低区分度最高的实验(下载官方同版本 DLL 对比);**冻结模块哈希差分**:解析 PE 导出表读 `_frozen` 数组(code/size),marshal.loads 后与官方 29 个冻结模块逐一 SHA-256 对比,把 7MB 运行库压缩到单个 47KB marshal 对象;注意 marshal 格式与字节码**版本强相关**(必须用题目对应 Python 版本,如 3.13.1 的 magic) - **周期 XOR + 已知明文恢复 key**:现象——6 字符 key 周期 XOR 的密文,暴力搜不可打印候选;原因——key 每个槽位被明文覆盖次数不足时解不出;对策——利用天然已知明文(如程序内明文成功消息),`密文 ^ 明文` 得 key 流,**统计每个槽位覆盖次数**(每个槽位 ≥2 次一致才可信);恢复后解密成功消息交叉验证