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.

install
source · Clone the upstream repo
git clone https://github.com/abelrguezr/hacktricks-skills
manifest: skills/binary-exploitation/libc-heap/use-after-free/use-after-free/SKILL.MD
source content

Use-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:

  1. Allocates space in the heap for an object
  2. Writes data to that memory location
  3. Frees the memory (marking it as available for reuse)
  4. 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()
    ,
    calloc()
    , or
    realloc()
  • Memory is freed with
    free()
  • The pointer is used after
    free()
    without reassignment
  • 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:

  1. When you
    free()
    a block, it's added to a free list
  2. New
    malloc()
    requests pull from that list
  3. Attackers can manipulate which blocks get reused
  4. 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

  1. Identify the UAF: Find where freed memory is accessed
  2. Determine what's stored: What data was in the freed chunk?
  3. Control reallocation: Allocate memory to get the freed chunk
  4. Write payload: Store your malicious data in the reallocated chunk
  5. Trigger the use: Cause the program to access the freed pointer
  6. 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

  1. NULL after free: Set pointers to NULL immediately after freeing

    free(ptr);
    ptr = NULL;
    
  2. Use smart pointers: In C++, prefer

    std::unique_ptr
    or
    std::shared_ptr

  3. Safe allocators: Use allocators with UAF detection (e.g., AddressSanitizer)

  4. Object pools: Use object pools that invalidate freed objects

For Analysts

  1. Static analysis: Use tools like Valgrind, AddressSanitizer
  2. Dynamic analysis: Monitor malloc/free patterns at runtime
  3. Code review: Look for the UAF pattern in code

Tools and Resources

Debugging Tools

  • gdb: Set breakpoints on
    malloc
    ,
    free
    , and the vulnerable access
  • valgrind: Detect use-after-free with
    --leak-check=full
  • AddressSanitizer: Compile with
    -fsanitize=address
    for UAF detection

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

  1. Assuming free() invalidates memory: It doesn't - the data remains until overwritten
  2. Ignoring allocator behavior: Different allocators handle free lists differently
  3. Missing the timing window: UAF exploitation requires precise timing between free and reallocation
  4. Overlooking ASLR: Address Space Layout Randomization may require additional techniques

Next Steps

After identifying a UAF vulnerability:

  1. Map the heap: Understand the memory layout
  2. Control the allocator: Manipulate which chunks get freed/allocated
  3. Craft the payload: Determine what data to write
  4. Test the exploit: Verify the UAF triggers as expected
  5. Bypass protections: Handle ASLR, stack canaries, etc.

References

  • glibc malloc implementation details
  • First-fit allocator behavior
  • Heap exploitation techniques
  • Memory corruption vulnerability classes