Buffer Overflow | SSE
Vulnerabilities in Software Applications
Introduction
- Presentation by Dr. Denis Ulybyshev
- Focus on vulnerabilities deriving from software applications written in memory-unsafe languages.
Outline
- Understanding the Memory Organization in Computing Systems
- Buffer Overflow Attack: Exploitation and Countermeasures
- Format String Attack: Exploitation and Countermeasures
- Integer Overflow and its Consequences
Memory-Unsafe Languages
- Definition: Memory-unsafe languages allow manipulation of memory directly, potentially leading to severe vulnerabilities.
- C/C++: These languages permit direct access via pointers without bounds checking; there are no garbage collection mechanisms.
- Java: Considered memory-safe due to runtime error detection that checks the bounds of objects (e.g., arrays) and pointer dereferences.
- Reference: Dhurjati et al. (2003)."Memory Safety Without Runtime Checks or Garbage Collection" in Proc. of the 2003 ACM SIGPLAN Conf. on Language, Compiler, and Tools for Embedded Systems. - Questions Addressed:
- What is a pointer? What is a dangling pointer?
- How many bytes are required to store an address?
Memory Hierarchy
- Memory processing is typically done using:
- Main memory (RAM)
- Disk drives (secondary storage) - Performance Order:
1. Registers (CPU): Fastest, but limited capacity.
2. Cache Memory: Faster than main memory.
3. Main Memory: Data is processed here, but slower than registers.
4. Disk Storage: Slowest. - Memory characteristics:
- Faster memory is more expensive.
- Lesser quantity is available at higher speeds.
- Programmers can access registers using Assembly language.
Stack vs. Heap Memory
- Stack Memory:
- Fast operations (push, pop)
- Limited volume, ordered, and managed automatically by the compiler.
- Stores local variables in C/C++. - Heap Memory:
- Slower access, larger volume, dynamically allocated.
- Managed by the programmer (manual memory management).
- Stores global variables in C/C++.
Program Variables Allocation
- Memory locations:
- Stack and heap reside in main memory; CPU contains registers.
- Programmers can configure stack size. - Register Types:
- Instruction Register: holds only one value at a time.
- Data Register: can store 4-16 values at once. - The compiler may optimize variable storage to registers when using the
registerkeyword, though its use is discouraged. - Strings in C/C++ are arrays of characters.
What Causes Buffer Overflow?
- Example scenario:
- An array is initialized for 4 characters. If more than 4 characters are added (e.g., 5 million), data spills over.
- Overflow could overwrite existing data in the stack, leading to potential memory corruption. - Consequence: In a networked application (e.g., online game), this could crash the game or corrupt servers (e.g., web or database servers).
Function Call Stack Example
- Function structure:
void f(int a, int b) {
int x;
}
void main() {
f(1, 2);
printf("hello world");
}
```
## Program Memory Stack
- Variables and pointers, such as `a`, `b`, and `ptr`, are managed in the memory stack area.
## Type Conversion
- **Narrowing Conversion Example**:
- Converting `short int` (2 bytes) to `char` (1 byte).
- If `257` is interpreted:
- Binary: `11111111 11111111 (b) = 255 (dec)`
- Binary: `100000000 00000000 (b) = 256 (dec)`
- Binary: `100000000 00000001 (b) = 257 (dec)`
## Big Endian vs. Little Endian
- **Byte Order Examples**:
- For `int a`, `b = 2`:
- In Little Endian: A1 B2 C3 D4
- In Big Endian: A1 B2 C3 D4
## Buffer Overflow Example 1
- Scenario:
- Examining behavior when inputting a name like "jane doe" versus excessively long strings (e.g., 5 million characters).
- Consequences of data being pushed onto the stack without bounds checking.
## Buffer Overflow Example 1 Fix
- Approach for preventing overflow:
- Implement a check to ensure if the input string length exceeds the allocated `sizeof(buffer)`, returning and exiting the program to avoid overflow.
## Buffer Overflow Example 2
- Source code demonstration:
c
#include
#include
void secretFunction() {
printf("Congrats! You have entered the secret function! The password is qwerty\n");
}
void FileCompress() {
char buffer[20];
// Other variables
}
```
Stack Memory Layout for FileCompress()
- Questions relating to stack usage in a 32-bit system regarding memory allocations and endian representations.
Buffer Overflow Consequences
- Possible outcomes of a buffer overflow:
1. Program functions as expected: No immediate crash but operates improperly.
2. Segmentation Fault: Fault occurs when accessing restricted memory.
3. Memory Access Violation: Attempting to access memory not owned by the process.
4. Overwriting Return Address: Redirecting execution to malicious payloads.
Vulnerable Program Coding Example
- Reads 300 bytes from a user-controlled file into a 400-byte string buffer, leading to buffer overflow.
Memory Management in Vulnerable Programs
- Example of a function that has likely buffer overflow issues:
int foo(char *str) {
char buffer[100];
strcpy(buffer, str); // Vulnerable statement
}
```
## How to Run Malicious Code
- Mechanisms to overwrite return addresses with malicious addresses, providing examples using Python.
## Buffer Overflow Exploitation Techniques
- Steps for exploiting stack-based buffer overflows, including compilation without stack protections and methods to craft payloads.
## Buffer Overflow Protection Mechanisms
- Protection techniques:
1. Non-executable stacks
2. Address Space Layout Randomization (ASLR): Adds randomness to memory addresses, complicating buffer overflow exploits.
3. Stack canaries: Use of guard variables to detect overflow.
4. Safe C functions: Using safer variants of potentially unsafe functions.
5. Static Code Analysis Tools: Such as Coverity and AddressSanitizer.
## Mitigating Buffer Overflow Vulnerabilities
- Discussion of methods and tools that offer poor mitigation or facilitate buffer overflow detection.
## Format String Attacks
- Definition of format string function `printf()` and how it can be exploited due to improper input handling.
## Format String Vulnerability Mechanics
- How format string vulnerabilities arise and can be exploited to modify program behavior or memory.
## Vulnerable Code Sample for Format String Attack
- Example of code susceptible to format string exploitation:
c
printf(input); // Vulnerable point
```
Various Attack Types Using Format Strings
- Effects of misusing format strings that result in unauthorized access or memory alterations:
- Crashing programs, printing stack data, modifying memory locations, and injecting malicious code.
Countermeasures Against Format String Attacks
- Safeguarding principles in code development:
- Avoid user inputs in format strings.
- Compiler warnings for format string mismatches.
Integer Overflow in C/C++
- Overview of integer types and their ranges:
| Type | Size (bytes) | Value Range |
|---------------|--------------|-----------------------------------|
| signed char | 1 | -128 to 127 |
| short int | 2 | -32,768 to 32,767 |
| int | 4 | -2,147,483,648 to 2,147,483,647 |
| unsigned int | 4 | 0 to 4,294,967,295 |
Internal Representation of Integers
- Explanation of maximum values represented with fixed number bits and conversions.
Handling of Integer Overflow
- Examples discussing overflow implications in different data types and programming scenarios.
Interesting Reads
- References for further reading on buffer overflow and integer overflows, including significant papers and articles.
Conclusion
- Summary of vulnerabilities in software applications due to improper memory handling in programming languages, especially those not enforcing memory safety, consequence examples, and various protection mechanisms.