Buffer Overflows James Walden Northern Kentucky University Topics

Buffer Overflows James Walden Northern Kentucky University

Topics 1. 2. 3. 4. 5. 6. What is a Buffer Overflow? Buffer Overflow Examples Program Stacks Smashing the Stack Shellcode Mitigations CSC 666: Secure Software Engineering

Buffer Overflows A program accepts too much input and stores it in a fixed length buffer that’s too small. char A[8]; short B; A A AA A A B B 0 0 0 0 0 3 gets(A); A A A A B B o v e r f l o ws 0 CSC 666: Secure Software Engineering

Buffer Overflow Examples Morris Worm Took down most of Internet in 1988. Exploited a buffer overflow in fingerd. Subsequent worms used overflow attacks too. MS 07 -004: Internet Explorer Buffer overflow in VML. Allows remote code execution. Not the first overflow in IE or other browsers. CSC 666: Secure Software Engineering

Buffer Overflow Example #1 What’s the mistake in this program? int main() { int array[5] = {1, 2, 3, 4, 5}; printf("%dn", array[5]); } Program output: > gcc -o buffer. c >. /buffer 7077876 CSC 666: Secure Software Engineering
![Buffer Overflow Example #2 Writing beyond the buffer: int main() { int array[5] = Buffer Overflow Example #2 Writing beyond the buffer: int main() { int array[5] =](http://slidetodoc.com/presentation_image_h2/f75b3149a119ba139cedec7f17505a7c/image-6.jpg)
Buffer Overflow Example #2 Writing beyond the buffer: int main() { int array[5] = {1, 2, 3, 4, 5}; int i; for( i=0; i <= 255; ++i ) array[i] = 41; } Program output: > gcc -o bufferw. c >. /bufferw Segmentation fault (core dumped) CSC 666: Secure Software Engineering

What happened to our program? The buffer overflow: Overwrote memory beyond buffer with 41. Memory page was not writable by program. OS terminated prog with segmentation fault. Do overflows always produce a crash? Most of the time, yes. Careful attacker can access valid memory. CSC 666: Secure Software Engineering

Why do programmers keep making the same mistake? C/C++ inherently unsafe. No bounds checking. Unsafe library functions: strcpy(), sprintf(), gets(), scanf(), etc. D, Java, Python, Ruby largely immune. C/C++ gains performance by not checking. CSC 666: Secure Software Engineering

Process Memory Regions Argv/Env: CLI arguments and environment Stack: generally grows downwards Heap: generally grows upwards BSS: unitialized global data Data: initialized global data Text: read-only program code CSC 666: Secure Software Engineering

Process Memory Layout argv, env high mem stack heap bss data text low mem CSC 666: Secure Software Engineering
![Memory Layout Example /* data segment: initialized global data */ int a[] = { Memory Layout Example /* data segment: initialized global data */ int a[] = {](http://slidetodoc.com/presentation_image_h2/f75b3149a119ba139cedec7f17505a7c/image-11.jpg)
Memory Layout Example /* data segment: initialized global data */ int a[] = { 1, 2, 3, 4, 5 }; /* bss segment: uninitialized global data */ int b; /* text segment: contains program code */ int main(int argc, char **argv) /* ptr to argv */ { /* stack: local variables */ int *c; /* heap: dynamic allocation by new or malloc */ c = (int *)malloc(5 * sizeof(int)); } CSC 666: Secure Software Engineering

Program Stack Layout b() { … } a() { b(); } main() { a(); } Low Memory Unallocated Stack Frame for b() Stack Frame for a() Stack Frame for main() High Memory CSC 666: Secure Software Engineering

Stack Frames § A function call produces a stack frame. – Return address of the caller. – Actual arguments used in function call. – Local variables. § Register EBP points to current frame. § Stack frame is deallocated on return. CSC 666: Secure Software Engineering

C Calling Convention 1. Push params on stack in reverse order. Parameter #N … Parameter #1 2. Issue a call instruction. 1. Pushes address of next instruction (the return address) onto stack. 2. Modifies EIP to point to start of function. CSC 666: Secure Software Engineering

Stack before Function Executes old stack frame Frame Pointer parameter #N … parameter #1 return address Stack Pointer CSC 666: Secure Software Engineering

Function Initialization 1. Function pushes FP (%ebp) onto stack. pushl %ebp 2. Sets FP to current SP. Allows function to access params as fixed indexes from base pointer. movl %esp, %ebp 3. Reserves stack space for local vars. subl $12, %esp CSC 666: Secure Software Engineering

Stack at Function Start old stack frame parameter #N … parameter #1 return address old FP local vars Frame Pointer Stack Pointer CSC 666: Secure Software Engineering

Function Return 1. Stores return value in %eax. movl $1, %eax 2. Restores stack and frame pointers. movl %esp, %ebp popl %ebp 3. Pops return address off stack and transfers control to that address. ret CSC 666: Secure Software Engineering

Controlling Execution Let’s make the program an infinite loop by changing the return value to start of main(). (gdb) disassemble main Dump of assembler code for main: 0 x 080483 c 1 <main+0>: push %ebp 0 x 080483 c 2 <main+1>: mov %esp, %ebp 0 x 080483 c 4 <main+3>: call 0 x 804839 c <print. Input> 0 x 080483 c 9 <main+8>: leave 0 x 080483 ca <main+9>: ret CSC 666: Secure Software Engineering
![Sending a non-ASCII Value void main() { char addr[44]; int i; for( i=0; i<=40; Sending a non-ASCII Value void main() { char addr[44]; int i; for( i=0; i<=40;](http://slidetodoc.com/presentation_image_h2/f75b3149a119ba139cedec7f17505a7c/image-20.jpg)
Sending a non-ASCII Value void main() { char addr[44]; int i; for( i=0; i<=40; i+=4 ) *(long *) &addr[i]=0 x 080483 c 1; puts(addr); } CSC 666: Secure Software Engineering

Does it work? (. /address; cat) |. /overflow input 1 input 2 input 3 Segmentation fault (core dumped) CSC 666: Secure Software Engineering

Code and Data What’s the difference between code and data? CSC 666: Secure Software Engineering

Code Injection Use a two step process: 1. Use buffer overflow to write machine code (shellcode) onto stack. 2. Rewrite return address to point to machine code on the stack. Program will do whatever we tell it to do in those machine instructions. CSC 666: Secure Software Engineering

Shellcode is machine code that starts a command shell. With a shell, you can run any command. CSC 666: Secure Software Engineering
![Shellcode in C. int main() { char *name[2]; name[0] = "/bin/sh"; name[1] = 0 Shellcode in C. int main() { char *name[2]; name[0] = "/bin/sh"; name[1] = 0](http://slidetodoc.com/presentation_image_h2/f75b3149a119ba139cedec7f17505a7c/image-25.jpg)
Shellcode in C. int main() { char *name[2]; name[0] = "/bin/sh"; name[1] = 0 x 0; execve(name[0], name, 0 x 0); } Running the program. > gcc –ggdb –static –o shellcode. c >. /shell sh-3. 00$ exit CSC 666: Secure Software Engineering
![From C to Machine Language char shellcode[] = "xebx 1 fx 5 ex 89x From C to Machine Language char shellcode[] = "xebx 1 fx 5 ex 89x](http://slidetodoc.com/presentation_image_h2/f75b3149a119ba139cedec7f17505a7c/image-26.jpg)
From C to Machine Language char shellcode[] = "xebx 1 fx 5 ex 89x 76x 08x 31xc 0x 88x 46x 07x 8 9x 46x 0 cxb 0x 0 b" "x 89xf 3x 8 dx 4 ex 08x 8 dx 56x 0 cxcdx 80x 31xd bx 89xd 8x 40xcd" "x 80xe 8xdcxffxff/bin/sh"; void main() { int *ret; ret = (int *)&ret + 2; (*ret) = (int)shellcode; } > gcc -o testsc 2. c >. /testsc 2 sh-3. 00$ exit CSC 666: Secure Software Engineering

Writing an Exploit 1. 2. 3. 4. Construct shellcode to inject. Find exploitable buffer in a program. Estimate address of buffer. Run program with an input that: 1. Injects shellcode into stack memory. 2. Overwrites return address with address of your shellcode. CSC 666: Secure Software Engineering

Improving the Odds Determining the correct address of your shellcode is difficult. What if you could use multiple addrs? Pad buffer with NOP instructions preceding the shellcode. If function returns anywhere in NOP pad, it will continue executing until it executes the shellcode. CSC 666: Secure Software Engineering

Overflow Exploits w/o the Stack Overflows can exist in other segments. Only the stack has return addresses. Must rewrite other addresses Function pointers Longjmp buffers Or alter security critical variables. CSC 666: Secure Software Engineering

Buffer Overflow Mitigations 1. 2. 3. 4. 5. 6. Use language with bounds checking. Do your own bounds checking. Avoid unsafe functions. Use safe functions securely. Operating system defenses. Compiler-based defenses. CSC 666: Secure Software Engineering

Languages with Bounds Checking High-level languages do bounds checks § § § Java OCaml Python Ruby Scheme Smalltalk C variants § CCured § Cyclone § D CSC 666: Secure Software Engineering

Bounds Checking Check input length before copying into buffer. int myfunction(const char *str) { char buf[1024]; /* strlen() doesn’t count NULL */ if (strlen(str) >= sizeof(buf)) { exit(1); } } CSC 666: Secure Software Engineering

Unsafe Functions: Input gets(char *s) Always an overflow. Cannot be checked. Use fgets(char *s, int size, FILE *stream); scanf(const char *fmt, …) Similar: _tscanf, wscanf, sscanf, fscanf, … Use of “%s” format allows overflow. Use “%Ns” to limit length of input. CSC 666: Secure Software Engineering

Unsafe Functions: strcat strcpy(char *dst, char *src) Similar: wscpy, wcscpy, mbscpy Overflow if dst smaller than src. strncpy(char *dst, const char *src, size_t n) Similar: _tcsncpy, wcscpyn, _mbsncpy, … No NULL termination if src >= dst. CSC 666: Secure Software Engineering

Bounded Function Pitfalls 1. Destination buffer overflows because bound depends on size of source data, not destination buffer. 2. Destination buffer left without null terminator, often as result of off-by-one error. 3. Destination buffer overflows because its bound is specified as the total size of the buffer, rather than space remaining. 4. Programs writes to arbitrary location in memory as destination buffer is not null-terminated and function begins writing at location of first null in destination buffer. CSC 666: Secure Software Engineering

Safe String Libraries UNIX Libraries C Bstrlib MT-Safe. Str strlcpy(), strlcat() Vstr C++ std: : string (STL) Windows Libraries C Safe CRT strlcpy(), strlcat() Str. Safe C++ CString (MFC) Safe C++ std: : string (STL) CSC 666: Secure Software Engineering

strlcpy() and strlcat() size_t strlcpy (char *dst, const char *src, size_t size); size_t strlcat (char *dst, const char *src, size_t size); § Size is max size of dest buffer (not maximum number of chars to copy), including NULL. § Destination buffer always NULL terminated § Return how much space would be required in destination buffer to perform operation. § BSD-style open source license. CSC 666: Secure Software Engineering

Character Sets § Chars represented using encoding forms that map code points to printable chars. § Fixed Width § ISO-8859 -1 § UTF-32 § Variable Width § UTF-8 § UTF-16 (Java, . NET) Character Encoding Code Point s ISO-8859 -1 UTF-8 73 73 ÿ ISO-8859 -1 UTF-8 FF C 3 BF CSC 666: Secure Software Engineering

Wide Characters C/C++ § char contains 1 -byte characters § wchar_t is 2 -byte, 4 -byte on some platforms Java and. NET strings § UTF-16 Buffer Overflow issues § Mixing up different character-set string types. § Are sizes measured in bytes or characters? CSC 666: Secure Software Engineering
![C++ String Dangers Using C-style strings with cin char username[16]; cin >> username; The C++ String Dangers Using C-style strings with cin char username[16]; cin >> username; The](http://slidetodoc.com/presentation_image_h2/f75b3149a119ba139cedec7f17505a7c/image-40.jpg)
C++ String Dangers Using C-style strings with cin char username[16]; cin >> username; The [] operator does no bounds checking. Converting from C++ to C-style strings: string: : data() output is not NULL terminated. string: : c_str() output is NULL terminated. CSC 666: Secure Software Engineering

Dealing with Overly Long Inputs § Prevent operation with an error message. § Possibly exit program too. § Truncate input to allowed length. § Can lead to null-termination errors. § Can cause input to be misinterpreted later. § Resize the buffer to accomodate input. § Limit resizing to avoid memory Do. S. CSC 666: Secure Software Engineering

Dynamic vs. Static Allocation Static § Simple § Easy to track buffer size for bounds checks. § Inflexible. § Limited options if size is too small. § Waste memory if size is too large. § § § Dynamic Complex Manually tracking buffer sizes can lead to overflows due to stale size data. Flexible Can lead to memory exhaustion if no limits. Possibility of use after free and double free errors. CSC 666: Secure Software Engineering

Non-executable Stack Memory protection prevents exploit code from being executed. – Some applications execute code on the stack/heap. – x 86 arch doesn’t have exec bit in page tables. – Segment limits can divide memory into two parts: executable and non-executable. • Keep program code in low memory. • Keep data and stack in high memory. • Coarse-grained. – NX Technology • Exec bit for page tables. • Added in AMD 64 and newer Intel P 4 processors. • Only works in PAE 64 -bit page table format. CSC 666: Secure Software Engineering

Arc Injection (return-into-libc) Arc injection transfers control to code that already exists in memory. Adds a new arc into program’s CFG. Change return address to existing function. libc has functions to start a shell. Allows exploit even if stack non-executable. Sophisticated arc injection attacks create multiple stack frames to run multiple functions that are in memory. CSC 666: Secure Software Engineering

Memory Layout Randomization Randomize layout of memory space § Stack location. § Shared library locations. § Heap location. PIE: Position Independent Executable § Default format: binary compiled to work at an address selected when program was compiled. § Gcc can compile binaries to be freely relocatable throughout address space. § gcc flags: -fpie –pie § Program loaded at different address for each invocation. CSC 666: Secure Software Engineering

Defence: Stackguard Compiler extension for gcc § code must be compiled w/ Stackguard Detects altered return address § § before function returns adds “canary” word to stack must overwrite canary to change return addr use random canary words for each function to avoid guessing attacks CSC 666: Secure Software Engineering

Stackguard Stack Layout old frame param 1 param 2 old PC canary word old FP local vars Frame Pointer Stack Pointer CSC 666: Secure Software Engineering

Stackguard Effectiveness § Code dependencies § are dynamic libraries stackguarded? § Compatibility § Recompiled entire Red. Hat Linux system. § Small performance cost § canary insert and check overhead on each call § Protects against future stack attacks. § Similar tools: § gcc -fstack-protector flag § Visual Studio 2005 CSC 666: Secure Software Engineering

Buffer Overflow: Key Points Buffer overflow attacks. § § § C/C++ perform no bounds checking. There is no difference btw code and data. Smashing the stack. Mitigating buffer overflows. § § § Use a language with bounds checking. Check your own bounds in C/C++. Use safe functions, string libraries. CSC 666: Secure Software Engineering

References 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. Aleph Null, “Smashing the Stack for Fun and Profit, ” Phrack 49, 1996. Brian Chess and Jacob West, Secure Programming with Static Analysis, Addison. Wesley, 2007. Johnathan Bartlett, Programming from the Ground Up, Bartlett Publishing, 2004. Matt Conover & w 00 Security Team, “w 00 on Heap Overflows, ” http: //www. w 00. org/files/articles/heaptut. txt Mark Graff and Kenneth van Wyk, Secure Coding: Principles & Practices, O’Reilly, 2003. Horizon, “Bypassing Non-executable Stack Protection on Solaris, ” http: //packetstormsecurity. nl/groups/horizon/stack. txt Greg Hoglund and Gary Mc. Graw, Exploiting Software: How to Break Code, Addison-Wesley, 2004. Michael Howard and David Le. Blanc, Writing Secure Code, 2 nd edition, Microsoft Press, 2003. Koziol, et. al, The Shellcoder’s Handbook: Discovering and Exploiting Security Holes, Wiley, 2004. Robert C. Seacord, Secure Coding in C and C++, Addison-Wesley, 2006. John Viega and Gary Mc. Graw, Building Secure Software, Addison-Wesley, 2002. David Wheeler, Secure Programming for UNIX and Linux HOWTO, http: //www. dwheeler. com/secure-programs/Secure-Programs-HOWTO/index. html, 2003.
- Slides: 50