270 likes | 1.1k Views
Non Malicious Program Errors (Buffer Overflows). Gabe Kanzelmeyer CS 450 4/14/10. Overview. What is buffer overflow? How memory is processed and the stack The threat Stack overrun attack Dangers Prevention. What is buffer overflow?. A buffer (array/string) that holds data
E N D
Non Malicious Program Errors (Buffer Overflows) Gabe Kanzelmeyer CS 450 4/14/10
Overview What is buffer overflow? How memory is processed and the stack The threat Stack overrun attack Dangers Prevention
What is buffer overflow? • A buffer (array/string) that holds data • Buffer stored in memory (finite) • Example. • char buffer[10] (sets aside buffer[0] – buffer[9]) • Consider: buffer[10] = ‘A’; • What will happen?
Compiler detects out of bounds • Consider: • buffer[i] = ‘A’; • What happens then? • Depends, cant identify problem until execution.
First two only effect the user. Malicious programmer focuses on accessing the second two .
How memory is processed and the stack Text – program code Data – global data Stack and Heap – allocate at run-time Stack - stores function arguments, local variables, values of selected registers
When a procedure is called, the return address for function call, is put into the stack Key importance for attacker Overwrite the return address stored on the stack, upon termination of the procedure, it would be loaded into the EIP register (instruction counter), potentially allowing any overflow code to be executed.
void f(int a, int b) { char buf[10]; } void main() { f(1, 2); }
The Threat • How to recognize where an attack may occur? • Return address on stack • Data on stack With this in mind lets consider the following…
-Frame address -Return address -overwritten Modified return address is pushed into instruction counter #include char *code = "AAAABBBBCCCCDDD"; //including the character '\0‘ //size = 16 bytes void main() { char buf[8]; strcpy(buf, code); }
Stack Overrun Attack 1. Discovering a code, which is vulnerable to a buffer overflow. 2. Determining the number of bytes to be long enough to overwrite the return address. 3. Calculating the address to point the alternate code. 4. Writing the code to be executed. 5. Linking everything together and testing
Victims code (victim.exe) #include #define BUF_LEN 40 void main(intargc, char **argv) { char buf[BUF_LEN]; if (argv > 1) { printf(„\buffer length: %d\nparameter length: %d”, BUF_LEN, strlen(argv[1]) ); strcpy(buf, argv[1]); } }
The Attack • Consider: • victim.exe AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAA If access violation error Try: • victim.exe AAAABBBBCCCCDDDDEEEEFFFFGGGG………
If successful, error message: • “The instruction at “0x4b4b4b4b” referenced memory at “0x4b4b4b4b”. The memory could not be read. • 0x4b is ASCII“K” • Return address has been overwritten with KKKK
From here you can do whatever you want • Inject shell code to gain “super user” access • Inject address to malicious code • Use vulnerable system to exploit Denial of service attack
Dangers • Poor programming practices • Text/string manipulation functions • strcpy() • strcat() • sprintf() • gets() • Etc…
Preventing buffer overflow • Library based defenses • Re-implemented unsafe functions (Libsafe) • Detects illegitimate code on the stack (SecureWave) Compiler based runtime boundaries