Securing C++ Virtual Function Calls and Preventing Memory Corruption Attacks

safedispatch securing c virtual function calls n.w
1 / 34
Embed
Share

Learn how virtual function calls are vulnerable to memory corruption attacks like control flow hijacking and vtable hijacking, and discover methods to prevent such vulnerabilities through code instrumentation and other techniques.

  • C++
  • Security
  • Virtual Functions
  • Memory Corruption
  • Hijacking

Uploaded on | 1 Views


Download Presentation

Please find below an Image/Link to download the presentation.

The content on the website is provided AS IS for your information and personal use only. It may not be sold, licensed, or shared on other websites without obtaining consent from the author. If you encounter any issues during the download, it is possible that the publisher has removed the file from their server.

You are allowed to download the files provided on this website for personal or commercial use, subject to the condition that they are used lawfully. All files are the property of their respective owners.

The content on the website is provided AS IS for your information and personal use only. It may not be sold, licensed, or shared on other websites without obtaining consent from the author.

E N D

Presentation Transcript


  1. SafeDispatch Securing C++ Virtual Function Calls from Memory Corruption Attacks Dongseok Jang Zachary Tatlock UC San Diego Sorin Lerner UC San Diego University of Washington

  2. Control Flow Hijacking Lead Program to Jump to Unexpected Code That does what attacker wants Example: Stack Buffer Overflow Attacks Well studied and hard to be critical by itself New Frontier : Vtable Hijacking

  3. Vtable Pointers Mechanism for Virtual Functions x class C { virtual int foo(); virtual int bar(); int fld; }; ... C *x = new C(); foo s impl vptr fld foo bar bar s impl vtable heap obj

  4. Vtable Pointers Virtual Call : 2-Step Dereferencing for Callee x->foo(); x foo s impl vptr = *((FPTR**)x); f = *(vptr + 0); f(x); vptr fld foo bar bar s impl vtable heap obj

  5. Vtable Hijacking Arbitrary Code x->foo(); x fake vtable foo s impl vptr = *((FPTR**)x); f = *(vptr + 0); f(x); bad fld foo bar bar s impl vtable heap obj

  6. Vtable Hijacking via Use-after-Free Use Corrupted Data for x s vptr x x C *x = new C(); x->foo(); delete x; // forget x = NULL; ... D *y = new D(); y->buf[0] = input(); ... x->foo(); buf[0] corrupted C::vptr x s fld buf[1] buf[1] y candidate for reallocation

  7. Vtable Hijacking: Real Case Vtable Hijacking of Chrome via Use-after-Free Pinkie Pie s demonstration at Pwn2Own Used to trigger ROP for sandbox escaping of Chrome Found in IE, Firefox, Chrome

  8. How to Prevent Vtable Hijacking? With Accuracy & Low Overhead?

  9. Code Instrumentation C *x = ... Check(x); x->foo();

  10. Code Instrumentation C *x = ... ASSERT(VPTR(x) Valid(C)); x->foo(); Valid(C) = { vptr of C or C s subclasses } Obtained by class hierarchy analysis (CHA)

  11. Code Instrumentation C *x = ... ASSERT(VPTR(x) Valid(C)); x->foo(); Simple Implementation Can Be Slow Involved data structure lookup/function calls

  12. Inlining Optimization C *x = ... ASSERT(VPTR(x) Valid(C)); x->foo(); vptr = *((FPTR**)x); f = *(vptr + 0); f(x); x->foo()

  13. Inlining Optimization C *x = ... ASSERT(VPTR(x) Valid(C)); vptr = *((FPTR**)x); f = *(vptr + 0); f(x); // ASSERT(vptr Valid(C));

  14. Inlining Optimization C *x = ... ASSERT(VPTR(x) Valid(C)); vptr = *((FPTR**)x); ASSERT(vptr Valid(C)); f = *(vptr + 0); f(x); // // ASSERT(vptr {C::vptr, D::vptr}); Say that C has only one subclass D Specialization of Checks

  15. Inlining Optimization C *x = ... ASSERT(VPTR(x) Valid(C)); vptr = *((FPTR**)x); ASSERT(vptr Valid(C)); ASSERT(vptr {C::vptr, D::vptr}); f = *(vptr + 0); f(x); // // // SAFE:

  16. Inlining Optimization C *x = ... ASSERT(VPTR(x) Valid(C)); vptr = *((FPTR**)x); ASSERT(vptr Valid(C)); ASSERT(vptr {C::vptr, D::vptr}); if (vptr == C::vptr) goto SAFE; if (vptr == D::vptr) goto SAFE; exit(-1); // // // SAFE: f = *(vptr + 0); f(x);

  17. Inlining Optimization C *x = ... ASSERT(VPTR(x) Valid(C)); vptr = *((FPTR**)x); ASSERT(vptr Valid(C)); ASSERT(vptr {C::vptr, D::vptr}); if (vptr == C::vptr) goto SAFE; if (vptr == D::vptr) goto SAFE; exit(-1); // Profile-guided Inlining How to Order Inlined Checked? // // SAFE: f = *(vptr + 0); f(x);

  18. Method Pointer Checking C *x = ... vptr = *((FPTR**)x); ASSERT(vptr {C::vptr, D::vptr}); f = *(vptr + 0); f(x) x->foo()

  19. Method Pointer Checking C *x = ... vptr = *((FPTR**)x); ASSERT(vptr {C::vptr, D::vptr}); f = *(vptr + 0); f(x) ASSERT(f ValidM(C,foo)); // Checking Callee Before It Is Called Provides same security as vtable checking

  20. Method Pointer Checking C *x = ... vptr = *((FPTR**)x); ASSERT(vptr {C::vptr, D::vptr}); f = *(vptr + 0); ASSERT(f ValidM(C,foo)); ASSERT(f {C::foo}); // // f(x) Say that C has one subclass D and D doesn t override C::foo() Save Checks for Shared Methods

  21. Member Pointers in C++ A *x = ... // m: index into a vtable // x->*m can be any methods of A (x->*m)() Say that A has 1000 methods Up to 1000 method ptr checks! Vtable Checking Can Be Faster

  22. Method Pointer Checking Fewer Checks for Usual Virtual Calls More Checks for Member Pointer Calls

  23. Hybrid Checking Method Checking for Usual Virtual Calls Vtable Checking for Member Pointer Calls

  24. Tamper Resistance Inserted Checks in Read-Only Memory Checking Data in Read-Only Memory

  25. Performance: Benchmark Chromium Browser Realistic : 3 millions of C++/C LOC Popular target of vtable hijacking Running On JS, HTML5 Benchmark

  26. Performance Unoptimized (Avg: 23%) 35 Runtime Overhead(%) 30 25 20 15 10 5 0 JS HTML

  27. Performance Profile-Guided Inlining (Avg: 6%) 35 Runtime Overhead(%) 0 JS 35 Runtime Overhead(%) 30 30 25 25 20 20 15 15 10 10 5 5 0 JS HTML HTML

  28. Performance Inlined Method Ptr Checking (3%) 35 Runtime Overhead(%) 0 JS JS 35 35 Runtime Overhead(%) Runtime Overhead(%) 30 30 30 25 25 25 20 20 20 15 15 15 10 10 10 5 5 5 0 0 JS HTML HTML HTML

  29. Performance Hybrid Checking (Avg: 2%) 35 Runtime Overhead(%) 30 25 20 15 10 5 0 JS HTML

  30. Code Size Overhead 7% Code Size Increase 8.3 MB out of 119 MB Checking Data + Inlined Checks

  31. Future Work Separate Compilation Link-time CHA / inlining Dynamic Link Library Runtime update of checking data

  32. Summary Vtable Hijacking Often happening in web browsers Compiler-based Approach Code Instrumentation / static Analysis Realistic Overhead Careful compiler optimizations

  33. Thank you! http://goto.ucsd.edu/safedispatch

More Related Content