COMP 4580 Computer Security Software Security III Dr. Noman Mohammed Winter 2019 Including slides from: David Brumley & others!
Outline Assembly Language Memory Layout Control Flow Hijacking Methods Buffer Overflow Attack Format String Attack n Reading from memory n Writing to memory Countermeasures 2
Format Strings printf( The number is: %d, 100); A format string is just a character string with special escape sequences that tell the function to insert variables printed in a specific format in place of the escape sequence. These escape sequences are also called format parameters, and for each one found in the format string, the function is expected to take an additional argument. 3
Format Parameters Parameter Output type Passed as %d Decimal Value %u Unsigned decimal Value %x Hexadecimal Value %s String Reference %n # of bytes written so far Reference 4
Format Strings in C Proper use of printf format string: int foo=1234; printf( foo = %d in decimal, %X in hex,foo,foo); n This will print foo = 1234 in decimal, 4D2 in hex Sloppy use of printf format string: char buf[13]= Hello, world! ; printf(buf); n should ve used printf( %s, buf); 5
Stack Diagram callee caller arg n arg 2 arg 1 return addr caller s ebp callee-save locals n-1 th specified argument 1 st specified argument format string 6
Example arg 4 42 printf caller arg 3 arg 2 arg 1 return addr caller s ebp callee-save locals address of world address of hello address of %s %s %u char s1[] = hello ; char s2[] = world ; printf( %s %s %u, s1, s2, 42); 7
Outline Assembly Language Memory Layout Control Flow Hijacking Methods Buffer Overflow Attack Format String Attack n Reading from memory n Writing to memory Countermeasures 8
Example 1. int foo(char *fmt) { 2. char buf[32]; 3. strcpy(buf, fmt); 4. printf(buf); 5. } 080483d4 <foo>: 80483d4: push %ebp 80483d5: mov %esp,%ebp 80483d7: sub $0x28,%esp ; allocate 40 bytes on stack 80483da: mov 0x8(%ebp),%eax ; eax := M[ebp+8] - addr of fmt 80483dd: mov %eax,0x4(%esp) ; M[esp+4] := eax - push as arg 2 80483e1: lea - 0x20(%ebp),%eax ; eax := ebp- 32 - addr of buf 80483e4: mov %eax,(%esp) ; M[esp] := eax - push as arg 1 80483e7: call 80482fc <strcpy@plt> 80483ec: lea - 0x20(%ebp),%eax ; eax := ebp- 32 - addr of buf again 80483ef: mov %eax,(%esp) ; M[esp] := eax - push as arg 1 80483f2: call 804830c <printf@plt> 80483f7: leave 80483f8: ret 9
Stack Diagram @ printf printf foo return addr caller s ebp buf (32 bytes) stale arg 2 arg 1 return addr foo s ebp locals addr of fmt addr of buf 1. int foo(char *fmt) { 2. char buf[32]; 3. strcpy(buf, fmt); => printf(buf); 5. } 10
Viewing Stack printf foo return addr caller s ebp buf (32 bytes) stale arg 2 arg 1 return addr foo s ebp locals 1. int foo(char *fmt) { 2. char buf[32]; 3. strcpy(buf, fmt); => printf(buf); 5. } What are the effects if fmt is: %x%x...%x 11 times 11
Viewing Specific Address 1 printf foo return addr caller s ebp buf (32 bytes) stale arg 2 arg 1 return addr foo s ebp locals 1. int foo(char *fmt) { 2. char buf[32]; 3. strcpy(buf, fmt); => printf(buf); 5. } Observe: buf is below (higher address) printf on the call stack, thus we can walk to it with the correct parameters. What if fmt is %x%s? 12
Viewing Specific Address 2 printf foo return addr caller s ebp (buf s other 28 bytes) 0xbffff747 stale arg 2 arg 1 return addr foo s ebp locals 1. int foo(char *fmt) { 2. char buf[32]; 3. strcpy(buf, fmt); => printf(buf); 5. } Encode address to peek in buf first. Address 0xbffff747 is \x47\xf7\xff\xbf in little endian. \x47\xf7\xff\xbf%x%s 13
Outline Assembly Language Memory Layout Control Flow Hijacking Methods Buffer Overflow Attack Format String Attack n Reading from memory n Writing to memory Countermeasures 14
Writing Stack with Format Strings %n format symbol tells printf to write the number of characters that have been printed printf( Overflow this!%n,&myvar); n Argument of printf is interpeted as destination address n This writes 14 into myvar ( Overflow this! has 14 characters) What if printf does not have an argument? char buf[16]= Overflow this!%n ; printf(buf); n Stack location pointed to by printf s internal stack pointer will be interpreted as address into which the number of characters will be written! 15
Specifying Length What does: int a; print? printf( - %10u- %n", 7350, &a); Print argument padded to 10 digits - 7350-16
Writing to Specific Address Encode address in format string: "\xc0\xc8\xff\xbf_%08x.%08x.%08x.%08x.%08x.%n" pop 5 dwords from stack to reach format string Writes a small num at destination 0xbfffc8c0 Can use four carefully-controlled writes to create an address at destination 17
Buffer Overflow vs. Format String Buffer Overflow Format String Public since Mid 1980 s June 1999 Danger realized 1990 s June 2000 Bu er Overflow Format String public since mid 1980 s June 1999 danger realized 1990 s June 2000 number of exploits a few thousand a few dozen considered as security threat programming bug techniques evolved and advanced basic techniques visibility sometimes very di cult to spot easy to find Number of exploits A few thousand A few dozen Considered as Security threat Programming bug Techniques Evolved and advanced Basic techniques Visibility Sometimes very difficult to spot Easy to find Source: Exploiting Format String Vulnerabilities by Team Teso. 18
Outline Assembly Language Memory Layout Control Flow Hijacking Methods Buffer Overflow Attack Format String Attack Countermeasures 19
Defenses Bugs are the root cause of hijacks! Safe programming practice strncpy instead of strcpy printf( %s, buf) instead of printf(buf) Find bugs with analysis tools Mitigation Techniques: StackGuard Address Space Randomization Non-executable stack 20
StackGuard Idea: prologue introduces a canary word between return addr and locals epilogue checks canary before function returns arg 2 arg 1 return addr caller s ebp callee-save CANARY locals %ebp Wrong Canary => Overflow 21 %esp
Address Space Randomization Traditional exploits need precise addresses stack-based overflows: location of shell code Problem: program s memory layout is fixed stack, heap, etc. Solution: randomize addresses of each region! Makes it difficult for hacker to predict beginning of inserted code 22
Address Space Randomization addr of buf (0xffffd5d8) addr of buf (0xffffd5d8) buf[63] caller s ebp buf 0xffffd618 caller s ebp buf 0xffffe428 Shellcode Shellcode 0xffffe3f8 Randomize! buf[0] 0xffffd5d8 23 Oops 0xffffd5d8
Non-executable Stack We can configure the stack to be non-executable, and thus preventing the malicious code from being executed. shellcode padding &buf CRASH Still a Denial-of-Service attack! 24
Recap Control Flow Hijacks happen when an attacker gains control of the instruction pointer. Two common hijack methods: buffer overflows format string attacks 25