340 likes | 504 Views
Defending against Stack Smashing attacks. Presented by: Micha Moffie. Stack Smashing. Occurs in C, C++ … not java … Buffer overflow & stack Smashing are one of the most frequently exploited program vulnerabilities. Vulnerabilities breakdown.
E N D
Defending against Stack Smashing attacks Presented by: Micha Moffie
Stack Smashing • Occurs in C, C++ … • not java … • Buffer overflow & stack Smashing are one of the most frequently exploited program vulnerabilities.
Vulnerabilities breakdown • Taken from: “Analysis of Security Vulnerabilities”
Outline • Stack smashing attack • Solutions: • StackGuard • Compiler Based • Transparent Defense Against SSA • Run time code instrumentation • StackGhost • Hardware facilitated stack protection
Stack Stack grows main( ) auto variables 10 +12 ptr to input string +8 return addr of foo( ) +4 Frame ptr frame ptr of foo( ) 0 dddd b[12] -4 Stack ptr cccc -8 b[8] bbbb -12 b[4] aaaa -16 b[0] Buffer grows Stack Smashing Attack - I main(int argc, char **argv) { … foo(argv[1], 10); … } void foo(int i, char *s) { char b[16]; strcpy(b, s); …… }
Stack Smashing Attack - II Stack Stack grows Attacker code executed in Stack Segment.. attack code attack code attack code +12 start of attack code 0x0012ff12 0x0012ff08 +8 0x0012ff12 0x0012ff04 +4 0x0012ff12 0x0012ff00 0 0x0012ff12 **** b[12] -4 return addr of foo( ) Has changed! it will return to 0x0012ff12, the attacker code **** -8 b[8] **** -12 b[4] **** -16 b[0] Buffer grows
Stack Smashing Attack • Exploits the fact that return address: • is on the stack • grows “down” • is located very close to a byte array with weak bounds checking
StackGuard • StackGuard: Automatic Detection and Prevention of Stack smashing Attacks • A compiler tool Recompile • Two techniques: • Detects • Prevent
StackGuard – Detect I • Add Canary Word next to return address • Observation (true only for buffer o.f.) • Return address is unaltered IFF canary word is unaltered • Guessing the Canary ? • Randomize
StackGuard – Detect II • When compiling the function, we add prologue and epilogue • Before execution of function push word canary into canary vector • in addition to the stack • After execution, before returning from function check whether canary is intact • Function returns Only if canary is intact
StackGuard – Prevent I • While function is active make the return address read-only • attacker cannot change the return address • any attempt will be detected • Use a library called MemGuard • mark virtual memory pages as read-only and trap every write • legitimate writes to stack causes trap • Unacceptable Performance penalty
StackGuard – Prevent II • Solution: cache 4 most recently return addresses using Pentium Debug registers • trap read/write/execute of virtual address loaded into debug register (return address) • Compiler is adjusted to emit stack frames with a minimum size of ¼ a page • eliminate the need for the top-of-stack page to be read only.
StackGuard - Results • Effectiveness
StackGuard - Results • Overhead
Outline • Stack smashing attack • Solutions: • StackGuard • Compiler Based • Transparent Defense Against SSA • Run time code instrumentation • StackGhost • Hardware facilitated stack protection
Run Time Transparent Defense • Transparent Run-Time Defense against stack smashing attacks • No need to recompile code • Does instrument the code (in memory) • libverify • Utilizing two dynamically loaded libraries • LibSafe • LibVerify
LibSave I • library loaded automatically • Intercepts known unsafe functions • strcpy, gets, scanf, …. • Computes (run-time) length of source string and upper bound of destination buffer • Observation: • destination buffer on the top frame cannot extend beyond the frame pointer - (safe upper limit) • What about local buffers on a previous frame pointer?
LibVerify I • library loaded automatically • Upon loading, instruments code: • All Functions are copied to heap region • For each function: • First instruction jumps to wrapper entry • Last instruction jumps to wrapper exit • Similar to StackGuard: • Wrapper entry saves a copy of canary • Wrapper exit verifies canary word • To simplify: • Actual return address used as canary word
Run Time Def - results • Effectiveness
Run Time Def - results • Overhead
Outline • Stack smashing attack • Solutions: • StackGuard • Compiler Based • Transparent Defense Against SSA • Run time code instrumentation • StackGhost • Hardware facilitated stack protection
StackGhost • StackGhost: Hardware Facilitated Stack Protection • Using hardware mechanisms & kernel modifications to guard application return address
Sparc Architectural Issues • Understand: • When stack is written to • Who initiates the request • Who operates the request
StackGhost - cont • Each time the register window is overflows or underflows call StackGhost • When overflow (push) • Encrypt the return address • When underflow (pop) • Decrypt the return address • Check address alignment
Encrypting … • Per-Kernel XOR cookie • XOR a fixed cookie with the return address • Per-Process XOR cookie • More Difficult to determine the cookie (still possible) • Encrypt address + stack frame using an encryption algorithm
StackGhost - results • Effectiveness • Does not prevent changing the return address • Distort – difficult for attacker to know what the actual return address will be • Unpredictable execution
StackGhost - results • Overhead
The End • Questions ? • References • Crispin Cowan, Calton Pu, Dave Maier, Heather Hinton, Peat Bakke, Steve Beattie, Aaron Grier, Perry Wagle, and Qian Zhang. Stackguard: Automatic adaptive detection and prevention of buffer-overflow attacks. pages 63-78. Proc. 7th, USENIX Security Conference, Jan 1998. • Arash Baratloo, Navjot Singh, and Timothy Tsai. Transparent run time defense against stack smashing attacks. Proc. of USENIX Annual Technical Conference, Jun 2000. • Mike Frantzen and Mike Shuey. Stackghost: Hardware facilitated stack protection. Proc. of the 10th USENIX Security Symposium, Aug 2001.
Stack Smashing attack - cont • Change the Return Address: The buffer overflow changes the return address to point to the attack code. When the function returns, instead of jumping back to where it was called from, it jumps to the attack code.