| name | libc-heap-exploitation |
| description | How to understand and exploit libc heap vulnerabilities in glibc and musl allocators. Use this skill whenever the user mentions heap exploitation, malloc/free vulnerabilities, chunk manipulation, arena analysis, bin attacks, or any heap-related binary exploitation tasks. Also trigger for debugging heap corruption, analyzing malloc_state structures, or working with heap chunks in GDB/pwndbg. |
Libc Heap Exploitation
A comprehensive guide to understanding and exploiting heap vulnerabilities in glibc and musl memory allocators.
Quick Reference
Core Concepts
- Heap: Dynamic memory region managed by
malloc/free
- Chunk: Individual allocated memory block with metadata headers
- Arena: Per-thread heap region (main arena + secondary arenas)
- Bins: Free chunk lists (fastbins, smallbins, largebins, unsortedbin)
- Subheaps: mmap'd memory regions for secondary arenas
Key Structures
malloc_chunk (glibc)
struct malloc_chunk {
INTERNAL_SIZE_T mchunk_prev_size;
INTERNAL_SIZE_T mchunk_size;
struct malloc_chunk* fd;
struct malloc_chunk* bk;
struct malloc_chunk* fd_nextsize;
struct malloc_chunk* bk_nextsize;
};
malloc_state (glibc)
struct malloc_state {
__libc_lock_define(, mutex);
int flags;
int have_fastchunks;
mfastbinptr fastbinsY[NFASTBINS];
mchunkptr top;
mchunkptr last_remainder;
mchunkptr bins[NBINS * 2 - 2];
unsigned int binmap[BINMAPSIZE];
struct malloc_state *next;
struct malloc_state *next_free;
INTERNAL_SIZE_T attached_threads;
INTERNAL_SIZE_T system_mem;
INTERNAL_SIZE_T max_system_mem;
};
Chunk Size Flags (last 3 bits of mchunk_size)
| Bit | Flag | Meaning |
|---|
| 0x1 | PREV_INUSE | Previous chunk is in use |
| 0x2 | IS_MMAPPED | Chunk obtained via mmap() |
| 0x4 | NON_MAIN_ARENA | Chunk from non-main arena |
Heap Analysis Workflow
Step 1: Identify the Allocator
# Check if glibc or musl
pwndbg> checksec
pwndbg> version
# For musl (Alpine), use muslheap plugin
pwndbg> mchunkinfo <address>
Step 2: Locate malloc_state
# glibc main arena is a global in libc
pwndbg> find libc.so.2 malloc_state
pwndbg> x/20gx $main_arena
# Or via __malloc_hook
pwndbg> p __malloc_hook
pwndbg> x/20gx __malloc_hook-0x10
Step 3: Inspect Chunks
# View chunk structure
pwndbg> heap_chunk <address>
# View all chunks in arena
pwndbg> heap
# Check chunk flags
pwndbg> p *(struct malloc_chunk*)<address>
# Get usable size
pwndbg> p memsize(chunk_ptr)
Step 4: Analyze Bins
# Fastbins (0-10)
pwndbg> fastbins
# Smallbins (11-124)
pwndbg> smallbins
# Largebins (125-126)
pwndbg> largebins
# Unsortedbin (127)
pwndbg> unsortedbin
Common Exploitation Patterns
1. Chunk Metadata Corruption
Goal: Overwrite chunk size to merge with adjacent chunks
char *chunk1 = malloc(0x50);
char *chunk2 = malloc(0x50);
memcpy(chunk1, payload, 0x50 + 0x10);
Key checks:
- Size must be aligned (16-byte on 64-bit)
- PREV_INUSE bit must be set for next chunk
- Size must be larger than MIN_CHUNK_SIZE
2. Use-After-Free (UAF)
Goal: Reuse freed chunk with controlled content
char *victim = malloc(0x50);
free(victim);
char *reuse = malloc(0x50);
Detection:
pwndbg> heap
# Look for chunks with same address but different allocation state
3. Double Free
Goal: Create overlapping chunks for arbitrary writes
char *chunk = malloc(0x50);
free(chunk);
free(chunk);
Exploitation:
- First malloc after double free gets the chunk
- Second malloc gets the same chunk (overlap)
- Write through one pointer affects the other
4. Fastbin Attack
Goal: Control fastbin linked list for arbitrary write
for (int i = 0; i < 7; i++) {
chunks[i] = malloc(0x20);
free(chunks[i]);
}
*(size_t*)(fake_chunk + 0x10) = target_address;
malloc(0x20);
Requirements:
- Fastbin top chunk size must match request
- Fastbin count < 7 (MAX_FASTBIN)
- Target address must be valid write location
5. Unsorted Bin Attack
Goal: Use unsortedbin consolidation for arbitrary read/write
char *large = malloc(0x100);
free(large);
char *leak = malloc(0x100);
Arena and Multithreading
Arena Creation
pthread_t t1;
pthread_create(&t1, NULL, thread_func, NULL);
Arena Limits
| Architecture | Max Arenas |
|---|
| 32-bit | 2 × CPU cores |
| 64-bit | 8 × CPU cores |
Subheap Behavior
# Subheaps use mmap instead of brk
pwndbg> vmmap
# Look for [anon] regions with heap-like patterns
# Subheap size defaults
# 32-bit: 1 MB
# 64-bit: 64 MB
musl mallocng Specifics
Key Differences from glibc
- No arenas: Single allocator for all threads
- Sizeclasses: Fixed-size allocation classes
- Slot cycling: User data offset may shift on reuse
- Guarded metadata: Cookies and out-of-band metadata
muslheap GDB Plugin
pwndbg> mchunkinfo <address>
# Shows:
# - stride: Allocation class size
# - cycling offset: User data offset shift
# - reserved: Whether chunk is reserved
# Example output:
# stride: 0x140
# cycling offset: 0x1 (userdata --> 0x7ffff7a94e40)
musl Exploitation Tips
- Target runtime objects over allocator metadata (guarded)
- Control reuse counts to predict cycling offsets
- Use strides without slack for predictable offsets
- Keep spans mapped for linear copy attacks
Debugging Checklist
Initial Setup
# Essential GDB commands
pwndbg> context
pwndbg> heap
pwndbg> bins
pwndbg> checksec
# For musl
pwndbg> mchunkinfo <address>
Common Issues
| Problem | Solution |
|---|
| Can't find malloc_state | Check if PIE, use find command |
| Chunk sizes don't match | Check alignment (16-byte on 64-bit) |
| Fastbin attack fails | Verify chunk size matches fastbin index |
| musl offset unpredictable | Use mchunkinfo to check cycling offset |
Verification Commands
# Verify chunk is in fastbin
pwndbg> fastbins
# Check if chunk address appears in fastbin list
# Verify chunk consolidation
pwndbg> heap
# Check if adjacent chunks merged
# Verify malloc_state leak
pwndbg> x/20gx <leaked_address>
# Should show malloc_state structure
Security Checks
glibc Heap Checks
- malloc_check: Validates chunk metadata
- free_check: Verifies chunk is valid for freeing
- unlink_check: Validates fd/bk pointers during consolidation
Bypassing Checks
References
Next Steps
After understanding heap basics, explore:
- Bin attacks: Fastbin, smallbin, largebin, unsortedbin exploitation
- Heap functions security checks: How malloc/free validate chunks
- Case studies: Real-world heap exploitation examples
- Advanced techniques: Tcache attacks, heap grooming, heap spraying