Hacktricks-skills use-after-free-exploitation
How to identify and exploit Use-After-Free (UAF) vulnerabilities in heap memory. Use this skill whenever the user mentions heap vulnerabilities, memory corruption, use-after-free, freed memory access, first-fit attacks, or binary exploitation involving heap management. This skill covers UAF detection, exploitation techniques, and practical attack scenarios.
git clone https://github.com/abelrguezr/hacktricks-skills
skills/binary-exploitation/libc-heap/use-after-free/use-after-free/SKILL.MDUse-After-Free (UAF) Exploitation
A skill for identifying and exploiting Use-After-Free vulnerabilities in heap memory management.
What is Use-After-Free?
A Use-After-Free vulnerability occurs when a program:
- Allocates space in the heap for an object
- Writes data to that memory location
- Frees the memory (marking it as available for reuse)
- Accesses the freed memory again through the original pointer
The critical issue: accessing freed memory is not illegal and produces no errors. If an attacker can allocate that freed memory and store arbitrary data, when the program accesses it through the original pointer, the attacker's data will be read instead of the original data.
When to Use This Skill
Use this skill when:
- Analyzing heap-based vulnerabilities in C/C++ programs
- Investigating memory corruption bugs
- Working with glibc malloc/free implementations
- Exploiting freed memory access patterns
- Understanding first-fit allocator attacks
- Preparing for CTF challenges involving heap exploitation
Identifying UAF Vulnerabilities
Code Patterns to Look For
// Classic UAF pattern char *ptr = malloc(100); strcpy(ptr, "data"); free(ptr); // Memory freed // ... later ... printf(ptr); // UAF: accessing freed memory!
Detection Checklist
- Memory is allocated with
,malloc()
, orcalloc()realloc() - Memory is freed with
free() - The pointer is used after
without reassignmentfree() - No NULL assignment after free (common mitigation)
- No double-free protection in place
First-Fit Attack Technique
How It Works
The first-fit attack exploits how memory allocators like glibc manage freed memory:
- When you
a block, it's added to a free listfree() - New
requests pull from that listmalloc() - Attackers can manipulate which blocks get reused
- This allows control over reallocated memory contents
Attack Flow
1. Target allocates chunk A → free(A) → chunk A is freed 2. Attacker allocates chunk B → gets chunk A's memory 3. Attacker writes malicious data to chunk B 4. Target accesses chunk A → reads attacker's data 5. If chunk A contained a function pointer → attacker controls execution
Exploitation Steps
- Identify the UAF: Find where freed memory is accessed
- Determine what's stored: What data was in the freed chunk?
- Control reallocation: Allocate memory to get the freed chunk
- Write payload: Store your malicious data in the reallocated chunk
- Trigger the use: Cause the program to access the freed pointer
- Achieve goal: Redirect execution, leak data, or corrupt state
Practical Exploitation Scenarios
Scenario 1: Function Pointer Hijacking
If the freed memory contained a function pointer:
struct callback { void (*func)(); int data; }; struct callback *cb = malloc(sizeof(*cb)); cb->func = legitimate_function; free(cb); // ... attacker reallocates ... cb->func(); // Calls attacker-controlled function!
Exploitation: Reallocate the chunk, overwrite the function pointer with your shellcode address.
Scenario 2: Data Corruption
If the freed memory contained sensitive data:
struct user { char *username; int privileges; }; struct user *u = malloc(sizeof(*u)); u->privileges = 0; free(u); // ... attacker reallocates ... if (u->privileges) { // Attacker can set this to 1! grant_admin(); }
Exploitation: Reallocate and set
privileges = 1 to escalate privileges.
Scenario 3: Information Leak
If the freed memory contained pointers or secrets:
struct secret { char *key; void *internal_ptr; }; struct secret *s = malloc(sizeof(*s)); // ... sensitive data stored ... free(s); // ... attacker reallocates ... printf(s->key); // Attacker can leak this!
Exploitation: Reallocate and read the leaked data through the original pointer.
Mitigation Techniques
For Developers
-
NULL after free: Set pointers to NULL immediately after freeing
free(ptr); ptr = NULL; -
Use smart pointers: In C++, prefer
orstd::unique_ptrstd::shared_ptr -
Safe allocators: Use allocators with UAF detection (e.g., AddressSanitizer)
-
Object pools: Use object pools that invalidate freed objects
For Analysts
- Static analysis: Use tools like Valgrind, AddressSanitizer
- Dynamic analysis: Monitor malloc/free patterns at runtime
- Code review: Look for the UAF pattern in code
Tools and Resources
Debugging Tools
- gdb: Set breakpoints on
,malloc
, and the vulnerable accessfree - valgrind: Detect use-after-free with
--leak-check=full - AddressSanitizer: Compile with
for UAF detection-fsanitize=address
Analysis Commands
# Compile with AddressSanitizer gcc -fsanitize=address -g vulnerable.c -o vulnerable # Run and detect UAF ./vulnerable # GDB heap analysis gdb ./vulnerable (gdb) break free (gdb) break malloc (gdb) run
Common Pitfalls
- Assuming free() invalidates memory: It doesn't - the data remains until overwritten
- Ignoring allocator behavior: Different allocators handle free lists differently
- Missing the timing window: UAF exploitation requires precise timing between free and reallocation
- Overlooking ASLR: Address Space Layout Randomization may require additional techniques
Next Steps
After identifying a UAF vulnerability:
- Map the heap: Understand the memory layout
- Control the allocator: Manipulate which chunks get freed/allocated
- Craft the payload: Determine what data to write
- Test the exploit: Verify the UAF triggers as expected
- Bypass protections: Handle ASLR, stack canaries, etc.
References
- glibc malloc implementation details
- First-fit allocator behavior
- Heap exploitation techniques
- Memory corruption vulnerability classes