Fuzzing JavaScript Engines with Aspect-preserving Mutation Soyeon - - PowerPoint PPT Presentation

fuzzing javascript engines with aspect preserving mutation
SMART_READER_LITE
LIVE PREVIEW

Fuzzing JavaScript Engines with Aspect-preserving Mutation Soyeon - - PowerPoint PPT Presentation

Fuzzing JavaScript Engines with Aspect-preserving Mutation Soyeon Park, Wen Xu, Insu Yun, Daehee Jang, Taesoo Kim Everyone uses web browser (+ JS engine) 4,000,000,000 2 New Tab https://gts3.org/ Bank Private Password account data


slide-1
SLIDE 1

Fuzzing JavaScript Engines with Aspect-preserving Mutation

Soyeon Park, Wen Xu, Insu Yun, Daehee Jang, Taesoo Kim

slide-2
SLIDE 2

Everyone uses web browser (+ JS engine)

2

4,000,000,000

slide-3
SLIDE 3

New Tab

https://gts3.org/

S&P’20!

3

Private data Bank account Password

slide-4
SLIDE 4

JS bugs are security-critical

5

2017 2018 2019 2020

( )

9/11 (82%)

slide-5
SLIDE 5

995K

797K

443K

Finding JS bugs is hard

  • Large codebase

6

1M

slide-6
SLIDE 6

8

  • Deep semantic bugs

Parser / Interpreter JIT compiler Executor JS engine

Finding JS bugs is hard

slide-7
SLIDE 7

9 2016 2017 2018 2019 Year 5 10 15 20 25 # of Bugs

JIT-OOB JIT-Type confusion JIT-Memory corruption Parser/Interpreter

  • Deep semantic bugs 1

Finding JS bugs is hard

1 Google Project Zero issue trackers and commits of ChakraCore for security updates by Aug 2019

Simple & shallow bugs Complex & deep bugs

slide-8
SLIDE 8

Motivating example

10

  • Special conditions are necessary to discover new bug from old ones
  • What human hacker is good at
slide-9
SLIDE 9

Motivating example

11

  • Special conditions are necessary to discover new bug from old ones
  • JIT-able condition by for-loop & empty object
slide-10
SLIDE 10

Motivating example

12

  • Special conditions are necessary to discover new bug from old ones
  • “Function” which has side-effect
slide-11
SLIDE 11

Motivating example

13

  • Special conditions are necessary to discover new bug from old ones
  • Instruction order
slide-12
SLIDE 12

Motivating example

14

  • Special conditions are necessary to discover new bug from old ones
  • Newly introduced code
slide-13
SLIDE 13

Aspects

  • Key features that guide to discover new bugs,

which are embedded in the Proof-of-Concept of existing bugs

15

Assign float values to an array and order of the instructions Type confusion

slide-14
SLIDE 14

Aspects

  • Key features that guide to discover new bugs,

which are embedded in the Proof-of-Concept of existing bugs

16

For loop to invoke JIT compiler Assign float values to an array and order of the instructions

slide-15
SLIDE 15

Aspects

  • Key features that guide to discover new bugs,

which are embedded in the Proof-of-Concept of existing bugs

17

For loop to invoke JIT compiler Arrow function to assign object value to the same array Assign float values to an array and order of the instructions

slide-16
SLIDE 16

Ou Our so solu lutio tion:

DIE: Fuzzing JS engine with generation and Aspect-preserving mutation

21

slide-17
SLIDE 17

DIE overview

22

Original Seeds

Preprocessing Input generation Execution Crash! Feedback

Dynamic & Static analysis

Typed-AST

w/ instrumented JS engine Code coverage

JS file

slide-18
SLIDE 18

Preprocessing for typed-AST

23

Original Seeds

Preprocessing Input generation Execution Crash! Feedback

Dynamic & Static analysis

Typed-AST

w/ instrumented JS engine Code coverage

JS file Instrument Dynamic Analysis

Type analysis

NUM NUM ARRAY

while

== a [] 1

NUM NUM IMMUTABL E

Typed-AST Type Information

AST

+

Static Analysis

Pre-Processing

Input generation

slide-19
SLIDE 19

Type Analysis: dynamic analysis

  • Execute instrumented corpus

24

recordType() var n = 3 recordType() var array = new Array(n) recordType()

Corpus

slide-20
SLIDE 20

Type Analysis: dynamic analysis

  • Execute instrumented corpus

25

recordType() var n = 3 recordType() var array = new Array(n) recordType()

Corpus

slide-21
SLIDE 21

Type Analysis: dynamic analysis

  • Execute instrumented corpus

26

recordType() var n = 3 recordType() var array = new Array(n) recordType()

Corpus

n : number

slide-22
SLIDE 22

Type Analysis: dynamic analysis

  • Execute instrumented corpus

27

recordType() var n = 3 recordType() var array = new Array(n) recordType()

Corpus

n : number array: numberArray

slide-23
SLIDE 23

Type Analysis: dynamic analysis

  • Execute instrumented corpus

28

Type Information

recordType() var n = 3 recordType() var array = new Array(n) recordType()

Corpus

n : number n : number array: numberArray

slide-24
SLIDE 24

Type Analysis: static analysis

29

Type Information

while == a [] 1

AST

+

  • Propagate type information from bottom to top with custom rules
slide-25
SLIDE 25

Type Analysis: static analysis

30

Type Information

while == a [] 1

AST

+

while == a [] 1

NUM NUM ARRAY NUM NUM IMMUTABLE

  • Propagate type information from bottom to top with custom rules

Typed-AST

slide-26
SLIDE 26

Input generation

31

Original Seeds

Preprocessing Input generation Execution Crash! Feedback

Dynamic & Static analysis

Typed-AST

w/ instrumented JS engine Code coverage

JS file Mutated Seeds

Generation Engine Mutation Engine

Mutated Typed-AST

Mutate (Aspect-preserving)

NUM ARRAY

while

== a [] .

NUM NUM IMMUTABL E

a [] a

“length”

NUM ARRAY NUM NUM NUM ARRAY

Input Generation

NUM NUM ARRAY

while

== a [] 1

NUM NUM IMMUTABL E

Typed-AST

slide-27
SLIDE 27

Aspect-preserving mutation

  • Type & structure preserving mutation

32

For loop to invoke JIT compiler Arrow function to assign object value to the same array Assign float values to an array and order of the instructions

slide-28
SLIDE 28

Type-preserving mutation

  • Mutate typed-AST node with same typed node

33 Generation Engine

while == a [] 1

Typed-AST

NUM NUM ARRAY NUM NUM IMMUTABLE

Type Information

+

slide-29
SLIDE 29

Type-preserving mutation

  • Mutate typed-AST node with same typed node

34 Generation Engine Mutation Engine

while == a [] 1

Typed-AST

NUM NUM ARRAY NUM NUM IMMUTABLE

a . length a []

NUM typed node

Type Information

+

slide-30
SLIDE 30

Type-preserving mutation

  • Mutate typed-AST node with same typed node

35 Generation Engine Mutation Engine

while == a [] 1

Typed-AST

NUM NUM ARRAY NUM NUM IMMUTABLE

while == a []

Mutated Typed-AST

NUM ARRAY NUM NUM IMMUTABLE

a . length a [] a . length a []

NUM ARRAY NUM NUM NUM typed node

Type Information

+

slide-31
SLIDE 31

Structure-preserving mutation

  • Selectively mutate nodes to avoid breaking control-flow structure

36

while == a [] 1

Typed-AST

NUM NUM ARRAY NUM NUM IMMUTABLE

Mutation Engine

slide-32
SLIDE 32

Structure-preserving mutation

37

while == a [] 1

Typed-AST

NUM NUM ARRAY NUM NUM IMMUTABLE

Mutation Engine

  • Selectively mutate nodes to avoid breaking control-flow structure
slide-33
SLIDE 33

Execution with instrumented JS engine

38

Original Seeds

Crash! Preprocessing Input generation Execution Feedback

Dynamic & Static analysis

Typed-AST

w/ instrumented JS engine Code coverage

JS file Coverage Feedback

Instrumented JS Engines

Execute

Execution/Feedback

Distributed Fuzzing Platform Mutated Seeds

Input generation

slide-34
SLIDE 34

Implementation

  • Core fuzzing engine
  • Type analyzer
  • Dynamic instrumentation tool
  • Generation engine
  • Mutation engine
  • AFL modification
  • Distributed fuzzing harness
  • Coordinator
  • Local agent
  • Crash reporter
  • Total

39

3,677 lines of TypeScript 222 lines of Python 10,545 lines of TypeScript 2,333 lines of TypeScript 453 lines of C 205 lines of TypeScript 1,419 lines of Python and Shell Script 492 lines of Python 19,346 lines of code

slide-35
SLIDE 35

Evaluation

Fuzzing JS engines with DIE in the wild ... and extra information to understand the techniques applied on DIE

40

slide-36
SLIDE 36

Fuzzing JS engines in the wild

  • We ran DIE up to 3 weeks against 3 major JS engines
  • 48 unique bugs in total
  • 39 fixed bug
  • 11 acknowledged CVEs
  • 27K USD bug bounty reward as of now

41

slide-37
SLIDE 37

Evaluation: effectiveness of leveraging aspect

  • DIE found 84 distinct crashes and 28 unique bugs in ChakaCore

42

Preserved aspect Bug Crash Structure & Type 14/28 (50.00%) 40/84 (47.62%) Structure-only 12/28 (42.86%) 32/84 (42.86%) Total 22/28 (92.86%) 72/84 (90.48%)

slide-38
SLIDE 38

Case study: CVE-2019-0990

43

  • corpus: CVE-2018-0777

Generation w/ type information Mutation (type preserving) Mutation (structure preserving)

slide-39
SLIDE 39

Evaluation: aspect preserving

  • Ratio difference of JIT-optimization phase invocation between the

generated inputs and seed files

  • vs DIEt : 1.53x
  • vs CodeAlchemist : 4.29x
  • vs Superion: negligible
  • Mutation-based fuzzer

44

Die Diet Superion CodeAlchemist 25 50 75 100 125 150 175 200 Optimization Invocation Rate (%)

Forward FGPeeps FGBuild Backward CaptureByteCodeRegUse BackEnd DeadStore GlobOpt Etc

DIEt : DIE without structure-preserving (type preserving only)

slide-40
SLIDE 40

Evaluation: validity of generated input

  • Error rate of generated inputs
  • vs Superion: 2.31x
  • vs CodeAlchemist: 2.31x
  • vs jsfunfuzz: 2.42x
  • DIEc produces less error rate than

vanilla

45

Vanilla Diec Die Superion CodeAlchemist jsfunfuzz

10 20 30 40 Error Rate (%) SyntaxError ReferenceError TypeError RangeError

DIEc : DIE without coverage feedback Original corpus

slide-41
SLIDE 41

Evaluation: comparison w/ state-of-the-art fuzzers

  • Number of unique crashes found by DIE vs state-of-the-art fuzzers

for 24 hours

47

JS engine DIE DIEt Superion CodeAlchemist ChakraCore 1.11.10 17 7 3 JavaScriptCore 2.24.2 2 V8 7.7.100 2 1 1 DIEt : DIE without structure-preserving (type preserving only)

slide-42
SLIDE 42

Conclusion

  • DIE is a JS engine fuzzer that preserves the aspects from PoC of

existing bugs achieved by type and structure preserving

  • Discovered 48 unique bugs with 11 CVEs assigned
  • Open sourced: https://github.com/sslab-gatech/DIE

48

slide-43
SLIDE 43

Thank you!

Q & A

49