Heap Exploitation
The heap is the dynamic memory managed by malloc/free. Unlike the stack, there are no return addresses to overwrite, but the memory manager (the allocator) stores metadata between and around chunks, and that metadata can be corrupted. Heap exploitation consists of manipulating that metadata —via overflows, use-after-free, double-free— to trick the allocator into arbitrary writes that end in control of the flow. It’s more complex than the stack and very dependent on the libc version.
The allocator (glibc / ptmalloc)
Section titled “The allocator (glibc / ptmalloc)”# a memory chunk has a header with metadata:[ prev_size ][ size | flags ][ ... user data ... ]# on free, free chunks are stored in linked lists (bins):tcache (glibc >=2.26) fast per-size lists (the modern target)fastbins LIFO lists for small chunksunsorted/small/large bins# the fd/bk pointers of those lists live in the freed chunk's dataThe key: when a chunk is freed, the allocator writes list pointers into its data area. If you control those pointers, you control where the allocator “thinks” free chunks are → malloc returns a pointer wherever you want.
Heap vulnerability classes
Section titled “Heap vulnerability classes”Heap overflow write past a chunk -> corrupt the next chunk's headerUse-After-Free (UAF) use a chunk after free -> read/write another's data, or bin pointersDouble-Free free twice -> corrupt the lists (tcache/fastbin)Type confusion treat an object as another typeClassic techniques (by libc version)
Section titled “Classic techniques (by libc version)”tcache poisoning (modern, the most common) corrupt a chunk's fd in tcache -> the next malloc returns a controlled addressfastbin dup fastbin double-free -> return the same chunk twiceunlink (old) abuse the unlink macro -> arbitrary writeHouse of <X> family of advanced techniques (Spirit, Force, Einherjar, Orange...) for scenarios with limited primitivestcache poisoning (the modern daily bread)
Section titled “tcache poisoning (the modern daily bread)”# with a UAF or double-free over tcache:1. free(A) # A goes to tcache; its fd points to the next free2. edit A->fd = target_address # corrupt the pointer (UAF/overflow)3. malloc() -> returns A4. malloc() -> returns target_address # write/read wherever you want!# typical target: __free_hook / __malloc_hook (old libc) or the GOT -> systemFrom arbitrary write to shell
Section titled “From arbitrary write to shell”# with a heap write-what-where:# old libc: overwrite __free_hook = system, then free(chunk with "/bin/sh")# modern libc (no hooks): FSOP (File Stream Oriented Programming),# overwrite _IO_FILE structures, or point to one_gadgetpwntools interaction and packinggdb + pwndbg/GEF heap commands: 'heap', 'bins', 'tcache' -> see the allocator stateglibc source / how2heap reference of techniques by version# how2heap (shellphish): reproducible examples of EVERY techniqueVersion dependency
Section titled “Version dependency”Heap exploitation changes a lot between glibc versions (mitigations are added: tcache key, safe-linking from 2.32, etc.). Always identify the exact libc version and use the applicable technique:
# safe-linking (glibc >=2.32): tcache/fastbin fd pointers are "encrypted" with the address# -> you need a heap leak to compute the correct valueFor the defense
Section titled “For the defense”- Updated glibc (heap mitigations: tcache key against double-free, safe-linking).
- Hardened allocators (e.g. hardened_malloc) in critical environments.
- Sanitizers (ASan, with UAF/heap-overflow detection) in development and fuzzing.
- Memory-safe languages (Rust) eliminate UAF/double-free by design.
- Code review of pointer/size handling; don’t use pointers after free (set to NULL).
Testing checklist
Section titled “Testing checklist”- Identify the exact glibc version
- Identify the bug: overflow / UAF / double-free
- See the heap state in gdb (heap/bins/tcache)
- Heap leak if safe-linking (>=2.32)
- tcache/fastbin poisoning → malloc returns a controlled address
- Write-what-where → __free_hook/GOT/FSOP → system/one_gadget
- Shell/flag locally → remote
- Practice the specific technique with how2heap