JMU
Buffer Overflows in C
Vulnerabilities, Attacks, and Mitigations


Prof. David Bernstein
James Madison University

Computer Science Department
bernstdh@jmu.edu


Getting Started
Vulnerabilities when Using Arrays - Length Faults
Vulnerabilities when Using Arrays - Length Faults (cont.)
Vulnerabilities when Using Arrays - Sentinel Faults
Vulnerabilities when Using Strings
Vulnerabilities when Using Strings - gets()
Vulnerabilities when Using Strings - strcpy()
Vulnerabilities when Using Strings - strcat()
Vulnerabilities when Using Strings - sprintf()
Vulnerabilities when Using Strings - Null Termination
Vulnerabilities when Using Strings - Null Termination (cont.)

An Example

char     a[10], b[10];

strncpy(a, "0123456789", 10); // a will not be null-terminated

strcpy(b, a);                 // b will probably overflow
  
Threats - Memory Corruption
Threats - Arbitrary Memory Writes
Threats - Corrupted Function Pointers
Threats - Stack Smashing
Attacks - Data Integrity
Attacks - Data Integrity (cont.)
Attacks - Program Termination/Availability
An Example
cexamples/bufferoverflow/smash.c
                
Attacks - Program Termination/Availability (cont.)
A Partial Result of Executing the Program (MS Visual C/Intelx86)
foo: 00401000
bar: 00401045
Stack (Before):
00000000
00000000
7FFDF000
0012FF80
0040108A
00410EDE
  
Interpreting the Stack

If you compile using gcc -S smash.c a file containing the assembly language code (named smash.s) will be generated.

If you compile using gcc -o smash smash.c and then run gdb smash you can use the command disassemble main to see the assembly code that will be executed (i.e., with resolved addresses).

Attacks - Program Termination/Availability (cont.)
Passing "Hello"
  Output              Interpretation

foo: 0x00401000
bar: 0x00401045
Stack (Before):
0x00000000
0x00000000
0x7ffdf000
0x0012ff80
0x0040108a            The return address for foo()
0x00410ede

Stack (After):
0x6c6c6548                lleH
0x0000006f                   o
0x7ffdf000
0x0012ff80
0x0040108a            The return address for foo()
0x00410ede
  
Attacks - Program Termination/Availability (cont.)
Passing "AAAAAAAAAAAAAAAAAAAAAAA"
  Output              Interpretation

foo: 0x00401000
bar: 0x00401045
Stack (Before):
0x00000000
0x00000000
0x7ffdf000
0x0012ff80
0x0040108a            The return address for foo()
0x00410ede

Stack (After):
0x41414141                AAAA
0x41414141                AAAA
0x41414141                AAAA
0x41414141                AAAA
0x41414141                AAAA (And the return address for foo()!)
0x41414141                AAAA
  
Attacks - Program Termination/Availability (cont.)
Attacks - Execution Integrity
Attacks - Execution Integrity (cont.)
Passing "StaticOverrun ABCDEFGHIJKLMNOP\x45\x10\x40"
  Output              Interpretation

foo: 0x00401000
bar: 0x00401045
Stack (Before):
0x77fb80db
0x77f94e68
0x7ffdf000
0x0012ff80
0x0040108a            The return address for foo()
0x00410eca

Stack (After):
0x44434241                DCBA
0x48474645                HGFE
0x4c4b4a49                LKJI
0x504f4e4d                PONM
0x00401045            The address of bar() (and the return address for foo()!)
0x00410eca            
  
Attacks - Arc Injection
Attacks - Code Injection
Attacks - Gadget Injection
Attacks - Gadget Injection (cont.)
Mitigation - Array Handling
Mitigation - String Handling
Runtime Mitigation - Validation/Sanitization
Runtime Mitigation - Size Checking
Runtime Mitigation - Size Checking (cont.)
Runtime Mitigation - Size Checking (cont.)
Runtime Mitigation - Stack Canaries
Runtime Mitigation - Stack Canaries (cont.)
Runtime Mitigation - Stack Canaries (cont.)
Environment-Based Mitigation - Addess Space Layout Randomization
Environment-Based Mitigation - Nonexecutable Stack
Environment-Based Mitigation - W^X
Environment-Based Mitigation - W^X (cont.)
Environment-Based Mitigation - Other Things
Experimenting with Buffer Overflows