COMP 4580 Computer Security Software Security I Dr. Noman Mohammed Winter 2019 Including slides from: David Brumley & others!
Software Security Software Lifecycle Requirements Design Implementation Testing Use Software problems are ubiquitous Therac-25 medical accelerator AT&T network outage 2
Adversarial Failures Software bugs are bad Consequences can be serious Even worse when an intelligent adversary wishes to exploit them! Force bugs into worst possible conditions/states Attacker able to violate security of your system (control, obtain private information,...) 3
Basics of Exploits A bug is a place where real execution behavior may deviate from expected behavior. An exploit is an input that gives an attacker an advantage Method Control Flow Hijack Denial of Service Information Disclosure Objective Gain control of the instruction pointer %eip Cause program to crash or stop servicing clients Leak private information, e.g., saved password 4
Control Flow Hijack Attacker s goal: Take over target machine (e.g. web server) Execute arbitrary code on target by hijacking application control flow Examples: Buffer overflow attacks Format string attacks 5
What is needed Attacker needs to know which CPU and OS used on the target machine: Our examples are for x86 running Linux Details vary slightly between CPUs and OSs: n Little endian vs. big endian (x86 vs. Motorola) n Stack Frame structure (Unix vs. Windows) We will review the basics today and will see the attacks in the next class 6
Outline Assembly Language Memory Layout 7
Turning C into Object Code Code in file: p.c Compile with command: gcc p.c -o p text C program (p.c) Compiler text Asm program (p.s) binary Assembler Object program (p.o) Linker Sta<c libraries (.a) binary Executable program (p) 8
The First Program - firstprog.c #include <stdio.h> int main() { int i; for(i=0; i < 10; i++) { printf("hello World!\n"); } } 9
How to Compile? 10
Assembly Language An assembly language is a low-level language for programming computers. Unlike C and other compiled languages, assembly language instructions have a direct one-to-one relationship with their corresponding machine language instructions. Each instruction (statement) in assembly language typically consists of an operation or opcode plus zero or more operands. 11
x86 Processor Registers6 Pro EIP EFLAGS EAX EDX ECX EBX ESP EBP ESI EDI Address of next instruction Condition codes General Purpose 12
Basic Ops and AT&T vs Intel Syntax source before destination destination before source Meaning AT&T Intel ebx = eax movl %eax, %ebx mov ebx, eax AT&T is at odds with assignment order. It is the default for objdump, and traditionally used for UNIX. Windows traditionally uses Intel, as is available via the objdump -M intel command line option 13
Disassembling Object Code Disassembler Objdump M intel -D a.out grep A20 main.: Objdump D a.out: useful tool for examining assembly code M intel: to show the output in Intel syntax grep A20 main.: piped into grep to display 20 lines after the reular expression main.: 14
Memory Address Machine Language Assembly Language 15
Hexadecimal Notation Each byte can be represented in hexadecimal notation, which is a base-16 numbering system. 0~9, A~F A byte has 256 (2^8) possible values. Thus, each byte can be described using 2 hexadecimal digits. Old Intel x86 processors have 2^32 possible addresses, while the 64-bit ones have 2^64 possible addresses. The 64-bit processors can run in 32-bit compatibility mode, which allows them to run 32-bit code quickly 16
Alternate Disassembly Within gdb Debugger gdb./a.out (gdb)disassemble main n disassembly of the main (gdb)break main n Breakpoint simply tells the debugger to pause the execution at the start of main (gdb)run (gdb)i r eip n The value of the register (instruction pointer) is displayed 17
Function Prologue 18
Function Prologue Function prologue is generated by the compiler to set up memory for the rest of the function's local variables. Part of the reason variables need to be declared in C is to aid the construction of this section of code. The debugger knows this part of the code is automatically generated and is smart enough to skip over it. 19
Examining Memory The GDB debugger provides a direct method to examine memory, using the command x x/11xb main Examine the 11 bytes in hexadecimal starting at main x/2xw $eip Debugger lets you reference registers directly, so $eip is equivalent to the value EIP contains at that moment Examine the 2 words (four-byte) in hexadecimal at $eip x/i $eip To display the memory as disassembled assembly language instructions. 20
On the x86 processor, values are stored in little-endian byte order, which means the least significant byte has lowest address 21
Outline Assembly Language Memory Layout 22
Memory Layout Stack Runtime stack E. g., local variables Heap Dynamically allocated storage When call malloc(), calloc(), new() Data Statically allocated data E.g., arrays & strings declared in code Text Executable machine instructions Read-only high address low address Stack Heap Data Text 23
Procedures/Functions We need to address several issues: 1. How to allocate space for local variables 2. How to pass parameters 3. How to pass return values 4. How to share 8 registers with an infinite number of local variables A stack frame provides space for these values Each procedure invocation has its own stack frame Stack discipline is LIFO n If procedure A calls B, B s frame must exit before A s 24
Carnegie Mellon Stack Frames Contents Local variables Return information Temporary space Previous Frame Management Space allocated when enter procedure n Set-up code Deallocated when return n Finish code Frame Pointer: %ebp Stack Pointer: %esp Frame for proc Stack Top 25
Function Call Chain blue( ) {... green()... } green( ) {... orange()... orange() } orange( ) {... orange()... } blue green orange orange... 26 orange
Function Call Chain Frame for blue Call to green pushes new frame blue green orange orange When orange returns it pops its frame orange... 27
On the stack int blue(int a, int b) { } char buf[16]; int c, d; if(a > b) c = a; else c = b; d = green(c, buf); return d; Need to access arguments Need space to store local vars (buf, c, and d) Need space to put arguments for callee Need a way for callee to return values Calling convention determines the above features 28
Carnegie Mellon Register Saving Conventions When procedure blue calls green: blue is the caller green is the callee Conventions Caller Save n Caller saves temporary values in its frame before the call Callee Save n Callee saves temporary values in its frame before using 29
Carnegie Mellon Register Usage %eax, %edx, %ecx Caller saves prior to call if values are used later %eax also used to return integer value %ebx, %esi, %edi Callee saves if wants to use them Caller- Save Temporaries Callee- Save Temporaries Special %eax %edx %ecx %ebx %esi %edi %esp %ebp 30
cdecl the default for Linux & gcc Int blue(int a, int b) { } char buf[16]; int c, d; if(a > b) c = a; else c = b; d = green(c, buf); return d; parameter area (caller) blue s initial stack frame to be created before calling green After green has been called b a caller s ebp callee-save locals (buf, c, d 24 bytes if stored on stack) caller-save buf c blue s ebp 31 %ebp frame %esp stack grow
Calling Conventions When blue attains control, 1. ess has already been pushed onto stack by caller b a %ebp (caller) %esp 32
Calling Conventions When blue attains control, 1. ess has already been pushed onto stack by caller 2. own the frame pointer - push caller s ebp - copy current esp into ebp - first argument is at ebp+8 b a caller s ebp %ebp and %esp 33
Calling Conventions When blue attains control, 1. ess has already been pushed onto stack by caller 2. own the frame pointer - push caller s ebp - copy current esp into ebp - first argument is at ebp+8 3. save values of other callee-save registers if used - edi, esi, ebx b a caller s ebp callee-save %ebp %esp 34
Calling Conventions When blue attains control, b 1. ess has already been pushed onto stack by caller 2. own the frame pointer - push caller s ebp - copy current esp into ebp - first argument is at ebp+8 3. save values of other callee-save registers if used - edi, esi, ebx blue s initial stack frame a caller s ebp callee-save locals (buf, c, d 24 bytes if stored on stack) %ebp %esp 4. allocate space for locals - subtracting from esp 35
Calling Conventions For caller blue to call callee green, b a caller s ebp callee-save locals (buf, c, d 24 bytes if stored on stack) %ebp %esp 36
Calling Conventions For caller blue to call callee green, 1. push any caller-save registers if their values are needed after green returns - eax, edx, ecx b a caller s ebp callee-save locals (buf, c, d 24 bytes if stored on stack) caller-save %ebp %esp 37
Calling Conventions For caller blue to call callee green, 1. push any caller-save registers if their values are needed after green returns - eax, edx, ecx 2. push arguments to green from right to left (reversed) - from callee s perspective, argument 1 is nearest in stack b a caller s ebp callee-save locals (buf, c, d 24 bytes if stored on stack) caller-save buf c %ebp %esp 38
Calling Conventions For caller blue to call callee green, b 1. push any caller-save registers if their values are needed after green returns - eax, edx, ecx 2. push arguments to green from right to left (reversed) - from callee s perspective, argument 1 is nearest in stack blue s stack frame a caller s ebp callee-save locals (buf, c, d 24 bytes if stored on stack) %ebp 3. push ess, i.e., the next instruction to execute in blue after green returns caller-save buf c %esp 39
Calling Conventions For caller blue to call callee green, b 1. push any caller-save registers if their values are needed after green returns - eax, edx, ecx 2. push arguments to green from right to left (reversed) - from callee s perspective, argument 1 is nearest in stack blue s stack frame a caller s ebp callee-save locals (buf, c, d 24 bytes if stored on stack) %ebp 3. push ess, i.e., the next instruction to execute in blue after green returns 4. transfer control to green - usually happens together with step 3 using call caller-save buf c 40 %esp
Calling Conventions When green attains control, 1. ess has already been pushed onto stack by blue b a caller s ebp callee-save locals (buf, c, d 24 bytes if stored on stack) caller-save buf c 41 %ebp %esp
Calling Conventions When green attains control, 1. ess has already been pushed onto stack by blue 2. own the frame pointer b a caller s ebp callee-save locals (buf, c, d 24 bytes if stored on stack) caller-save buf c blue s ebp 42 %ebp and %esp
Calling Conventions When green attains control, 1. ess has already been pushed onto stack by blue 2. own the frame pointer 3. (green is doing its stuff) b a caller s ebp callee-save locals (buf, c, d 24 bytes if stored on stack) caller-save buf c blue s ebp 43 %ebp %esp
Calling Conventions When green attains control, 1. ess has already been pushed onto stack by blue 2. own the frame pointer 3. (green is doing its stuff) 4. store return value, if any, in eax 5. deallocate locals - adding to esp 6. restore any callee-save registers b a caller s ebp callee-save locals (buf, c, d 24 bytes if stored on stack) caller-save buf c blue s ebp 44 %ebp and %esp
Calling Conventions When green attains control, 1. ess has already been pushed onto stack by blue 2. own the frame pointer 3. (green is doing its stuff) 4. store return value, if any, in eax 5. deallocate locals - adding to esp 6. restore any callee-save registers 7. restore blue s frame pointer - pop %ebp b a caller s ebp callee-save locals (buf, c, d 24 bytes if stored on stack) caller-save buf c 45 %ebp %esp
Calling Conventions When green attains control, 1. ess has already been pushed onto stack by blue 2. own the frame pointer 3. (green is doing its stuff) 4. store return value, if any, in eax 5. deallocate locals - adding to esp 6. restore any callee-save registers 7. restore blue s frame pointer - pop %ebp 8. return control to blue - ret - pops ess from stack and jumps there b a caller s ebp callee-save locals (buf, c, d 24 bytes if stored on stack) caller-save buf c 46 %ebp %esp
Calling Conventions When blue regains control, b a caller s ebp callee-save locals (buf, c, d 24 bytes if stored on stack) caller-save buf c %ebp %esp 47
Calling Conventions When blue regains control, 1. clean up arguments to green - adding to esp 2. restore any caller-save registers - pops 3. b a caller s ebp callee-save locals (buf, c, d 24 bytes if stored on stack) %ebp %esp 48
Terminology Function Prologue instructions to set up stack space and save callee saved registers Typical sequence: push ebp ebp = esp esp = esp - <frame space> Function Epilogue - instructions to clean up stack space and restore callee saved registers Typical Sequence: leave // esp = ebp, pop ebp ret // pop and jump to ret addr 49
Recap Compiler workflow GDB debugger provides a method to examine memory Memory Layout Text, Data, Heap and Stack Stack grows down Pass arguments, callee and caller saved, stack frame 50