<<

Buffer Overflows Definitions

• Technique to force execution of malicious code Buffer: a contiguous block of that with unauthorized privileges holds multiple instances of the same type ( arrays) – launch a command shell – search local disk or network for sensitive Overflow: to fill over the brim, to fill more than full – register with command and control network as a Buffer Overflow: happens when a program attempts to zombie write data outside of the memory allocated for that • Can be applied both locally and remotely data • Attack technique is independent of machine architecture and – Usually affects buffers of fixed size • Can be tricky to execute, but extremely effective • Also known as Buffer Overrun

Buffer Overflow CS177 2013 Buffer Overflow CS177 2013 1 2

Simple Example Another Example

function foo(char * a) { Off-by-one errors are common and can be char b[100]; exploitable! (see Phrack 55) ... strcpy(b, a); // (dest, source) char B[10]; ... B[10] = x; } •Array starts at index zero • What is the size of the string located at "a"? • Is it even a null-terminated string? •So [10] is 11th element • What if it was "strcpy(a, b);" instead? •One byte outside buffer was referenced –What is the size of the buffer pointed to by "a"?

Buffer Overflow CS177 2013 Buffer Overflow CS177 2013 3 4

What Happens When Memory Real Example: efingerd.c, v. 1.5 Outside a Buffer Is Accessed? • CAN-2002-0423 static char *lookup_addr(struct in_addr • If memory doesn't exist: in) { –Bus error static char addr[100]; struct hostent *he; • If memory protection denies access: he = gethostbyaddr(...) – strcpy (addr, he->h_name); –General protection fault return addr; } • If access is allowed, memory next to the buffer can be accessed • How big is he->h_name? –Heap • Who controls the results of gethostbyaddr? –Stack • How secure is DNS? Can you be tricked into –Etc... looking up a maliciously engineered value?

Buffer Overflow CS177 2013 Buffer Overflow CS177 2013 5 6

1 Fundamental "C" Problems “Overflowing” Functions • gets() • You can't know the length of buffers just – void main() { char buf[512]; from a pointer gets(buf); –Partial solution: pass the length as a separate } argument • strcpy(), strcat() • "C" string functions aren't safe – int main(int argc, char ** argv) { – No guarantees that the new string will be null- char buf[512]; terminated! strcpy(buf, argv[1]); } – Doing all checks completely and properly is • sprintf(), vsprintf(), scanf(), sscanf(), fscanf() tedious and tricky • and also your own custom input routines… Buffer Overflow CS177 2013 Buffer Overflow CS177 2013 7 8

Process Memory Organization Process Memory Organization

• Text section (.text) • Stack section – Includes instructions and read-only data – Used for implementing procedure abstraction – Usually marked read-only • Heap section • Modifications cause segment faults – Used for dynamically allocated data • Data section (.data, .bss) – Initialized and uninitialized data • Environment/Argument section – Static variables – Used for environment data – Global variables – Used for the command line data

Buffer Overflow CS177 2013 Buffer Overflow CS177 2013 9 10

Linux Process Layout The Stack

• Process memory partitioned into segments • The stack usually grows towards lower .text Program code .data Initialized static data memory addresses .bss Unitialized static data • This is the way the stack grows on many heap Dynamically-allocated memory architectures including the Intel, Motorola, stack Program SPARC, and MIPS processors • Each memory segment has a • The stack pointer (SP) points to the top of set of permissions associated with it the stack (usually last valid address) – Read, write, and execute (rwx)

Buffer Overflow CS177 2013 Buffer Overflow CS177 2013 11 12

2 Frame Structure Structure of the ix86 Stack

• Used to implement • The stack is composed of frames procedure abstraction • Frames are pushed on the stack as a consequence • Stack composed of frames, of function calls (function prolog) each of which corresponds to a unique function • The address of the current frame is stored in the invocation Frame Pointer (FP) register – function arguments – On Intel architectures EBP is used for this purpose – return address (eip) – frame pointer (ebp) • Each frame contains – local “automatic” data – The function’s actual parameters • Grows downward from – The return address to jump to at the end of the function higher to lower memory addresses – The pointer to the previous frame – Function’s local variables Buffer Overflow CS177 2013 Buffer Overflow CS177 2013 13 14

Stack Frame Setup and Teardown Stack Frame Setup and Teardown

8048716 mov %eax,(%esp) 8048716 mov %eax,(%esp) 8048719 call 80485ed 8048719 call 80485ed 80485ed push %ebp 80485ed push %ebp 80485ee mov %esp,%ebp 80485ee mov %esp,%ebp 80485f1 sub $0x34,%esp 80485f1 sub $0x34,%esp ...... 804866c add $0x34,%esp 804866c add $0x34,%esp 8048670 pop %ebp 8048670 pop %ebp 8048671 ret 8048671 ret

Buffer Overflow CS177 2013 Buffer Overflow CS177 2013 15 16

Stack Frame Setup and Teardown Stack Frame Setup and Teardown

8048716 mov %eax,(%esp) 8048716 mov %eax,(%esp) 8048719 call 80485ed 8048719 call 80485ed 80485ed push %ebp 80485ed push %ebp 80485ee mov %esp,%ebp 80485ee mov %esp,%ebp 80485f1 sub $0x34,%esp 80485f1 sub $0x34,%esp ...... 804866c add $0x34,%esp 804866c add $0x34,%esp 8048670 pop %ebp 8048670 pop %ebp 8048671 ret 8048671 ret

Buffer Overflow CS177 2013 Buffer Overflow CS177 2013 17 18

3 Stack Frame Setup and Teardown Stack Frame Setup and Teardown

8048716 mov %eax,(%esp) 8048716 mov %eax,(%esp) 8048719 call 80485ed 8048719 call 80485ed 80485ed push %ebp 80485ed push %ebp 80485ee mov %esp,%ebp 80485ee mov %esp,%ebp 80485f1 sub $0x34,%esp 80485f1 sub $0x34,%esp ...... 804866c add $0x34,%esp 804866c add $0x34,%esp 8048670 pop %ebp 8048670 pop %ebp 8048671 ret 8048671 ret

Buffer Overflow CS177 2013 Buffer Overflow CS177 2013 19 20

Stack Frame Setup and Teardown Stack Frame Setup and Teardown

8048716 mov %eax,(%esp) 8048716 mov %eax,(%esp) 8048719 call 80485ed 8048719 call 80485ed 80485ed push %ebp 80485ed push %ebp 80485ee mov %esp,%ebp 80485ee mov %esp,%ebp 80485f1 sub $0x34,%esp 80485f1 sub $0x34,%esp ...... 804866c add $0x34,%esp 804866c add $0x34,%esp 8048670 pop %ebp 8048670 pop %ebp 8048671 ret 8048671 ret

Buffer Overflow CS177 2013 Buffer Overflow CS177 2013 21 22

Stack Frame Setup and Teardown Vulnerability of Stack Structure

8048716 mov %eax,(%esp) A small problem: return address (eip) 8048719 call 80485ed is inlined with user-controlled 80485ed push %ebp buffers – What can happen if copy into 80485ee mov %esp,%ebp stack-allocated buffer is not 80485f1 sub $0x34,%esp bounds-checked? ... 804866c add $0x34,%esp 8048670 pop %ebp 8048671 ret

Buffer Overflow CS177 2013 Buffer Overflow CS177 2013 23 24

4 Vulnerability of Stack Structure Vulnerability of Stack Structure

A small problem: return address is A small problem: return address is inlined with user-controlled inlined with user-controlled buffers buffers – What can happen if copy into – What can happen if copy into stack-allocated buffer is not stack-allocated buffer is not bounds-checked? bounds-checked? – User can control values of other – User can control values of other variables, frame pointer, and variables, frame pointer, and return address return address – If user overwrites the return – If user overwrites the return address on stack, what happens address on stack, what happens when function returns when function returns? Result: process will execute arbitrary code of the user’s choosing

Buffer Overflow CS177 2013 Buffer Overflow CS177 2013 25 26

Side Effects of Buffer Overflow Smashing the Stack

Depend On 8048716 mov %eax,(%esp) • How much data is written past the bounds 8048719 call 80485ed 80485ed push %ebp • What data is overwritten 80485ee mov %esp,%ebp 80485f1 sub $0x34,%esp • Whether the program attempts to read the ... data overwritten 804866c add $0x34,%esp 8048670 pop %ebp • What data replaces the memory that gets 8048671 ret overwritten

Buffer Overflow CS177 2013 Buffer Overflow CS177 2013 27 28

Smashing the Stack Smashing the Stack

...... 8048624 mov 0x8(%ebp),%eax 8048624 mov 0x8(%ebp),%eax 8048627 mov %eax,0x4(%esp) 8048627 mov %eax,0x4(%esp) 804862b lea 0xffffffe4(%ebp),%eax 804862b lea 0xffffffe4(%ebp),%eax 804862e mov %eax,(%esp) 804862e mov %eax,(%esp) 8048631 call 80483f8 8048631 call 80483f8 ...... 804866c add $0x34,%esp 804866c add $0x34,%esp 8048670 pop %ebp 8048670 pop %ebp 8048671 ret 8048671 ret

Buffer Overflow CS177 2013 Buffer Overflow CS177 2013 29 30

5 Smashing the Stack Smashing the Stack

...... 8048624 mov 0x8(%ebp),%eax 8048624 mov 0x8(%ebp),%eax 8048627 mov %eax,0x4(%esp) 8048627 mov %eax,0x4(%esp) 804862b lea 0xffffffe4(%ebp),%eax 804862b lea 0xffffffe4(%ebp),%eax 804862e mov %eax,(%esp) 804862e mov %eax,(%esp) 8048631 call 80483f8 8048631 call 80483f8 ...... 804866c add $0x34,%esp 804866c add $0x34,%esp 8048670 pop %ebp 8048670 pop %ebp 8048671 ret 8048671 ret

Buffer Overflow CS177 2013 Buffer Overflow CS177 2013 31 32

Smashing the Stack Smashing the Stack

...... 8048624 mov 0x8(%ebp),%eax 8048624 mov 0x8(%ebp),%eax 8048627 mov %eax,0x4(%esp) 8048627 mov %eax,0x4(%esp) 804862b lea 0xffffffe4(%ebp),%eax 804862b lea 0xffffffe4(%ebp),%eax 804862e mov %eax,(%esp) 804862e mov %eax,(%esp) 8048631 call 80483f8 8048631 call 80483f8 ...... 804866c add $0x34,%esp 804866c add $0x34,%esp 8048670 pop %ebp 8048670 pop %ebp 8048671 ret 8048671 ret 3133780 xor %eax,%eax

Buffer Overflow CS177 2013 Buffer Overflow CS177 2013 33 34

Buffer Overflow Memory Layout for Frame • Data is copied without checking boundaries • Data “overflows” a pre-allocated buffer and overwrites the return address Buffer FP RET *str Stack... • Normally this causes a segmentation fault • If correctly crafted, it is possible overwrite the return address with a user-defined value • It is possible to cause a jump to user-defined code (e.g., code that invokes a shell) • The code may be part of the overflowing data (or not) • The code will be executed with the privileges of the running program Buffer Overflow CS177 2013 Buffer Overflow CS177 2013 35 36

6 Buffer Overflow Buffer Overflow

Shell invocation code Shell invocation code

Top of memory Top of memory

*str *str Return address Return address Pointer to previous frame Pointer to previous frame buffer (16 bytes) buffer (16 bytes)

Stack grows Stack grows

Bottom of memory Bottom of memory Buffer Overflow CS177 2013 Buffer Overflow CS177 2013 37 38

How to Exploit a Buffer Overflow The Shell Code

void main() { • Different variations to accommodate different char *name[2]; architectures name[0] = "/bin/sh"; – Assembly instructions name[1] = NULL; – Operating system calls execve(name[0], name, NULL); exit(0); – Alignment } • Linux buffer overflows explained in the paper • System calls in assembly are invoked by “Smashing The Stack For Fun And Profit” by Aleph One, published on Phrack Magazine, 49(7) saving parameters either on the stack or in registers and then calling the software • Most difficult task: generate the correct “” interrupt (0x80 in linux)

Buffer Overflow CS177 2013 Buffer Overflow CS177 2013 39 40

High Level View Executing the Shell Code

• Compile attack code • Extract the binary for the piece that actually does the work Buffer FP RET Stack... • Insert the compiled code into the buffer Shell code Buffer addr – Before or after the return address • Figure out where overflow code should jump Long String • Place that address in the buffer at the proper location so that the normal return address gets overwritten

Buffer Overflow CS177 2013 Buffer Overflow CS177 2013 41 42

7 Guessing the Buffer Address NOP Sled • In most cases the address of the buffer is not known • It has to be “guessed” (and the guess must be very Use a series of NOPs at the beginning of the overflowing precise) buffer so that the jump does not need to be too precise (aka no-operation sled) • Given the same environment and knowing the size of command-line arguments the address of the stack can be roughly guessed “Guessed” Offset Stack Pointer • The stack address of a program can be obtained by using the function Buffer FP RET Stack... unsigned long get_sp(void) { __asm__("movl %esp,%eax"); NOPs Shell code Almost the buffer addr } • We also have to guess the offset of the buffer with respect to the stack pointer Long String Buffer Overflow CS177 2013 Buffer Overflow CS177 2013 43 44

Heap Overflows Other Buffer Overflows

• Overflowing dynamically allocated (heap) buffers may overwrite malloc’s • Return into libc (control is passed to library call instead of shell code, e.g., system()) “bookkeeping” structs • Dtor overflow (C “global” destructor • Example struct from dlmalloc function override) struct malloc_chunk { INTERNAL_SIZE_T prev_size; • C++ VPTR overflows (overwriting C++ INTERNAL_SIZE_T size; virtual function pointers) struct malloc_chunk *bk; struct malloc_chunk *fd; };

Buffer Overflow CS177 2013 Buffer Overflow CS177 2013 45 46

Remote Buffer Overflows Solutions to Buffer Overflows

• Buffer overflow in a network server program can • Write decent programs be exercised by an outside user • Use a language that performs boundary checking • Often provides the attacker with an interactive (e.g., , C#, Python) shell on the machine • Use Libsafe as a replacement for dangerous functions – Resulting session has the privileges of the process • Use fgets, snprintf, strncat, strncpy, ... running the compromised network service • Use of canary values on function frames • One of the most common techniques to get remote • Make the stack non-executable (e.g., OpenWall project). This may solve some of the problems but not access to a system all of them • Misuse-based intrusion detection

Buffer Overflow CS177 2013 Buffer Overflow CS177 2013 47 48

8 Canaries on a Stack Canaries

• Add a few bytes containing special values between • Technique to detect and prevent buffer overflows by prepending a variables on the stack and the return address. “canary” to sensitive information • Before the function returns, check that the values • If canary is “destroyed,” a preceding are intact. buffer is assumed to have been –If not, there has been a buffer overflow overflowed • Terminate program • Implementations exist for both the • If hacker’s goal was a Denial-of-Service, then it stack and heap still happens, but the machine is not compromised – StackGuard [Cowan97] – SSP (aka ProPolice) [Etoh01] • If the canary can be read by an attacker, then a – dlmalloc heap protection buffer overflow exploit can be made to rewrite the – Visual C++ /GS canary

Buffer Overflow CS177 2013 Buffer Overflow CS177 2013 49 50

Canaries Canaries

• Technique to detect and prevent • Technique to detect and prevent buffer overflows by prepending a buffer overflows by prepending a “canary” to sensitive information “canary” to sensitive information • If canary is “destroyed,” a preceding • If canary is “destroyed,” a preceding buffer is assumed to have been buffer is assumed to have been overflowed overflowed • Implementations exist for both the • Implementations exist for both the stack and heap stack and heap – StackGuard [Cowan97] – StackGuard [Cowan97] – MemGuard – SSP (aka ProPolice) [Etoh01] – SSP (aka ProPolice) [Etoh01] – dlmalloc heap protection – dlmalloc heap protection – Microsoft Visual C++ /GS – Microsoft Visual C++ /GS

Buffer Overflow CS177 2013 Buffer Overflow CS177 2013 51 52

StackGuard MemGuard • Compiler extension to gcc • Protects return address when function is called and – prologue pushes random canary on the stack unprotects when function returns – epilogue checks that canary value unchanged • Mark pages containing return • Assumes return address is unaltered IFF canary pointer as read-only and emulates writes to word is unaltered nonprotected words on page • Can be bypassed if – 1800 times the cost of normal write – Overflow skips over the canary word • Use Pentium debug registers to hold return – Canary word can be guessed addresses and configure as read only • Only protects against stack smashing attacks – Can only protect top four frames at any time • Only protects against stack smashing attacks

Buffer Overflow CS177 2013 Buffer Overflow CS177 2013 53 54

9 Address Space Layout Randomization Address Space Layout Randomization (ASLR) (ASLR) • Technique to randomly perturb locations of • Technique to randomly perturb locations of memory areas memory areas • Force attacker to guess addresses of • Force attacker to guess addresses of important code or data with low probability important code or data with low probability • Effectiveness dependent on amount of • Effectiveness dependent on amount of entropy introduced by scheme entropy introduced by scheme – increase space within which a memory area – increase space within which a memory area may be positioned may be positioned – decreasing the period of perturbation – decreasing the period of perturbation – rearranging contents of a memory area – rearranging contents of a memory area • Various implementations • Various implementations – PaX – PaX – OpenBSD – OpenBSD – ExecShield – ExecShield

Buffer Overflow CS177 2013 Buffer Overflow CS177 2013 55 56

Non-executable memory Misuse-based Intrusion Detection

• Technique to exclusively allocate memory • Systems that examine events from for either code or data the network, host, or application • May be implemented in hardware as PTE 90 for evidence of malicious behavior write bit or emulated in software 90 nop – SPARC, Alpha, PowerPC, IA-64 processors • Attacks described by signatures 90 nop – PaX – signature can be modeled as a – ExecShield (RedHat) 90 nop conjunction of constraints on a time-ordered series of events – WX (OpenBSD) 6a 0b push $0xb 58 pop %eax – if all constraints for a signature – NX (AMD processors) are satisfied, system assumes an – XD (Intel processors, identical to NX) 99 cltd attack has occurred, otherwise – data execution prevention, or DEP (recent events are considered normal Windows releases) • NIDSs contain many signatures • Prevents attacker from injecting data to be Signature for buffer overflow exploits executed as code content:"|90 90 6a 0b ...|"

Buffer Overflow CS177 2013 Buffer Overflow CS177 2013 57 58

Misuse-based Intrusion Detection Misuse-based Intrusion Detection

Shellcode • Unfortunately, there are many Shellcode • Unfortunately, there are many ways to write shellcode ways to write shellcode 90 nop – apply semantics-preserving 90 nop – apply semantics-preserving transformations transformations 90 nop 90 nop – use decoder routine to obfuscate – use decoder routine to obfuscate 90 nop payload 58 pop %eax payload 90 nop – use bootstrap routine to fetch 58 pop %eax – use bootstrap routine to fetch 6a 0b push $0xb different modules 6a 0b push $0xb different modules 58 pop %eax • Matching against specific exploit 58 pop %eax • Matching against specific exploit payloads is fundamentally the payloads is fundamentally the 99 cltd wrong approach 99 cltd wrong approach • Rather, should attempt to model • Rather, should attempt to model conditions leading to exploitation conditions leading to exploitation Signature of the vulnerability Signature of the vulnerability content:"|90 90 6a 0b ...|" content:"|90 90 6a 0b ...|"

Buffer Overflow CS177 2013 Buffer Overflow CS177 2013 59 60

10 Misuse-based Intrusion Detection Misuse-based Intrusion Detection

Shellcode • Unfortunately, there are many Shellcode • Unfortunately, there are many ways to write shellcode ways to write shellcode 90 nop – apply semantics-preserving 90 nop – apply semantics-preserving transformations transformations 90 nop 90 nop – use decoder routine to obfuscate – use decoder routine to obfuscate 58 pop %eax payload 58 pop %eax payload 58 pop %eax – use bootstrap routine to fetch 58 pop %eax – use bootstrap routine to fetch 6a 0b push $0xb different modules 31 c0 xor %eax%eax different modules 58 pop %eax • Matching against specific exploit 83 c0 0b add $0xb,%eax • Matching against specific exploit payloads is fundamentally the payloads is fundamentally the 31 d2 xor %edx,%edx wrong approach 31 d2 xor %edx,%edx wrong approach • Rather, should attempt to model • Rather, should attempt to model conditions leading to exploitation conditions leading to exploitation Signature of the vulnerability Signature of the vulnerability content:"|90 90 6a 0b ...|" content:"|90 90 6a 0b ...|"

Buffer Overflow CS177 2013 Buffer Overflow CS177 2013 61 62

Misuse-based Intrusion Detection Misuse-based Intrusion Detection

Shellcode • Unfortunately, there are many Shellcode • Unfortunately, there are many ways to write shellcode ways to write shellcode 90 nop – apply semantics-preserving 90 nop – apply semantics-preserving transformations transformations 90 nop 90 nop – use decoder routine to obfuscate – use decoder routine to obfuscate 58 pop %eax payload 58 pop %eax payload 58 pop %eax – use bootstrap routine to fetch 58 pop %eax – use bootstrap routine to fetch 31 d2 xor %edx%edx different modules 31 d2 xor %edx%edx different modules 31 c0 xor %eax,%eax • Matching against specific exploit 89 d0 mov %edx,%eax • Matching against specific exploit payloads is fundamentally the payloads is fundamentally the 83 c0 0b add %0xb,%eax wrong approach 83 c0 0b add %0xb,%eax wrong approach • Rather, should attempt to model • Rather, should attempt to model conditions leading to exploitation conditions leading to exploitation Signature of the vulnerability Signature of the vulnerability content:"|90 90 6a 0b ...|" content:"|90 90 6a 0b ...|"

Buffer Overflow CS177 2013 Buffer Overflow CS177 2013 63 64

Misuse-based Intrusion Detection Moral of the Buffer Overflow Problem

Shellcode • Unfortunately, there are many ways to write shellcode 90 nop – apply semantics-preserving • Always do transformations 90 nop – use decoder routine to obfuscate 58 pop %eax payload 58 pop %eax – use bootstrap routine to fetch • Price of bounds checking is efficiency 31 d2 xor %edx%edx different modules 89 d0 mov %edx,%eax • Matching against specific exploit – Generally C favors efficiency in most tradeoffs payloads is fundamentally the 83 c0 0b add %0xb,%eax wrong approach • Rather, should attempt to model conditions leading to exploitation Signature of the vulnerability content:"|90 90 6a 0b ...|"

Buffer Overflow CS177 2013 Buffer Overflow CS177 2013 65 66

11