Write-up for: https://exploit.education/phoenix/heap-zero/.
The goal is to redirect execution to the winner() function. This could be achieved by overwriting
fp function pointer of
f is located after
d on the heap.
d is filled using
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
free crash later on.
Since there is no memory protection (like ASLR), we can simply find out the address of the
function using objdump:
user@phoenix-amd64:/opt/phoenix/i486$ objdump -d heap-zero | grep winner 08048835 <winner>:
Now we need the offset of
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
[::-1] reverses a string in Python.