‹ 首页

exploiting-glibc-heap-vulnerabilities

@xalgord · 收录于 昨天 · 上游提交 昨天

Methodology for exploiting glibc ptmalloc2 heap vulnerabilities during authorized engagements — use-after-free, double-free, heap overflow, and bin-based attacks (tcache poisoning, fast-bin dup, unsorted/large-bin) — including modern mitigations (tcache key, safe-linking, hook removal) and how to obtain leaks and arbitrary read/write.

适合你,如果在合法测试中需利用堆漏洞获取内存读写

/ 通过 npx 安装 校验哈希
npx oh-my-skill add xalgord/xalgorix/exploiting-glibc-heap-vulnerabilities
/ 通过 bash 安装
curl -fsSL https://oh-my-skill.com/install.sh | bash -s -- xalgord/xalgorix/exploiting-glibc-heap-vulnerabilities
/ 已经装过?验证本机副本,不用重装
npx oh-my-skill verify xalgord/xalgorix/exploiting-glibc-heap-vulnerabilities
安装目标可用 --agent / --scope 或 --to 明确指定;省略时只会在唯一已存在的 agent 目录上自动选择,零命中或多命中会停止并提示。content_hash 缺失或不一致均拒装。
807GitHub stars
~2.2K上下文体积 · 单文件
索引托管

怎么用

技能原文 SKILL.md作者撰写 · MIT · eeaf26b

Exploiting glibc Heap Vulnerabilities

When to Use
  • During authorized exploitation of programs that dynamically manage memory with malloc/calloc/free and contain use-after-free, double-free, heap overflow, or off-by-one (poison-null-byte) bugs.
  • When the stack is not the corruption surface but you control freed-chunk contents, chunk size fields, or allocation ordering, and want to convert that into an arbitrary read/write or code-pointer overwrite.
  • When selecting a bin-specific primitive: tcache poisoning, fast-bin dup, unsorted-bin attack, large-bin attack, House of Force/Einherjar/Botcake, etc.
  • When you must account for the target glibc version's mitigations (tcache key, safe-linking, removed malloc hooks).
Critical: Concepts/Steps Most Often Missed
  • Identify the glibc version FIRST — it dictates the whole strategy. tcache double-free detection (2.29+), safe-linking of singly-linked lists (2.32+), and removal of __malloc_hook/__free_hook (2.34+) each invalidate "classic" techniques. A how2heap PoC for 2.27 will simply abort on 2.35.
  • Safe-linking mangles the next pointer. From glibc 2.32, tcache/fastbin next is stored as stored = target ^ (chunk_addr >> 12). You almost always need a heap leak to forge a valid poisoned pointer; without it you hit malloc(): unaligned tcache chunk detected.
  • Returned pointers must be 16-byte aligned. A poisoned target that is not aligned aborts before you get control. Target aligned addresses (or use the chunk's own alignment).
  • tcache fills before fastbins/unsorted. The tcache (7 entries per size) intercepts frees first. To exercise a fast-bin or unsorted-bin attack you must first fill the tcache (free 7 chunks of that size) so the 8th lands in the intended bin.
  • Modern end goals are not hooks. With hooks gone, pivot to: overwrite an application code pointer/vtable, get a chunk over another heap object for arbitrary R/W, or set up FSOP/__free_hook-equivalents/ROP. House of Botcake is the standard way to create the overlap needed for modern tcache poisoning.
  • Double-free needs the key bypass. free(A); free(B); free(A) works on fastbins (free another chunk in between) but tcache's key field aborts plain double-frees on 2.29+ unless bypassed.
How to CONFIRM

Use a heap-aware debugger: pwndbg/gef commands heap, bins, tcachebins, vis_heap_chunks, or muslheap's mchunkinfo for musl. Confirm a double-free/overlap by allocating after the corruption and observing two pointers with the same address (e.g. i1 and i2 equal). Confirm tcache poisoning by allocating twice and verifying the second malloc returns your target address. Confirm a leak by reading a freed unsorted/small-bin chunk's fd/bk, which points into main_arena (libc) — a recognizable libc-relative address.

Workflow
Step 1: Fingerprint the Allocator and Bug
pwn checksec ./vuln
./vuln &; cat /proc/$!/maps | grep libc        # find libc path/version
strings libc.so.6 | grep "GNU C Library"       # exact version -> picks the technique

Classify the primitive: UAF (read/write after free), double-free, linear heap overflow (overwrite next chunk's size/fd), or off-by-one NUL (shrink/extend a size field).

Step 2: Get an Info Leak (libc / heap base)
# Fill tcache (7 frees), free one more so it enters the unsorted bin,
# then read the victim's fd/bk -> points into main_arena (libc).
# A heap leak (needed for safe-linking) comes from reading a freed tcache fd.
from pwn import *
libc = ELF('./libc.so.6')
# after leaking an unsorted-bin fd into 'leak':
libc.address = leak - (libc.symbols['__malloc_hook'] + 0x10)   # main_arena offset
heap_base = (heap_leak << 12)                                   # invert safe-linking shift
Step 3: Tcache Poisoning (most common modern primitive)
# Requires: ability to edit a freed chunk + (glibc>=2.32) a heap leak
victim = malloc(0x40)            # then free it into tcache
target = libc.symbols['__free_hook']   # or an app code pointer / __malloc_hook (legacy)

# Forge the safe-linked next pointer (glibc 2.32+)
fake_next = target ^ (victim_chunk_addr >> 12)
edit_freed_chunk(victim, p64(fake_next))

a = malloc(0x40)                 # consumes corrupted entry
b = malloc(0x40)                 # returns chunk AT target -> arbitrary write
Step 4: Fast-bin Dup / Double-Free Variant
# Fast-bin dup (tcache full): free A, free B, free A again -> A appears twice
free(A); free(B); free(A)
p1 = malloc(sz)                  # = A
edit(p1, p64(target - 0x10))     # overwrite fd to point near target (mind size check)
malloc(sz); malloc(sz)           # second malloc returns the target region
# Modern: use House of Botcake to overlap, then tcache-poison (see Step 3)

Then escalate: overwrite __free_hook with system and free a chunk containing "/bin/sh", or overwrite a GOT entry (Partial RELRO), or drop a one_gadget. Under Full RELRO + hook removal, pivot to FSOP or a controlled vtable.

Key Concepts

| Concept | Description | |---------|-------------| | Chunk metadata | prev_size, size (low 3 bits = A/M/P flags), and fd/bk reused as list pointers when free. | | tcache | Per-thread cache, 7 entries/size, LIFO singly-linked; first bin to receive frees and serve allocs. | | Fast bins | Singly-linked LIFO for small sizes; minimal checks -> classic fd overwrite to arbitrary alloc. | | Unsorted bin | Holds recently freed large/coalesced chunks; fd/bk leak main_arena (libc address). | | tcache poisoning | Overwrite a freed entry's next so a later malloc returns an attacker-chosen address. | | Safe-linking | glibc 2.32+ stores next as ptr ^ (chunk>>12); needs a heap leak to forge. | | Double-free / fast-bin dup | Free a chunk twice (key/intermediate-free bypass) to alias two live pointers. | | House of Botcake | Modern technique using unsorted-bin consolidation to overlap chunks for tcache poisoning. | | global_max_fast | Overwriting it enlarges fast-bin size range, re-enabling fast-bin attacks on big chunks. |

Tools & Systems

| Tool | Purpose | |------|---------| | gdb + pwndbg/GEF | heap, bins, tcachebins, vis_heap_chunks, arena, find for leaks/layout. | | pwntools | Allocation driver scripting, ELF for libc symbol offsets, p64/u64, leak math, IO. | | how2heap (shellphish) | Reference PoCs for each technique per glibc version. | | one_gadget | Single-shot execve("/bin/sh") gadget in libc after a leak. | | libc-database / libc.blukat.me | Identify the exact libc version from two leaked symbol addresses. | | muslheap | musl mallocng equivalent inspection (mchunkinfo: stride, cycling offset) for Alpine targets. | | radare2 / Ghidra | Reverse the allocation logic and locate target app structures/code pointers. |

Common Scenarios
Scenario 1: UAF + heap overflow -> arbitrary write (modern glibc)

Fill tcache, push a chunk to the unsorted bin, re-allocate overwriting only the first 8 bytes to leak the residual libc pointer. Then use a 1-byte size overflow to overlap chunks, free into tcache, and poison next (with the heap leak for safe-linking) to return a chunk over a sensitive structure.

Scenario 2: Double-free (fast-bin dup) -> hook overwrite (legacy)

Tcache full; free(h); free(i); free(h) aliases h. Allocate, point fd just before __malloc_hook, allocate twice, write a one_gadget. (Only valid on pre-2.34 glibc.)

Scenario 3: Off-by-one NUL -> double-free via size confusion

Allocate A,B,C (0x110); free B; free A and re-alloc to trigger the NUL overflow shrinking B's size to 0x100; free B again -> two tcache bins (0x110 and 0x100) point to the same address. Leverage with tcache poisoning.

Scenario 4: tcache metadata (indexes) corruption

Free the chunk holding tcache bookkeeping so a 0x100-shaped value is treated as a chunk; allocate it back to overwrite multiple bin heads at once, pivoting several size classes.

Output Format
## glibc Heap Exploitation Finding

**Vulnerability**: Heap use-after-free / double-free (CWE-416 / CWE-415)
**Severity**: Critical (arbitrary read/write -> RCE)
**Binary**: ./vuln (amd64), glibc 2.35 (safe-linking, hooks removed)

### Primitives
- UAF read on freed unsorted-bin chunk -> libc base 0x7f...000
- Heap leak from freed tcache fd -> heap base 0x55...000 (defeats safe-linking)
- House of Botcake overlap -> tcache poisoning -> arbitrary write

### Exploitation
Poisoned tcache next (mangled) to return a chunk over the FILE vtable (FSOP),
redirecting exit() flow to system("/bin/sh").

### Impact
Arbitrary code execution as the service account.

### Recommendation
1. Fix the lifetime bug: null pointers after free, prevent reuse/double-free.
2. Build with -D_FORTIFY_SOURCE=2, Full RELRO, PIE; keep glibc current (safe-linking, hook removal).
3. Add allocation hardening (e.g. hardened allocators, MALLOC_CHECK_/glibc tcache checks) where feasible.
4. Validate all size/length inputs to prevent overflow into chunk metadata.
按 MIT 许可原样转载,未经改动 · 在 GitHub 查看 →

评论

登录即可评论;带「已验证安装」的,是发布者名下有本店的安装或持有记录。