executing-plans
executing-plans
Use when executing an implementation plan in the current session as the implementer yourself — your human partner chose inline execution, or no subagent tool is available
re-crash-triage崩溃/漏洞样本分析:确定性复现、ASAN/UBSAN 报告解读、输入最小化 (afl-tmin/cmin)、gdb 回溯定位、rr 录制重放、PoC 产出。 触发词:崩溃、crash、ASAN、UBSAN、未定义行为、UAF、堆溢出、越界、段错误、segfault、 core dump、PoC、漏洞分析、崩溃分析。
Independent GitHub snapshot · Automated classification · Original documentation governs
所有工具先验证再使用。复现崩溃是动态执行,默认沙箱内跑([[re-analyze/platform-tips]] 最高原则,见 [[re-sandbox]])。
sudo apt install clang / sudo dnf install clang / sudo pacman -S clang / macOS Xcode 自带sudo apt install gcc(ASAN 内置在 gcc,无独立包);Fedora sudo dnf install gcc;Arch sudo pacman -S gccgcc -fsanitize=address,undefined -g -fno-omit-frame-pointer -o target_asan target.c(clang 参数相同)AddressSanitizer 字样sudo apt install gdbsudo dnf install gdbsudo pacman -S gdbbrew install gdb(需 codesign 授权);Xcode 自带 lldb 亦可(见 [[re-lldb]])gdb --versionsudo apt install rr(universe 仓库)sudo dnf install rrparu -S rr(AUR 包;官方仓库无 rr)git clone https://github.com/rr-debugger/rr && mkdir rr/obj && cd rr/obj
cmake -DCMAKE_BUILD_TYPE=Release ../rr && make -j$(nproc) && sudo make install
perf_event_paranoid > 1 时超慢,先放开:
sudo sysctl kernel.perf_event_paranoid=1
rr check 会检查 PMU/perf_event 可用性与已知限制,通过后再用;嵌套虚拟化、未透传 PMU 的容器里 rr 无法录制valgrind --tool=helgrind 或 -fsanitize=thread 构建定位;纯 ASLR 抖动可先 set disable-randomization on 排除rr --versionafl-tmin / afl-cmin 随包安装)afl-cmin 尤其重要): afl-cmin 需要目标可被 AFL 观测——通常要求它由 AFL 插桩构建(afl-clang-fast / afl-gcc),否则会报「无插桩 / not instrumented」而失败。afl-tmin 的约束弱得多(可按纯崩溃判据工作),未插桩目标通常也能跑gcc -fsanitize=address -g)而没有走 afl-clang-fast 时,afl-cmin 不保证能跑。先确认构建方式;不是 AFL 编译器产出时,改用 afl-tmin 逐个最小化,或回 [[re-fuzzing]] 重建插桩版本afl-tmin -h / afl-cmin -h按顺序执行;崩溃输入与 PoC 先 sha256 存证([[re-triage]] 方法)。
sha256sum crash_input > crash_input.sha256
./target < crash_input # stdin 输入
./target crash_input # 文件输入
./target -f crash_input # 按目标实际参数形态
ulimit -c unlimited;cat /proc/sys/kernel/core_pattern 若指向 systemd-coredump/apport 则 core 会被系统收走(见坑 4)-fsanitize=address -g -fno-omit-frame-pointer 构建,见工具准备):
heap-buffer-overflow / stack-buffer-overflow / global-buffer-overflow:越界读写——报告含越界方向(READ of size N / WRITE of size N)与越界偏移heap-use-after-free:UAF——看 freed by 与 allocated by 两段栈,找释放点与再使用点attempting double-free:重复释放SEGV:空指针/野指针访问,细节需 gdb 补(第 4 步)#0 帧是崩溃点,别只看行号——结合数据流向判断是哪个输入字节导致afl-tmin -i crash_input -o crash.min -- ./target @@
# 多个崩溃输入先按路径去重(需 AFL 插桩,见工具准备):
afl-cmin -i crashes_dir -o minimized -- ./target @@
@@ 只适用于「文件参数」目标(AFL 把 @@ 替换成输入文件路径)。目标是 stdin 读输入时不要用 @@,把「文件 → stdin」这一步补进命令行,例如:
afl-tmin -i crash_input -o crash.min -- sh -c './target < "$1"' _ @@
或在目标自带 -f <file> 之类文件参数时用它替代 @@;先按第 1 步确认过的真实输入形态选写法gdb -q ./target
(gdb) set disable-randomization on # 关 ASLR 便于地址对照
(gdb) run crash.min
(gdb) bt # 完整回溯
(gdb) info registers # 崩溃点寄存器
(gdb) x/16i $pc # 崩溃点反汇编
gdb -q ./target /path/to/corebt 全是 ??(无符号):记模块基址 + 偏移,进 [[re-ghidra]] / [[re-ida]] 反编译补帧(见坑 5)rr record ./target crash_input
rr replay # 打开 gdb 会话
(rr) continue # 跑回崩溃点
(rr) bt
(rr) reverse-continue # 崩溃前反向执行找根因
crash.min + sha256 + 复现命令(环境:ASAN 构建参数、运行参数、输入通道)out/crashes/)交本技能分析(本技能也反向使用其 afl-tmin/cmin 工具链)rr record ./target input)在崩溃点自动停止,rr replay + reverse-continue 反向定位根因;先 set disable-randomization on 排除 ASLR 因素-fsanitize=undefined 抓 UB;影响与可达性判断以真实 release 行为为准(ASAN 报出的是潜在漏洞,需确认)ulimit -c unlimited 后崩溃仍无 core 文件;原因——core_pattern 指向 systemd-coredump(管道方式)/apport 拦截;对策——先 cat /proc/sys/kernel/core_pattern 确认落点,再按落点取回:
core_pattern 形如 |/usr/lib/systemd/systemd-coredump ...:core 已被 systemd 接管,不要急着改全局设置,直接取用即可——coredumpctl list 找条目(按可执行名/时间),coredumpctl info <PID|可执行名> 看元数据,coredumpctl dump <PID> -o core 导出,或 coredumpctl gdb <PID> 直接进 gdb 调试。这比改 core_pattern 更完整,也不影响系统上其它程序的 core 行为/var/crash/,用 apport-unpack 展开sudo sysctl kernel.core_pattern=core(core 落到进程工作目录,注意只对之后启动的进程生效)gdb --args ./target crash.min 直接跑,不依赖 core 文件bt 全 ??、地址对不上;原因——strip / 静态链接 / 二进制与 core 版本不一致;对策——core 与二进制必须同版本(对比 sha256);记录崩溃模块基址与偏移,在 [[re-ghidra]] / [[re-ida]] 按偏移定位函数,换算回 gdb 地址