Interactive Visualization

Use-After-Free

A pointer outlives the memory it points to. The allocator hands that memory to someone else — and the old pointer becomes a weapon.

Ready. Step through the program to see how a use-after-free becomes code execution.
Current Scenario
A C++ program allocates a User object on the heap with a virtual method. It frees the object, then later (through a bug in cleanup logic) calls the method through the stale pointer. Meanwhile, an attacker has triggered an allocation of the same size — the allocator hands them the freed block, and they fill it with a fake vtable that points to their shellcode.
Vulnerable Code
1User* u = new User("alice");
2u->greet(); // normal use
3delete u; // object freed
4// u still holds the old address (dangling)
5attacker_alloc(FAKE_VTABLE); // reuses the freed block
6u->greet(); // UAF: dispatch through fake vtable
Pointers
u
UNSET
atk
UNSET
Heap (block at 0x7f8a0040, 32 bytes)
Execution Log
[INIT] Program loaded. Heap is empty.

Why use-after-free is dangerous

The bug itself is small: a pointer is used after the memory it references has been returned to the allocator. The danger is what the allocator does next. Modern heap allocators reuse freed blocks aggressively, often handing the same address back to the very next allocation of the matching size class.

An attacker who controls allocations — for example, by submitting strings to a web service or triggering features in a browser — can deliberately race in and take ownership of the freed block. They fill it with attacker-chosen bytes. When the original code dereferences its stale pointer, it reads those bytes as if they were still its own object.

In C++ and other object-oriented languages, the most common exploitation path is a virtual function call. Objects with virtual methods store a hidden pointer to a vtable — a table of function pointers — at the start of the object. Overwrite the vtable pointer, point it at attacker-controlled memory, and the next virtual call jumps wherever the attacker wants. Combined with techniques like ROP (Return-Oriented Programming), this gives full code execution.

The defensive answer is layered: smart pointers (unique_ptr, shared_ptr) that tie lifetime to scope; memory-safe languages like Rust whose borrow checker rejects use-after-free at compile time; and runtime defenses like delayed free, heap isolation, and type-after-type allocators that refuse to hand a freed block to a different type. None of these are perfect — but each one closes off attack surface that decades of CVEs have shown attackers will absolutely exploit.

In the wild

CVE-2021-30551
Chrome V8
Type confusion in V8 leading to use-after-free. Exploited in the wild by NSO Group's Pegasus chain. Patched in Chrome 91.0.4472.101.
CVE-2022-0609
Chrome Animation
Use-after-free in animation code. Targeted attacks against South Korean media and political organizations. Forced an emergency Chrome release.
CVE-2023-23397
Microsoft Outlook
Privilege elevation via NTLM hash leak combined with object-lifetime bugs. Patched March 2023; exploitation observed pre-patch.
CVE-2024-38080
Windows Hyper-V
Use-after-free in Hyper-V leading to local privilege escalation to SYSTEM. Patched July 2024 Patch Tuesday after observed exploitation.