Computer Systems Security CS 628A: Pramod Subramanyan Indian Institute of Technology Kanpur
Computer Systems Security CS 628A: Pramod Subramanyan Indian Institute of Technology Kanpur
CS 628A
Pramod Subramanyan
Indian Institute of Technology Kanpur
1
MODULE 1: CONTROL HIJACKING
2
Acknowledgements
• Suman Jana
• Sandeep Shukla
• Dan Boneh (Stanford University)
• John C. Mitchell (Stanford University)
• Nicolai Zeldovich (MIT)
• Jungmin Park (Virginia Tech)
• Patrick Schaumont (Virginia Tech)
• Web Resources
3
Control Hijacking
Basic Control
Hijacking Attacks
4
Example 1
#include <stdio.h>
int main()
{
volatile int number = 0;
char buffer[8];
printf("number=%d\n", number);
gets(buffer);
printf("number=%d\n", number);
return 0;
}
$ python -c 'print "a"*8' | ./stack0
$ python -c 'print "a"*9' | ./stack0
5
Example 2
int main(int argc, char* argv[])
{
volatile int number = 0;
char buffer[16];
if (argc != 2) return 0;
printf("number=%d\n", number);
sprintf(buffer, "hello %s", argv[1]);
printf("buffer=%s\n", buffer);
printf("number=%d\n", number);
return 0;
}
* $ ./stack1 `python -c 'print "a"*16'`
* $ ./stack1 `python -c 'print "a"*17'`
6
Example 3
#include <stdio.h>
#include <string.h>
int checkpwd(const char* pwd)
{
int good = 0;
char buffer[8];
strcpy(buffer, pwd);
if(strcmp(buffer, "blahblah") == 0) good = 1;
if(strcmp(buffer, "wahhwahh") == 0) good = 1;
return good;
}
int main(int argc, char* argv[])
{
if (argc != 2) return 1;
if (checkpwd(argv[1])) {
printf("=====================\n");
printf("|| access granted ||\n");
printf("=====================\n");
} else { printf("denied!\n"); }
return 0;
}
void win()
{
printf("you win!\n");
}
return 0;
}
printf("number=%d\n", number);
sprintf(buffer, "hello %s", argv[1]);
printf("buffer=%s\n", buffer);
printf("number=%d\n", number);
delete [] buffer;
return 0;
}
11
Control hijacking attacks
• 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
– Integer overflow attacks
– Format string vulnerabilities
12
Example 1: buffer overflows
• Extremely common bug in C/C++ programs.
– First major exploit: 1988 Internet Worm. fingerd.
600
500
400
300
100
0
1995 1997 1999 2001 2003 2005
Source: NVD/CVE
What is needed
• Understanding C functions, the stack, and the heap.
• Know how system calls are made
• The exec() system call
14
Linux Process Memory Layout
15
Stack Frame
http://post.queensu.ca/~trd/377/tut5/stack.html
high
arguments
return address
stack frame pointer
exception handlers
argument: str
return address
stack frame pointer
char buf[128]
SP 17
What are buffer overflows?
What if *str is 136 bytes long? void func(char *str) {
After strcpy: char buf[128];
strcpy(buf, str);
do-something(buf);
}
argument: str
return address
stack frame pointer
*str Problem:
no length checking in strcpy()
char buf[128]
SP 18
Basic stack exploit high
Program P: exec(“/bin/sh”)
char buf[128]
low
19
The NOP slide high
Program P
Problem: how does attacker
determine ret-address?
NOP Slide
Solution: NOP slide
• Guess approximate stack state
when func() is called
return address
• Insert many NOPs before program P:
nop , xor eax,eax , inc ax
char buf[128]
low
20
Details and examples
• Some complications:
– Program P should not contain the ‘\0’ character.
– Overflow should not crash program before func()
exists.
22
Buffer overflow opportunities
• Exception handlers: (Windows SEH attacks)
– Overwrite the address of an exception handler in stack
frame.
Heap
buf[128] FuncPtr or
stack
method #1
FP1
ptr FP2 method #2
FP3
method #3
data vtable
data
ptr
buf[256] vtable
24
object T
Finding buffer overflows
• To find overflow:
– Run web server on local machine
– Issue malformed requests (ending with “$$$$$” )
• Many automated tools exist (called fuzzers)
– If web server crashes,
search core dump for “$$$$$” to find overflow location
25
Control Hijacking
26
More Hijacking Opportunities
27
Integer Overflows (see Phrack 60)
28
An example
void func( char *buf1, *buf2, unsigned int len1, len2) {
char temp[256];
if (len1 + len2 > 256) {return -1} // length check
memcpy(temp, buf1, len1); // cat buffers
memcpy(temp+len1, buf2, len2);
do-something(temp); // do stuff
}
140
120
100
80
60
40
20
0
1996 1998 2000 2002 2004 2006
Source: NVD/CVE
30
Format string bugs
31
Format String Example 1
#include <stdio.h>
#include <stdlib.h>
int main() {
int A = 5, B = 7, count_one, count_two;
•
// Example of a %n format string
printf("The number of bytes written up to this
point X%n is being stored in count_one, and the
number of bytes up to here X%n is being stored in
count_two.\n", &count_one, &count_two);
// Stack Example
printf("A is %d and is at %08x. B is %x.\n", A,
&A, B);
exit(0); $ ./a.out
} The number of bytes written up to this point X is being
stored in count_one, and the number of bytes up to
here X is being storied in count_two.
count_one: 46
count_two: 113
A is 5 and is at bffff7f4. B is 7.
32
Format String Example 2
#include <stdio.h>
#include <stdlib.h>
int main() {
int A = 5, B = 7, count_one, count_two;
// Stack Example
printf("A is %d and is at %08x. B is %x.\n", A, &A);
exit(0);
}
$ ./a.out
The number of bytes written up to this point X is being
stored in count_one, and the number of bytes up to
here X is being storied in count_two.
count_one: 46
count_two: 113
A is 5 and is at bffff7f4. B is b7fd6ff4
33
Format String Example 3
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
if(argc < 2) {
printf("Usage: %s <text to print>\n", argv[0]);
exit(0);
}
strcpy(text, argv[1]);
printf("\n");
// Debug output
printf("[*] test_val @ 0x%08x = %d 0x%08x\n", &test_val, test_val,
test_val);
exit(0);
}
$ ./fmt_vuln testing%x
34
Format string problem
int func(char *user) {
fprintf( stderr, user);
}
35
Vulnerable functions
Any function using a format string.
Printing:
printf, fprintf, sprintf, …
vprintf, vfprintf, vsprintf, …
Logging:
syslog, err, warn
36
Exploit
• Dumping arbitrary memory:
– Walk up stack until desired pointer is found.
– printf( “%08x.%08x.%08x.%08x|%s|”)
– printf( “%08x.%08x.%08x.%08x.%n”)
37
Control Hijacking
Platform Defenses
38
Preventing hijacking attacks
1. Fix bugs:
– Audit software
• Automated tools: Coverity, Prefast/Prefix.
– Rewrite software in a type safe languange (Java, ML)
• Difficult for existing (legacy) code …
• Limitations:
– Some apps need executable heap (e.g. JITs).
– Does not defend against `Return Oriented Programming’
exploits 40
Attack: Return Oriented Programming (ROP)
stack libc.so
args
ret-addr exec()
sfp printf()
42
Response: randomization
• ASLR: (Address Space Layout Randomization)
– Map shared libraries to rand location in process
memory
Attacker cannot jump directly to exec function
– Deployment: (/DynamicBase)
• Windows 7: 8 bits of randomness for DLLs
– aligned to 64K page in a 16MB region 256 choices
• Windows 8: 24 bits of randomness on 64-bit processors
• Other randomization methods:
– Sys-call randomization: randomize sys-call id’s
– Instruction Set Randomization (ISR)
43
ASLR Example
Booting twice loads libraries into different locations:
Run-time Defenses
45
Run time checking: StackGuard
• Many run-time checking techniques …
– we only discuss methods relevant to overflow protection
• Solution 1: StackGuard
– Run time tests for stack integrity.
– Embed “canaries” in stack frames and verify their integrity
prior to function return.
Frame 2 Frame 1
top
local canary sfp ret str local canary sfp ret str of
stack
46
Canary Types
• Random canary:
– Random string chosen at program startup.
– Insert canary string into every stack frame.
– Verify canary before returning from function.
• Exit program if canary changed. Turns potential exploit into DoS.
– To corrupt, attacker must learn current random string.
47
StackGuard (Cont.)
• StackGuard implemented as a GCC patch
– Program must be recompiled
String args
Growth
ret addr Protects pointer args and local
pointers from a buffer overflow
SFP
CANARY
args
String
Growth ret addr
Canary protects ret-addr and
SFP exception handler frame
exception handlers
CANARY
high
ptr to mem
next handler buf next
next handler next handler
attack code
52
Defenses: SAFESEH and SEHOP
• /SAFESEH: linker flag
– Linker produces a binary with a table of safe exception handlers
– System will not jump to exception handler not on list
53
Summary: Canaries are not full proof
• Canaries are an important defense tool, but do not prevent all
control hijacking attacks:
– Heap-based attacks still possible
– Integer overflow attacks still possible
– /GS by itself does not prevent Exception Handling attacks
(also need SAFESEH and SEHOP)
54
What if can’t recompile: Libsafe
• Solution 2: Libsafe (Avaya Labs)
– Dynamically loaded library (no need to recompile app.)
– Intercepts calls to strcpy (dest, src)
• Validates sufficient space in current stack frame:
|frame-pointer – dest| > strlen(src)
• If so, does strcpy. Otherwise, terminates application
top
sfp ret-addr dest src buf sfp ret-addr of
stack
Advanced
Hijacking Attacks
58
Heap Spray Attacks
59
Heap-based control hijacking
• Compiler generated function pointers (e.g. C++ code)
method #1
FP1
ptr FP2 method #2
FP3
method #3
data vtable
Object T
data
ptr
buf[256] vtable
60
object T
Heap-based control hijacking
• Compiler generated function pointers (e.g. C++ code)
method #1
FP1
ptr FP2 method #2
FP3
method #3
data vtable
Object T
shell
code
• After overflow of buf we have:
data
ptr
buf[256] vtable
61
object T
A reliable exploit?
<SCRIPT language="text/javascript">
shellcode = unescape("%u4343%u4343%...");
overflow-string = unescape(“%u2332%u4276%...”);
cause-overflow( overflow-string ); // overflow buf[ ]
</SCRIPT>
???
data
ptr
buf[256] vtable shellcode
62
Heap Spraying [SkyLined 2004]
heap
vtable
heap
object O
non-writable pages