360 likes | 371 Views
This presentation explores the untrustworthiness of computer systems and the importance of protecting them. Topics covered include buffer overflow attacks, internet worms, and techniques such as StackGuard and MemGuard for preventing and detecting these attacks. Automated detection of buffer overrun vulnerabilities is also discussed.
E N D
Untrustworthiness and Protection Computer Systems Security and Information Survivability - Presented by Deepak Kumar
Buffer Overflow Attacks • Internet Worm of November 1988. • Collected host, network, and user information. • Then broke into other machines using flaws present in those systems’ software. • Flaws: • fingerd and gets; no bounds checking. scanf/fscanf/sscanf, strcat/strcpy, sprintf • sendmail - DEBUG command exploited.
Buffer Overflow Attacks • Exploit a lack of bounds checking on the size of input being stored in a buffer array. • Attacker can make arbitrary changes to program state stored adjacent to the array. • Commonly found in C programs. Why? • C lacks array bounds checking. • C programmers avoid error checking for performance reasons.
Buffer Overflow Attacks (contd) • Most common data structure – the stack – “stack smashing attack”. • 2 mutually dependent goals: • Inject Attack Code (attacker provides executable input string). • Change the Return Address (Buffer overflow changes the RA to point to the attack code). • Which programs are attacked? • Usually, privileged daemons (i.e., under root).
StackGuard • a compiler extension that enhances executable code produced by the compiler. • detects and thwarts buffer-overflow attacks against the stack. • transparent to the normal function of programs. Stack Smashing Buffer Overflow Attack
StackGuard (contd) • Prevents changes to active RAs in 2 ways: • By detecting change of the RA before the function returns. (more efficient and portable). • By completely preventing the write to the RA (more secure). Canary Word Next to Return Address
StackGuard - Detecting RA Change Before Return • Detection done before a function returns. • A canary word placed next to the RA on the stack. • When function returns, it first checks to see that the canary word is intact before jumping to the RA pointed word. • Key: RA is unaltered iff the canary word is unaltered. (How?) – true for buffer overflow attacks.
StackGuard - Detecting RA Change Before Return • StackGuard implementation - simple patch to gcc 2.7.2.2. • gcc function_prologue and function_epilogue functions - altered to emit code to place and check canary words. • Problem: Attackers can develop buffer overflows insensitive to StackGuard. • Solution: Randomize the Canary.
StackGuard - Preventing RA Changes With MemGuard • “Quasi-invariants” – optimistic specializations. • Treat return addresses on the stack as quasi-invariant during the activation lifetime of the function. • RA read-only (invariant) prevents effective buffer overflow against the stack. • MemGuard – tool to help debug optimistic specializations functions locates code statements that change quasi-invariant values.
StackGuard • MemGuard used to protect an RA when a function is called, & un-protect the RA when the function returns. • Adaptive Defense Strategies Function Prologue Code: Protecting the Return Address With MemGuard
Automated Detection of Buffer Overrun Vulnerabilities • Involves a synthesis of ideas from program analysis, theory, and systems security. • Main Idea: to apply standard static analysis techniques. • Formulate the buffer overrun detection problem as an integer constraint problem. • Use some simple graph theoretic techniques to construct an efficient algorithm for solving the integer constraints.
Automated Detection of Buffer Overrun Vulnerabilities • Security knowledge used to formulate heuristics capture the class of security-relevant bugs that tend to occur in real programs. • Aim for scalability at the cost of precision. Reason: to analyze large programs – like sendmail. • Result: Some false negatives and false positives.
Automated Detection of Buffer Overrun Vulnerabilities The architecture of the buffer overflow detection prototype. • 2 fundamental new insights: • Treat C strings as an abstract data type. • Model buffers as pairs of integer ranges (allocated size, currently used length). • A secondary contribution: scalable and very fast integer range analysis – can handle cyclic data dependencies without loss of precision by invoking a fixpoint theorem.
Automated Detection of Buffer Overrun Vulnerabilities • Z = Set of integers. Z∞ = Z U {-∞, +∞}. • A Range is a set R ≤ Z∞ of the form [m, n] = {i € Z∞ : m ≤ i ≤ n}. • S is a subset of Z∞, inf S and sup S. • inf[m, n] = m; sup[m, n] = n. • Range Closure of S ≤ Z∞, is the minimal range R containing S, i.e., R = [inf S, sup S].
Automated Detection of Buffer Overrun Vulnerabilities • Integer Range Expression e: e ::= v | n | n x v | e + e | e – e | max(e,…,e) | min(e,…,e) where n € Z and v € Vars, a set of range variables. • Integer Range Constraint e ≤ v
Automated Detection of Buffer Overrun Vulnerabilities Modeling the effects of string operations: some examples.
Automated Detection of Buffer Overrun Vulnerabilities • Theorem: Every constraint system has a unique least solution. • Constraint generation: • proceeds by traversing the parse tree for the input C source code • generating a system of integer range constraints. • With each integer program variable v, a range variable is associated.
Automated Detection of Buffer Overrun Vulnerabilities • alloc(s), len(s). • Safety property to be verified: len(s) ≤ alloc(s) • Flow-insensitive analysis. • Model function calls monomorphically. • Problems due to pointer aliasing. • Theorem: We can solve the constraint subsystem associated with a cycle in linear time.
Automated Detection of Buffer Overrun Vulnerabilities • Early experience with prototype • Linux net tools • Sendmail 8.9.3 • Sendmail 8.7.5 • Performance • Sub-optimal but usable. • Scalable. • Limitation: Large number of false alarms due to imprecision in the range analysis.
Rational Purify • A tool that developers and testers are using to find memory leaks and access errors. • Detects the following at the point of occurrence: • reads or writes to freed memory. • reads or writes beyond an array boundary. • reads from uninitialized memory. • Upon demand, employs a garbage detector to find and identify existing memory leaks. • Purify finds run-time-detectable errors.
Purify - Detecting Memory Access Errors • Purify "traps" every memory access a program makes. • Maintains and checks a state code for each byte of memory. • Accesses inconsistent with the current state cause a diagnostic message to be printed. • The function CATCH_ME is called (breakpoint). Memory State Transition Diagram
Purify - Catching Array Bounds Violations • To catch array bounds violations, Purify allocates a small "red-zone" at the beginning and end of each block returned by malloc. • The bytes in the red-zone recorded as unallocated. • If a program accesses these bytes, Purify signals an array bounds error.
Purify - Object Code Insertion • Uses object code insertion to augment a program with checking logic. • Done before or after linking. • Advantages: • setup performance. • convenience. • multi-language support. • completeness. Example Make
Type-Safe Languages - Java • Buffer Overrun problem – due to lack of type safety in C. • Type-safety is one of the foundations of the Java security model. • Java Security Goals –programs should be: • Safe from malevolent programs • Non-intrusive • Authenticated
Java Security • Encrypted • Audited • Well-defined • Verified • Well-behaved • C2 or B1 certified • Java SandBox - provide an environment on the computer where the program can play but confined within certain bounds.
The Java Sandbox • Minimal Sandbox - Access to CPU, screen, keyboard, and mouse, and to its own memory. • Default Sandbox - Access to CPU and its own memory as well as access to the web server from which it was loaded. • Access to CPU, its memory, its web server, and to a set of program-specific resources. • Open Sandbox – access to all resources.
Anatomy of a Java Application • Bytecode verifier • Class loader • Access controller • Security manager • Security package • Key database
Java Language Security • Java Language Security Constructs • every primitive data element has an access level associated with it which can be: • Private • Default (or package) • Protected • Public • Credit Card example - www.Acme.com and www.EvilSite.org.
Rules • Access methods are strictly adhered to. • Programs cannot access arbitrary memory locations. • Entities that are declared as final must not be changed. • Variables may not be used before they are initialized. • Array bounds must be checked on all array accesses. • Objects cannot be arbitrarily cast into other objects.
Enforcement of Rules • Compiler Enforcement • The Bytecode Verifier • Class file has correct format. • Final classes not subclassed, and final methods not overridden. • Every class has a single superclass.
Enforcement of Rules (contd) • No illegal data conversion of primitive data types (e.g., int to Object). • No illegal data conversion of objects occurs. • no operand stack overflows or underflows. • Runtime Enforcement • Array bounds checking • Object casting
The Class Loader • Initially, only the class loader knows certain information about classes that have been loaded into the virtual machine. • Only the class loader knows where a particular class originated. • Only the class loader knows whether or not a particular class was signed.
Class Loader • Class Loaders and Security Enforcement • Class Loaders and Namespaces • Anatomy of a Class Loader • The Internal Class Loader • The Applet Class Loader • The RMI Class Loader • The Secure Class Loader • The URL Class Loader
Security Manager • Ultimately responsible for determining most of the parameters of the Java sandbox. • Ultimately determines whether operations should be permitted or rejected. • Trusted and Untrusted Classes. An untrusted class cannot directly connect to the database server
Access Controller • Decides whether access to a critical system resource should be permitted or denied. • The CodeSource Class. • Permissions. • Protection Domains. • AccessController Class. • Guarded Objects. Coordination of the security manager and the access controller.
Summary • Buffer Overflow attacks due to memory vulnerabilities in C. • Methods to prevent buffer overflow attacks: • StackGuard. • Static Analysis. • Array Bounds Check (Rational Purify). • TypeSafe Language – Java. • Java Security.