mcpField
E
exploiting-memory-corruption

exploiting-memory-corruption

github.com/trilwu安全17747 次安装12 周前更新
代码仓库

关于 exploiting-memory-corruption

用于授权二进制安全测试、CTF 和实验环境的原生内存破坏利用技能。它将漏洞类型与利用原语及技术对应,并依据目标缓解措施和分配器行为选择方法。

主要功能

  1. 01枚举二进制缓解措施
  2. 02将漏洞类型映射到利用原语
  3. 03构建 ROP 与代码复用链
  4. 04运用 glibc 堆利用技术
  5. 05使用 pwntools 逐步开发利用程序
  6. 06在授权实验范围内测试

适用场景

  1. 01评估 ELF 或 PE 二进制文件中的崩溃
  2. 02开发 CTF pwn 挑战的利用程序
  3. 03针对已启用的缓解措施测试 ROP
  4. 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在栈/堆上执行 shellcodeROP / 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 — 此处的出口模式和仅供实验室使用的默认设置

评论

支持 Markdown