Skip to main content

Overview

The unsorted bin attack is a heap exploitation technique that allows writing a large value (a heap address) to an arbitrary memory location. It exploits the linking mechanism of the unsorted bin to perform an arbitrary write, typically used as a setup step for more complex attacks.
This technique was patched in glibc 2.29. It only works on glibc versions < 2.29.

Glibc Version Compatibility

Working Versions

glibc 2.23 - 2.28

Patched

glibc 2.29+ (April 2019)
Patch Information: glibc commit b90ddd08

What Does This Technique Achieve?

This attack allows you to:
  • Write a large value (heap address) to an arbitrary memory location
  • Overwrite global_max_fast - enable fastbin attacks on larger chunks
  • Corrupt function pointers - if you can tolerate a heap address value
  • Setup for further exploitation - prepare the heap for follow-up attacks
The unsorted bin attack is generally prepared for further attacks. A common target is the global_max_fast variable in libc, which when overwritten enables fastbin attacks on arbitrarily large chunks.

The Vulnerability

The attack requires:
  1. Heap overflow or UAF - ability to overwrite a freed chunk’s bk pointer
  2. Known target address - where you want to write the large value
  3. Subsequent malloc - to trigger the unsorted bin processing

Technical Details

Unsorted Bin Linking

When a chunk is allocated from the unsorted bin, malloc performs:
By controlling victim->bk, we control where bck->fd points, causing malloc to write unsorted_chunks(av) (a heap address) to target_address - 16 bytes.

The Write Primitive

The offset of 16 bytes accounts for the fd pointer position in the chunk structure. On 32-bit systems, use offset of 8 bytes.

Memory Layout

Step-by-Step Exploitation

1

Allocate and Free Chunk

Create a chunk and free it to place in unsorted bin:
After this, p->bk points back to unsorted_chunks(av).
2

Identify Target

Choose your target address (must be writable):
3

Corrupt bk Pointer

Exploit vulnerability to overwrite the bk pointer:
Make sure to subtract the correct offset based on architecture:
  • 64-bit: target_addr - 16 or &target - 2 (for uint64_t*)
  • 32-bit: target_addr - 8 or &target - 2 (for uint32_t*)
4

Trigger Allocation

Call malloc to trigger the unsorted bin processing:
During this malloc:
  1. Victim is removed from unsorted bin
  2. bck = victim->bk = &stack_var - 2
  3. bck->fd = unsorted_chunks(av) writes heap address to stack_var
5

Verify the Write

Check that the target was overwritten:

Full Source Code

Common Attack Targets

1. global_max_fast

The most common target for unsorted bin attack is global_max_fast in libc.
Overwriting global_max_fast with a large value allows you to:
  • Treat larger chunks as fastbin chunks
  • Bypass fastbin size checks
  • Enable fastbin attacks on arbitrary-sized chunks

2. Function Pointers

If you can tolerate the heap address value:

Why This Works

The key is in the unsorted bin’s doubly-linked list management:

The Patch (glibc 2.29)

The patch added this check:
This validates that victim->bk->fd points back to victim, preventing the attack.

Exploitation in Practice

1

Leak libc address

Use unsorted bin to leak libc addresses first
2

Unsorted bin attack

Overwrite global_max_fast to large value
3

Fastbin attack

Exploit fastbin to get arbitrary allocation
4

Code execution

Overwrite __malloc_hook or similar

0CTF 2016

zerostorage - Classic unsorted bin attack usage

Practice

Try it in your browser

Debug this technique interactively on Ret2 Wargames (glibc 2.27)
  • Unsorted Bin Into Stack - Get arbitrary allocation instead of write
  • Large Bin Attack - Similar concept with large bins (still works in modern glibc)
  • [House of Roman/techniques/house/house-of-roman) - Combines unsorted bin attack with other primitives

References