关于 exploiting-memory-corruption
用于授权二进制安全测试、CTF 和实验环境的原生内存破坏利用技能。它将漏洞类型与利用原语及技术对应,并依据目标缓解措施和分配器行为选择方法。
主要功能
- 01枚举二进制缓解措施
- 02将漏洞类型映射到利用原语
- 03构建 ROP 与代码复用链
- 04运用 glibc 堆利用技术
- 05使用 pwntools 逐步开发利用程序
- 06在授权实验范围内测试
适用场景
- 01评估 ELF 或 PE 二进制文件中的崩溃
- 02开发 CTF pwn 挑战的利用程序
- 03针对已启用的缓解措施测试 ROP
- 04调查 glibc 上的堆内存破坏
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ trilwu/ secskills --skill exploiting-memory-corruption安装后在 Claude Code 中输入/exploiting-memory-corruption确认已加载。
详细介绍
利用内存损坏漏洞
逆向工程可以告诉你二进制程序存在漏洞。漏洞利用则是另一门独立的技艺:将漏洞转化为可控原语,再进一步转化为代码执行,同时应对目标实际启用的缓解措施。这一过程是一连串转换——从漏洞到原语,从原语到信息泄露,再从信息泄露到控制权;每个环节都取决于二进制程序的防护措施允许什么,而不是照搬套路。
适用场景
- 你发现 ELF/PE 程序崩溃或存在已知类型的漏洞,需要评估其可利用性并构建可用的漏洞利用程序
- 构造 ROP/JOP 链、ret2libc 攻击或堆布局操控序列
- 在实验环境或 CTF 目标上绕过特定的缓解措施(ASLR、NX/DEP、canary、PIE、RELRO)
- 处理经过授权的二进制漏洞利用任务或 CTF pwn 挑战
不适用场景
- 还原二进制程序的行为——反汇编、反编译、算法还原——应使用
analyzing-binaries;如果还不了解漏洞,应先完成这一步。 - 在能够看到代码之前解包或去虚拟化受保护的二进制程序——请使用
unpacking-protected-binaries。 - Web、反序列化或注入漏洞——这些属于各自的技能(
testing-web-applications、exploiting-deserialization);本技能仅针对原生内存损坏漏洞。 - 专门针对内核/驱动程序的漏洞利用——相关原语差异很大(没有 libc、SMEP/SMAP/KASLR、系统调用上下文),因此不在本技能范围内;但用户态方法仍有参考价值。
- 通过模糊测试来发现漏洞——这是漏洞发现步骤;本技能从你已经拿到崩溃样本后开始。
首先枚举缓解措施
你能构建的漏洞利用程序取决于启用了哪些防护。在制定计划前先检查它们(使用 checksec,或使用 pwntools 的 checksec/ELF):
| 缓解措施 | 阻止的行为 | 常用应对方法 |
|---|---|---|
| NX / DEP | 在栈/堆上执行 shellcode | ROP / ret2libc——复用现有的可执行代码 |
| ASLR | 硬编码地址 | 利用信息泄露获取基址,再计算偏移量 |
| Stack canary | 朴素地覆盖栈返回地址 | 泄露 canary、改为覆盖其他内容,或对会分叉的服务进行暴力破解 |
| PIE | 硬编码二进制程序自身的地址 | 泄露一个二进制地址;在此之前只能进行相对/部分覆盖 |
| Partial RELRO | 几乎不阻止任何操作——GOT 仍可写 | 可以考虑覆盖 GOT |
| Full RELRO | 覆盖 GOT | 目标为 __malloc_hook/__free_hook(2.34 之前),或仅使用 ROP 的路径 |
决定工作顺序的两个问题是:我能否获取信息泄露(ASLR/PIE),以及我能写入哪里(RELRO)。其他一切都由这两点决定。
从漏洞类型到原语
在选择技术之前,先明确你手上有什么:
- 栈缓冲区溢出 → 可直接控制保存的返回地址;在 canary 允许的情况下,这是构造 ROP 链最直接的途径。
- 堆溢出 / off-by-one → 破坏相邻的 chunk 元数据或对象指针;可用原语取决于你能操控的堆布局。
- 释放后使用 → 用攻击者数据重新分配已释放的槽位,使过期指针在你的控制下被使用;这是伪造 vtable/对象的经典途径。
- 类型混淆 → 将一种类型的字段当作另一种类型使用,通常可获得读写原语,或直接获得可控调用。
- 格式字符串 → 使用
%n进行定向写入,使用%p/%s获取信息泄露;一个漏洞往往既能泄露信息,也能写入数据。 - 整数溢出 / OOB → 通常是实现上述某种漏洞的手段(例如计算出的长度过小,导致堆溢出)。
这一步的目标是获得三种原语之一:控制流劫持、任意读或任意写。先获得原语,再继续构建漏洞利用程序。
ROP 与代码复用
启用 NX 后,你可以按自己选择的顺序执行程序自身的字节:
- 查找 gadget:使用 ROPgadget 或 ropper;寻找
pop rdi; ret这类寄存器控制指令序列,以便为调用设置参数。 - ret2libc——获取 libc 基址后,跳转到
system("/bin/sh");当 libc 可用且已泄露时,这是最直接的调用链。 - ret2csu:当找不到合适的 gadget 时,利用 pre-2.34 二进制中
__libc_csu_init的尾部来控制rdx/rsi。 - SROP(sigreturn-oriented):当 gadget 很少,但你可以布置伪造的 signal frame 并跳转到
sigreturn时使用。 - ret2dlresolve:通过强制动态链接器解析函数来调用该函数;没有泄露且启用了部分 RELRO 时很有用。
- one_gadget:找到一个能执行 shell 的 libc 地址;当其约束条件满足时,可将最后阶段合并为一步。
使用 libc-database 将泄露的 libc 与对应构建版本匹配,确保偏移正确——针对错误 libc 构建的调用链会悄无声息地失败。
堆利用(glibc ptmalloc)
堆利用的核心是布局:安排内存分配,使破坏操作落在有用的位置。具体技术取决于 glibc 版本,因为分配器的检查一直在不断收紧。
- tcache poisoning(2.26+)——杠杆效应最大的现代原语:破坏已释放 tcache 块的
next,使下一次malloc返回任意指针。在 2.32+ 中,指针会经过 safe-linking 混淆(与其存储地址右移 12 位后的值进行 XOR),因此需要堆地址泄露才能伪造指针;而 2.34 移除了过去用于结束调用链的__free_hook/__malloc_hook目标。 - fastbin dup——通过向 fastbin 重复释放同一块,使其被返回两次;在较新的 glibc 中要注意优先使用 tcache 的行为。
- unsorted-bin 泄露——unsorted bin 中已释放的块会保存
main_arena指针;读取该指针即可泄露 libc 地址,从而绕过 ASLR。 - House of * 技术(Force、Orange、Einherjar 及更新的技术)——每种技术都会利用特定的分配器不变量,在简单原语受阻时实现任意写入;仅在布局需要时才使用。
使用 pwndbg 或 GEF 执行这些操作——heap、bins 和 tcache 命令会显示状态,让你根据实际情况而非脑中模型来调整堆布局。
循环调试
使用 pwntools 逐步构建利用程序,并在加入下一步之前验证每个环节:触发崩溃,证明可以控制指令指针,获取泄露并确认计算出的基址,然后执行写入,最后拿到 shell。某个阶段表现异常时,应在恰当的位置使用 gdb.attach() 附加调试,而不是盯着整条调用链排查。本地可用但远程失效的利用程序,几乎总是存在环境差异——libc 版本、栈对齐(为 movaps 多出的一个 ret),或依赖环境的泄露。
范围与授权
漏洞利用开发应针对你拥有的二进制文件、CTF 目标、实验室 VM,或你受明确委托测试的软件——此处默认采用 lab_only 出站模式,因为对生产环境运行可用的漏洞利用属于入侵,而非研究。请特别注意以下两点:
- 第三方软件中的 0-day 应通过协调披露处理,而非公开发布。构建概念验证,通过供应商的渠道报告;在修复发布前,不要公开武器化漏洞利用程序。
- 切勿对你无权控制的系统测试漏洞利用程序,以“看看是否有效”。命中内存破坏漏洞会导致服务崩溃;这会影响他人系统的可用性。
应当摒弃的错误说法
- “EIP/RIP 被覆盖后程序崩溃了,所以它可以被利用。” 控制指令指针只是起点,而非终点。现代缓解措施意味着,如果没有信息泄露,崩溃可能毫无进展;在声称漏洞可被利用之前,先评估是否能构造出可利用的原语。
- “本地能运行,直接交付吧。” 远程环境中的 libc、ASLR 熵和栈对齐都可能不同。先匹配目标 libc,并在真实环境中测试,再报告其可用。
- “直接把 shellcode 喷到栈上就行。” NX 默认启用已有十多年。如果你要将 shellcode 写入栈并跳转执行,先确认 NX 确实已关闭,再投入时间。
- “最后一步交给 one_gadget 就行。” 它的约束条件(特定寄存器为空、特定栈状态)往往无法满足。先检查这些条件;同时准备好 ret2libc 作为备用方案。
- “照着文章里的堆利用技巧做就行。” 分配器检查因版本而异,包括 tcache 键、计数检查和 safe-linking。先确认目标 glibc 版本,并确认该技巧仍适用于此版本。
ATT&CK 覆盖范围
根据 secskills-core/ttp-index.json 生成——编辑该文件,然后运行
python3 scripts/sync_attack.py --write。在报告中引用 ID 之前,请对照当前 ATT&CK 版本重新核实。
执行(TA0002)
- T1203 客户端执行漏洞利用——另见
performing-social-engineering、analyzing-malware
权限提升(TA0004)
- T1068 权限提升漏洞利用——另见
escalating-linux-privileges、escalating-windows-privileges
横向移动(TA0008)
- T1210 远程服务漏洞利用——另见
enumerating-network-services
这些 ATT&CK 技术的检测内容:engineering-detections。主动搜索:hunting-threats。入侵后响应:responding-to-incidents。
参考资料
analyzing-binaries— 先恢复代码并了解漏洞unpacking-protected-binaries— 需要解包或去虚拟化二进制文件时reviewing-cryptography— 目标是密码学原语而非内存时maintaining-engagement-state— 此处的出口模式和仅供实验室使用的默认设置