phonebook is a basic heap challenge I did during the dctf event. It’s basically just a heap overflow wich allows us to overflow a function pointer with for example the address of system.
The bug
1 2 3 4 5 6 7 8
$ ./phonebook Choose an option: [1-5] 1. Store someone's information 2. Edit information 3. Call someone 4. Unfriend someone 5. Add the hidden_note >
We can create an entity and then initialize: a name, a numero and a function pointer.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
int __fastcall create(unsignedint a1) { int result; // eax structentity *s;// [rsp+18h] [rbp-8h]
if ( people[a1] ) returnprintf("Person with id %d already exists!", a1); s = malloc(0x20uLL); s->name = get_name(); LODWORD(s->name_size) = strlen(s->name); printf("Phone number: "); fgets(s, 8, _bss_start); // phone number s->func = choose_relation(); result = s; people[a1] = s; return result; }
We can give it a new lentgh and if that’s not equal to the current size field it frees the current name pointer and allocates a new name pointer without updating the size field. Which means if we edit the name pointer with a smaller size, the name pointer will be smaller compared to the size field, then we just have to edit again the size field to make it equal to v4->name_size to trigger a heap overflow through the v4->name pointer.
Leak libc
Now we’re able to overflow through the name pointer we have to find how the leak the libc, a nice way would be to leak it by using free’d chunks in the unsortedbin. Or we can leak the entity->func function pointer which would give us a leak of the binary base address, then we would have to edit the name pointer with the got entry of puts to leak its address within the libc.
To do so we can create another entity right after the name pointer:
leak binary base address by overwriting the null byte (edit_phone_number) and then print the phone numer.
leak libc base address by overwriting the name field of the second entity with the got entry of puts
PROFIT
Then we just have to overwrite the function pointer with the address of system which takes as first argument a pointer to the entity structure of edit the phone number of the entity we wanna use because that’s the first field of the structure which means we make it equivalent to a system("/bin/sh").