Download presentation
1
Mitigation of Buffer Overflow Attacks
2
Stack Overflow Review A buffer on the stack has an un-checked bound.
A malicious input could modify program control flow by overwriting data on the stack, e.g. saved EIP. Malicious code can be injected on the stack and EIP can be made to point to it. Key to a successful stack overflow attack The modified control gets loaded into EIP e.g. the vulnerable function successfully “returns;” Must be able to predict the address of the injected code The injected code must be executable What if those conditions cannot be met?
3
Mitigation1: stack address randomization
The OS randomly picks a location for the program stack. The chance the attacker can guess the correct stack location is slim. Where shall EIP point to? However, there are multiple ways to get around it.
4
Getting around stack randomization through indirect jump
beginning of the buffer NOP sled Shell Code EIP Shell Code ESP 0x42122ba7: JMP ESP (0xffe4)
5
Thoughts Any register that points to somewhere after the beginning of the vulnerable buffer could work. We can look for the “jump code” by searching the virtual memory space. System libraries are a good place to start. A library’s code may not even have the jump code in its instructions, but we could still find the jump code anyway (Why?).
6
StackGuard A compile-time mechanism that detects/prevents modification of saved EIP during function execution. When the function starts, a “canary word” is put on the stack in between the function’s local variables and saved EIP. If a local buffer is overrun, the canary will have to be “killed” before the saved EIP can be modified. Before function returns, checks whether the canary is still intact. If not, hand program control to a pre-defined exception handler and terminate the program.
7
StackGuard address growth function’s return address .text .data
heap malloc’ed data address growth > heap < stack ESP local variables AAAAAAAAAAA AAAAAAAAAAAAAAA AAAAAAAAAAA AAAAAAAAAAAAAAA EBP saved EBP A A A A canary word A A A A function’s return address saved EIP A A A A function’s argument main() local variables argc, **argv, **envp environment var’s bottom of stack
8
Types of Canary Terminator canary Random canary XOR canary
A character that in most cases will terminate a malicious string, e.g. NULL. Random canary A random value produced at program execution time The random value is stored in a global variable XOR canary A random value XOR’ed with saved EIP On function return, the canary is XOR’ed with the random value and the result compared with saved EIP
9
Limitation of StackGuard
Will not work if the exploit does not depend upon modifying saved EIP Buffer overflow in certain stack layouts could give the attacker ability to modify any memory location with any value This opens up a number of new options to hijack the program’s control flow, e.g. modify the entrance table of exception handlers or system functions The same limitation applies to other similar mechanisms e.g. StackShield
10
Circumvent StackGuard
.text .data heap malloc’ed data Unsafe copy overwrites value of ptr (where). address growth > heap function body: … copy(buf, attacker-controlled data); copy(ptr, attacker-controlled data); < stack ESP char buf[]; char* ptr; AAAAAAAAAAA AAAAAAAAAAAAAAA AAAAAAAAAAA AAAAAAAAAAAAAAA EBP saved EBP canary word Any copy with attacker-provided data (what) saved EIP function’s argument main() local variables Modify any memory location (where) with arbitrary data (what). argc, **argv, **envp environment var’s bottom of stack
11
Non-executable Stack OS/architecture protection of virtual memory so that injected code cannot run NX bit: mark certain memory pages (e.g. stack pages) non-executable W^X bit: a page cannot be both writable and executable Consequences Injected shellcode on the stack cannot be executed Deviates from von-Neumann architecture e.g. run-time code generation may be affected
12
Limitation of non-executable stack
Will not work if the exploit does not rely on code injected on the stack. Code can be injected in other memory segments, e.g. heap. Or no need to inject code at all!
13
Getting around non-executable stack through return-into-libc
AAAAAAAAAAAAAAAAAAAAAAAAAAAA ???? EIP W1 ???? ???? W2 ESP libc’s return address libc’s argv[1] entrance address of a libc function system(…); “/bin/sh” entrance address of the next libc function you want to run, e.g., exit();
14
Thoughts Whenever a new defense against software exploit is invented, a new way to get around it emerges. These defensive mechanisms are reactive and address a particular way of attack, not the underlying vulnerability. But how many ways of attack are there? To reduce the “attack surface,” we must also address the underlying vulnerabilities. Defensive programming Using type-safe languages and static code analysis
15
Implication on System Security
We must assume that software applications will have security vulnerabilities in them Proper design of protection mechanisms is essential to mitigate the threats
Similar presentations
© 2024 SlidePlayer.com. Inc.
All rights reserved.