mcpField
H
heap-exploitation

heap-exploitation

github.com/yaklang安全2.6k3.7k 次安装6 周前更新
代码仓库

关于 heap-exploitation

面向安全研究人员和 CTF 参与者的堆利用参考技能,按 glibc 版本梳理分配器行为、漏洞原语与利用技巧,包括 safe-linking 和地址泄漏方法。

主要功能

  1. 01ptmalloc2 chunk 与 bin 参考
  2. 02堆与 libc 地址泄漏方法
  3. 03按 glibc 版本映射攻击
  4. 04safe-linking 编码与解码
  5. 05常见堆漏洞模式
  6. 06pwndbg 堆检查命令

适用场景

  1. 01为堆漏洞选择利用路径
  2. 02按 glibc 版本调整 tcache poisoning
  3. 03查找堆或 libc 地址泄漏
  4. 04使用 pwndbg 检查分配器状态

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/yaklang/hack-skills --skill heap-exploitation

安装后在 Claude Code 中输入/heap-exploitation确认已加载。

附带文件HOUSE_OF_TECHNIQUES.mdIO_FILE_EXPLOITATION.md

详细介绍

技能:堆利用——专家攻击手册

AI 加载指令:glibc 堆利用专家技术。涵盖 ptmalloc2 内部机制、bin 结构、tcache 机制、libc/堆泄漏方法,以及根据 glibc 版本选择攻击方式。内容提炼自 ctf-wiki 的堆利用章节、how2heap 和真实世界的利用案例。基础模型经常混淆 glibc 版本限制,并遗漏 2.32 引入的 safe-linking(PROTECT_PTR)。

0. 相关路由

进阶参考

1. PTMALLOC2 结构速查

malloc_chunk 布局(64 位)
         chunk pointer (returned by malloc - 0x10)
         ┌──────────────────────────┐
    0x00 │  prev_size (if prev free)│
    0x08 │  size        | A | M | P │  ← P=PREV_INUSE, M=IS_MMAPPED, A=NON_MAIN_ARENA
         ├──────────────────────────┤  ← user data starts here (returned pointer)
    0x10 │  fd (if free)            │  ← forward pointer to next free chunk
    0x18 │  bk (if free)            │  ← backward pointer to prev free chunk
    0x20 │  fd_nextsize (large only)│
    0x28 │  bk_nextsize (large only)│
         └──────────────────────────┘
Bin 类型
Bin大小范围(64 位)结构LIFO/FIFO
tcache(每线程)≤ 0x410(每种大小 7 个条目)单向链表(next 指针)LIFO
fastbin≤ 0x80(默认值)单向链表(fd)LIFO
unsortedbin任意已释放大小双向循环链表FIFO
smallbin< 0x400双向循环链表FIFO
largebin≥ 0x400双向链表,按大小排序已排序
关键全局结构
结构位置用途
main_arenalibc .data 段包含 bin 头、top chunk、system_mem
mp_libc .datamalloc 参数(tcache 设置、mmap 阈值)
tcache_perthread_struct堆(首次分配时)每线程的 tcache bin 和计数

2. 泄漏方法

libc 基址泄漏
方法前提条件技术
Unsortedbin fd/bk释放一个大于 tcache 范围的 chunk(或填满 tcache)fd/bk → main_arena + 0x60(或根据版本为 +0x70)→ libc 基址
Smallbin fd/bkchunk 从 unsortedbin 移至 smallbin与 unsortedbin 泄漏相同
stdout FILE 泄漏写入 _IO_2_1_stdout_破坏 _IO_write_base 以泄漏 libc 数据(参见 IO_FILE)
堆基址泄漏
方法前提条件技术
Tcache fd 指针释放两个 tcache chunk,读取第一个 chunk 的 fdfd → 堆地址(在 ≥ 2.32 中经过 XOR)
Fastbin fd释放两个 fastbin chunkfd → 堆地址
UAF 读取对已释放 chunk 进行释放后使用直接读取 fd/bk
Safe-Linking 解码(glibc ≥ 2.32)
# PROTECT_PTR: fd_stored = (chunk_addr >> 12) ^ real_fd
# To decode: real_fd = fd_stored ^ (chunk_addr >> 12)
# To encode: fd_stored = (chunk_addr >> 12) ^ target_addr

def deobfuscate(stored_fd, chunk_addr):
    return stored_fd ^ (chunk_addr >> 12)

def obfuscate(target, chunk_addr):
    return (chunk_addr >> 12) ^ target

3. 按 GLIBC 版本划分的攻击类别

glibc < 2.26(无 tcache)
攻击所需原语结果
Fastbin dupDouble free任意分配
Unsortedbin attack破坏 unsortedbin bk将 main_arena 地址写入目标(用于覆盖 __malloc_hook 附近)
Unlink attack堆溢出覆盖 prev_size + fd/bk任意写入(需已知堆指针)
House of Force覆盖 top chunk 大小任意分配
House of Spirit写入伪造的 chunk 头在伪造 chunk 处进行 fastbin 分配
Off-by-one null用空字节溢出到下一个 chunk 的大小字段重叠 chunk
glibc 2.26–2.28(有 tcache,无 key)
攻击说明
Tcache poisoning覆盖 tcache fd → 任意分配,无大小检查
Tcache dup对 tcache 中的 chunk 进行 Double free(尚无 double-free 检测)
之前的所有攻击仍然有效,但 chunk 会优先进入 tcache
glibc 2.29–2.31(引入 tcache key)
攻击绕过 tcache key 的方法
Tcache dup在第二次释放前,破坏 key 字段(位于 chunk+0x18)
House of Botcake双重释放:一个位于 unsortedbin,一个位于 tcache → 形成重叠
Tcache stashing unlink滥用 smallbin→tcache 补充机制,获取任意 chunk
glibc 2.32–2.33(safe-linking / PROTECT_PTR)
攻击适配方式
Tcache poisoning使用 (chunk_addr >> 12) ^ target 对目标进行编码
需要堆泄漏需要堆地址才能解码/编码 safe-linked 指针
Fastbin dup同样需要编码
glibc ≥ 2.34(移除 hooks)
变更影响
移除 __malloc_hook无法覆盖 hook 来使用 one_gadget
移除 __free_hook无法覆盖 hook
移除 __realloc_hook无法利用 realloc 技巧满足 one_gadget 的约束

2.34 之后的目标:有关 _IO_FILE、exit_funcs、TLS_dtor_list、_dl_fini,请参见 arbitrary-write-to-rce。


4. 常见漏洞模式

漏洞描述利用路径
UAF(释放后使用)释放后访问 chunk读取:泄漏 fd/bk;写入:破坏 fd 以进行 tcache poisoning
双重释放对同一个 chunk 调用两次 free()Tcache dup(绕过 key)或 fastbin dup
堆溢出写入超出 chunk 边界破坏下一个 chunk 的元数据(size、fd、bk)
Off-by-one溢出一个字节空字节 → 缩小下一个 chunk 的大小 → 形成重叠 chunk
Off-by-null特指 \x00 溢出清除 PREV_INUSE → 触发向后合并
未初始化读取不清零便读取堆内存从回收的 chunk 中泄漏 fd/bk

5. 工具

# pwndbg heap inspection
pwndbg> heap                      # display all chunks
pwndbg> bins                      # show all bin contents
pwndbg> tcachebins                # tcache status
pwndbg> fastbins                  # fastbin status
pwndbg> unsortedbin               # unsortedbin content
pwndbg> vis_heap_chunks           # visual heap layout
pwndbg> find_fake_fast &__malloc_hook  # find nearby fake fastbin chunks

# how2heap — reference implementations
git clone https://github.com/shellphish/how2heap

# heapinspect
pip install heapinspect
heapinspect <pid>

# pwntools helpers
from pwn import *
libc = ELF('./libc.so.6')
print(hex(libc.symbols['__malloc_hook']))
print(hex(libc.symbols['__free_hook']))

6. 决策树

Heap vulnerability identified
├── What is the primitive?
│   ├── UAF (read + write)
│   │   ├── Can read freed chunk? → Leak libc (unsortedbin) or heap (tcache fd)
│   │   └── Can write freed chunk? → Tcache poisoning / fastbin dup
│   ├── Double free
│   │   ├── glibc < 2.29 → direct tcache dup
│   │   ├── glibc 2.29-2.31 → corrupt tcache key first, or House of Botcake
│   │   └── glibc ≥ 2.32 → need heap leak for safe-linking encode
│   ├── Heap overflow (controlled size)
│   │   ├── Overwrite next chunk size → overlapping chunks → UAF
│   │   └── Overwrite fd directly → arbitrary allocation
│   ├── Off-by-one / off-by-null
│   │   ├── Null byte into size → House of Einherjar (backward consolidation)
│   │   └── One byte into size → shrink chunk, create overlap
│   └── Arbitrary write (from overlap or poisoned allocation)
│       ├── glibc < 2.34 → __malloc_hook / __free_hook → one_gadget
│       ├── glibc ≥ 2.34 → _IO_FILE vtable, exit_funcs, TLS_dtor_list
│       └── Partial RELRO → GOT overwrite
│
├── Need libc leak?
│   ├── Free chunk into unsortedbin (size > 0x410 or fill 7 tcache)
│   ├── Read fd/bk → main_arena offset → libc base
│   └── Alternative: stdout FILE partial overwrite for leak
│
└── Need heap leak? (glibc ≥ 2.32)
    ├── Read tcache fd from freed chunk
    └── Decode: real_addr = stored_fd ^ (chunk_addr >> 12)

评论

支持 Markdown