Hacktricks-skills heap-unlink-exploitation
How to analyze and exploit the unlink operation in glibc heap management. Use this skill whenever the user mentions heap exploitation, unlink attacks, glibc malloc, heap chunks, double-linked lists, heap leaks, libc leaks, or any CTF challenge involving heap memory corruption. This skill helps understand the unlink mechanism, security checks, and how to leak addresses from unlinked chunks.
git clone https://github.com/abelrguezr/hacktricks-skills
skills/binary-exploitation/libc-heap/heap-memory-functions/unlink/SKILL.MDHeap Unlink Exploitation
This skill helps you understand and exploit the
unlink operation in glibc's heap management system. The unlink function is critical for heap exploitation because it's where many vulnerabilities manifest.
When to Use This Skill
Use this skill when:
- You're working on a CTF challenge involving heap exploitation
- You need to understand how glibc's malloc handles chunk removal
- You want to leak libc or heap addresses through unlink operations
- You're analyzing heap corruption vulnerabilities
- You need to understand the security checks in unlink
The Unlink Operation
What is Unlink?
When a chunk is freed, glibc removes it from its bin list using the
unlink_chunk function. This operation manipulates the doubly-linked list pointers (fd and bk) to remove the chunk from the list.
The Core Unlink Logic
mchunkptr fd = p->fd; mchunkptr bk = p->bk; fd->bk = bk; bk->fd = fd;
This is the dangerous part: unlink writes to memory at
and fd
without verifying they point to valid locations. If you can control these pointers through heap corruption, you can write arbitrary values to arbitrary addresses.bk
Visual Representation
Before unlink: [fd] <-> [P] <-> [bk] | | | v v v bk P fd After unlink: [fd] <-> [bk] | | v v bk fd
Security Checks
Modern glibc versions include several checks to prevent exploitation:
1. Size Check
if (chunksize(p) != prev_size(next_chunk(p))) malloc_printerr("corrupted size vs. prev_size");
- Verifies the chunk's size matches the
field in the next chunkprev_size - Bypass: Ensure size consistency when crafting exploits
2. Double-Linked List Integrity
if (fd->bk != p || bk->fd != p) malloc_printerr("corrupted double-linked list");
- Confirms the pointers form a valid doubly-linked list
- Bypass: Maintain pointer consistency in your fake chunks
3. Nextsize Checks (for non-small bins)
if (p->fd_nextsize->bk_nextsize != p || p->bk_nextsize->fd_nextsize != p) malloc_printerr("corrupted double-linked list (not small)");
- Additional checks for large bins with nextsize pointers
- Bypass: Handle nextsize pointers if targeting large bins
Address Leaks Through Unlink
Unlinked chunks don't clean their pointers, making them valuable for information leaks.
Libc Address Leaks
| Chunk Position | Pointer | Leaks |
|---|---|---|
| Head of list | | in libc |
| End of list | | in libc |
| Only chunk in list | and | in libc |
Heap Address Leaks
| Chunk Position | Pointer | Leaks |
|---|---|---|
| Head of list | | Next available heap chunk |
| End of list | | Previous available heap chunk |
| Middle of list | and | Adjacent heap chunks |
Exploitation Patterns
Pattern 1: Arbitrary Write via Unlink
If you can corrupt
fd and bk pointers:
- Allocate chunks A, B, C in sequence
- Corrupt B's
to point tofdtarget_addr - 8 - Corrupt B's
to point tobktarget_addr - 16 - Free B (triggers unlink)
- Result:
gets overwritten with controlled valuetarget_addr
Pattern 2: Libc Leak
- Allocate a chunk in a bin
- Free it (it becomes unlinked but pointers remain)
- Read the chunk's
orfd
pointerbk - Calculate libc base from the leaked
addressmalloc_state
Pattern 3: Heap Leak
- Allocate multiple chunks
- Free one chunk (unlinked)
- Read its
/fd
to discover other heap addressesbk - Use this to calculate heap base or find other allocations
Practical Workflow
Step 1: Identify the Vulnerability
Look for:
- Use-after-free bugs
- Heap buffer overflows
- Double-free vulnerabilities
- Off-by-one errors in heap allocations
Step 2: Map the Heap Layout
- Determine chunk sizes and positions
- Identify which bin each chunk belongs to
- Understand the doubly-linked list structure
Step 3: Plan the Exploit
- Decide your goal (arbitrary write, leak, etc.)
- Calculate required pointer values
- Ensure all security checks will pass
- Craft the payload
Step 4: Execute and Verify
- Trigger the unlink operation
- Verify the write/leak succeeded
- Proceed with the rest of the exploit
Common Pitfalls
- Size mismatches: Ensure
matcheschunksize
in next chunkprev_size - Alignment issues: Heap chunks must be properly aligned (typically 8 or 16 bytes)
- Bin selection: Different bins have different checks (small vs. large bins)
- Top chunk: Don't try to unlink the top chunk
- In-use chunks: Can only unlink free chunks in bins
Debugging Tips
Using GDB with Heap Analysis
# Load the binary gdb ./vulnerable_program # Enable heap debugging set follow-fork-mode child # Use heap tools heap heap chunks heap bins
Using Pwntools
from pwn import * # Connect to the target p = process('./vulnerable') # Use heap analysis from pwn import heap heap(p)
Example Scenario
Challenge: A program has a use-after-free vulnerability in a heap-allocated buffer.
Goal: Leak libc address to bypass ASLR.
Approach:
- Allocate chunk A (victim)
- Allocate chunk B (to corrupt)
- Free A (it goes to a bin)
- Overwrite A's
/fd
through B's overflowbk - Free B (triggers unlink on A)
- Read A's pointers to leak libc
Related Concepts
- Heap bins: tcache, smallbins, largebins, unsortedbin
- Chunk structure: size, prev_size, fd, bk, fd_nextsize, bk_nextsize
- Other heap attacks: House of Force, House of Spirit, Tcache poisoning
- Memory protection: ASLR, PIE, Stack canaries, Heap canaries
References
Remember: Heap exploitation is complex and version-dependent. Always verify your assumptions against the target's glibc version and configuration.