C and C++: vulnerabilities, exploits and countermeasures
Yves Younan Security Research Group Research In Motion [email protected]
Monday, February 13, 2012
Introduction
C/C++ programs: some vulnerabilities exist which could allow code injection attacks Code injection attacks allow an attacker to execute foreign code with the privileges of the vulnerable program Major problem for programs written in C/C++ Focus will be on:
Illustration of code injection attacks Countermeasures for these attacks
Yves Younan Monday, February 13, 2012
C and C++: vulnerabilities, exploits and countermeasures
March, 2012
2 / 149
Lecture overview
Memory management in C/C++ Vulnerabilities Countermeasures Conclusion
Yves Younan Monday, February 13, 2012
C and C++: vulnerabilities, exploits and countermeasures
March, 2012
3 / 149
Memory management in C/C++
Memory is allocated in multiple ways in C/C++:
Automatic (local variables in a function) Static (global variables) Dynamic (malloc or new)
Programmer is responsible for
Correct allocation and deallocation in the case of dynamic memory Appropriate use of the allocated memory
Bounds checks, type checks
Yves Younan Monday, February 13, 2012
C and C++: vulnerabilities, exploits and countermeasures
March, 2012
4 / 149
Memory management in C/C++
Memory management is very error prone Typical bugs:
Writing past the bounds of the allocated memory Dangling pointers: pointers to deallocated memory Double frees: deallocating memory twice Memory leaks: never deallocating memory
For efficiency reasons, C/C++ compilers dont detect these bugs at run-time:
C standard states behavior of such programs is undefined
Yves Younan Monday, February 13, 2012
C and C++: vulnerabilities, exploits and countermeasures
March, 2012
5 / 149
Process memory layout
Arguments/Environment Stack Unused and Shared Memory
Heap Static & Global Data Program code
Yves Younan Monday, February 13, 2012
C and C++: vulnerabilities, exploits and countermeasures
March, 2012
6 / 149
Lecture overview
Memory management in C/C++ Vulnerabilities
Code injection attacks Buffer overflows Format string vulnerabilities Integer errors
Countermeasures Conclusion
Yves Younan Monday, February 13, 2012
C and C++: vulnerabilities, exploits and countermeasures
March, 2012
7 / 149
Code injection attacks
To exploit a vulnerability and execute a code injection attack, an attacker must:
Find a bug that can allow an attacker to overwrite interesting memory locations Find such an interesting memory location Copy target code in binary form into the memory of a program
Can be done easily, by giving it as input to the program
Use the vulnerability to modify the location so that the program will execute the injected code
Yves Younan Monday, February 13, 2012
C and C++: vulnerabilities, exploits and countermeasures
March, 2012
8 / 149
Interesting memory locations
Stored code addresses: modified -> code can be executed when the program loads them into the IP
Return address: address where the execution must resume when a function ends Global Offset Table: addresses here are used to execute dynamically loaded functions Virtual function table: addresses are used to know which method to execute (dynamic binding in C++) Dtors functions: called when programs exit
Yves Younan Monday, February 13, 2012
C and C++: vulnerabilities, exploits and countermeasures
March, 2012
9 / 149
Interesting memory locations
Function pointers: modified -> when called, the injected code is executed Data pointers: modified -> indirect pointer overwrites
First the pointer is made to point to an interesting location, when it is dereferenced for writing the location is overwritten
Attackers can overwrite many locations to perform an attack
Yves Younan Monday, February 13, 2012
C and C++: vulnerabilities, exploits and countermeasures
March, 2012
10 / 149
Lecture overview
Memory management in C/C++ Vulnerabilities
Code injection attacks Buffer overflows
Stack-based buffer overflows Indirect Pointer Overwriting Heap-based buffer overflows and double free Overflows in other segments
Format string vulnerabilities Integer errors
Countermeasures
Yves Younan Monday, February 13, 2012 C and C++: vulnerabilities, exploits and countermeasures March, 2012 11 / 149
Buffer overflows: impact
Code red worm: estimated loss world-wide: $ 2.62 billion Sasser worm: shut down X-ray machines at a swedish hospital and caused Delta airlines to cancel several transatlantic flights Zotob worm: crashed the DHS US-VISIT program computers, causing long lines at major international airports All three worms used stack-based buffer overflows Stuxnet the worm that targeted Irans nuclear program used a buffer overflow as one of its vulnerabilities
Yves Younan Monday, February 13, 2012 C and C++: vulnerabilities, exploits and countermeasures March, 2012 12 / 149
Buffer overflows: numbers
NIST national vulnerability database (jan-dec 2011):
631 buffer overflow vulnerabilities
16.18% of total vulnerabilities reported 509 of these have a high severity rating
These buffer overflow vulnerabilities make up 30% of the vulnerabilities with high severity for the period
Of the remaining 122 vulnerabilities, 116 are marked as having medium severity
Yves Younan Monday, February 13, 2012
C and C++: vulnerabilities, exploits and countermeasures
March, 2012
13 / 149
Buffer overflows: what?
Write beyond the bounds of an array Overwrite information stored behind the array Arrays can be accessed through an index or through a pointer to the array Both can cause an overflow Java: not vulnerable because it has no pointer arithmetic and does bounds checking on array indexing
Yves Younan Monday, February 13, 2012
C and C++: vulnerabilities, exploits and countermeasures
March, 2012
14 / 149
Buffer overflows: how?
How do buffer overflows occur?
By using an unsafe copying function (e.g. strcpy) By looping over an array using an index which may be too high Through integer errors
How can they be prevented?
Using copy functions which allow the programmer to specify the maximum size to copy (e.g. strncpy) Checking index values Better checks on integers
Yves Younan Monday, February 13, 2012 C and C++: vulnerabilities, exploits and countermeasures March, 2012 15 / 149
Buffer overflows: example
void function(char *input) { char str[80]; strcpy(str, input); } int main(int argc, char **argv) { function(argv[1]); }
Yves Younan Monday, February 13, 2012
C and C++: vulnerabilities, exploits and countermeasures
March, 2012
16 / 149
Shellcode
Small program in machine code representation Injected into the address space of the process int main() {
! ! ! ! ! ! ! ! ! ! ! printf("You win\n"); ! ! exit(0) ! ! } static char shellcode[] = ! ! "\x6a\x09\x83\x04\x24\x01\x68\x77" ! ! "\x69\x6e\x21\x68\x79\x6f\x75\x20" ! ! "\x31\xdb\xb3\x01\x89\xe1\x31\xd2" ! ! "\xb2\x09\x31\xc0\xb0\x04\xcd\x80" ! ! "\x32\xdb\xb0\x01\xcd\x80";
Yves Younan Monday, February 13, 2012 C and C++: vulnerabilities, exploits and countermeasures March, 2012 17 / 149
Lecture overview
Memory management in C/C++ Vulnerabilities
Code injection attacks Buffer overflows
Stack-based buffer overflows Indirect Pointer Overwriting Heap-based buffer overflows and double free Overflows in other segments
Format string vulnerabilities Integer errors
Countermeasures
Yves Younan Monday, February 13, 2012 C and C++: vulnerabilities, exploits and countermeasures March, 2012 18 / 149
Stack-based buffer overflows
Stack is used at run time to manage the use of functions:
For every function call, a new record is created
Contains return address: where execution should resume when the function is done Arguments passed to the function Local variables
If an attacker can overflow a local variable he can find interesting locations nearby
Yves Younan Monday, February 13, 2012
C and C++: vulnerabilities, exploits and countermeasures
March, 2012
19 / 149
Stack-based buffer overflows
Old unix login vulnerability
int login() { char user[8], hash[8], pw[8]; printf("login:"); gets(user); lookup(user,hash); printf("password:"); gets(pw); if (equal(hash, hashpw(pw))) return OK; else return INVALID; }
Yves Younan Monday, February 13, 2012 C and C++: vulnerabilities, exploits and countermeasures March, 2012 20 / 149
Stack-based buffer overflows
Other stack frames IP login: char user[8], hash[8], pw[8]; printf(username:); gets(user); lookup(user,hash); printf(password:); gets(pw); if (equal(hash,hashpw(pw))) return OK; else return INVALID; FP Return address login Saved frame pointer login user hash SP pw
Yves Younan Monday, February 13, 2012
C and C++: vulnerabilities, exploits and countermeasures
March, 2012
21 / 149
Stack-based buffer overflows
Other stack frames login: char user[8], hash[8], pw[8]; printf(username:); gets(user); lookup(user,hash); printf(password:); gets(pw); if (equal(hash,hashpw(pw))) return OK; else return INVALID; FP Return address login Saved frame pointer login user hash SP pw IP
Yves Younan Monday, February 13, 2012
C and C++: vulnerabilities, exploits and countermeasures
March, 2012
22 / 149
Stack-based buffer overflows
Other stack frames login: char user[8], hash[8], pw[8]; printf(username:); gets(user); lookup(user,hash); printf(password:); gets(pw); if (equal(hash,hashpw(pw))) return OK; else return INVALID; FP Return address login Saved frame pointer login user hash SP pw
IP
Yves Younan Monday, February 13, 2012
C and C++: vulnerabilities, exploits and countermeasures
March, 2012
23 / 149
Stack-based buffer overflows
Other stack frames login: char user[8], hash[8], pw[8]; printf(username:); gets(user); lookup(user,hash); printf(password:); gets(pw); if (equal(hash,hashpw(pw))) return OK; else return INVALID; FP Return address login Saved frame pointer login user hash SP pw
IP
Yves Younan Monday, February 13, 2012
C and C++: vulnerabilities, exploits and countermeasures
March, 2012
24 / 149
Stack-based buffer overflows
Other stack frames login: char user[8], hash[8], pw[8]; printf(username:); gets(user); lookup(user,hash); printf(password:); gets(pw); if (equal(hash,hashpw(pw))) return OK; else return INVALID; FP Return address login Saved frame pointer login user hash SP pw
IP
Yves Younan Monday, February 13, 2012
C and C++: vulnerabilities, exploits and countermeasures
March, 2012
25 / 149
Stack-based buffer overflows
Attacker can specify a password longer than 8 characters Will overwrite the hashed password Attacker enters:
AAAAAAAABBBBBBBB Where BBBBBBBB = hashpw(AAAAAAAA)
Login to any user account without knowing the password Called a non-control data attack
Yves Younan Monday, February 13, 2012 C and C++: vulnerabilities, exploits and countermeasures March, 2012 26 / 149
Stack-based buffer overflows
Other stack frames login: char user[8], hash[8], pw[8]; printf(username:); gets(user); lookup(user,hash); printf(password:); gets(pw); if (equal(hash,hashpw(pw))) return OK; else return INVALID; FP Return address login Saved frame pointer login user hash SP pw
IP
Yves Younan Monday, February 13, 2012
C and C++: vulnerabilities, exploits and countermeasures
March, 2012
27 / 149
Stack-based buffer overflows
Stack IP f0: ... call f1 ... FP Other stack frames Return address f0 Saved frame pointer f0 Local variables f0
SP f1: buffer[] overflow() ...
Yves Younan Monday, February 13, 2012
C and C++: vulnerabilities, exploits and countermeasures
March, 2012
28 / 149
Stack-based buffer overflows
Stack f0: IP ... call f1 ... FP Other stack frames Return address f0 Saved frame pointer f0 Local variables f0 f1: buffer[] overflow() ... Arguments f1
SP
Yves Younan Monday, February 13, 2012
C and C++: vulnerabilities, exploits and countermeasures
March, 2012
29 / 149
Stack-based buffer overflows
Stack f0: ... call f1 ... IP Other stack frames Return address f0 Saved frame pointer f0 Local variables f0 f1: buffer[] overflow() ... Arguments f1 FP Overwritten Return address return address f1 Saved frame pointer f1 Injected Buffer code
SP
Yves Younan Monday, February 13, 2012 C and C++: vulnerabilities, exploits and countermeasures
March, 2012
30 / 149
Stack-based buffer overflows
Stack f0: ... call f1 ... Other stack frames Return address f0 Saved frame pointer f0 Local variables f0 f1: buffer[] overflow() ... Arguments f1 FP Overwritten return address
IP
SP
Yves Younan Monday, February 13, 2012 C and C++: vulnerabilities, exploits and countermeasures
Injected code
March, 2012
31 / 149
Stack-based buffer overflows
Stack f0: ... call f1 ... SP f1: buffer[] overflow() ... IP Injected code Other stack frames Return address f0 Saved frame pointer f0 Local variables f0
Yves Younan Monday, February 13, 2012
C and C++: vulnerabilities, exploits and countermeasures
March, 2012
32 / 149
Stack-based buffer overflows
Exercises
From Geras insecure programming page
http://community.corest.com/~gera/ InsecureProgramming/
For the following programs:
Assume Linux on Intel 32-bit Draw the stack layout right after gets() has executed Give the input which will make the program print out you win!
Yves Younan Monday, February 13, 2012
C and C++: vulnerabilities, exploits and countermeasures
March, 2012
33 / 149
Stack-based buffer overflows
int main() { ! int cookie; ! char buf[80]; ! printf("b: %x c: %x\n", &buf, &cookie); ! gets(buf); ! if (cookie == 0x41424344) ! ! printf("you win!\n"); }
Yves Younan Monday, February 13, 2012 C and C++: vulnerabilities, exploits and countermeasures March, 2012 34 / 149
Stack-based buffer overflows
Stack main: cookie buf[80] printf() gets() ... FP Return address Frame pointer cookie SP buf
IP
Yves Younan Monday, February 13, 2012
C and C++: vulnerabilities, exploits and countermeasures
March, 2012
35 / 149
Stack-based buffer overflows
Stack main: cookie buf[80] printf() gets() ... FP Return address Frame pointer ABCD SP buf
IP
perl -e 'print "A"x80; print "DCBA"' | ./s1
Yves Younan Monday, February 13, 2012 C and C++: vulnerabilities, exploits and countermeasures March, 2012 36 / 149
Stack-based buffer overflows
int main() { ! int cookie; ! char buf[80]; ! printf("b: %x c: %x\n", &buf, &cookie); ! gets(buf); } buf is at location 0xbffffce4 in memory
Yves Younan Monday, February 13, 2012
C and C++: vulnerabilities, exploits and countermeasures
March, 2012
37 / 149
Stack-based buffer overflows
Stack main: cookie buf[80] printf() gets() ... FP Return address Frame pointer cookie SP buf
IP
Yves Younan Monday, February 13, 2012
C and C++: vulnerabilities, exploits and countermeasures
March, 2012
38 / 149
Stack-based buffer overflows
#define RET 0xbffffce4 int main() { ! char buf[93]; int ret; memset(buf, '\x90', 92); memcpy(buf, shellcode, strlen(shellcode)); *(long *)&buf[88] = RET; buf[92] = 0; printf(buf); }
Yves Younan Monday, February 13, 2012
C and C++: vulnerabilities, exploits and countermeasures
March, 2012
39 / 149
Stack-based buffer overflows
IP
main: cookie buf[80] printf() gets() ...
FP
Stack 0xbffffce4 0x90909090 0x90909090
0xbffffce4
Injected code
40
Yves Younan Monday, February 13, 2012
C and C++: vulnerabilities, exploits and countermeasures
March, 2012
/ 149
Finding inserted code
Generally (on kernels < 2.6) the stack will start at a static address Finding shell code means running the program with a fixed set of arguments/fixed environment This will result in the same address Not very precise, small change can result in different location of code Not mandatory to put shellcode in buffer used to overflow Pass as environment variable
Yves Younan Monday, February 13, 2012 C and C++: vulnerabilities, exploits and countermeasures March, 2012 41 / 149
Controlling the environment
Passing shellcode as environment variable: Stack start - 4 null bytes - strlen(program name) - null byte (program name) - strlen(shellcode) 0xBFFFFFFF - 4 - strlen(program name) -1 - strlen(shellcode) Stack start: 0xBFFFFFFF 0,0,0,0 Program name Env var n Env var n-1 Env var 0 Arg n Arg n-1 Arg 0 Low addr High addr
Yves Younan Monday, February 13, 2012
C and C++: vulnerabilities, exploits and countermeasures
March, 2012
42 / 149
Lecture overview
Memory management in C/C++ Vulnerabilities
Code injection attacks Buffer overflows
Stack-based buffer overflows Indirect Pointer Overwriting Heap-based buffer overflows and double free Overflows in other segments
Format string vulnerabilities Integer errors
Yves Younan Monday, February 13, 2012 C and C++: vulnerabilities, exploits and countermeasures March, 2012 43 / 149
Indirect Pointer Overwriting
Overwrite a target memory location by overwriting a data pointer
An attackers makes the data pointer point to the target location When the pointer is dereferenced for writing, the target location is overwritten If the attacker can specify the value of to write, he can overwrite arbitrary memory locations with arbitrary values
Yves Younan Monday, February 13, 2012
C and C++: vulnerabilities, exploits and countermeasures
March, 2012
44 / 149
Indirect Pointer Overwriting
Stack IP f0: ... call f1 ... FP Other stack frames Return address f0 Saved frame pointer f0 Local variables f0
SP f1: ptrbuffer[] = &data; overflow() buffer[] ... overflow(); *ptr = value; ... data
Yves Younan Monday, February 13, 2012
C and C++: vulnerabilities, exploits and countermeasures
March, 2012
45 / 149
Indirect Pointer Overwriting
Stack f0: ... call f1 ... Other stack frames Return address f0 Saved frame pointer f0 Local variables f0 IP f1: ptrbuffer[] = &data; overflow() buffer[] ... overflow(); *ptr = value; ... data Arguments f1 FP Return address f1 Saved frame pointer f1 Pointer Buffer
SP
Yves Younan Monday, February 13, 2012
C and C++: vulnerabilities, exploits and countermeasures
March, 2012
46 / 149
Indirect Pointer Overwriting
Stack f0: ... call f1 ... Other stack frames Return address f0 Saved frame pointer f0 Local variables f0 f1: ptrbuffer[] = &data; ptr overflow() = &data; buffer[] ... overflow(); *ptr = value; ... data Arguments f1 FP Return address f1 Saved frame pointer f1 Overwritten pointer Injected code
IP
SP
Yves Younan Monday, February 13, 2012
C and C++: vulnerabilities, exploits and countermeasures
March, 2012
47 / 149
Indirect Pointer Overwriting
Stack f0: ... call f1 ... Other stack frames Return address f0 Saved frame pointer f0 Local variables f0 f1: ptrbuffer[] = &data; ptr overflow() = &data; buffer[] ... overflow(); *ptr = value; ... data Arguments f1 FP Modified return address Saved frame pointer f1 Overwritten pointer Injected code
IP
SP
Yves Younan Monday, February 13, 2012
C and C++: vulnerabilities, exploits and countermeasures
March, 2012
48 / 149
Indirect Pointer Overwriting
Stack f0: ... call f1 ... FP Other stack frames Return address f0 Saved frame pointer f0 Local variables f0
SP f1: ptrbuffer[] = &data; ptr overflow() = &data; buffer[] ... overflow(); *ptr = value; ... data
IP
Injected code
Yves Younan Monday, February 13, 2012
C and C++: vulnerabilities, exploits and countermeasures
March, 2012
49 / 149
Indirect Pointer Overwriting
static unsigned int a = 0; int main(int argc, char **argv) { int *b = &a; char buf[80]; printf("buf: %08x\n", &buf); gets(buf); *b = strtoul(argv[1], 0, 16); } buf is at 0xbffff9e4
Yves Younan Monday, February 13, 2012 C and C++: vulnerabilities, exploits and countermeasures March, 2012 50 / 149
Indirect Pointer Overwriting
main: f1: buffer[] b = &a; overflow() buf[80] ... gets(); *b = argv[1]; ...
IP
Stack FP Return address Saved frame pointer b buf
SP
Yves Younan Monday, February 13, 2012
C and C++: vulnerabilities, exploits and countermeasures
March, 2012
51 / 149
Indirect Pointer Overwriting
#define RET 0xbffff9e4+88 int main() { char buf[84]; int ret; memset(buf, '\x90', 84); memcpy(buf, shellcode, strlen(shellcode)); *(long *)&buffer[80] = RET; printf(buffer); } ./exploit | ./s3 bffff9e4
Yves Younan Monday, February 13, 2012 C and C++: vulnerabilities, exploits and countermeasures March, 2012 52 / 149
Indirect Pointer Overwriting
main: f1: buffer[] b = &a; overflow() buf[80] ... gets(); *b = argv[1]; ... Stack FP Return address Saved frame pointer b buf
IP
SP
Yves Younan Monday, February 13, 2012
C and C++: vulnerabilities, exploits and countermeasures
March, 2012
53 / 149
Indirect Pointer Overwriting
main: f1: buffer[] b = &a; overflow() buf[80] ... gets(); *b = argv[1]; ... Stack FP Return address Saved frame pointer b buf
IP
SP
Yves Younan Monday, February 13, 2012
C and C++: vulnerabilities, exploits and countermeasures
March, 2012
54 / 149
Lecture overview
Memory management in C/C++ Vulnerabilities
Code injection attacks Buffer overflows
Stack-based buffer overflows Indirect Pointer Overwriting Heap-based buffer overflows and double free Overflows in other segments
Format string vulnerabilities Integer errors
Yves Younan Monday, February 13, 2012 C and C++: vulnerabilities, exploits and countermeasures March, 2012 55 / 149
Heap-based buffer overflows
Heap contains dynamically allocated memory
Managed via malloc() and free() functions of the memory allocation library A part of heap memory that has been processed by malloc is called a chunk No return addresses: attackers must overwrite data pointers or function pointers Most memory allocators save their memory management information in-band Overflows can overwrite management information
Yves Younan Monday, February 13, 2012
C and C++: vulnerabilities, exploits and countermeasures
March, 2012
56 / 149
Heap management in dlmalloc
Used chunk
Chunk1 Size of prev. chunk Size of chunk1 User data
Yves Younan Monday, February 13, 2012
C and C++: vulnerabilities, exploits and countermeasures
March, 2012
57 / 149
Heap management in dlmalloc
Free chunk: doubly linked list of free chunks
Chunk1
Size of prev. chunk Size of chunk1 Forward pointer Backward pointer Old user data
Yves Younan Monday, February 13, 2012
C and C++: vulnerabilities, exploits and countermeasures
March, 2012
58 / 149
Heap management in dlmalloc
Removing a chunk from the doubly linked list of free chunks:
#define unlink(P, BK, FD) { BK = P->bk; FD = P->fd; FD->bk = BK; BK->fd = FD; }
This is:
P->fd->bk = P->bk P->bk->fd = P->fd
Yves Younan Monday, February 13, 2012 C and C++: vulnerabilities, exploits and countermeasures March, 2012 59 / 149
Heap management in dlmalloc
Chunk1 Size of prev. chunk Size of chunk1 Forward pointer Backward pointer Old user data Chunk2 Size of prev. chunk Size of chunk2 Forward pointer Backward pointer Old user data Chunk3 Size of prev. chunk Size of chunk3 Forward pointer Backward pointer Old user data
Yves Younan Monday, February 13, 2012
C and C++: vulnerabilities, exploits and countermeasures
March, 2012
60 / 149
Heap management in dlmalloc
Chunk1 Size of prev. chunk Size of chunk1 Forward pointer Backward pointer Old user data Chunk2 Size of prev. chunk Size of chunk2 Forward pointer Backward pointer Old user data Chunk3 Size of prev. chunk Size of chunk3 Forward pointer Backward pointer Old user data
Yves Younan Monday, February 13, 2012
C and C++: vulnerabilities, exploits and countermeasures
March, 2012
61 / 149
Heap management in dlmalloc
Chunk1 Size of prev. chunk Size of chunk1 Forward pointer Backward pointer Old user data Chunk2 Size of prev. chunk Size of chunk2 Forward pointer Backward pointer Old user data Chunk3 Size of prev. chunk Size of chunk3 Forward pointer Backward pointer Old user data
Yves Younan Monday, February 13, 2012
C and C++: vulnerabilities, exploits and countermeasures
March, 2012
62 / 149
Heap management in dlmalloc
Chunk1 Size of prev. chunk Size of chunk1 Forward pointer Backward pointer Old user data Chunk2 Size of prev. chunk Size of chunk2 Forward pointer Backward pointer Old user data Chunk3 Size of prev. chunk Size of chunk3 Forward pointer Backward pointer Old user data
Yves Younan Monday, February 13, 2012
C and C++: vulnerabilities, exploits and countermeasures
March, 2012
63 / 149
Heap-based buffer overflows
Chunk1 Size of prev. chunk Size of chunk1 User data Chunk2
Size of chunk1 Size of chunk2 Forward pointer Backward pointer Old user data
Yves Younan Monday, February 13, 2012
C and C++: vulnerabilities, exploits and countermeasures
March, 2012
64 / 149
Heap-based buffer overflows
Chunk1 Size of prev. chunk Size of chunk1 Injected code Return address Chunk2 Size of chunk1 Size of chunk2 fwd: pointer to target bck: pointer to inj. code Old user data
call f1 ...
Yves Younan Monday, February 13, 2012
C and C++: vulnerabilities, exploits and countermeasures
March, 2012
65 / 149
Heap-based buffer overflows
Chunk1 Size of prev. chunk Size of chunk1 Injected code Overwritten return address Chunk2 Size of chunk1 Size of chunk2 fwd: pointer to target bck: pointer to inj. code Old user data
After unlink
call f1 ...
Yves Younan Monday, February 13, 2012
C and C++: vulnerabilities, exploits and countermeasures
March, 2012
66 / 149
Dangling pointer references
Pointers to memory that is no longer allocated Dereferencing is unchecked in C Generally leads to crashes Can be used for code injection attacks when memory is deallocated twice (double free) Double frees can be used to change the memory management information of a chunk
Yves Younan Monday, February 13, 2012
C and C++: vulnerabilities, exploits and countermeasures
March, 2012
67 / 149
Double free
Chunk2 Size of prev. chunk Size of chunk2 Forward pointer Backward pointer Old user data Chunk3 Size of prev. chunk Size of chunk3 Forward pointer Backward pointer Old user data
Yves Younan Monday, February 13, 2012
C and C++: vulnerabilities, exploits and countermeasures
March, 2012
68 / 149
Double free
Chunk2 Size of prev. chunk Size of chunk2 Forward pointer Backward pointer Old user data Chunk3 Size of prev. chunk Size of chunk3 Forward pointer Backward pointer Old user data
Yves Younan Monday, February 13, 2012
C and C++: vulnerabilities, exploits and countermeasures
March, 2012
69 / 149
Double free
Chunk2 Size of prev. chunk Size of chunk2 Forward pointer Backward pointer Old user data Chunk2 Size of prev. chunk Size of chunk2 Forward pointer Backward pointer Old user data Chunk3 Size of prev. chunk Size of chunk3 Forward pointer Backward pointer Old user data
Yves Younan Monday, February 13, 2012
C and C++: vulnerabilities, exploits and countermeasures
March, 2012
70 / 149
Double free
Chunk2 Size of prev. chunk Size of chunk2 Forward pointer Backward pointer Old user data Chunk3 Size of prev. chunk Size of chunk3 Forward pointer Backward pointer Old user data
Yves Younan Monday, February 13, 2012
C and C++: vulnerabilities, exploits and countermeasures
March, 2012
71 / 149
Double free
Unlink: chunk stays linked because it points to itself
Chunk2 Size of prev. chunk Size of chunk2 Forward pointer Backward pointer Old user data
Yves Younan Monday, February 13, 2012
C and C++: vulnerabilities, exploits and countermeasures
March, 2012
72 / 149
Double free
If unlinked to reallocate: attackers can now write to the user data part
Chunk2 Size of prev. chunk Size of chunk2 Forward pointer Backward pointer Old user data
Yves Younan Monday, February 13, 2012
C and C++: vulnerabilities, exploits and countermeasures
March, 2012
73 / 149
Double free
It is still linked in the list too, so it can be unlinked again
Chunk2 Size of prev. chunk Size of chunk2 Forward pointer Backward pointer Injected code Return address
call f1 ...
Yves Younan Monday, February 13, 2012
C and C++: vulnerabilities, exploits and countermeasures
March, 2012
74 / 149
Double free
After second unlink
Chunk2 Size of prev. chunk Size of chunk2 Forward pointer Backward pointer Injected code
Overwritten return address
call f1 ...
Yves Younan Monday, February 13, 2012
C and C++: vulnerabilities, exploits and countermeasures
March, 2012
75 / 149
Lecture overview
Memory management in C/C++ Vulnerabilities
Code injection attacks Buffer overflows
Stack-based buffer overflows Indirect Pointer Overwriting Heap-based buffer overflows and double free Overflows in other segments
Format string vulnerabilities Integer errors
Yves Younan Monday, February 13, 2012 C and C++: vulnerabilities, exploits and countermeasures March, 2012 76 / 149
Overflows in the data/bss
Data segment contains global or static compile-time initialized data Bss contains global or static uninitialized data Overflows in these segments can overwrite:
Function and data pointers stored in the same segment Data in other segments
Yves Younan Monday, February 13, 2012
C and C++: vulnerabilities, exploits and countermeasures
March, 2012
77 / 149
Overflows in the data/bss
ctors: pointers to functions to execute at program start dtors: pointers to functions to execute at program finish GOT: global offset table: used for dynamic linking: pointers to absolute addresses
Data Ctors Dtors GOT BSS
Heap
Yves Younan Monday, February 13, 2012
C and C++: vulnerabilities, exploits and countermeasures
March, 2012
78 / 149
Overflow in the data segment
char buf[256]={1}; int main(int argc,char **argv) { ! strcpy(buf,argv[1]); }
Yves Younan Monday, February 13, 2012
C and C++: vulnerabilities, exploits and countermeasures
March, 2012
79 / 149
Overflow in the data segment
Data Ctors Dtors GOT BSS 0x00000000 buf[256]
Yves Younan Monday, February 13, 2012
C and C++: vulnerabilities, exploits and countermeasures
March, 2012
80 / 149
Overflow in the data section
int main (int argc, char **argv) { char buffer[476]; char *execargv[3] = { "./abo7", buffer, NULL }; char *env[2] = { shellcode, NULL }; int ret; ret = 0xBFFFFFFF - 4 - strlen (execargv[0]) - 1 - strlen (shellcode); memset(buffer, '\x90', 476); *(long *)&buffer[472] = ret; execve(execargv[0],execargv,env); }
Yves Younan Monday, February 13, 2012
C and C++: vulnerabilities, exploits and countermeasures
March, 2012
81 / 149
Overflow in the data segment
Data Ctors Dtors GOT BSS RET buf[256]
Yves Younan Monday, February 13, 2012
C and C++: vulnerabilities, exploits and countermeasures
March, 2012
82 / 149
Lecture overview
Memory management in C/C++ Vulnerabilities
Code injection attacks Buffer overflows Format string vulnerabilities Integer errors
Countermeasures Conclusion
Yves Younan Monday, February 13, 2012 C and C++: vulnerabilities, exploits and countermeasures March, 2012 83 / 149
Format string vulnerabilities
Format strings are used to specify formatting of output:
printf(%d is %s\n, integer, string); -> 5 is five
Variable number of arguments Expects arguments on the stack Problem when attack controls the format string:
printf(input); should be printf(%s, input);
Yves Younan Monday, February 13, 2012 C and C++: vulnerabilities, exploits and countermeasures March, 2012 84 / 149
Format string vulnerabilities
Stack
Can be used to read arbitrary values from the stack
%s %x %x Will read 1 string and 2 integers from the stack
Other stack frames Return address f0 Saved frame pointer f0 Local variable f0 string Arguments printf: format string Return address printf Saved frame ptr printf
FP SP
Yves Younan Monday, February 13, 2012
C and C++: vulnerabilities, exploits and countermeasures
March, 2012
85 / 149
Format string vulnerabilities
Stack
Can be used to read arbitrary values from the stack
%s %x %x Will read 1 string and 2 integers from the stack
Other stack frames Return address f0 Saved frame pointer f0 Local variable f0 string Arguments printf: format string Return address printf Saved frame ptr printf
FP SP
Yves Younan Monday, February 13, 2012
C and C++: vulnerabilities, exploits and countermeasures
March, 2012
86 / 149
Format string vulnerabilities
Format strings can also write data:
%n will write the amount of (normally) printed characters to a pointer to an integer %200x%n will write 200 to an integer
Using %n, an attacker can overwrite arbitrary memory locations:
The pointer to the target location can be placed some where on the stack Pop locations with %x until the location is reached Write to the location with %n
Yves Younan Monday, February 13, 2012 C and C++: vulnerabilities, exploits and countermeasures March, 2012 87 / 149
Lecture overview
Memory management in C/C++ Vulnerabilities
Code injection attacks Buffer overflows Format string vulnerabilities Integer errors
Integer overflows Integer signedness errors
Countermeasures Conclusion
Yves Younan Monday, February 13, 2012
C and C++: vulnerabilities, exploits and countermeasures
March, 2012
88 / 149
Integer overflows
For an unsigned 32-bit integer, 2^32-1 is the largest value it can contain Adding 1 to this, will wrap around to 0. Can cause buffer overflows
int main(int argc, char **argv){ unsigned int a; char *buf; a = atol(argv[1]); buf = (char*) malloc(a+1); }
malloc(0) - result is implementation defined: either NULL is returned or malloc will allocate the smallest possible chunk: in Linux: 8 bytes
Yves Younan Monday, February 13, 2012 C and C++: vulnerabilities, exploits and countermeasures March, 2012 89 / 149
Lecture overview
Memory management in C/C++ Vulnerabilities
Code injection attacks Buffer overflows Format string vulnerabilities Integer errors
Integer overflows Integer signedness errors
Countermeasures Conclusion
Yves Younan Monday, February 13, 2012
C and C++: vulnerabilities, exploits and countermeasures
March, 2012
90 / 149
Integer signedness errors
Value interpreted as both signed and unsigned
int main(int argc, char **argv) { int a; char buf[100]; a = atol(argv[1]); if (a < 100) strncpy(buf, argv[2], a); }
For a negative a:
In the condition, a is smaller than 100 Strncpy expects an unsigned integer: a is now a large positive number
Yves Younan Monday, February 13, 2012 C and C++: vulnerabilities, exploits and countermeasures March, 2012 91 / 149
Lecture overview
Memory management in C/C++ Vulnerabilities Countermeasures
Safe languages Probabilistic countermeasures Separation and replication countermeasures Paging-based countermeasures Bounds checkers Verification countermeasures Conclusion
Yves Younan Monday, February 13, 2012 C and C++: vulnerabilities, exploits and countermeasures March, 2012 92 / 149
Safe languages
Change the language so that correctness can be ensured
Static analysis to prove safety If it cant be proven safe statically, add runtime checks to ensure safety (e.g. array unsafe statically -> add bounds checking) Type safety: casts of pointers are limited Less programmer pointer control
Yves Younan Monday, February 13, 2012
C and C++: vulnerabilities, exploits and countermeasures
March, 2012
93 / 149
Safe languages
Runtime type-information Memory management: no explicit management
Garbage collection: automatic scheduled deallocation Region-based memory management: deallocate regions as a whole, pointers can only be dereferenced if region is live
Focus on languages that stay close to C
Yves Younan Monday, February 13, 2012
C and C++: vulnerabilities, exploits and countermeasures
March, 2012
94 / 149
Safe languages
Cyclone: Jim et al.
Pointers:
NULL check before dereference of pointers (*ptr) New type of pointer: never-NULL (@ptr) No artihmetic on normal (*) & never-NULL (@) pointers Arithmetic allowed on special pointer type (?ptr): contains extra bounds information for bounds check Uninitialized pointers cant be used
Region-based memory management Tagged unions: functions can determine type of arguments: prevents format string vulnerabilities
Yves Younan Monday, February 13, 2012 C and C++: vulnerabilities, exploits and countermeasures March, 2012 95 / 149
Safe languages
CCured: Necula et al.
Stays as close to C as possible Programmer has less control over pointers: static analysis determines pointer type
Safe: no casts or arithmetic; only needs NULL check Sequenced: only arithmetic; NULL and bounds check Dynamic: type cant be determined statically; NULL, bounds and run-time type check
Garbage collection: free() is ignored
Yves Younan Monday, February 13, 2012
C and C++: vulnerabilities, exploits and countermeasures
March, 2012
96 / 149
Lecture overview
Memory management in C/C++ Vulnerabilities Countermeasures
Safe languages Probabilistic countermeasures Separation and replication countermeasures Paging-based countermeasures Bounds checkers Verification countermeasures Conclusion
Yves Younan Monday, February 13, 2012 C and C++: vulnerabilities, exploits and countermeasures March, 2012 97 / 149
Probabilistic countermeasures
Based on randomness Canary-based approach
Place random number in memory Check random number before performing action If random number changed an overflow has occurred
Obfuscation of memory addresses Address Space Layout Randomization Instruction Set Randomization
Yves Younan Monday, February 13, 2012
C and C++: vulnerabilities, exploits and countermeasures
March, 2012
98 / 149
Canary-based countermeasures
StackGuard (SG): Cowan et al.
Places random number before the return address when entering function Verifies that the random number is unchanged when returning from the function If changed, an overflow has occurred, terminate program
Yves Younan Monday, February 13, 2012
C and C++: vulnerabilities, exploits and countermeasures
March, 2012
99 / 149
StackGuard (SG)
Stack f0: ... call f1 ... IP Other stack frames Return address f0 Saved frame pointer f0 Canary Local variables f0 f1: ptrbuffer[] = &data; overflow() buffer[] ... overflow(); *ptr = value; ... data Arguments f1 FP Return address f1 Saved frame pointer f1 Canary Pointer Buffer
SP
Yves Younan Monday, February 13, 2012
C and C++: vulnerabilities, exploits and countermeasures
March, 2012
100 / 149
StackGuard (SG)
Stack f0: ... call f1 ... Other stack frames Return address f0 Saved frame pointer f0 Canary Local variables f0 f1: ptrbuffer[] = &data; overflow() buffer[] ... overflow(); *ptr = value; ... data Arguments f1 FP Return address f1 Saved frame pointer f1 Canary Pointer Injected code
101
IP
SP
Yves Younan Monday, February 13, 2012
C and C++: vulnerabilities, exploits and countermeasures
March, 2012
/ 149
Canary-based countermeasures
Propolice (PP): Etoh & Yoda
Same principle as StackGuard Protects against indirect pointer overwriting by reorganizing the stack frame:
All arrays are stored before all other data on the stack (i.e. right next to the random value) Overflows will cause arrays to overwrite other arrays or the random value
Part of GCC >= 4.1 Stack Cookies in Visual Studio
Yves Younan Monday, February 13, 2012 C and C++: vulnerabilities, exploits and countermeasures March, 2012 102 / 149
Propolice (PP)
Stack f0: ... call f1 ... IP Other stack frames Return address f0 Saved frame pointer f0 Canary Local variables f0 f1: ptrbuffer[] = &data; overflow() buffer[] ... overflow(); *ptr = value; ... data Arguments f1 FP Return address f1 Saved frame pointer f1 Canary Buffer SP Pointer
Yves Younan Monday, February 13, 2012
C and C++: vulnerabilities, exploits and countermeasures
March, 2012
103 / 149
Propolice (PP)
Stack f0: ... call f1 ... IP Other stack frames Return address f0 Saved frame pointer f0 Canary Local variables f0 f1: ptrbuffer[] = &data; overflow() buffer[] ... overflow(); *ptr = value; ... data Arguments f1 FP Return address f1 Saved frame pointer f1 Canary Buffer SP Pointer
Yves Younan Monday, February 13, 2012
C and C++: vulnerabilities, exploits and countermeasures
March, 2012
104 / 149
Heap protector (HP)
Chunk1 Size of prev. chunk Size of chunk1 Checksum User data Chunk2 Size of chunk1 Size of chunk2 Checksum Forward pointer Backward pointer Old user data
Heap protector: Robertson et al.
Adds checksum to the chunk information Checksum is XORed with a global random value On allocation checksum is added On free (or other operations) checksum is calculated, XORed, and compared
March, 2012 105 / 149
Yves Younan Monday, February 13, 2012
C and C++: vulnerabilities, exploits and countermeasures
Contrapolice (CP)
Chunk1 Canary1 Size of prev. chunk Size of chunk1 User data Canary1 Canary2 Size of chunk1 Size of chunk2 Forward pointer Backward pointer Old user data Canary2
106
Contrapolice: Krennmair
Stores a random value before and after the chunk Before exiting from a string copy operation, the random value before is compared to the random value after If they are not the same, an overflow has occured
Chunk2
Yves Younan Monday, February 13, 2012
C and C++: vulnerabilities, exploits and countermeasures
March, 2012
/ 149
Problems with canaries
Random value can leak For SG: Indirect Pointer Overwriting For PP: overflow from one array to the other (e.g. array of char overwrites array of pointer) For HP, SG, PP: 1 global random value CP: different random number per chunk CP: no protection against overflow in loops
Yves Younan Monday, February 13, 2012
C and C++: vulnerabilities, exploits and countermeasures
March, 2012
107 / 149
Probabilistic countermeasures
Obfuscation of memory addresses
Also based on random numbers Numbers used to encrypt memory locations Usually XOR
a XOR b = c c XOR b = a
Yves Younan Monday, February 13, 2012
C and C++: vulnerabilities, exploits and countermeasures
March, 2012
108 / 149
Obfuscation of memory addresses
PointGuard: Cowan et al.
Protects all pointers by encrypting them (XOR) with a random value Decryption key is stored in a register Pointer is decrypted when loaded into a register Pointer is encrypted when loaded into memory Forces the compiler to do all memory access via registers Can be bypassed if the key or a pointer leaks Randomness can be lowered by using a partial overwrite
Yves Younan Monday, February 13, 2012
C and C++: vulnerabilities, exploits and countermeasures
March, 2012
109 / 149
Partial overwrite
XOR: 0x41424344 XOR 0x20304050 = 0x61720314 However, XOR encrypts bitwise 0x44 XOR 0x50 = 0x14 If injected code relatively close: 1 byte: 256 possibilities 2 bytes: 65536 possibilities
Yves Younan Monday, February 13, 2012
C and C++: vulnerabilities, exploits and countermeasures
March, 2012
110 / 149
Partial overwrite
Stack f0: ... call f1 ... IP Other stack frames Return address f0 Saved frame pointer f0 Data Other Local variables f0 f1: ptrbuffer[] = &data; overflow() buffer[] ... overflow(); *ptr = value; ... Arguments f1 FP Return address f1 Saved frame pointer f1 Encrypted pointer Buffer
SP
Yves Younan Monday, February 13, 2012
C and C++: vulnerabilities, exploits and countermeasures
March, 2012
111 / 149
Partial overwrite
Stack f0: ... call f1 ... Other stack frames Return address f0 Saved frame pointer f0 Data Other Local variables f0 f1: ptrbuffer[] = &data; overflow() buffer[] ... overflow(); *ptr = value; ... Arguments f1 FP Return address f1 Saved frame pointer f1 Encrypted pointer Injected code
IP
SP
Yves Younan Monday, February 13, 2012
C and C++: vulnerabilities, exploits and countermeasures
March, 2012
112 / 149
Partial overwrite
Stack f0: ... call f1 ... Other stack frames Return address f0 Saved frame pointer f0 Data Other Local variables f0 f1: ptrbuffer[] = &data; overflow() buffer[] ... overflow(); *ptr = value; ... Arguments f1 FP Modified return address Saved frame pointer f1 Encrypted pointer Injected code
IP
SP
Yves Younan Monday, February 13, 2012
C and C++: vulnerabilities, exploits and countermeasures
March, 2012
113 / 149
Probabilistic countermeasures
Address space layout randomization: PaX team
Compiler must generate PIC Randomizes the base addresses of the stack, heap, code and shared memory segments Makes it harder for an attacker to know where in memory his code is located Can be bypassed if attackers can print out memory addresses: possible to derive base address
Implemented in Windows Vista / Linux >= 2.6.12
Yves Younan Monday, February 13, 2012
C and C++: vulnerabilities, exploits and countermeasures
March, 2012
114 / 149
Heap-spraying
Technique to bypass ASLR If an attacker can control memory allocation in the program (e.g. in the browser via javascript) Allocate a significant amount of memory
For example: 1GB or 2GB
Fill memory with a bunch of nops, place shell code at the end Reduces amount of randomization offered by ASLR Jumping anywhere in the nops will cause the shellcode to be executed eventually
Yves Younan Monday, February 13, 2012
C and C++: vulnerabilities, exploits and countermeasures
March, 2012
115 / 149
Probabilistic countermeasures
Randomized instruction sets: Barrantes et al./Kc et al.
Encrypts instructions while they are in memory Decrypts them when needed for execution If attackers dont know the key their code will be decrypted wrongly, causing invalid code execution If attackers can guess the key, the protection can be bypassed High performance overhead in prototypes: should be implemented in hardware
Yves Younan Monday, February 13, 2012
C and C++: vulnerabilities, exploits and countermeasures
March, 2012
116 / 149
Probabilistic countermeasures
Rely on keeping memory secret Programs that have buffer overflows could also have information leakage Example:
char buffer[100]; strncpy(buffer, input, 100); Printf(%s, buffer);
Strncpy does not NULL terminate (unlike strcpy), printf keeps reading until a NULL is found
Yves Younan Monday, February 13, 2012 C and C++: vulnerabilities, exploits and countermeasures March, 2012 117 / 149
Lecture overview
Memory management in C/C++ Vulnerabilities Countermeasures
Safe languages Probabilistic countermeasures Separation and replication countermeasures Paging-based countermeasures Bounds checkers Verification countermeasures Conclusion
Yves Younan Monday, February 13, 2012 C and C++: vulnerabilities, exploits and countermeasures March, 2012 118 / 149
Separation and replication of information
Replicate valuable control-flow information
Copy control-flow information to other memory Copy back or compare before using
Separate control-flow information from other data
Write control-flow information to other places in memory Prevents overflows from overwriting control flow information
These approaches do not rely on randomness
Yves Younan Monday, February 13, 2012
C and C++: vulnerabilities, exploits and countermeasures
March, 2012
119 / 149
Separation of information
Dnmalloc: Younan et al.
Does not rely on random numbers Protection is added by separating the chunk information from the chunk Chunk information is stored in separate regions protected by guard pages Chunk is linked to its information through a hash table Fast: performance impact vs. dlmalloc: -10% to +5% Used as the default allocator for Samhein (open source IDS)
Yves Younan Monday, February 13, 2012
C and C++: vulnerabilities, exploits and countermeasures
March, 2012
120 / 149
Dnmalloc
Low addresses
Heap Data Heap Data Heap Data Heap Data Heap Data Heap Data Heap Data Heap Data
Hashtable
Guard page Ptr to chunkinfo Ptr to chunkinfo Ptr to chunkinfo Ptr to chunkinfo Ptr to chunkinfo
Chunkinfo region
Guard page Management information Management information Management information Management information Management information
High addresses
Control data
Regular data
Yves Younan Monday, February 13, 2012
C and C++: vulnerabilities, exploits and countermeasures
March, 2012
121 / 149
Separation of information
Multistack: Younan et al.
Does not rely on random numbers Separates the stack into multiple stacks, 2 criteria:
Risk of data being an attack target (target value) Risk of data being used as an attack vector (source value)
Return addres: target: High; source: Low Arrays of characters: target: Low; source: High
Default: 5 stacks, separated by guard pages
Stacks can be reduced by using selective bounds checking: to reduce source risk: ideally 2 stacks
Fast: max. performance overhead: 2-3% (usually 0)
Yves Younan Monday, February 13, 2012 C and C++: vulnerabilities, exploits and countermeasures March, 2012 122 / 149
Dnstack
Pointers Array of pointers Structures (no arrays) Integers Guard page Structs (no char array) Array of struct (no char array) Arrays Alloca() Floats Guard page Structures (with char. array) Array of structures (with char array) Guard page Array of characters
Saved registers Guard page
Guard page
Stacks are at a fixed location from each other If source risk can be reduced: maybe only 2 stacks
Map stack 1,2 onto stack one Map stack 3,4,5 onto stack two
Yves Younan Monday, February 13, 2012 C and C++: vulnerabilities, exploits and countermeasures March, 2012 123 / 149
Lecture overview
Memory management in C/C++ Vulnerabilities Countermeasures
Safe languages Probabilistic countermeasures Separation and replication countermeasures Paging-based countermeasures Bounds checkers Verification countermeasures Conclusion
Yves Younan Monday, February 13, 2012 C and C++: vulnerabilities, exploits and countermeasures March, 2012 124 / 149
Paging-based countermeasure
Non-executable memory (called NX or XN)
Pages of memory can be marked executable, writeable and readable Older Intel processors would not support the executable bit which meant that readable meant executable Eventually the bit was implemented, allowing the OS to mark data pages (such as the stack and heap writable but not executable) OpenBSD takes it further by implementing W^X (writable XOR executable) Programs doing JIT have memory that is both executable and writable
Yves Younan Monday, February 13, 2012 C and C++: vulnerabilities, exploits and countermeasures March, 2012 125 / 149
Stack-based buffer overflowed on NX
Stack f0: ... call f1 ... Other stack frames Return address f0 Saved frame pointer f0 Local variables f0 f1: buffer[] overflow() ... Arguments f1 FP Overwritten return address
IP
SP
Injected code
Yves Younan Monday, February 13, 2012
C and C++: vulnerabilities, exploits and countermeasures
March, 2012
126 / 149
Stack-based buffer overflow on NX
Stack f0: ... call f1 ... SP f1: buffer[] overflow() ... IP crash: memory not executable Injected code Other stack frames Return address f0 Saved frame pointer f0 Local variables f0
Yves Younan Monday, February 13, 2012
C and C++: vulnerabilities, exploits and countermeasures
March, 2012
127 / 149
Bypassing non-executable memory
Early exploits would return to existing functions (called return-to-libc) to bypass these countermeasures
Places the arguments on the stack and then places the address of the function as the return addres
This simulates a function call
For example calling system(/bin/bash) would place the address of the executable code for system as return address and would place a pointer to the string /bin/bash on the stack
Yves Younan Monday, February 13, 2012 C and C++: vulnerabilities, exploits and countermeasures March, 2012 128 / 149
Paging-based countermeasures
Stack f0: ... call f1 ... IP Other stack frames Return address f0 Saved frame pointer f0 Local variables f0 f1: buffer[] overflow() ... Arguments f1 FP Overwritten Return address return address f1 Saved frame pointer f1 Injected Buffer code
SP
Yves Younan Monday, February 13, 2012
C and C++: vulnerabilities, exploits and countermeasures
March, 2012
129 / 149
Paging-based countermeasures
f0: ... call f1 ... Stack Other stack frames Return address f0 Saved frame pointer f0 string /bin/bash Pointer to /bin/bash FP system: ... int 0x80 SP Overwritten return address
IP
f1: buffer[] overflow() ...
Yves Younan Monday, February 13, 2012
C and C++: vulnerabilities, exploits and countermeasures
March, 2012
130 / 149
Return oriented programming
More generic return-to-libc Returns to existing assembly code, but doesnt require it to be the start of the function:
Any code snippet that has the desired functionality followed by a ret can be used
For example:
Code snippet that does pop eax, followed by ret Next code snippet does mov ecx, eax followed by ret Final code snippet does jmp ecx Code gets executed at the address in ecx
Shown to be Turing complete for complex libraries like libc
Yves Younan Monday, February 13, 2012 C and C++: vulnerabilities, exploits and countermeasures March, 2012 131 / 149
Return oriented programming
f0: ... call f1 ... f3: ... mov ecx, eax ret f4: ... jmp ecx ... FP f2: ... pop eax ret SP Stack Other stack frames Return address f0 Saved frame pointer f0 return after mov return after pop To be popped in eax Overwritten return address
IP
f1: buffer[] overflow() ...
Yves Younan Monday, February 13, 2012
C and C++: vulnerabilities, exploits and countermeasures
March, 2012
132 / 149
Return oriented programming
x86 has variable length instructions, ranging from 1 to 17 bytes. ROP doesnt have to jump to the beginning of an instruction The middle of an instruction could be interpreted as an instruction that has the desired functionality, followed by a ret (either as part of that instruction or the following instruction) Also possible that jumping into a middle of an instruction causes subsequent instructions to be interpreted differently
Yves Younan Monday, February 13, 2012 C and C++: vulnerabilities, exploits and countermeasures March, 2012 133 / 149
Return oriented programming
x86 has variable length instructions, ranging from 1 to 17 bytes. ROP doesnt have to jump to the beginning of an instruction The middle of an instruction could be interpreted as an instruction that has the desired functionality, followed by a ret (either as part of that instruction or the following instruction) Also possible that jumping into a middle of an instruction causes subsequent instructions to be interpreted differently
Yves Younan Monday, February 13, 2012 C and C++: vulnerabilities, exploits and countermeasures March, 2012 134 / 149
Return oriented programming
movl [ebp-44], 0x00000001 machine code: c7 45 d4 01 00 00 00
test edi, 0x00000007
machine code: f7 c7 07 00 00 00
setnzb [ebp-61]
machine code: 0f 95 45 c3 00 f7 c7 07 00 00 00 0f 95 45 c3
add bh, dh mov edi, 0x0F000000 xchg eax, ebp inc ebp ret
Example adapted from Return-oriented Programming: Exploitation without Code Injection by Buchanan et al.
Yves Younan C and C++: vulnerabilities, exploits and countermeasures March, 2012 135 / 149
Monday, February 13, 2012
Lecture overview
Memory management in C/C++ Vulnerabilities Countermeasures
Safe languages Probabilistic countermeasures Separation and replication countermeasures Paging-based countermeasures Bounds checkers Verification countermeasures Conclusion
Yves Younan Monday, February 13, 2012 C and C++: vulnerabilities, exploits and countermeasures March, 2012 136 / 149
Bounds checkers
Ensure arrays and pointers do not access memory out of bounds through runtime checks Slow:
Bounds checking in C must check all pointer operations, not just array index accesses (as opposed to Java) Usually too slow for production deployment
Some approaches have compatibility issues Two major approaches: add bounds info to pointers, add bounds info to objects
Yves Younan Monday, February 13, 2012 C and C++: vulnerabilities, exploits and countermeasures March, 2012 137 / 149
Bounds checkers
Add bounds info to pointers
Pointer contains
Current value Upper bound Lower bound
Two techniques
Change pointer representation: fat pointers
Fat pointers are incompatible with existing code (casting)
Store extra information somewhere else, look it up
Problems with existing code: if (global) pointer is changed, info is out of sync
Yves Younan Monday, February 13, 2012 C and C++: vulnerabilities, exploits and countermeasures March, 2012 138 / 149
Bounds checkers
Add bounds info to objects
Pointers remain the same Look up bounds information based on pointers value Check pointer arithmetic:
If result of arithmetic is larger than base object + size -> overflow detected Pointer use also checked to make sure object points to valid location
Other lighter-weight approaches
Yves Younan Monday, February 13, 2012
C and C++: vulnerabilities, exploits and countermeasures
March, 2012
139 / 149
Bounds checkers
Safe C: Austin et al.
Safe pointer: value (V), pointer base (B), size (S), class (C), capability (CP) V, B, S used for spatial checks C and CP used for temporal checks
Prevents dangling pointers Class: heap, local or global, where is the memory allocated Capability: forever, never
Checks at pointer dereference
Yves Younan
First temp check: is the pointer still valid? Bounds check: is the pointer within bounds?
C and C++: vulnerabilities, exploits and countermeasures
March, 2012
140 / 149
Monday, February 13, 2012
Bounds checkers
Jones and Kelly
Austin not compatible with existing code Maps object size onto descriptor of object (base, size) Pointer dereference/arithmetic
Check descriptor If out of bounds: error
Object created in checked code
Add descriptor
Pointers can be passed to existing code
Yves Younan Monday, February 13, 2012 C and C++: vulnerabilities, exploits and countermeasures March, 2012 141 / 149
Bounds checkers
CRED: Ruwase and Lam
Extension of Jones and Kelly Problems with pointer arithmetic
1) pointer goes out-of-bounds, 2) is not dereferenced, 3) goes in-bounds again Out-of-bounds arithmetic causes error Many programs do this
Create OOB object when going out-of-bounds
When OOB object dereferenced: error When pointer arithmetic goes in-bounds again, set to correct value
Yves Younan Monday, February 13, 2012 C and C++: vulnerabilities, exploits and countermeasures March, 2012 142 / 149
Bounds checkers
PariCheck: Younan et al. Bounds are stored as a unique number over a region of memory Object inhabits one or more regions, each region has the same unique number Check pointer arithmetic
Look up unique number of object that pointer is pointing to, compare to unique number of the result of the arithmetic, if different -> overflow Faster than existing bounds checkers: ~50% overhead
Yves Younan Monday, February 13, 2012 C and C++: vulnerabilities, exploits and countermeasures March, 2012 143 / 149
Lecture overview
Memory management in C/C++ Vulnerabilities Countermeasures
Safe languages Probabilistic countermeasures Separation and replication countermeasures Paging-based countermeasures Bounds checkers Verification countermeasures Conclusion
Yves Younan Monday, February 13, 2012 C and C++: vulnerabilities, exploits and countermeasures March, 2012 144 / 149
Verification countermeasures
Ensure that the values in use are sane
A typical example of this is safe unlinking
Safe unlinking was introduced to various heap allocators to ensure that the doubly linked list is sane before being used For example before unlinking, do the following checks:
P->fd->bk should be equal to P P->bk->fd should also be equal to P If both conditions hold, then proceed with unlinking
Yves Younan Monday, February 13, 2012 C and C++: vulnerabilities, exploits and countermeasures March, 2012 145 / 149
Lecture overview
Memory management in C/C++ Vulnerabilities
Buffer overflows Format string vulnerabilities Integer errors
Countermeasures Conclusion
Yves Younan Monday, February 13, 2012
C and C++: vulnerabilities, exploits and countermeasures
March, 2012
146 / 149
Countermeasures in modern OSes
Various countermeasures have been deployed in modern operating systems
ASLR StackGuard Safe unlinking Non-executable memory
These have made exploitations of these attacks significantly harder However, attackers have found various ways of bypassing these countermeasures
Yves Younan Monday, February 13, 2012 C and C++: vulnerabilities, exploits and countermeasures March, 2012 147 / 149
Embedded and mobile devices
Vulnerabilities also present and exploitable on embedded devices iPhone LibTIFF vulnerability massively exploited to unlock phones Almost no countermeasures
Windows CE6 has stack cookies
Different priorities: performance is much more important on embedded devices Area of very active research
Yves Younan Monday, February 13, 2012 C and C++: vulnerabilities, exploits and countermeasures March, 2012 148 / 149
Conclusion
Many attacks, countermeasures, countercountermeasures, etc. exist Search for good and performant countermeasures to protect C continues Best solution: switch to a safe language, if possible More information:
Y. Younan, W. Joosen and F. Piessens. Code injection in C and C++: A survey of vulnerabilities and Countermeasures Y. Younan. Efficient countermeasures for software vulnerabilities due to memory management errors . Erlingsson, Y. Younan, F. Piessens, Low-level software security by example
Yves Younan Monday, February 13, 2012 C and C++: vulnerabilities, exploits and countermeasures March, 2012 149 / 149