A Tool for Pro-active Defense Against the Buffer Overrun Attack D. Bruschi, E. Rosti, R. Banfi Presented By: Warshavsky Alex
Overview Introduction General Background The Attack Buffer Overrun Detector Existing Solutions Conclusions
Computer Security Problems Security unconscious design Programming errors –Buffer overruns –Buffer overflow –Stack smashing
Why to let it happen ? Language Flexibility Language Efficiency As a result … Everything left to the programmer
Motivation Login program, late 70’s Internet Worm, November 1988 CERT- CC (Computer Emergency Response Team Coordination Center), 1997, 15 of 28 bugs
What is needed to solve the problem ? Compiler tools Static analysis tools Buffer Overrun Detector
Overview Introduction General Background The Attack Buffer Overrun Detector Existing Solutions Conclusions
General Background or Why Buffer Overruns are a security issue Unix Access Control System Function call execution model C Language
Unix Access Control System Who owns the process ? –Real user identifier ( ruid ) –Effective user identifier ( euid ) setuid() system call R W X R W X R W X suid sgid sticky Owner Group Other
Function Call Execution Model Low addresses High addresses text initialized data bss heap user stack argc argv pointers env pointers argv strings env strings Process in memory Function call: parameters return address stack pointer frame pointer local variables
C Language Considered as a high level assembly Easy to make a mistake Easy to forget … Libraries aren’t safe
Overview Introduction General Background The Attack Buffer Overrun Detector Existing Solutions Conclusions
The Attack Pass the execve(“/bin/sh”,NULL) object code char shellcode[] = “\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b" "\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd” "\x80\xe8\xdc\xff\xff\xff/bin/sh"; Overwrite the return address Hope your code will be executed Don’t forget the SUID bit and super user privilege level Stack is executable !!!
An example Low addresses High addresses argc !!!\0 low! stringverf er o buff i = 5 heap bss void my_func(int a, char *buff){ char buf1[6]; a = 4; strcpy(buf1,buff); } void main(){ char string=“buffer overflow!!!!”; int i; i = 5; my_func(i, string); i = 3; } program counter frame pointer stack pointer LIVE
An example Low addresses High addresses argc !!!\0 low! stringverf er o buff i = 5 *buff a = 5 return address stack pointer frame pointer buf1 heap bss void my_func(int a, char *buff){ char buf1[6]; a = 4; strcpy(buf1,buff); } void main(){ char string=“buffer overflow!!!!”; int i; i = 5; my_func(i, string); i = 3; } program counter frame pointer stack pointer LIVE
An example Low addresses High addresses argc !!!\0 low! stringverf er o buff i = 5 *buff a = 4 return address stack pointer frame pointer buf1 heap bss void my_func(int a, char *buff){ char buf1[6]; a = 4; strcpy(buf1,buff); } void main(){ char string=“buffer overflow!!!!”; int i; i = 5; my_func(i, string); i = 3; } program counter frame pointer stack pointer LIVE
An example Low addresses High addresses argc !!!\0 low! stringverf er o buff i = 5 *buff a = 4 return address!!!\0 stack pointerlow! frame pointerverf er o buf1buff heap bss void my_func(int a, char *buff){ char buf1[6]; a = 4; strcpy(buf1,buff); } void main(){ char string=“buffer overflow!!!!”; int i; i = 5; my_func(i, string); i = 3; } program counter frame pointer stack pointer LIVE
Another example void __stdcall foo(int a, int b); main() { int num; num = 5; foo(num,num+1); num = 1; printf("num is now %d \n",num); } void __stdcall foo(int a, int b) { int * p; p = &b ; p -= 2 ; (*p)+= 7; } Output: num is now 5
Overview Introduction General Background The Attack Buffer Overrun Detector Existing Solutions Conclusions
Buffer Overrun Detector Finding Critical Programs Searching for Segmentation Violation Exploiting Segmentation Violation
Finding Critical Programs setuid to root programs accept input parameters access environment variables configuration file
Searching for Segmentation Violation Large inputs Brute force approach
Exploiting Segmentation Violation Finding the stack location containing the return address Finding the new value for the return address
Overview Introduction General Background The Attack Buffer Overrun Detector Existing Solutions Conclusions
Existing Solutions Compiler patchesCompiler patches Library patchesLibrary patches Operating System PatchesOperating System Patches Writing safe code ! Writing safe code !
Compiler Patches Compile time bound checks Run time checks on pointer manipulation Examples –GCC patch at Imperial College (2-3,30) –Purify, memory accesses (5) –StackGuard - return address –MemGuard - memory accesses
StackGuard Low addresses High addresses !!!\0 low! stringverf er o buff i = 5 *buff a = 4 return address CANARY stack pointer frame pointer buf1 heap bss void my_func(int a, char *buff){ char buf1[2]; a = 4; strcpy(buf1,buff); } void main(){ char string=“buffer overflow!!!!”; int i; i = 5; my_func(i, string); i = 3; } program counter frame pointer stack pointer LIVE
StackGuard Low addresses High addresses !!!\0 low! stringverf er o buff i = 5 *buff a = 4 return address!!!\0 CANARYlow! stack pointerverf frame pointerer o buf1buff heap bss void my_func(int a, char *buff){ char buf1[2]; a = 4; strcpy(buf1,buff); } void main(){ char string=“buffer overflow!!!!”; int i; i = 5; my_func(i, string); i = 3; } program counter frame pointer stack pointer LIVE
Library Patches Assembly coded integrity checks Almost no performance impact But … User function aren’t checked ! Portability is limited
Operating System Patches Making stack non executable Program protection at no cost But... Kernel has to be patched GCC relies on executable stack Functional languages need it
Conclusions A tool for automatic detection of buffer overruns was presented Nothing beats writing a good code
It almost The End
Fuzz Revisited: A Re-examination of the Reliability of UNIX Utilities and Services By: Miller, Koski, Lee, Maganty, Murthy, Natarjan, Steidl. University of Wisconsin
Introduction Fuzz Generator Test over 80 utility programs on 9 UNIX platforms Test Network Services Test X-Windows apps Test checking return values of system calls
Conclusions The failure rate of commercial versions of UNIX (Sun, IBM, SGI, DEC, NEXT) - 18%-23% The failure rate of Linux - 9%, GNU - 6 % Network services are robust X-Windows more than 50% on random input, more than 25% on legal inputs X servers are robust malloc() - 25 out of 53 (47%) crashed
THE END