220 likes | 315 Vues
Explore how NINJA system prevents attacks by executing relocatable functions and constant-based address randomization in software layout to mitigate intrusion threats. Learn about ASLR limitations and the entropy challenges it poses for executable files. Discover the strategy of rewriting and relocating functions to achieve a secured executable layout against Return-Oriented Programming (ROP) attacks in modern software designs.
E N D
Securing Programs by Continuous Address Space Randomization TugrulInce tugrul@cs.umd.edu PD Week ’13
Code Layout • Software and hardware have evolved to run programs fast • Optimizing compilers • Complex code transformations • Inlining • Packed code layout • Execution environments are very strict • Every piece of code occupies a predetermined location • Each module has a fixed address at runtime • Hard to modify executables
Problems with Code Layout • Intrusion attacks benefit from strict program layouts • Attackers guess locations of critical functions • Function locations are constant for non-PIE executables • Relative distances between functions are constant even in shared libraries • Current randomization techniques only change the base address • Very sensitive to information leakage
A Typical Function Call … void currentFunc() { … foo(arg1, …, argN); … } void foo(int arg1, …, int argN) { char buffer[64]; scanf(“%s”, buffer); … return; } int system(char* cmd) { // run cmd } Current Func. arg1 … argN Saved RIP Saved RBP buffer foo
Return-Programming Attack … void currentFunc() { … foo(arg1, …, argN); … } void foo(int arg1, …, int argN) { char buffer[64]; scanf(“%s”, buffer); … return; } int system(char* cmd) { // run cmd } Current Func. arg1 … … &buffer argN … Saved RIP &system() Saved RBP … buffer Malicious command foo
Return-Programming Attack … void currentFunc() { … foo(arg1, …, argN); … } void foo(int arg1, …, int argN) { char buffer[64]; scanf(“%s”, buffer); … return; } int system(char* cmd) { // run cmd } Current Func. arg1 … I need to guess the location of system() and where return address is stored … &buffer argN … Saved RIP &system() Saved RBP … buffer Malicious command foo
Preventing Attacks • Address Space Layout Randomization (ASLR) • Conventional approach • Rebase executable files (including shared libraries) • ASLR has many limitations • One randomization constant for the whole executable • If attacker learns one address in the executable, s/he knows the full map • Randomization constant fixed during execution • Allows multiple tries (brute-force) • No randomization for child processes • Attackers might have unlimited identical processes to attack
Entropy with ASLR • ASLR promises high entropy • 40-bits of entropy on patched kernels • Actual entropy is much less • All executables are loaded at addresses that start with 0x00007f---------- • Executables are loaded very close to each other • Least-significant 12-bit-offset of a function address is constant 12-16 bits 0 0 0 0 7 F B C 3 A X 1 2 12-16 bits of entropy … … Executable A 0x00007fxxxy------ 0x00007fxxxy---123 64-bit Address Space 0x00007f---------- 0x00007f---------- Executable B 0x00007fxxxz------ 0x00007fxxxz---456 … … similar offset
NINJA System Overview • NINJA: No Intrusion by Jumping Around • Rewrite executableswith completely relocatable functions • Link with a first-party runtime relocator Executable Relocatable Executable execution foo foo' Binary Rewriter Relocator
Completely Relocatable Functions • Position independent code (PIC) • Dependent on location after initial relocation of executable • Relative addressing • Remove dependencies to location • Instruction-pointer based addressing • Calls with • absolute addresses • relative addressing • Table-based branches
Editing the Executable • Instruction-pointer based addressing • Updating offsets is impractical • Why not use a constant instead of the instruction-pointer? • No need to update the offset Target Offset mov 0x0, 0x100(%rip) ??? Instruction Instruction
Editing the Executable • Our constant: initial location of the function • Store this value on stack • All IP-based addresses are updated to use this new value and a modified offset • (IP + Offset) = (<Initial Function Location> + Offset’) • mov 0x0, 0x100(%rip) mov 0x0, 0x80(%r15) • Shared Libraries • This constant initially depends on the instruction-pointer • During first relocation, it is replaced with a real constant • No modification of code for relocation after the first one
Editing the Executable • Function Table • Calls go through this table • Updated at runtime • Table-based branches • Table contains only offsets • Add instruction-pointer to offsets to determine target Initial Location Current Location Execution Count Active Call Count Size jmp *rax Block 1 Block 2 Block 3 Block 4
Editing the Executable • Accessing parameters on stack • Need to update offsets to rsp / rbp … PrevFunc. Frame Parameter Return Addr. Stack Ptr. Prev. Frame Ptr. Initial Func. Loc. • Add call to Relocator at function exit
Runtime Relocation Strategy • Relocate individual functions • Randomly after a given time interval (R) • After they execute N times • How to pick a reasonable N? • N = 1 : relocate after every function execution • High overhead • N = 10,000 : infrequent relocation • Adaptive Strategy: Pick Nwith respect to execution frequency • Profiling data • High N for functions that execute often • Low N for functions that execute rarely
Experimental Evaluation • Linux (Ubuntu 11.04) • Maximum 28-bits of entropy • Measurements • Overhead using benchmarks from SPEC CPU 2006 • Time for successful attack using a modified version of Apache HTTP Server
Attacks on NINJA • ASLR with PIE: Attacks take an average of 4.9 hours • Range: 16 seconds to more than 14 hours • NINJA: low probability of successful attack • Probability of a successful attack in itries is given by:
Probability of Successful Attack 20 25 210 215 220 225 230 235 240
Successful Attack Probability in 24 hrs Probability of Successful Attack (log scale) 1 8 16 24 Elapsed Time (hours)
Conclusion • Strict layout of code makes programs vulnerable • Process functions to be completely relocatable • Relocate functions at runtime • After Nth execution • Periodically at timed intervals • Attackers cannot identify function locations on time to attack