Skip to content
Rahul Sridhar edited this page Feb 6, 2022 · 8 revisions

Heap layout

This is the best resource out there for learning about heap: https://heap-exploitation.dhavalkapil.com/.

Nice bin diagrams at https://sploitfun.wordpress.com/2015/02/10/understanding-glibc-malloc/.

uaf.io has some of the best CTF chal heap tutorials http://uaf.io/exploitation/2017/03/19/0ctf-Quals-2017-BabyHeap2017.html

malloc_chunk diagrams at http://etutorials.org/Networking/network+security+assessment/Chapter+13.+Application-Level+Risks/13.5+Heap+Overflows/

malloc_state diagram: http://uaf.io/assets/malloc_state.png

Advice

  • Know where all the mallocs and frees are! Do I control sizes passed to malloc? Are there size restrictions? How do I trigger mallocs and frees?

Tooling

Use angelboy's angelheap for heap commands heapinfo, parseheap, tracemalloc on, etc.

I also use voltron memory view to get a live view of the heap region.

voltron view memory --address <heapaddr> -w 2

Leak targets

Leak a libc address and a heap address (two birds with one stone!) by printing contents of a free unsorted bin chunk (flink and blink pointers). Assumes you have overlapping chunks somehow.

Overwrite targets

  • malloc_hook First, find the main_arena address; then malloc_hook is &main_arena-0x16

The next time malloc is called, the overwritten hook will be run. Note that malloc hooks are disabled starting from glibc 2.34.

  • top_chunk Change the location that malloc serves chunks from.

Attack vectors

If you have fastbins, try to use fastbin attack to overwrite a fd ptr of a chunk.

Fastbin attacks -> Allow you to allocate a malloc chunk ANYWHERE. Allocate a chunk over the stack? Overwrite return address, bypass canary. Allocate a chunk over libc? Overwrite malloc_hook or top_chunk.

Only restriction is that the size of fastbin chunk must be a valid fastbin size. This is ok because fastbin sizes are everywhere in memory, 0x7f for libc/stack addresses and 0x55 for code/heap addresses.

If you have smallbins/unsorted bins, try to get overlapping chunks -> leak + write heap data.

Overlapping chunks

What can you overwrite size and prev_size fields with? Just a null byte is enough, see House of Einherjar.

You can also forge a fake chunks on the heap 'out of thin air', by writing fake size and prev_size as user data. You can use these to satisfy security checks or trigger consolidations, etc.

Heap massaging/heap feng shui

Allocate a sequence of chunks at beginning of exploit so you have space to work with.

Allocate a small chunk at the end, to prevent accidental consolidations with top chunk.

Bypassing security checks

When you encounter one, look it up to see why it triggered and when. Then, go back and fix the constraint. You can try testing on a malloc playground instead of the challenge binary to figure out how to bypass the check.

Finding main arena

In GDB:

If you have debug symbols in your libc, you can get the address with symbol &main_arena.

x/40gx (long long)(&main_arena)-0x30

pwndbg has the arena(s) utility to show the location of main_arena.

Another way without symbols, suggested by uafio, is to find the address of the top chunk in the heap, then search memory for references to it.

> search -8 0x555555757060                                                             
libc-2.24.so    0x7ffff7dd3b58 0x555555757060 /* '`puUUU' */

and subtract 0x58 to get the main_arena address.