-
Notifications
You must be signed in to change notification settings - Fork 1
Heap
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
- 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?
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 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.
-
malloc_hookFirst, find themain_arenaaddress; thenmalloc_hookis&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_chunkChange the location that malloc serves chunks from.
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.
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.
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.
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.
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.