SafeDispatch Securing C++ Virtual Calls from Memory Corruption Attacks by Jang, Dongseok and Tatlock, Zachary and Lerner, Sorin in NDSS, 2014 Alexander Hefele Fakultät für Informatik Technische Universität München December 16, 2016 Alexander Hefele SafeDispatch December 16, 2016 1 / 17
Outline 1 Introduction 2 SafeDispatch Class Hierarchy Analysis Method Checking Instrumentation Optimizations 3 Alternatives 4 Evaluation 5 Security implications 6 Related work Alexander Hefele SafeDispatch December 16, 2016 2 / 17
Introduction Real World Exploits Most applications are written in C++, not in pure C C++ has more features that are exploitable Not many defense methods available Exploits nowadays focus on these vulnerabilities Alexander Hefele SafeDispatch December 16, 2016 3 / 17
Introduction Dynamic Dispatch in C++ Implemented with vtables First word of C++ object with virtual methods is pointer to its vtable Vtables store one function pointer for each virtual method 00 08 16 24 32 40 vtab ptr attr 1... attr n vptr 1 vptr 2... vptr m Alexander Hefele SafeDispatch December 16, 2016 4 / 17
Introduction Vtable hijacking Can be triggered by many different programming errors Use-after-free Buffer overflow (stack and heap) Type confusion attacks Manipulate vtable pointer Let it point to the vtable of some other object Or even create own vtable Hijack control flow whenever object calls one of its virtual methods Execute existing methods Of other objects In arbitrary order With different parameters Very powerful exploitation technique Alexander Hefele SafeDispatch December 16, 2016 5 / 17
Vtable hijacking example 1 c l a s s S h e l l { 2 p u b l i c : v i r t u a l s t r i n g run ( s t r i n g cmd) {... } 3 } 4 c l a s s Window { 5 p u b l i c : v i r t u a l v o i d d i s p l a y ( s t r i n g s ) {... } 6 } 7 c l a s s MobileWin : p u b l i c Window { 8 p u b l i c : v i r t u a l v o i d d i s p l a y ( s t r i n g s ) {... } 9 } 10 v o i d t a b _ r e q u e s t _ h a n d l e r _ l o o p ( v o i d ) { 11 S h e l l sh = NULL ; 12 Window win = SMALL_SCREEN? new MobileWin ( ) : new Window ( ) ; 13 w h i l e (TRUE) { 14 TabRequest r = recv_tab_request ( ) ; 15 s w i t c h ( r. k i n d ) { 16 c a s e GET_DATE: 17 i f ( sh == NULL) 18 sh = new S h e l l ( ) ; 19 s t r i n g d = sh >run ( " d a t e " ) ; 20 send_tab_response ( r. originating_ tab, d ) ; 21 break ; 22 c a s e DISPLAY_ALERT : 23 win >d i s p l a y ( r. msg ) ; 24 break ; 25 c a s e GET_HTML: 26... 27 d e l e t e win ; // a c c i d e n t a l d e l e t e, win p t r now d a n g l i n g 28... 29 break ; 30 } 31 } 32 } Alexander Hefele SafeDispatch December 16, 2016 6 / 17
Introduction Existing vtable hijacking defenses Either incomplete or don t specifically take advantage of the C++ type system Reference counting is not sufficient Control flow integrity based methods are inefficient Solution: SafeDispatch Check integrity of virtual method calls Compare runtime method implementation with static type of the object Insert checking code at every virtual method call Alexander Hefele SafeDispatch December 16, 2016 7 / 17
SafeDispatch Class Hierarchy Analysis (CHA) General idea Compile-time analysis of class hierarchy Compute mapping from each class and virtual method to the set of valid method implementations Example: Alexander Hefele SafeDispatch December 16, 2016 8 / 17
SafeDispatch Class Hierarchy Analysis (CHA) Downsides Increases compile time Always overestimates the set of valid method implementations Requires all code to be available at compile time Alexander Hefele SafeDispatch December 16, 2016 9 / 17
SafeDispatch Method Checking Instrumentation Overview Call special check-function before every virtual method call check-function ensures that virtual method is in set computed by the CHA Data Structures Array of sets Every element of array corresponds to one class and one method Sets are unordered arrays of valid pointers to method addresses check-call requires array lookup and linear search Average set size is very small (1.44) Alexander Hefele SafeDispatch December 16, 2016 10 / 17
SafeDispatch Optimizations Partially inline check-function calls based on profiling information Run program with one input and measure method calls Inline most frequent method calls in order of frequency Devirtualization Possible if there is only one single valid method implementation Completely replace the vtable lookup for that method Low-level optimizations to improve branch prediction Don t call superclass method, but the method of the child class Set up the call arguments before the check which method to take to prevent code duplication Alexander Hefele SafeDispatch December 16, 2016 11 / 17
Alternatives Background: the this-pointer Needed for multiple inheritance Offset of data fields of each inherited class is stored in vtable Not protected by our previous approach Vtable checking Verify vtable pointer instead of function pointer at each method call Basis: modified CHA Replace check-function by vt_check-function Called before method implementation lookup Consequences Higher security guarantee than method checking Higher runtime overhead Number of valid vtables number of valid method implementations Alexander Hefele SafeDispatch December 16, 2016 12 / 17
Alternatives Background: Method pointers 1 c l a s s A { p u b l i c : v i r t u a l v o i d f o o ( i n t ) {... } } 2 c l a s s B : A { p u b l i c : v i r t u a l v o i d f o o ( i n t ) {... } } 3 4 v o i d (A : : f ) ( i n t ) = &A : : f o o ; 5 A a = new A( ) ; 6 ( a > f ) ( 5 ) ; 7 a = new B( ) ; 8 ( a > f ) ( 5 ) ; Method pointers store vtable index instead of concrete address Method pointer protection Very expensive with method checking approach With vtable checking: simply add condition that index is in range Hybrid approach Method checking at traditional call sites Vtable checking at method pointer call sites Alexander Hefele SafeDispatch December 16, 2016 13 / 17
Evaluation Testing Conditions Target: Google Chromium Benchmarks: JavaScript and HTML performance suits Runtime Overhead: 2.1% for the hybrid approach Memory Overhead: 7% for the hybrid approach Alexander Hefele SafeDispatch December 16, 2016 14 / 17
Security implications Guarantees Every virtual method call invokes a valid implementation of that method Cannot accidentally be nullified by a programming error Protection against all vtable hijacking attacks Protection against accidental illegal typecasts by the programmer SafeDispatch is always safe to apply Limitations Attacker could still invoke a method implementation of a child class Does not prevent corrupting arbitrary function pointer values Dynamically loaded libraries (not compiled with SafeDispatch) are not protected Requires CHA on the entire program Security tradeoff for using method checking over vtable checking Alexander Hefele SafeDispatch December 16, 2016 15 / 17
Related work Other protection mechanisms Reference counting Only protects use-after-free errors Reference counts are also stored on the heap Control Flow Integrity Encompasses more than just dynamic dispatch Generally has higher overhead GCC VTV Only uses vtable checking instead of method checking Supports separate compilation Alexander Hefele SafeDispatch December 16, 2016 16 / 17
Thank you for your attention! Questions? Source: Jang, Dongseok and Tatlock, Zachary and Lerner, Sorin. SafeDispatch: Securing C++ Virtual Calls from Memory Corruption Attacks. In NDSS, 2014. Alexander Hefele SafeDispatch December 16, 2016 17 / 17