SystemsSec 2016W Lecture 13
Topics & Readings
- Reading: Aleph One (aka Elias Levy), Smashing The Stack For Fun And Profit (Phrack 49, 1996)
- Buffer Overflow Attack
- Memory Corruption Attack
Class Notes
Unsafe Language
Defined as languages, such as C, that are susceptible to buffer overflow attacks. Safe languages are not susceptible because they have really strong compilers.
Secure systems are not susceptible to overflow attacks because the reference monitor is small enough to verify and remove any bugs. The reference monitor is also resilient due to the fact that it is outside the domain of process execution.
Memory Corruption Attack
Figure 1: System structure with certain portions of memory re severed for those types
In a buffer overflow attack you can essentially over write some other portion of memory. For example an attacker may put too much information into the memory portion reserved for string such that it overflows into the memory space reserved for array. Safe languages such as Java are not susceptible to memory corruption attacks unless there is some bug in the compiler.
A common way to know that your code is vulnerable to a buffer overflow/memory corruption attack is if you get a segmentation fault.
Classic Buffer Overflow Attack
Figure 2:
Code Pointer: Not typically writing to pointer. You are writing to region you where pointer is.
Bad Code: The bad code attacker injects is "shell code"
The bad code comes from user input (network, keyboard, disk), in the program itself (just run in different way), environment variable. You can use function pointers, etc, but most code pointers used are return addresses. Return addresses are stored on stack (built in modern processes). You have stack for local variables (when you enter function you allocate space for that function, and when you return from that function you clean up local variables). There is no requirement that local variable stack and return address stack be the same but in practice they are. Local variables stick around longer, and it can be something that attackers can modify. Local variables can be modified using C functions such as gets().
Since attackers are trying to change the code pointer to their bad code, they must figure out where their code is in memory. To do this the bad code is created in such a way that there is a "landing strip" at the beginning of the code. This "landing strip" is usually a bunch of NO OPS. This gives an attacker a bit of extra cushion to ensure that their code could be executed.
Buffer Overflow Prevention
Fuzzing
To find Buffer Overflow/Memory Corruption Attack vulnerability you try to find segmentation fault using fuzzing. Fuzzing: you take program and throw well formed legitimate data at it first. As the fuzzing progresses you tweak it (essentially starts well formed and then gets more random). Fuzzing can be done without source code.
Randomization of Stack
Buffer Overflow defenses make it hard to find landing strip. The best method is to make it hard for attacker to store bad code in memory (example randomize stack).