Type Casting Verification: Stopping an Emerging Attack Vector - - PowerPoint PPT Presentation

type casting verification stopping an emerging attack
SMART_READER_LITE
LIVE PREVIEW

Type Casting Verification: Stopping an Emerging Attack Vector - - PowerPoint PPT Presentation

Type Casting Verification: Stopping an Emerging Attack Vector Byoungyoung Lee, Chengyu Song, Taesoo Kim, and Wenke Lee Georgia Institute of Technology 1 Vulnerability Trends Microsoft vulnerability trends (2013) Use-after-free Stack


slide-1
SLIDE 1

Type Casting Verification: Stopping an Emerging Attack Vector

Byoungyoung Lee, Chengyu Song, Taesoo Kim, and Wenke Lee Georgia Institute of Technology

1

slide-2
SLIDE 2

Vulnerability Trends

2

Microsoft vulnerability trends (2013)

Use-after-free Stack overflow Heap overflow Bad casting (or type confusion)

slide-3
SLIDE 3

Microsoft vulnerability trends (2013)

Stack Overflows

# of Stack overflows is decreasing

slide-4
SLIDE 4

Microsoft vulnerability trends (2013)

# of Use-after-free is increasing  Preventing Use-after-free with Dangling Pointers Nullification [NDSS ’15]

Use-After-Free

slide-5
SLIDE 5

5

Bad-casting

Bad-casting (or type confusion) is still not solved.

slide-6
SLIDE 6

Type Conversions in C++

  • static_cast

– Compile-time conversions – Fast: no extra verification in run-time – No information on actually allocated types in runtime.

  • dynamic_cast

– Run-time conversions – Requires Runtime Type Information (RTTI) – Slow: Extra verification by parsing RTTI – Typically prohibited in performance critical applications

6

slide-7
SLIDE 7

Upcasting and Downcasting

  • Upcasting

– From a derived class to its parent class

  • Downcasting

– From a parent class to one of its derived classes

7

slide-8
SLIDE 8

Upcasting and Downcasting

  • Upcasting

– From a derived class to its parent class

  • Downcasting

– From a parent class to one of its derived classes

7

Element HTMLElement SVGElement

slide-9
SLIDE 9

Upcasting and Downcasting

  • Upcasting

– From a derived class to its parent class

  • Downcasting

– From a parent class to one of its derived classes Upcasting

7

Element HTMLElement SVGElement

slide-10
SLIDE 10

Upcasting and Downcasting

  • Upcasting

– From a derived class to its parent class

  • Downcasting

– From a parent class to one of its derived classes Downcasting Upcasting

7

Element HTMLElement SVGElement

slide-11
SLIDE 11

Upcasting and Downcasting

  • Upcasting

– From a derived class to its parent class

  • Downcasting

– From a parent class to one of its derived classes Downcasting Upcasting

Upcasting is always safe, but downcasting is not!

7

Element HTMLElement SVGElement

slide-12
SLIDE 12

Downcasting is not always safe!

class P { virtual ~P() {} int m_P; }; class D: public P { virtual ~D() {} int m_D; };

8

slide-13
SLIDE 13

Downcasting is not always safe!

vftptr for P int m_P

class P { virtual ~P() {} int m_P; }; class D: public P { virtual ~D() {} int m_D; };

Access scope of P*

8

slide-14
SLIDE 14

Downcasting is not always safe!

vftptr for P int m_P vftptr for D int m_P int m_D

class P { virtual ~P() {} int m_P; }; class D: public P { virtual ~D() {} int m_D; };

Access scope of P* Access scope of D*

8

slide-15
SLIDE 15

Downcasting can be Bad-casting

P *pS = new P(); D *pD = static_cast<D*>(pS); pD->m_D;

9

slide-16
SLIDE 16

Downcasting can be Bad-casting

P *pS = new P(); D *pD = static_cast<D*>(pS); pD->m_D;

Bad-casting occurs: D is not a sub-object of P  Undefined behavior

D *pD = static_cast<D*>(pS);

9

slide-17
SLIDE 17

Downcasting can be Bad-casting

P *pS = new P(); D *pD = static_cast<D*>(pS); pD->m_D; pD->m_D;

Memory corruptions

9

slide-18
SLIDE 18

Downcasting can be Bad-casting

P *pS = new P(); D *pD = static_cast<D*>(pS); pD->m_D; pD->m_D;

Memory corruptions

9

vftptr for P int m_P

slide-19
SLIDE 19

Downcasting can be Bad-casting

P *pS = new P(); D *pD = static_cast<D*>(pS); pD->m_D; pD->m_D;

Memory corruptions

9

vftptr for P int m_P

&(pD->m_D)

slide-20
SLIDE 20

Downcasting can be Bad-casting

P *pS = new P(); D *pD = static_cast<D*>(pS); pD->m_D; pD->m_D;

Memory corruptions

9

vftptr for P int m_P int m_D

&(pD->m_D)

slide-21
SLIDE 21

Downcasting can be Bad-casting

P *pS = new P(); D *pD = static_cast<D*>(pS); pD->m_D; pD->m_D;

Memory corruptions

9

vftptr for P int m_P int m_D

&(pD->m_D)

slide-22
SLIDE 22

Real-world Exploits on Bad-casting

Element SVGElement HTMLElement

  • CVE-2013-0912

– A bad-casting vulnerability in Chrome – Used in 2013 Pwn2Own

HTMLUnknownElement ContainerNode

10

slide-23
SLIDE 23

Real-world Exploits on Bad-casting

Element SVGElement HTMLElement

  • CVE-2013-0912

– A bad-casting vulnerability in Chrome – Used in 2013 Pwn2Own

HTMLUnknownElement ContainerNode

  • 1. Allocated

10

slide-24
SLIDE 24

Real-world Exploits on Bad-casting

Element SVGElement HTMLElement

  • CVE-2013-0912

– A bad-casting vulnerability in Chrome – Used in 2013 Pwn2Own

HTMLUnknownElement ContainerNode

  • 2. Upcasting
  • 1. Allocated

10

slide-25
SLIDE 25

Real-world Exploits on Bad-casting

Element SVGElement HTMLElement

  • CVE-2013-0912

– A bad-casting vulnerability in Chrome – Used in 2013 Pwn2Own

HTMLUnknownElement ContainerNode

  • 2. Upcasting
  • 3. Downcasting
  • 1. Allocated

10

slide-26
SLIDE 26

Real-world Exploits on Bad-casting

Element SVGElement HTMLElement

  • CVE-2013-0912

– A bad-casting vulnerability in Chrome – Used in 2013 Pwn2Own

HTMLUnknownElement ContainerNode

  • 2. Upcasting
  • 3. Downcasting
  • 1. Allocated

96 bytes 160 bytes

10

slide-27
SLIDE 27

Element SVGElement HTMLElement ContainerNode

11

Real-world Exploits on Bad-casting

PseudoElement Node EventTarget TreeShared<Node> ScriptWrapperble NoBaseWillBeGarbageCollectedFinalized<> VTTElement VTTElement LabelableElement HtmlTableElement HTMLRubyElement HTMLFontElement HTMLMenuElement HTMLLabelElement

HTMLUnknownElement

57 classes!

slide-28
SLIDE 28

Element SVGElement HTMLElement ContainerNode

11

Real-world Exploits on Bad-casting

PseudoElement Node EventTarget TreeShared<Node> ScriptWrapperble NoBaseWillBeGarbageCollectedFinalized<> VTTElement VTTElement LabelableElement HtmlTableElement HTMLRubyElement HTMLFontElement HTMLMenuElement HTMLLabelElement

HTMLUnknownElement

57 classes!

Very complex class hierarchies  Error-prone type casting operations

slide-29
SLIDE 29

Existing Solutions and Challenges

  • Replace all static_cast into dynamic_cast
  • dynamic_cast on a polymorphic class (with RTTI)

– A pointer points to a virtual function table pointer – Traversing a virtual function table leads to RTTI

vftptr …

ptr

&std::type_info 1st virtual function Offset to the top

A class name

12

slide-30
SLIDE 30

Existing Solutions and Challenges

  • dynamic_cast on a non-polymorphic class

– A pointer points to the first member variable – Simply traversing such a variable leads to a runtime crash

… ...

ptr

13

slide-31
SLIDE 31

Existing Solutions and Challenges

  • dynamic_cast on a non-polymorphic class

– A pointer points to the first member variable – Simply traversing such a variable leads to a runtime crash

… ...

ptr C++ supports no reliable methods to resolve whether a pointer points to polymorphic or non-polymorphic classes.

13

slide-32
SLIDE 32

Existing Solutions and Challenges

  • dynamic_cast on a non-polymorphic class

– A pointer points to the first member variable – Simply traversing such a variable leads to a runtime crash

… ...

ptr C++ supports no reliable methods to resolve whether a pointer points to polymorphic or non-polymorphic classes.

13

Previous solutions including Undefined Behavior Sanitizer relies on blacklists.

slide-33
SLIDE 33

CaVer: CastVerifier

  • CaVer: CastVerifier

– A bad-casting detection tool

  • Design goals

– Easy-to-deploy: no blacklists – Reasonable runtime performance

14

slide-34
SLIDE 34

CaVer Overview

15

Emit THTable Instrumentation Source code

Compile

slide-35
SLIDE 35

CaVer Overview

15

Emit THTable Instrumentation CaVer Runtime Source code

Compile Link

slide-36
SLIDE 36

CaVer Overview

15

Emit THTable Instrumentation CaVer Runtime Source code

Compile Link Secured executable

slide-37
SLIDE 37

static_cast<D*>(ptr);

Technical Goal of CaVer

16

P *ptr = new P;

slide-38
SLIDE 38

static_cast<D*>(ptr);

Technical Goal of CaVer

16

P *ptr = new P;

Allocated

slide-39
SLIDE 39

static_cast<D*>(ptr);

Technical Goal of CaVer

16

P *ptr = new P;

Allocated To be casted

slide-40
SLIDE 40

static_cast<D*>(ptr);

Technical Goal of CaVer

16

P *ptr = new P;

Object (P)

ptr

Allocated To be casted

slide-41
SLIDE 41

static_cast<D*>(ptr);

Technical Goal of CaVer

16

P *ptr = new P;

Object (P)

ptr

Allocated To be casted

  • Q. What are the class

relationships b/w P and D?  THTable

slide-42
SLIDE 42

static_cast<D*>(ptr);

Technical Goal of CaVer

16

P *ptr = new P;

Object (P)

ptr

Allocated To be casted

  • Q. Is ptr points to P or D?

 Runtime type tracing

  • Q. What are the class

relationships b/w P and D?  THTable

slide-43
SLIDE 43

Type Hierarchy Table (THTable)

17

hash(“P”) hash(“D”) … … hash(“P”)

THTable (P) THTable (D)

  • A set of all legitimate classes to be converted

– Class names are hashed for fast comparison – Hierarchies are unrolled to avoid recursive traversal

slide-44
SLIDE 44

Type Hierarchy Table (THTable)

17

hash(“P”) hash(“D”) … … hash(“P”)

THTable (P) THTable (D)

  • A set of all legitimate classes to be converted

– Class names are hashed for fast comparison – Hierarchies are unrolled to avoid recursive traversal Hashed class names

slide-45
SLIDE 45

Type Hierarchy Table (THTable)

17

hash(“P”) hash(“D”) … … hash(“P”)

THTable (P) THTable (D)

  • A set of all legitimate classes to be converted

– Class names are hashed for fast comparison – Hierarchies are unrolled to avoid recursive traversal Unrolled linearly

slide-46
SLIDE 46

Runtime Type Tracing

18

P *ptr = new P; P *ptr = new P; trace(ptr, &THTable(P));

slide-47
SLIDE 47

Runtime Type Tracing

18

P *ptr = new P;

Object (P)

ptr P *ptr = new P; trace(ptr, &THTable(P)); hash(“P”) …

THTable (P)

slide-48
SLIDE 48

Runtime Type Tracing

18

P *ptr = new P;

Object (P)

ptr P *ptr = new P; trace(ptr, &THTable(P)); hash(“P”) …

THTable (P) &THTable(P)

slide-49
SLIDE 49

Runtime Type Tracing

18

P *ptr = new P;

Object (P)

ptr P *ptr = new P; trace(ptr, &THTable(P)); hash(“P”) …

THTable (P) &THTable(P) Maintain an internal mapping from objects to metadata Heap: Alignment based direct mapping Stack: Per-thread red-black tree Global : Per-process red-black tree

slide-50
SLIDE 50

Runtime Type Tracing

18

P *ptr = new P;

Object (P)

ptr P *ptr = new P; trace(ptr, &THTable(P)); hash(“P”) …

THTable (P) &THTable(P) Decoupled metadata  Overcome RTTI’s limitation

slide-51
SLIDE 51

Runtime Type Verification

19

static_cast<D*>(ptr);

To be casted

slide-52
SLIDE 52

Runtime Type Verification

19

Object (P)

ptr hash(“P”) …

THTable (P) &THTable(P)

static_cast<D*>(ptr);

To be casted

slide-53
SLIDE 53

Runtime Type Verification

19

Object (P)

ptr hash(“P”) …

THTable (P) &THTable(P)

static_cast<D*>(ptr);

To be casted

  • 1. Locate metadata associated

with the object

slide-54
SLIDE 54

Runtime Type Verification

19

Object (P)

ptr hash(“P”) …

THTable (P) &THTable(P)

static_cast<D*>(ptr);

To be casted

  • 2. Locate associated THTable
slide-55
SLIDE 55

Runtime Type Verification

19

Object (P)

ptr hash(“P”) …

THTable (P) &THTable(P)

static_cast<D*>(ptr);

To be casted

  • 3. Enumerate THTable

and check if hash(“D”) exists.

slide-56
SLIDE 56

Runtime Type Verification

19

Object (P)

ptr hash(“P”) …

THTable (P) &THTable(P)

static_cast<D*>(ptr);

To be casted

THTable(P) does not have D  Bad-casting!

slide-57
SLIDE 57

Performance Optimization

  • Selective object tracing

– Not all objects are involved in downcasting – Statically identify such objects, and skip tracing them

  • Reusing verification results

– A verification process has to be the same for same class – A verification result is cached for reuses

20

slide-58
SLIDE 58

Implementation

  • Based on LLVM Compiler suites

–Added 3,540 lines of C++ code

  • Currently support Linux x86-64
  • CaVer can be activated with one extra compiler flag

21

slide-59
SLIDE 59

Evaluation

  • How much efforts are required to deploy CaVer?
  • How effective is CaVer in detecting bad-casting?
  • What is the overall runtime overhead of CaVer?

22

slide-60
SLIDE 60

Deployment Efforts

  • Build configuration changes

– 21 and 10 lines were changed in Chromium and Firefox – No blacklists are required

  • CaVer successfully

– Build both browsers – Run both browsers without runtime crashes

23

slide-61
SLIDE 61

CaVer Report Example

24

== CaVer : Bad-casting detected @SVGViewSpec.cpp:87:12 Casting an object of “blink::HTMLUnknownElement” from “blink::Element” to “blink::SVGElement” Pointer 0x60c000008280 Alloc base 0x60c000008280 Offset 0x000000000000 THTable 0x7f7963aa20d0 #1 0x7f795d76f1a4 in viewTarget SVGViewSpec.cpp:87 #2 0x7f795d939d1c in viewTargetAttribute V8SVGViewSpec.cpp:56 ...

slide-62
SLIDE 62

CaVer Report Example

24

== CaVer : Bad-casting detected @SVGViewSpec.cpp:87:12 Casting an object of “blink::HTMLUnknownElement” from “blink::Element” to “blink::SVGElement” Pointer 0x60c000008280 Alloc base 0x60c000008280 Offset 0x000000000000 THTable 0x7f7963aa20d0 #1 0x7f795d76f1a4 in viewTarget SVGViewSpec.cpp:87 #2 0x7f795d939d1c in viewTargetAttribute V8SVGViewSpec.cpp:56 ...

Detailed casting information

slide-63
SLIDE 63

CaVer Report Example

24

== CaVer : Bad-casting detected @SVGViewSpec.cpp:87:12 Casting an object of “blink::HTMLUnknownElement” from “blink::Element” to “blink::SVGElement” Pointer 0x60c000008280 Alloc base 0x60c000008280 Offset 0x000000000000 THTable 0x7f7963aa20d0 #1 0x7f795d76f1a4 in viewTarget SVGViewSpec.cpp:87 #2 0x7f795d939d1c in viewTargetAttribute V8SVGViewSpec.cpp:56 ...

Detailed casting information Runtime call stacks

slide-64
SLIDE 64

New vulnerabilities

  • CaVer discovered 11 new vulnerabilities

– 2 cases in Firefox (won bug bounty awards) – 9 cases in GNU libstdc++ – All reported to and fixed by vendors

25

slide-65
SLIDE 65

Runtime Overhead

26

0% 20% 40% 60% 80% 100% 120% 140% Octane SunSpider Dromaeo-JS Dromaeo-DOM

Chromium Firefox

On average, Chromium: 7.6% Firefox: 64.6%

slide-66
SLIDE 66

Applications of CaVer

  • A back-end bug detection tool
  • A runtime attack mitigation tool

– Limitations of previous mitigations techniques

  • Focusing on certain attack methods

–e.g., CFI or ROP techniques

  • Not effective if an exploit relies on other attack

methods –e.g., non-control data attack – CaVer tackles the root cause of bad-casintg.

27

slide-67
SLIDE 67

Conclusions

  • Proposed CaVer, a new runtime bad-casting

detection mechanism

  • Discovered 11 new bad-casting vulnerabilities in

Firefox and libstdc++

28

slide-68
SLIDE 68

Thank you!

29