Software Defense Mechanisms: PaX and the future past continuous
Who am I? NOT Brad Spengler – I have decent ears NOT Brad Spengler – I have decent ears Tiago Assumpção Tiago Assumpção NOT an academic NOT an academic An undisciplined curious person with lots of energy to be spent on whatever is valued by his self An undisciplined curious person with lots of energy to be spent on whatever is valued by his self
Who am I? (cont.) NOT a PaX developer… however… NOT a PaX developer… however… Have had delightful discussions with PaX Team about whatever blows your hair back Have had delightful discussions with PaX Team about whatever blows your hair back Have been improving the project [2] Have been improving the project [2] Have been questioning the project [3] Have been questioning the project [3]
In praise of hacking “The speculations of Thales, Anaximander, and Anaximenes are to be regarded as scientific hypotheses (...) The questions they asked were good questions, and their vigour inspired subsequent investigators.” “The speculations of Thales, Anaximander, and Anaximenes are to be regarded as scientific hypotheses (...) The questions they asked were good questions, and their vigour inspired subsequent investigators.” RUSSELL, Bertrand; History of Western Philosophy p. 37
What is PaX? Quite simply: the greatest advance in system security in over a decade that you’ve never heard of Quite simply: the greatest advance in system security in over a decade that you’ve never heard of Less simply: It provides non-executable memory pages and full address space layout randomization (ASLR) for a wide variety of architectures. Less simply: It provides non-executable memory pages and full address space layout randomization (ASLR) for a wide variety of architectures. – Brad “grears” Spengler
What is PaX? Linux kernel patch Linux kernel patch Free-software & open-source is good for the general researcher Free-software & open-source is good for the general researcher Universal solutions: concepts easily extentend to any modern platform Universal solutions: concepts easily extentend to any modern platform
Why is PaX? Given a vector: Given a vector: Payload (code/data) injection Payload (code/data) injection Context (memory/registers/etc.) manipulation Context (memory/registers/etc.) manipulation Intentional Control Flow modification Intentional Control Flow modification
Outline PaX PaX SEGMEXEC SEGMEXEC PAGEEXEC PAGEEXEC KERNEXEC KERNEXEC ASLR ASLR RANDMMAP RANDMMAP RANDKSTACK RANDKSTACK PIE PIE UDEREF UDEREF
Outline (cont.) PaX’ Facts PaX’ Facts Past Continuous Past Continuous Control Flow Verification Control Flow Verification KERNSEAL KERNSEAL
PaX - SEGMEXEC SEGMEXEC is PaX’s implementation of per- page non-executable user pages using the segmentation logic of IA-32 (Intel x86 architecture) and virtual memory area mirroring (developed by PaX). SEGMEXEC is PaX’s implementation of per- page non-executable user pages using the segmentation logic of IA-32 (Intel x86 architecture) and virtual memory area mirroring (developed by PaX).
PaX – SEGMEXEC (cont.) The segmentation logic is fairly straightforward: The segmentation logic is fairly straightforward: Data Segment (DS) Data Segment (DS) Code Segment (CS) Code Segment (CS) There exist these two segments for user pages as well as kernel pages. There exist these two segments for user pages as well as kernel pages. PaX splits the address space down the middle: the bottom half for data, the top for code. PaX splits the address space down the middle: the bottom half for data, the top for code. Segmentation is a “window” into the address space Segmentation is a “window” into the address space No performance hit No performance hit
PaX – SEGMEXEC (cont.) User Code & Data Segments 3GB Without SEGMEXEC User Code Segment 1.5GB User Data Segment 1.5GB With SEGMEXEC
PaX – SEGMEXEC (cont.) PaX’s VMA mirroring involves duplicating every executable page in the lower half of the address space into the upper half. PaX’s VMA mirroring involves duplicating every executable page in the lower half of the address space into the upper half. Instruction fetch attempts at addresses located in the data segment that don’t have any code located at its mirrored address will cause a page fault. PaX handles this page fault and kills the task. Instruction fetch attempts at addresses located in the data segment that don’t have any code located at its mirrored address will cause a page fault. PaX handles this page fault and kills the task.
PaX – SEGMEXEC (cont.) c000 r-xp /home/bradly/cat 0804c d000 rw-p /home/bradly/cat 0804d rw-p r-xp /lib/ld so rw-p /lib/ld so rw-p 2001e r-xp /lib/libc so a000 rw-p /lib/libc so 2014a c000 rw-p 2014c d1000 r--p /usr/lib/locale/locale-archive 5ffff rw-p c000 r-xp /home/bradly/cat r-xp /lib/ld so 8001e r-xp /lib/libc so c000 r-xp /home/bradly/cat 0804c d000 rw-p /home/bradly/cat 0804d rw-p r-xp /lib/ld so rw-p /lib/ld so rw-p 4001e r-xp /lib/libc so a000 rw-p /lib/libc so 4014a c000 rw-p 4014c d1000 r--p /usr/lib/locale/locale-archive bfffe000-c rw-p Without SEGMEXEC With SEGMEXEC
PaX – SEGMEXEC (cont.) Instruction fetch attempt at 0x Segmentation logic translates 0x into 0x Does 0x belong to any mapping? Success Violation, process is terminated YES NO
PaX - PAGEEXEC PAGEEXEC was PaX’s first implementation of non-executable pages. PAGEEXEC was PaX’s first implementation of non-executable pages. Because of SEGMEXEC, it’s not used anymore on x86 (so I won’t discuss the implementation). Because of SEGMEXEC, it’s not used anymore on x86 (so I won’t discuss the implementation). Platforms which support the executable bit in hardware are implemented under PAGEEXEC (currently alpha, ppc, parisc, sparc, sparc64, amd64, and ia64) Platforms which support the executable bit in hardware are implemented under PAGEEXEC (currently alpha, ppc, parisc, sparc, sparc64, amd64, and ia64)
PaX - KERNEXEC KERNEXEC is PaX’s implementation of proper page protection in the kernel KERNEXEC is PaX’s implementation of proper page protection in the kernel ‘const’ finally means read only in the kernel ‘const’ finally means read only in the kernel Read-only system call table Read-only system call table Read-only interrupt descriptor table (IDT) Read-only interrupt descriptor table (IDT) Read-only global descriptor table (GDT) Read-only global descriptor table (GDT) Data is non-executable Data is non-executable Uses the same concept of segmentation as SEGMEXEC Uses the same concept of segmentation as SEGMEXEC Cannot co-exist with module support (currently) Cannot co-exist with module support (currently)
PaX - ASLR Full ASLR randomizes the locations of the following memory objects: Full ASLR randomizes the locations of the following memory objects: Executable image Executable image Brk-managed heap Brk-managed heap Library images Library images Mmap-managed heap Mmap-managed heap User space stack User space stack Kernel space stack Kernel space stack
PaX – ASLR (cont.) Notes on amount of randomization: Notes on amount of randomization: The following values are for 32bit architectures. They are larger on 64bit architectures, though not twice as large (since they generally don’t use 64 bits for the address space). The following values are for 32bit architectures. They are larger on 64bit architectures, though not twice as large (since they generally don’t use 64 bits for the address space). Stack – 24 bits (28 bits for argument/environment pages) Stack – 24 bits (28 bits for argument/environment pages) Mmap – 16 bits Mmap – 16 bits Executable – 16 bits Executable – 16 bits Heap – 12 bits (or 24 bits if executable is randomized also) Heap – 12 bits (or 24 bits if executable is randomized also)
PaX – ASLR (cont.) The randomizations applied to each memory region are independent of each other The randomizations applied to each memory region are independent of each other Because PaX guarantees no arbitrary code execution, exploits will most likely need to access different memory regions. Because PaX guarantees no arbitrary code execution, exploits will most likely need to access different memory regions. So, if the exploit needs access to libraries and the stack, the bits that must be guessed are the sum of the two regions: 40 bits (or 44). The chance of such an attack succeeding while depending on hard coded addresses is effectively zero. So, if the exploit needs access to libraries and the stack, the bits that must be guessed are the sum of the two regions: 40 bits (or 44). The chance of such an attack succeeding while depending on hard coded addresses is effectively zero.
PaX – ASLR (cont.) c000 r-xp /home/bradly/cat 0804c d000 rw-p /home/bradly/cat 0804d rw-p 4edaa000-4edbe000 r-xp /lib/ld so 4edbe000-4edbf000 rw-p /lib/ld so 4edbf000-4edc0000 rw-p 4edc8000-4eeef000 r-xp /lib/libc so 4eeef000-4eef4000 rw-p /lib/libc so 4eef4000-4eef6000 rw-p 4eef6000-4f07b000 r--p /usr/lib/locale/locale-archive bf3dc000-bf3dd000 rw-p c000 r-xp /home/bradly/cat 0804c d000 rw-p /home/bradly/cat 0804d rw-p 43d8c000-43da0000 r-xp /lib/ld so 43da da1000 rw-p /lib/ld so 43da da2000 rw-p 43daa000-43ed1000 r-xp /lib/libc so 43ed ed6000 rw-p /lib/libc so 43ed ed8000 rw-p 43ed d000 r--p /usr/lib/locale/locale- archive b54f9000-b54fa000 rw-p Two runs of a binary with stack, mmap, and heap randomization
PaX – ASLR (cont.) RANDKSTACK RANDKSTACK Randomizes the kernel’s stack Randomizes the kernel’s stack Randomized on each system call, so info- leaking the randomization is useless Randomized on each system call, so info- leaking the randomization is useless Randomizes 5 bits of the stack. Brute forcing generally shouldn’t be possible, as each attempt will most likely crash the kernel. Randomizes 5 bits of the stack. Brute forcing generally shouldn’t be possible, as each attempt will most likely crash the kernel.
PaX – ASLR (cont.) PIE PIE Special type of ELF binary (the same used for shared libraries) Special type of ELF binary (the same used for shared libraries) Position independent code (PIC) Position independent code (PIC) Allows for relocation of the binary at a random location Allows for relocation of the binary at a random location Needed to achieve Full ASLR Needed to achieve Full ASLR Requires a recompile and re-link of applications Requires a recompile and re-link of applications
PaX – Dangling Pointers “Dangling pointers and wild pointers in computer programming are pointers that do not point to a valid object of the appropriate type, or to a distinguished null pointer value in languages which support this” “Dangling pointers and wild pointers in computer programming are pointers that do not point to a valid object of the appropriate type, or to a distinguished null pointer value in languages which support this”Wikipedia
PaX – Dangling Pointers (cont.) Most i386 OSs don't separate the userland virtual address space from that of the kernel. Most i386 OSs don't separate the userland virtual address space from that of the kernel. Linux 2.6 has per-cpu GDTs; LDTs are untouched Linux 2.6 has per-cpu GDTs; LDTs are untouched BSDs creates flat per-process LDTs BSDs creates flat per-process LDTs Windows creates flat per-process LDTs Windows creates flat per-process LDTs
PaX – Dangling Pointers (cont.) Thence, whenever userland can make the kernel (unexpectedly) dereference a pointer within its range of control, it holds ability to controlling the data (and, possibly, code) flow of the kernel by virtue of providing the attack elements in its own address space. Thence, whenever userland can make the kernel (unexpectedly) dereference a pointer within its range of control, it holds ability to controlling the data (and, possibly, code) flow of the kernel by virtue of providing the attack elements in its own address space. Real-life [4] Real-life [4]
PaX – UDEREF Kernel & User Segments 4GB Without UDEREF Kernel Segments 1GB User Segments 3GB With UDEREF
PaX – UDEREF (cont.) Segment selectors are properly set Segment selectors are properly set Few modifications are done regarding user/kernel, kernel/kernel system calls Few modifications are done regarding user/kernel, kernel/kernel system calls
Facts PaX PaX 24/28 bit stack randomization 24/28 bit stack randomization 16 bit mmap randomization 16 bit mmap randomization Completely implemented in the kernel. Can be implemented transparently and retain binary compatibility with all distributions. Completely implemented in the kernel. Can be implemented transparently and retain binary compatibility with all distributions.
Facts (cont.) PaX PaX Cuts usable address space in half (though this can be changed if it becomes a problem) Cuts usable address space in half (though this can be changed if it becomes a problem) Support for non-executable and read-only kernel pages on i386 Support for non-executable and read-only kernel pages on i386
PaX PaX Per-system call kernel stack randomization Per-system call kernel stack randomization Brk-managed heap randomization Brk-managed heap randomization Ability to enable/disable all features on a per binary basis Ability to enable/disable all features on a per binary basis Annihilates the possibility of exploiting kernel dereferencing pointer vulnerabilities Annihilates the possibility of exploiting kernel dereferencing pointer vulnerabilities Facts (cont.)
PaX PaX Supports the same user space features on i386, alpha, ppc, parisc, sparc, sparc64, amd64, and ia64 Supports the same user space features on i386, alpha, ppc, parisc, sparc, sparc64, amd64, and ia64 Supports a per-page implementation of non- executable pages on ppc Supports a per-page implementation of non- executable pages on ppc Facts (cont.)
PaX – Past Continuous Control Flow Verification Control Flow Verification Basic blocks Basic blocks A basic block is a sequence of statements that is always entered at the beginning and exited at the end, that is: A basic block is a sequence of statements that is always entered at the beginning and exited at the end, that is: The first statement is a LABEL The first statement is a LABEL The last statement is a JUMP or a CJUMP The last statement is a JUMP or a CJUMP There are no other LABELs, JUMPs, or JUMPs There are no other LABELs, JUMPs, or JUMPs APPEL, Andrew W.; Modern Compiler Implementation in ML p. 180
PaX – Past Continuous Control Flow Verification Control Flow Verification Control Flow Graph (CFG) Control Flow Graph (CFG) “In computer science, a control flow graph (CFG) is a representation, using graph notation, of all paths that might be traversed through a program during its execution. Each node in the graph represents a basic block, (…)” “In computer science, a control flow graph (CFG) is a representation, using graph notation, of all paths that might be traversed through a program during its execution. Each node in the graph represents a basic block, (…)”Wikipedia
PaX – Past Continuous Control Flow Verification Control Flow Verification
PaX – Past Continuous Control Flow Verification Control Flow Verification Call graphs Call graphs “A call graph (also known as a call multigraph) is a directed graph that represents calling relationship among subroutines in a computer program” “A call graph (also known as a call multigraph) is a directed graph that represents calling relationship among subroutines in a computer program”Wikipedia
PaX – Past Continuous Control Flow Verification Control Flow Verification
PaX – Past Continuous Control Flow Verification Control Flow Verification Static analysis Static analysis Build call graph for program P Build call graph for program P Build set S of callers Build set S of callers Build set Q of callees Build set Q of callees Build set R of relationships between S and Q, creating magic value for each Build set R of relationships between S and Q, creating magic value for each
PaX – Past Continuous Control Flow Verification Control Flow Verification Code generation Code generation Create proper prologues for every member of S Create proper prologues for every member of S Create proper epilogues for every member of Q Create proper epilogues for every member of Q Magic Values Magic Values Hard to predict by exhaustive search values kept within safe memory regions, they are verified in run-time Hard to predict by exhaustive search values kept within safe memory regions, they are verified in run-time
PaX – Past Continuous Control Flow Verification Control Flow Verificationcallee epilogue:mov register,[esp] cmp [register+1],MAGIC jnz.1 retn.1: jmp esp caller: call callee test eax,MAGIC
PaX – Past Continuous Control Flow Verification: Nondeterminism Control Flow Verification: Nondeterminism Branch tables: run-time environment Branch tables: run-time environment OO virtual methods and function pointers OO virtual methods and function pointers
PaX – Past Continuous Control Flow Verification Control Flow Verification GOT entries GOT entries Made read-only by tweaking the static and the dynamic linker Made read-only by tweaking the static and the dynamic linker.ctors/.dtors.ctors/.dtors Made read-only by modifying the link-editor script Made read-only by modifying the link-editor script
PaX – Past Continuous Control Flow Verification Control Flow Verification Are of a dynamic nature Are of a dynamic nature atexit() handlers atexit() handlers malloc() callbacks malloc() callbacks linuxthread callbacks (atfork() handlers) linuxthread callbacks (atfork() handlers)
PaX – Past Continuous (cont.) Control Flow Verification: Results Control Flow Verification: Results Breaks my attack [3] – brief explanation? – and anything that rely on the following premisses Breaks my attack [3] – brief explanation? – and anything that rely on the following premisses execute existing code out of original program order execute existing code out of original program order execute existing code in original program order with arbitrary data execute existing code in original program order with arbitrary data
PaX – Past Continuous (cont.) Control Flow Verification: Results Control Flow Verification: Results Opens a wide range of possibilities for improving systemic security Opens a wide range of possibilities for improving systemic security Call graph trust relationship ensures that (in most cases) all control flow (including intra-procedural) can’t be broken with a very low performance impact Call graph trust relationship ensures that (in most cases) all control flow (including intra-procedural) can’t be broken with a very low performance impact Call graph trust relationship allows data integrity verification (KERNSEAL) Call graph trust relationship allows data integrity verification (KERNSEAL)
PaX – Past Continuous KERNSEAL KERNSEAL Liveness Analysis Liveness Analysis “We say a variable is live if it holds a value that may be needed in the future, so this analysis is called liveness analysis” “We say a variable is live if it holds a value that may be needed in the future, so this analysis is called liveness analysis” APPEL, Andrew W.; Modern Compiler Implementation in ML p. 211
PaX – Past Continuous KERNSEAL KERNSEAL The set of live variables at line L2 is {b, c}, but the set of live variables at line L1 is only {b} since variable c is updated in line 2. The value of variable a is never used, so the variable is never live. The set of live variables at line L2 is {b, c}, but the set of live variables at line L1 is only {b} since variable c is updated in line 2. The value of variable a is never used, so the variable is never live. L1: b := 3; L2: c := 5; L3: a := b + c; goto L1;
PaX – Past Continuous KERNSEAL KERNSEAL Liveness Analysis: Dataflow equations Liveness Analysis: Dataflow equations “Liveness of variables ‘flows’ around the edges of the control-flow graph; determining the live range of each variable is na example of a dataflow problem” “Liveness of variables ‘flows’ around the edges of the control-flow graph; determining the live range of each variable is na example of a dataflow problem” APPEL, Andrew W.; Modern Compiler Implementation in ML p. 213
PaX – Past Continuous KERNSEAL KERNSEAL Liveness Analysis: Terminology Liveness Analysis: Terminology Out-edges: nodes leading to successor nodes Out-edges: nodes leading to successor nodes In-edges: nodes coming from predecesor nodes In-edges: nodes coming from predecesor nodes pred[n], holding the set of predecessors of node n pred[n], holding the set of predecessors of node n succ[n], holding the set of successors of node n succ[n], holding the set of successors of node n
PaX – Past Continuous KERNSEAL KERNSEAL Liveness Analysis: Terminology Liveness Analysis: Terminology Uses: the set of variables in use at a given node Uses: the set of variables in use at a given node Defs: the set of variables assigned at a given node Defs: the set of variables assigned at a given node
PaX – Past Continuous KERNSEAL KERNSEAL Liveness Analysis: Terminology Liveness Analysis: Terminology Liveness: “A variable is live on an edge if there is a directed path from tha edge to a use of the variable that does not go through any def. A variable is live-in at a node if it is live on any of the in-edges of that node; it is live-out at a node if it is live on any of the out-edges of the node.” Liveness: “A variable is live on an edge if there is a directed path from tha edge to a use of the variable that does not go through any def. A variable is live-in at a node if it is live on any of the in-edges of that node; it is live-out at a node if it is live on any of the out-edges of the node.” APPEL, Andrew W.; Modern Compiler Implementation in ML p. 213
PaX – Past Continuous KERNSEAL KERNSEAL Liveness Analysis: Liveness Analysis: The dataflow equations used for a given basic block s and exiting block f in live variable analysis The dataflow equations used for a given basic block s and exiting block f in live variable analysisWikipedia
PaX – Past Continuous KERNSEAL KERNSEAL Liveness Analysis Liveness Analysis Allows access control of specific code procedures – known a priori – towards sensitive data (kernel data) Allows access control of specific code procedures – known a priori – towards sensitive data (kernel data) Process structures Process structures Object Credentials Object Credentials Kernel Function Pointers Kernel Function Pointers And others And others
PaX – Past Continuous KERNSEAL KERNSEAL Design Design Unreadable memory pages Read-only memory pages Read-write memory pages
PaX – Past Continuous KERNSEAL KERNSEAL Example: protect user credentials info Example: protect user credentials info Perform liveness analysis for deriving specific code blocks that may have legit read/write access to it Perform liveness analysis for deriving specific code blocks that may have legit read/write access to it Set memory properties holding the data structures to read-only Set memory properties holding the data structures to read-only Embed (through instrumentation) write-key procedure to allowing legit code to access the structure Embed (through instrumentation) write-key procedure to allowing legit code to access the structure
PaX – Past Continuous KERNSEAL KERNSEAL Results Results Strengthen of Trusted Computing Base (TCB) Strengthen of Trusted Computing Base (TCB) Defense in Depth: even if compromised, kernel operations towards sensitive memory areas are restricted by nature Defense in Depth: even if compromised, kernel operations towards sensitive memory areas are restricted by nature Provides strong trust-relationship infrastructure to creating several other protection mechanisms in different layers of the kernel as well as of the user space Provides strong trust-relationship infrastructure to creating several other protection mechanisms in different layers of the kernel as well as of the user space
Questions? Thanks!!! contact me at
References [1] [1] [2] [2] [3] [3] [4] March/ html [4] March/ htmlhttp://lists.immunitysec.com/pipermail/dailydave/2007- March/ htmlhttp://lists.immunitysec.com/pipermail/dailydave/2007- March/ html