Skip to main content
skill CX Codex

heap-exploitation — Claude Code skill: glibc heap attack playbook

A playbook for ptmalloc2 heap exploitation: UAF, double free, overflow, plus tcache, fastbin and unsortedbin attacks. Useful for CTF work and glibc bug triage.

Install into Claude Code · Skills CLI (Vercel) All methods and platforms ↓
npx skills add yaklang/hack-skills --skill heap-exploitation -a claude-code
Open on GitHub

What heap-exploitation does

The skill hands the agent a reference on ptmalloc2 internals: the malloc_chunk layout, a bin table with size ranges and LIFO/FIFO order, and where main_arena, mp_ and tcache_perthread_struct live. A separate section covers libc and heap address leaks, including safe-linking decode via XOR with the chunk address shifted right by 12.

Attack selection is split by glibc version. Below 2.26 you get fastbin dup, unsortedbin attack, unlink and House of Force. In 2.26–2.28 tcache arrives with no key check; 2.29–2.31 adds the key, bypassed with House of Botcake or tcache stashing unlink. From 2.32 PROTECT_PTR is on, so forging pointers needs a heap leak first. From 2.34 __malloc_hook, __free_hook and __realloc_hook are gone, and the skill points to _IO_FILE, exit_funcs and TLS_dtor_list instead.

It also maps common bugs to exploitation paths: use-after-free, double free, chunk overflow, off-by-one and off-by-null clearing PREV_INUSE. For debugging it lists pwndbg commands — heap, bins, tcachebins, fastbins, unsortedbin. When the overflow sits on the stack rather than the heap, the skill routes you to stack-overflow-and-rop.

What it helps with

  • pick the right attack for a given glibc version
  • leak a libc address through unsortedbin
  • bypass safe-linking when forging a tcache fd
  • turn a double free into allocation at a chosen address
  • find a write target on glibc 2.34 and newer

Example prompts for the agent

  • analyze this binary, find the UAF and propose a heap exploitation chain
  • which tcache attack works on glibc 2.31?
  • compute the safe-linked fd value given the chunk address

How to install heap-exploitation

1Skills CLI (Vercel)

npx skills add yaklang/hack-skills --skill heap-exploitation -a claude-code

2Manually: put the files in place

~/.claude/skills/heap-exploitation/SKILL.md

Copy the whole skill folder; for one project use .claude/skills/heap-exploitation/

Step by step, with commands for each platform: How to install skills in Claude Code: five ways

Questions about heap-exploitation

How do I install heap-exploitation in Claude?

Run npx skills add yaklang/hack-skills --skill heap-exploitation -a claude-code. The skill file then lands at ~/.claude/skills/heap-exploitation/SKILL.md.

What does heap-exploitation do?

It is a glibc heap exploitation playbook: ptmalloc2 structure, bin mechanics, address leak methods and attack choice by glibc version. The agent leans on it when a task involves UAF, double free or chunk overflow.

Why do hook overwrites fail on glibc 2.34?

That release removed __malloc_hook, __free_hook and __realloc_hook, so the one_gadget-via-hook trick is out. The skill lists other targets: _IO_FILE, exit_funcs, TLS_dtor_list.

Source text

SKILL.md · MIT
---
name: heap-exploitation
description: >-
  Heap exploitation playbook. Use when targeting ptmalloc2/glibc heap vulnerabilities including UAF, double free, overflow, off-by-one/null, and leveraging tcache/fastbin/unsortedbin attacks for arbitrary write or code execution.
---

# SKILL: Heap Exploitation — Expert Attack Playbook

> **AI LOAD INSTRUCTION**: Expert glibc heap exploitation techniques. Covers ptmalloc2 internals, bin structures, tcache mechanics, libc/heap leak methods, and attack selection by glibc version. Distilled from ctf-wiki heap sections, how2heap, and real-world exploitation. Base models often confuse glibc version constraints and miss safe-linking (PROTECT_PTR) introduced in 2.32.

## 0. RELATED ROUTING

- [stack-overflow-and-rop](../stack-overflow-and-rop/SKILL.md) — when the overflow is on the stack rather than the heap
- [format-string-exploitation](../format-string-exploitation/SKILL.md) — leak heap/libc addresses via format string
- [arbitrary-write-to-rce](../arbitrary-write-to-rce/SKILL.md) — convert heap arbitrary write into code execution
- [binary-protection-bypass](../binary-protection-bypass/SKILL.md) — bypass ASLR/RELRO to use heap write effectively

### Advanced References

- [HOUSE_OF_TECHNIQUES.md](./HOUSE_OF_TECHNIQUES.md) — House of Force/Spirit/Orange/Einherjar/Roman/Pig/Banana/Cat/Apple and tcache attacks
- [IO_FILE_EXPLOITATION.md](./IO_FILE_EXPLOITATION.md) — _IO_FILE vtable hijack, FSOP, stdout/stdin abuse, exit flow exploitation

---

## 1. PTMALLOC2 STRUCTURE QUICK REFERENCE

### malloc_chunk Layout (64-bit)

```
         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 Types

| Bin | Size Range (64-bit) | Structure | LIFO/FIFO |
|---|---|---|---|
| tcache (per-thread) | ≤ 0x410 (7 entries per size) | Singly linked (next pointer) | LIFO |
| fastbin | ≤ 0x80 (default) | Singly linked (fd) | LIFO |
| unsortedbin | Any freed size | Doubly linked circular | FIFO |
| smallbin | < 0x400 | Doubly linked circular | FIFO |
| largebin | ≥ 0x400 | Doubly linked + size-sorted | Sorted |

### Key Global Structures

| Structure | Location | Purpose |
|---|---|---|
| `main_arena` | libc .data segment | Contains bin heads, top chunk, system_mem |
| `mp_` | libc .data | malloc parameters (tcache settings, mmap threshold) |
| `tcache_perthread_struct` | Heap (first allocation) | Per-thread tcache bins and counts |

---

## 2. LEAK METHODS

### Libc Base Leak

| Method | Precondition | Technique |
|---|---|---|
| Unsortedbin fd/bk | Free a chunk > tcache range (or fill tcache) | fd/bk → `main_arena + 0x60` (or +0x70 depending on version) → libc base |
| Smallbin fd/bk | Chunk moved from unsortedbin to smallbin | Same as unsortedbin leak |
| stdout FILE leak | Write to `_IO_2_1_stdout_` | Corrupt `_IO_write_base` to leak libc data (see IO_FILE) |

### Heap Base Leak

| Method | Precondition | Technique |
|---|---|---|
| Tcache fd pointer | Free two tcache chunks, read first's fd | fd → heap address (XOR'd in ≥ 2.32) |
| Fastbin fd | Free two fastbin chunks | fd → heap address |
| UAF read | Use-after-free on freed chunk | Read fd/bk directly |

### Safe-Linking Decode (glibc ≥ 2.32)

```python
# 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. ATTACK CATEGORIES BY GLIBC VERSION

### glibc < 2.26 (No tcache)

| Attack | Primitive Needed | Result |
|---|---|---|
| Fastbin dup | Double free | Arbitrary allocation |
| Unsortedbin attack | Corrupt unsortedbin bk | Write `main_arena` addr to target (used for __malloc_hook nearby overwrite) |
| Unlink attack | Heap overflow into prev_size + fd/bk | Arbitrary write (with known heap pointer) |
| House of Force | Top chunk size overwrite | Arbitrary allocation |
| House of Spirit | Write fake chunk header | Fastbin allocation at fake chunk |
| Off-by-one null | Null byte overflow into next chunk size | Overlapping chunks |

### glibc 2.26–2.28 (tcache, no key)

| Attack | Notes |
|---|---|
| Tcache poisoning | Overwrite tcache fd → arbitrary allocation, no size check |
| Tcache dup | Double free into tcache (no double-free detection yet) |
| All previous attacks | Still work, but chunks go to tcache first |

### glibc 2.29–2.31 (tcache key introduced)

| Attack | Bypass for tcache key |
|---|---|
| Tcache dup | Corrupt `key` field (at chunk+0x18) before second free |
| House of Botcake | Double free: one in unsortedbin, one in tcache → overlapping |
| Tcache stashing unlink | Abuse smallbin→tcache refill to get arbitrary chunk |

### glibc 2.32–2.33 (safe-linking / PROTECT_PTR)

| Attack | Adaptation |
|---|---|
| Tcache poisoning | Encode target with `(chunk_addr >> 12) ^ target` |
| Heap leak required | Need heap addr to decode/encode safe-linked pointers |
| Fastbin dup | Same encoding required |

### glibc ≥ 2.34 (hooks removed)

| Change | Impact |
|---|---|
| `__malloc_hook` removed | Cannot overwrite hook for one_gadget |
| `__free_hook` removed | Cannot overwrite hook |
| `__realloc_hook` removed | Cannot use realloc trick for one_gadget constraints |

**Post-2.34 targets**: see [arbitrary-write-to-rce](../arbitrary-write-to-rce/SKILL.md) for `_IO_FILE`, `exit_funcs`, `TLS_dtor_list`, `_dl_fini`.

---

## 4. COMMON VULNERABILITY PATTERNS

| Vulnerability | Description | Exploitation Path |
|---|---|---|
| UAF (Use-After-Free) | Access chunk after free | Read: leak fd/bk; Write: corrupt fd for tcache poisoning |
| Double Free | free() same chunk twice | Tcache dup (bypass key) or fastbin dup |
| Heap Overflow | Write past chunk boundary | Corrupt next chunk's metadata (size, fd, bk) |
| Off-by-one | One byte overflow | Null byte → shrink next chunk size → overlapping chunks |
| Off-by-null | Specifically `\x00` overflow | Clear PREV_INUSE → trigger backward consolidation |
| Uninitialized read | Read heap memory without clearing | Leak fd/bk from recycled chunk |

---

## 5. TOOLS

```bash
# 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. DECISION TREE

```
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)
```

© yaklang · MIT · yaklang/hack-skills

Similar skills

Everything for Security →

From the same set93

ssrf-server-side-request-forgery A skill for reviewing SSRF in features that fetch URLs, resolve hostnames, import remote content, or reach internal services. CX Codex +1 3,900installs traffic-analysis-pcap A playbook for network capture analysis: Wireshark filters, protocol breakdowns, covert channel detection and TLS decryption. CX Codex +1 3,700installs oauth-oidc-misconfiguration Testing playbook for OAuth 2.0 and OpenID Connect configurations. It guides security reviews of redirect URIs, state parameters, PKCE enforcement, and account binding flows. CX Codex +1 3,700installs csrf-cross-site-request-forgery A CSRF testing playbook for state-changing web flows, token checks, SameSite behavior, JSON requests, login CSRF, and OAuth state. CX Codex +1 3,700installs business-logic-vuln Routes security testing toward business logic and state machine flaws. Focuses on race conditions, stacked discounts, quota bypasses, and workflow abuse. CX Codex +1 3,700installs recon-for-sec Routes initial reconnaissance for a new application, from attack-surface mapping to the next security testing path. CX Codex +1 3,700installs ios-pentesting-tricks A playbook for iOS app testing: keychain extraction, URL scheme hijacking, Universal Links abuse and runtime hooks. CX Codex +1 3,700installs cors-cross-origin-misconfiguration Guides testing of CORS misconfigurations, origin reflection, and credentialed API access. Useful when auditing cross-origin boundaries and cache policies. CX Codex +1 3,700installs

Project sponsors

Companies that keep this analytics open
Gold sponsor

Impressions, clicks and code copies — open statistics. We keep the numbers public for the same reason NeBlask itself is public. Become a sponsor