Data-Oriented Programming On the Expressiveness of Non-Control Data - - PowerPoint PPT Presentation

data oriented programming
SMART_READER_LITE
LIVE PREVIEW

Data-Oriented Programming On the Expressiveness of Non-Control Data - - PowerPoint PPT Presentation

Data-Oriented Programming On the Expressiveness of Non-Control Data Attacks Hong Hu , Shweta Shinde, Sendroiu Adrian, Zheng Leong Chua, Prateek Saxena, Zhenkai Liang Department of Computer Science National University of Singapore Control


slide-1
SLIDE 1

Data-Oriented Programming

On the Expressiveness of Non-Control Data Attacks

Hong Hu, Shweta Shinde, Sendroiu Adrian, Zheng Leong Chua, Prateek Saxena, Zhenkai Liang Department of Computer Science National University of Singapore

slide-2
SLIDE 2

Control Attacks are Getting Harder

2

slide-3
SLIDE 3

Control Attacks are Getting Harder

3

Memory space Code Data CFG

slide-4
SLIDE 4

Control Attacks are Getting Harder

  • Code injection

4

Memory space Code Data CFG

slide-5
SLIDE 5

Control Attacks are Getting Harder

  • Code injection

5

Memory space Code Data Data w/ DEP

Data Execution Prevention

CFG

slide-6
SLIDE 6

Control Attacks are Getting Harder

  • Code injection
  • Code reuse

– return-to-libc – return-oriented programming (ROP)

6

Memory space Code Data Data w/ DEP

Data Execution Prevention

CFG

slide-7
SLIDE 7

Control Attacks are Getting Harder

  • Code injection
  • Code reuse

– return-to-libc – return-oriented programming (ROP)

7

Memory space Code Data Data w/ DEP

Data Execution Prevention Control Flow Integrity

CFG w/ CFI

slide-8
SLIDE 8

A New Attack Class

  • Assume: conform to CFI & DEP

8

Memory space Code Data w/ DEP CFG w/ CFI

slide-9
SLIDE 9

A New Attack Class

  • Assume: conform to CFI & DEP
  • Attackers’ capability on arbitrary vul. programs?

9

Memory space Code Data w/ DEP CFG

Nothing Turing-complete Specific computation

w/ CFI

slide-10
SLIDE 10

Non-Control Data Attacks

10

  • Corrupt/leak several bytes of security-critical data
slide-11
SLIDE 11

Non-Control Data Attacks

11

  • Corrupt/leak several bytes of security-critical data

//set root privilege * seteuid(0); ...... //set normal user privilege seteuid(pw->pw_uid); //execute user’s command //offset depends on IE version + safemode = *(DWORD *) (jsobj + offset); if(safemode & 0xB == 0) { Turn_on_God_Mode(); }

+ Yang Yu. Write Once, Pwn Anywhere. In Black Hat USA 2014 * Shuo Chen, Jun Xu, Emre C. Sezer, Prachi Gauriar, and Ravishankar K. Iyer. Non-Control-Data Attacks Are Realistic Threats. In USENIX 2005.

slide-12
SLIDE 12

Non-Control Data Attacks

12

  • Special cases relying on particular data/functions

– user id, safemode, private key, etc – interpreter – printf() (with “%n”), etc

//set root privilege * seteuid(0); ...... //set normal user privilege seteuid(pw->pw_uid); //execute user’s command //offset depends on IE version + safemode = *(DWORD *) (jsobj + offset); if(safemode & 0xB == 0) { Turn_on_God_Mode(); }

+ Yang Yu. Write Once, Pwn Anywhere. In Black Hat USA 2014 * Shuo Chen, Jun Xu, Emre C. Sezer, Prachi Gauriar, and Ravishankar K. Iyer. Non-Control-Data Attacks Are Realistic Threats. In USENIX 2005.

  • Corrupt/leak several bytes of security-critical data

Nothing Turing-complete Specific computation

slide-13
SLIDE 13

Contributions

13

  • Non-control data attacks can be Turing-complete
slide-14
SLIDE 14

Contributions

14

  • Non-control data attacks can be Turing-complete
  • Data-Oriented Programming (DOP)

– build expressive non-control data attacks – independent of any specific data / functions

slide-15
SLIDE 15

Contributions

15

  • Non-control data attacks can be Turing-complete
  • Data-Oriented Programming (DOP)

– build expressive non-control data attacks – independent of any specific data / functions

  • DOP builds attacks on real-world programs

– bypass ASLR w/o address leakage – simulate a network bot – enable code injection

slide-16
SLIDE 16

1 struct server{int *cur_max, total, typ;} *srv; 2 int quota = MAXCONN; int *size, *type; 3 char buf[MAXLEN]; 4 size = &buf[8]; type = &buf[12] 5 ... 6 while (quota--) { 7 readData(sockfd, buf); // stack bof 8 if(*type == NONE ) break; 9 if(*type == STREAM) 10 *size = *(srv->cur_max); 11 else { 12 srv->typ = *type; 13 srv->total += *size; 14 } //...(following code skipped)... 15 }

Motivating Example

16

Vulnerable Program

slide-17
SLIDE 17

1 struct server{int *cur_max, total, typ;} *srv; 2 int quota = MAXCONN; int *size, *type; 3 char buf[MAXLEN]; 4 size = &buf[8]; type = &buf[12] 5 ... 6 while (quota--) { 7 readData(sockfd, buf); // stack bof 8 if(*type == NONE ) break; 9 if(*type == STREAM) 10 *size = *(srv->cur_max); 11 else { 12 srv->typ = *type; 13 srv->total += *size; 14 } //...(following code skipped)... 15 }

Motivating Example

17

Vulnerable Program

slide-18
SLIDE 18

1 struct server{int *cur_max, total, typ;} *srv; 2 int quota = MAXCONN; int *size, *type; 3 char buf[MAXLEN]; 4 size = &buf[8]; type = &buf[12] 5 ... 6 while (quota--) { 7 readData(sockfd, buf); // stack bof 8 if(*type == NONE ) break; 9 if(*type == STREAM) 10 *size = *(srv->cur_max); 11 else { 12 srv->typ = *type; 13 srv->total += *size; 14 } //...(following code skipped)... 15 }

Motivating Example

18

Vulnerable Program

slide-19
SLIDE 19

1 struct server{int *cur_max, total, typ;} *srv; 2 int quota = MAXCONN; int *size, *type; 3 char buf[MAXLEN]; 4 size = &buf[8]; type = &buf[12] 5 ... 6 while (quota--) { 7 readData(sockfd, buf); // stack bof 8 if(*type == NONE ) break; 9 if(*type == STREAM) 10 *size = *(srv->cur_max); 11 else { 12 srv->typ = *type; 13 srv->total += *size; 14 } //...(following code skipped)... 15 }

Motivating Example

19

1 struct Obj {struct Obj *next; int prop;} 2 3 void updateList(struct Obj *list, int addend){ 4 for(; list != NULL; list = list->next) 5 list->prop += addend; 6 }

Vulnerable Program Malicious Computation

slide-20
SLIDE 20

1 struct server{int *cur_max, total, typ;} *srv; 2 int quota = MAXCONN; int *size, *type; 3 char buf[MAXLEN]; 4 size = &buf[8]; type = &buf[12] 5 ... 6 while (quota--) { 7 readData(sockfd, buf); // stack bof 8 if(*type == NONE ) break; 9 if(*type == STREAM) 10 *size = *(srv->cur_max); 11 else { 12 srv->typ = *type; 13 srv->total += *size; 14 } //...(following code skipped)... 15 }

Motivating Example

20

1 struct Obj {struct Obj *next; int prop;} 2 3 void updateList(struct Obj *list, int addend){ 4 for(; list != NULL; list = list->next) 5 list->prop += addend; 6 }

Vulnerable Program Malicious Computation

CFG w/ CFI 6 7 8 9 10 12 13 14

slide-21
SLIDE 21

1 struct server{int *cur_max, total, typ;} *srv; 2 int quota = MAXCONN; int *size, *type; 3 char buf[MAXLEN]; 4 size = &buf[8]; type = &buf[12] 5 ... 6 while (quota--) { 7 readData(sockfd, buf); // stack bof 8 if(*type == NONE ) break; 9 if(*type == STREAM) 10 *size = *(srv->cur_max); 11 else { 12 srv->typ = *type; 13 srv->total += *size; 14 } //...(following code skipped)... 15 }

Motivating Example

21

1 struct Obj {struct Obj *next; int prop;} 2 3 void updateList(struct Obj *list, int addend){ 4 for(; list != NULL; list = list->next) 5 list->prop += addend; 6 }

Vulnerable Program Malicious Computation

CFG w/ CFI 6 7 8 9 10 12 13 14

slide-22
SLIDE 22

1 struct server{int *cur_max, total, typ;} *srv; 2 int quota = MAXCONN; int *size, *type; 3 char buf[MAXLEN]; 4 size = &buf[8]; type = &buf[12] 5 ... 6 while (quota--) { 7 readData(sockfd, buf); // stack bof 8 if(*type == NONE ) break; 9 if(*type == STREAM) 10 *size = *(srv->cur_max); 11 else { 12 srv->typ = *type; 13 srv->total += *size; 14 } //...(following code skipped)... 15 }

Motivating Example

22

1 struct Obj {struct Obj *next; int prop;} 2 3 void updateList(struct Obj *list, int addend){ 4 for(; list != NULL; list = list->next) 5 list->prop += addend; 6 }

Vulnerable Program Malicious Computation

CFG w/ CFI 6 7 8 9 10 12 13 14

slide-23
SLIDE 23

4 for(; list != NULL; list = list->next) 5 list->prop += addend; 6 while (quota--) { 7 readData(sockfd, buf); 8 if(*type == NONE ) break; 9 if(*type == STREAM) 10 *size = *(srv->cur_max); 11 else { 12 srv->typ = *type; 13 srv->total += *size; 14 } 15 }

Motivating Example (cont.)

23

?

simulate

vulnerable program malicious computation

slide-24
SLIDE 24

4 for(; list != NULL; list = list->next) 5 list->prop += addend; stack srv quota size type buf[] cur_ max total typ 6 while (quota--) { 7 readData(sockfd, buf); 8 if(*type == NONE ) break; 9 if(*type == STREAM) 10 *size = *(srv->cur_max); 11 else { 12 srv->typ = *type; 13 srv->total += *size; 14 } 15 }

Motivating Example (cont.)

24

Memory space

?

simulate

vulnerable program malicious computation

slide-25
SLIDE 25

4 for(; list != NULL; list = list->next) 5 list->prop += addend; stack srv quota size type buf[] cur_ max total typ 6 while (quota--) { 7 readData(sockfd, buf); 8 if(*type == NONE ) break; 9 if(*type == STREAM) 10 *size = *(srv->cur_max); 11 else { 12 srv->typ = *type; 13 srv->total += *size; 14 } 15 }

Motivating Example (cont.)

25

Memory space

?

simulate

vulnerable program malicious computation

next prop next prop list addend heap

slide-26
SLIDE 26

4 for(; list != NULL; list = list->next) 5 list->prop += addend; stack srv quota size type buf[] cur_ max total typ 6 while (quota--) { 7 readData(sockfd, buf); 8 if(*type == NONE ) break; 9 if(*type == STREAM) 10 *size = *(srv->cur_max); 11 else { 12 srv->typ = *type; 13 srv->total += *size; 14 } 15 }

Motivating Example (cont.)

26

Memory space

next prop next prop list addend

?

simulate

vulnerable program malicious computation

heap

slide-27
SLIDE 27

4 for(; list != NULL; list = list->next) 5 list->prop += addend; stack srv quota size type buf[] cur_ max total typ 6 while (quota--) { 7 readData(sockfd, buf); 8 if(*type == NONE ) break; 9 if(*type == STREAM) 10 *size = *(srv->cur_max); 11 else { 12 srv->typ = *type; 13 srv->total += *size; 14 } 15 }

Motivating Example (cont.)

27

Memory space

next prop next prop list addend

?

simulate

vulnerable program malicious computation

heap

slide-28
SLIDE 28

4 for(; list != NULL; list = list->next) 5 list->prop += addend; stack srv quota size type buf[] cur_ max total typ 6 while (quota--) { 7 readData(sockfd, buf); 8 if(*type == NONE ) break; 9 if(*type == STREAM) 10 *size = *(srv->cur_max); 11 else { 12 srv->typ = *type; 13 srv->total += *size; 14 } 15 }

Motivating Example (cont.)

28

Memory space

next prop next prop list addend

?

simulate

vulnerable program malicious computation

heap

slide-29
SLIDE 29

4 for(; list != NULL; list = list->next) 5 list->prop += addend; stack srv quota size type buf[] cur_ max total typ 6 while (quota--) { 7 readData(sockfd, buf); 8 if(*type == NONE ) break; 9 if(*type == STREAM) 10 *size = *(srv->cur_max); 11 else { 12 srv->typ = *type; 13 srv->total += *size; 14 } 15 }

Motivating Example (cont.)

29

Memory space

next prop next prop list addend

?

simulate

vulnerable program malicious computation

heap

slide-30
SLIDE 30

4 for(; list != NULL; list = list->next) 5 list->prop += addend; stack srv quota size type buf[] cur_ max total typ 6 while (quota--) { 7 readData(sockfd, buf); 8 if(*type == NONE ) break; 9 if(*type == STREAM) 10 *size = *(srv->cur_max); 11 else { 12 srv->typ = *type; 13 srv->total += *size; 14 } 15 }

Motivating Example (cont.)

30

Memory space

next prop next prop list addend

?

simulate

vulnerable program malicious computation

heap

slide-31
SLIDE 31

4 for(; list != NULL; list = list->next) 5 list->prop += addend; stack srv quota size type buf[] cur_ max total typ 6 while (quota--) { 7 readData(sockfd, buf); 8 if(*type == NONE ) break; 9 if(*type == STREAM) 10 *size = *(srv->cur_max); 11 else { 12 srv->typ = *type; 13 srv->total += *size; 14 } 15 }

Motivating Example (cont.)

31

Memory space

next prop next prop list addend cur_ max total typ

?

simulate

vulnerable program malicious computation

heap

slide-32
SLIDE 32

4 for(; list != NULL; list = list->next) 5 list->prop += addend; stack srv quota size type buf[] cur_ max total typ 6 while (quota--) { 7 readData(sockfd, buf); 8 if(*type == NONE ) break; 9 if(*type == STREAM) 10 *size = *(srv->cur_max); 11 else { 12 srv->typ = *type; 13 srv->total += *size; 14 } 15 }

Motivating Example (cont.)

32

Memory space

next prop next prop list addend

?

simulate

vulnerable program malicious computation

heap

slide-33
SLIDE 33

4 for(; list != NULL; list = list->next) 5 list->prop += addend; stack srv quota size type buf[] cur_ max total typ 6 while (quota--) { 7 readData(sockfd, buf); 8 if(*type == NONE ) break; 9 if(*type == STREAM) 10 *size = *(srv->cur_max); 11 else { 12 srv->typ = *type; 13 srv->total += *size; 14 } 15 }

Motivating Example (cont.)

33

Memory space

next prop next prop list addend

?

cur_ max total typ

simulate

vulnerable program malicious computation

heap

slide-34
SLIDE 34

4 for(; list != NULL; list = list->next) 5 list->prop += addend; stack srv quota size type buf[] cur_ max total typ 6 while (quota--) { 7 readData(sockfd, buf); 8 if(*type == NONE ) break; 9 if(*type == STREAM) 10 *size = *(srv->cur_max); 11 else { 12 srv->typ = *type; 13 srv->total += *size; 14 } 15 }

Motivating Example (cont.)

34

Memory space

next prop next prop list addend

?

cur_ max total typ

simulate

vulnerable program malicious computation

heap

slide-35
SLIDE 35

4 for(; list != NULL; list = list->next) 5 list->prop += addend; stack srv quota size type buf[] cur_ max total typ 6 while (quota--) { 7 readData(sockfd, buf); 8 if(*type == NONE ) break; 9 if(*type == STREAM) 10 *size = *(srv->cur_max); 11 else { 12 srv->typ = *type; 13 srv->total += *size; 14 } 15 }

Motivating Example (cont.)

35

Memory space

next prop next prop list addend

?

simulate

vulnerable program malicious computation

heap

slide-36
SLIDE 36

4 for(; list != NULL; list = list->next) 5 list->prop += addend; stack srv quota size type buf[] cur_ max total typ 6 while (quota--) { 7 readData(sockfd, buf); 8 if(*type == NONE ) break; 9 if(*type == STREAM) 10 *size = *(srv->cur_max); 11 else { 12 srv->typ = *type; 13 srv->total += *size; 14 } 15 }

Motivating Example (cont.)

36

Memory space

next prop next prop list addend

?

simulate

vulnerable program malicious computation

heap STREAM

slide-37
SLIDE 37

4 for(; list != NULL; list = list->next) 5 list->prop += addend; stack srv quota size type buf[] cur_ max total typ 6 while (quota--) { 7 readData(sockfd, buf); 8 if(*type == NONE ) break; 9 if(*type == STREAM) 10 *size = *(srv->cur_max); 11 else { 12 srv->typ = *type; 13 srv->total += *size; 14 } 15 }

Motivating Example (cont.)

37

Memory space

next prop next prop list addend

?

simulate

vulnerable program malicious computation

heap STREAM

slide-38
SLIDE 38

4 for(; list != NULL; list = list->next) 5 list->prop += addend; stack srv quota size type buf[] cur_ max total typ 6 while (quota--) { 7 readData(sockfd, buf); 8 if(*type == NONE ) break; 9 if(*type == STREAM) 10 *size = *(srv->cur_max); 11 else { 12 srv->typ = *type; 13 srv->total += *size; 14 } 15 }

Motivating Example (cont.)

38

Memory space

next prop next prop list addend

?

simulate

vulnerable program malicious computation

heap STREAM

slide-39
SLIDE 39

4 for(; list != NULL; list = list->next) 5 list->prop += addend; stack srv quota size type buf[] cur_ max total typ 6 while (quota--) { 7 readData(sockfd, buf); 8 if(*type == NONE ) break; 9 if(*type == STREAM) 10 *size = *(srv->cur_max); 11 else { 12 srv->typ = *type; 13 srv->total += *size; 14 } 15 }

Motivating Example (cont.)

39

Memory space

next prop next prop list addend

?

simulate

vulnerable program malicious computation

heap STREAM cur_ max cur_ max total typ

slide-40
SLIDE 40

4 for(; list != NULL; list = list->next) 5 list->prop += addend; stack srv quota size type buf[] cur_ max total typ 6 while (quota--) { 7 readData(sockfd, buf); 8 if(*type == NONE ) break; 9 if(*type == STREAM) 10 *size = *(srv->cur_max); 11 else { 12 srv->typ = *type; 13 srv->total += *size; 14 } 15 }

Motivating Example (cont.)

40

Memory space

next prop next prop list addend

?

simulate

vulnerable program malicious computation

heap STREAM

slide-41
SLIDE 41

4 for(; list != NULL; list = list->next) 5 list->prop += addend; stack srv quota size type buf[] cur_ max total typ 6 while (quota--) { 7 readData(sockfd, buf); 8 if(*type == NONE ) break; 9 if(*type == STREAM) 10 *size = *(srv->cur_max); 11 else { 12 srv->typ = *type; 13 srv->total += *size; 14 } 15 }

Motivating Example (cont.)

41

Memory space

next prop next prop list addend STREAM

simulate

vulnerable program malicious computation

heap

slide-42
SLIDE 42

Data-Oriented Programming

A Generic Technique

42

slide-43
SLIDE 43
  • General construction

– w/o dependency on specific data / functions

Data-Oriented Programming (DOP)

43

slide-44
SLIDE 44
  • General construction

– w/o dependency on specific data / functions

  • Expressive attacks

– towards Turing-complete computation

Data-Oriented Programming (DOP)

44

slide-45
SLIDE 45
  • General construction

– w/o dependency on specific data / functions

  • Expressive attacks

– towards Turing-complete computation

  • Elements

– data-oriented gadgets – gadget dispatchers

Data-Oriented Programming (DOP)

45

slide-46
SLIDE 46

Data-Oriented Gadgets

  • x86 instruction sequence

– show in normal execution (CFI)

46

CFG 6 7 8 9 10 12 13 14

slide-47
SLIDE 47

Data-Oriented Gadgets

  • x86 instruction sequence

– show in normal execution (CFI)

Addition: srv->total += *size; 1 mov (%esi), %ebx //load micro-op 2 mov (%edi), %eax //load micro-op 3 add %ebx, %eax //addition 4 mov %eax, (%edi) //store micro-op

47

CFG 6 7 8 9 10 12 13 14

slide-48
SLIDE 48

Data-Oriented Gadgets

  • x86 instruction sequence

– show in normal execution (CFI) – save results in memory – load micro-op --> semantics micro-op --> store micro-op

Addition: srv->total += *size; 1 mov (%esi), %ebx //load micro-op 2 mov (%edi), %eax //load micro-op 3 add %ebx, %eax //addition 4 mov %eax, (%edi) //store micro-op

48

CFG 6 7 8 9 10 12 13 14

slide-49
SLIDE 49

Data-Oriented Gadgets

  • x86 instruction sequence

– show in normal execution (CFI) – save results in memory – load micro-op --> semantics micro-op --> store micro-op

Addition: srv->total += *size; 1 mov (%esi), %ebx //load micro-op 2 mov (%edi), %eax //load micro-op 3 add %ebx, %eax //addition 4 mov %eax, (%edi) //store micro-op

49

CFG 6 7 8 9 10 12 13 14 Memory space

slide-50
SLIDE 50

Data-Oriented Gadgets

  • x86 instruction sequence

– show in normal execution (CFI) – save results in memory – load micro-op --> semantics micro-op --> store micro-op

Addition: srv->total += *size; 1 mov (%esi), %ebx //load micro-op 2 mov (%edi), %eax //load micro-op 3 add %ebx, %eax //addition 4 mov %eax, (%edi) //store micro-op Load: *size = *(srv ->cur_max); 1 mov (%esi), %ebx //load micro-op 2 mov (%edi), %eax //load micro-op 3 mov 0xb(%ebx), %eax //load 4 mov %eax, (%edx) //store micro-op

50

CFG 6 7 8 9 10 12 13 14 Memory space

slide-51
SLIDE 51

Data-Oriented Gadgets

  • x86 instruction sequence

– show in normal execution (CFI) – save results in memory – load micro-op --> semantics micro-op --> store micro-op

Addition: srv->total += *size; 1 mov (%esi), %ebx //load micro-op 2 mov (%edi), %eax //load micro-op 3 add %ebx, %eax //addition 4 mov %eax, (%edi) //store micro-op Load: *size = *(srv ->cur_max); 1 mov (%esi), %ebx //load micro-op 2 mov (%edi), %eax //load micro-op 3 mov 0xb(%ebx), %eax //load 4 mov %eax, (%edx) //store micro-op

51

CFG 6 7 8 9 10 12 13 14 Memory space

slide-52
SLIDE 52

Gadget Dispatcher

round1 round2 round3 roundN

…… corruptible by mem-err

52

loop selector

slide-53
SLIDE 53

Gadget Dispatcher

round1 round2 round3 roundN

…… corruptible by mem-err

53

loop selector

  • Chain data-oriented gadgets “legitimately”

– loop ---> repeatedly invoke gadgets – selector ---> selectively activate gadgets

slide-54
SLIDE 54

Gadget Dispatcher

  • Chain data-oriented gadgets “legitimately”

– loop ---> repeatedly invoke gadgets – selector ---> selectively activate gadgets

round1 round2 round3 roundN

…… corruptible by mem-err

54

loop selector 1 2 3 4

slide-55
SLIDE 55

Gadget Dispatcher

  • Chain data-oriented gadgets “legitimately”

– loop ---> repeatedly invoke gadgets – selector ---> selectively activate gadgets

round1 round2 round3 roundN

…… corruptible by mem-err

55

loop selector 1 2 3 5 6 4 7

slide-56
SLIDE 56

Gadget Dispatcher

  • Chain data-oriented gadgets “legitimately”

– loop ---> repeatedly invoke gadgets – selector ---> selectively activate gadgets

round1 round2 round3 roundN

…… corruptible by mem-err

56

loop selector 1 2 3 5 6 4 7 1 2 3 4

slide-57
SLIDE 57

Gadget Dispatcher

  • Chain data-oriented gadgets “legitimately”

– loop ---> repeatedly invoke gadgets – selector ---> selectively activate gadgets

round1 round2 round3 roundN

…… corruptible by mem-err

57

loop selector 1 2 3 5 6 4 7 1 2 3 4

slide-58
SLIDE 58

Gadget Dispatcher

  • Chain data-oriented gadgets “legitimately”

– loop ---> repeatedly invoke gadgets – selector ---> selectively activate gadgets

round1 round2 round3 roundN

…… corruptible by mem-err

58

loop selector 6 while (quota--) { 7 readData(sockfd, buf); 8 if(*type == NONE ) break; 9 if(*type == STREAM) *size = *(srv->cur_max); 10 else{ srv->typ = *type; srv->total += *size; } 14 } // loop // selector 1 2 3 5 6 4 7 1 2 3 4

slide-59
SLIDE 59

Turing-completeness

  • DOP emulates a minimal language MINDOP

– MINDOP is Turing-complete

59

Semantics Statements In C Data-Oriented Gadgets in DOP arithmetic / logical a op b *p op *q assignment a = b *p = *q load a = *b *p = **q store *a = b **p = *q jump goto L vpc = &input conditional jump if (a) goto L vpc = &input if *p p – &a; q – &b; op – any arithmetic / logical operation

slide-60
SLIDE 60

Attack Construction

60

6 while (quota--) { 7 readData(sockfd, buf); 8 if(*type == NONE ) break; 9 if(*type == STREAM) 10 *size = *(srv->cur_max); 11 else { 12 srv->typ = *type; 13 srv->total += *size; 14 } //...(code skipped)... 15 }

slide-61
SLIDE 61

Attack Construction

  • Gadget identification

– statically identify load-semantics-store chain from LLVM IR

61

6 while (quota--) { 7 readData(sockfd, buf); 8 if(*type == NONE ) break; 9 if(*type == STREAM) 10 *size = *(srv->cur_max); 11 else { 12 srv->typ = *type; 13 srv->total += *size; 14 } //...(code skipped)... 15 }

slide-62
SLIDE 62

Attack Construction

  • Gadget identification

– statically identify load-semantics-store chain from LLVM IR

  • Dispatcher identification

– static identify loops with gadgets from LLVM IR

62

6 while (quota--) { 7 readData(sockfd, buf); 8 if(*type == NONE ) break; 9 if(*type == STREAM) 10 *size = *(srv->cur_max); 11 else { 12 srv->typ = *type; 13 srv->total += *size; 14 } //...(code skipped)... 15 }

slide-63
SLIDE 63

Attack Construction

  • Gadget identification

– statically identify load-semantics-store chain from LLVM IR

  • Dispatcher identification

– static identify loops with gadgets from LLVM IR

  • Gadget stitching

– select gadgets and dispatchers (manual) – check stitchability (manual)

63

6 while (quota--) { 7 readData(sockfd, buf); 8 if(*type == NONE ) break; 9 if(*type == STREAM) 10 *size = *(srv->cur_max); 11 else { 12 srv->typ = *type; 13 srv->total += *size; 14 } //...(code skipped)... 15 }

slide-64
SLIDE 64

Evaluation

64

slide-65
SLIDE 65

Evaluation – Feasibility

9 x86 programs with 9 vulnerabilities

– Nginx, ProFTPD, Wu-FTPD, sshd, Bitcoind, – Wireshark, sudo, musl libc, mcrypt

65

slide-66
SLIDE 66

Evaluation – Feasibility

9 x86 programs with 9 vulnerabilities

– Nginx, ProFTPD, Wu-FTPD, sshd, Bitcoind, – Wireshark, sudo, musl libc, mcrypt

  • x86 Gadgets

– 7518 in total, 1273 reachable via selected CVEs – 8 programs can simulate all MINDOP operations

  • x86 Dispatchers

– 1443 in total, 110 reachable from selected CVEs

66

slide-67
SLIDE 67

Evaluation – Feasibility

9 x86 programs with 9 vulnerabilities

– Nginx, ProFTPD, Wu-FTPD, sshd, Bitcoind, – Wireshark, sudo, musl libc, mcrypt

  • x86 Gadgets

– 7518 in total, 1273 reachable via selected CVEs – 8 programs can simulate all MINDOP operations

  • x86 Dispatchers

– 1443 in total, 110 reachable from selected CVEs

  • 2 programs can build Turing-complete attack
  • 3 end-to-end attacks

67

slide-68
SLIDE 68

Case Study: Bypassing Randomization

  • Previous methods

– information leakage to network

  • Defeat ASLR w/o address leakage to network?

68

slide-69
SLIDE 69

Case Study: Bypassing Randomization

  • Previous methods

– information leakage to network

  • Defeat ASLR w/o address leakage to network?
  • Vulnerable ProFTPD

– use OpenSSL for authentication – a dereference chain to the private key

69

slide-70
SLIDE 70

Case Study: Bypassing Randomization

  • Previous methods

– information leakage to network

  • Defeat ASLR w/o address leakage to network?
  • Vulnerable ProFTPD

– use OpenSSL for authentication – a dereference chain to the private key

Private Key BN_ULONG * d2 BIGNUM * d1 struct rsa_st * rsa EVP_PKEY*privatekey CERT_PKEY * key struct cert_st * cert @0x080dbc28 SSL_CTX * ssl_ctx

70

slide-71
SLIDE 71

Case Study: Bypassing Randomization

  • Gadgets

Private Key BN_ULONG * d2 BIGNUM * d1 struct rsa_st * rsa EVP_PKEY*privatekey CERT_PKEY * key struct cert_st * cert @0x080dbc28 SSL_CTX * ssl_ctx MOV ADD LOAD *p = *q *X = *X + offset *Z = **Y

71

slide-72
SLIDE 72

Case Study: Bypassing Randomization

  • Gadgets
  • Dispatcher

Private Key BN_ULONG * d2 BIGNUM * d1 struct rsa_st * rsa EVP_PKEY*privatekey CERT_PKEY * key struct cert_st * cert @0x080dbc28 SSL_CTX * ssl_ctx MOV ADD LOAD *p = *q *X = *X + offset *Z = **Y while (1) { user_request = get_user_request(); dispatch(user_request); } func1() { memory_error; MOV;} func2() { ADD; } func3() { LOAD; }

72

slide-73
SLIDE 73

Case Study: Bypassing Randomization

Private Key BN_ULONG * d2 BIGNUM * d1 struct rsa_st * rsa EVP_PKEY*privatekey CERT_PKEY * key struct cert_st * cert @0x080dbc28 SSL_CTX * ssl_ctx

MOV ADD MOV LOAD MOV *X = *0x080dbc28 (ssl_ctx) *X = *X + offset1 *Y = *X *Z = **Y *0x080dbc28 = *Z (cert)

73

slide-74
SLIDE 74

Case Study: Bypassing Randomization

Private Key BN_ULONG * d2 BIGNUM * d1 struct rsa_st * rsa EVP_PKEY*privatekey CERT_PKEY * key struct cert_st * cert @0x080dbc28 SSL_CTX * ssl_ctx

MOV ADD MOV LOAD MOV *X = *0x080dbc28 (ssl_ctx) *X = *X + offset1 *Y = *X *Z = **Y *0x080dbc28 = *Z (cert)

74

ssl_ctx @0x080dbc28 cert

slide-75
SLIDE 75

Case Study: Bypassing Randomization

Private Key BN_ULONG * d2 BIGNUM * d1 struct rsa_st * rsa EVP_PKEY*privatekey CERT_PKEY * key struct cert_st * cert @0x080dbc28 SSL_CTX * ssl_ctx

75

d2 @0x080dbc28

MOV ADD MOV LOAD MOV *X = *0x080dbc28 (ssl_ctx) *X = *X + offset1 *Y = *X *Z = **Y *0x080dbc28 = *Z (cert)

slide-76
SLIDE 76

Case Study: Bypassing Randomization

Private Key BN_ULONG * d2 BIGNUM * d1 struct rsa_st * rsa EVP_PKEY*privatekey CERT_PKEY * key struct cert_st * cert @0x080dbc28 SSL_CTX * ssl_ctx

76

d2 @0x080dbc28

write(outsock, buf, strlen(buf));

buf

MOV ADD MOV LOAD MOV *X = *0x080dbc28 (ssl_ctx) *X = *X + offset1 *Y = *X *Z = **Y *0x080dbc28 = *Z (cert)

slide-77
SLIDE 77

Case Study: Bypassing Randomization

Private Key BN_ULONG * d2 BIGNUM * d1 struct rsa_st * rsa EVP_PKEY*privatekey CERT_PKEY * key struct cert_st * cert @0x080dbc28 SSL_CTX * ssl_ctx

77

d2 @0x080dbc28

write(outsock, buf, strlen(buf));

buf

MOV ADD MOV LOAD MOV *X = *0x080dbc28 (ssl_ctx) *X = *X + offset1 *Y = *X *Z = **Y *0x080dbc28 = *Z (cert)

slide-78
SLIDE 78

Case Study: Bypassing Randomization

Private Key BN_ULONG * d2 BIGNUM * d1 struct rsa_st * rsa EVP_PKEY*privatekey CERT_PKEY * key struct cert_st * cert @0x080dbc28 SSL_CTX * ssl_ctx

78

d2 @0x080dbc28

write(outsock, buf, strlen(buf));

buf

MOV ADD MOV LOAD MOV *X = *0x080dbc28 (ssl_ctx) *X = *X + offset1 *Y = *X *Z = **Y *0x080dbc28 = *Z (cert)

leak private key to network

slide-79
SLIDE 79

dlopen() – Dynamic Linking Interface

  • Load the dynamic library into memory space

– resolve symbols based on binary metadata – patch program due to relocation – like LoadLibrary() on Windows

79

slide-80
SLIDE 80

dlopen() – Dynamic Linking Interface

  • Load the dynamic library into memory space

– resolve symbols based on binary metadata – patch program due to relocation – like LoadLibrary() on Windows

  • Dynamic loader can do arbitrary computation*

80

* R. Shapiro, S. Bratus, and S. W. Smith, ““Weird Machines” in ELF: A Spotlight on the Underappreciated Metadata,” in WOOT 2013.

exec() sysexec ld.so bin libc.so RTLD_ START() _start() bin ld.so libc.so file access before run

slide-81
SLIDE 81

dlopen() – Dynamic Linking Interface

  • Load the dynamic library into memory space

– resolve symbols based on binary metadata – patch program due to relocation – like LoadLibrary() on Windows

  • Dynamic loader can do arbitrary computation*
  • The same to dlopen()

81

* R. Shapiro, S. Bratus, and S. W. Smith, ““Weird Machines” in ELF: A Spotlight on the Underappreciated Metadata,” in WOOT 2013.

exec() sysexec ld.so bin libc.so RTLD_ START() _start() bin ld.so libc.so file access before run

slide-82
SLIDE 82
  • Attacks with dlopen

82

dlopen() { } head …… dynamic library list link_map

Case Study: Simulating A Network Bot

slide-83
SLIDE 83
  • Attacks with dlopen

– send malicious payload

ProFTPD’s memory Malicious payload

83

dlopen() { } head …… dynamic library list link_map

Case Study: Simulating A Network Bot

slide-84
SLIDE 84
  • Attacks with dlopen

– send malicious payload – corrupt link list & call dlopen

ProFTPD’s memory Malicious payload

84

dlopen() { } head …… dynamic library list link_map

Case Study: Simulating A Network Bot

slide-85
SLIDE 85
  • Attacks with dlopen

– send malicious payload – corrupt link list & call dlopen

ProFTPD’s memory Malicious payload

85

dlopen() { } head …… dynamic library list link_map

invalid input

Case Study: Simulating A Network Bot

slide-86
SLIDE 86
  • Attacks with dlopen

– send malicious payload – corrupt link list & call dlopen

ProFTPD’s memory Malicious payload

86

dlopen() { } head …… dynamic library list link_map

invalid input no call to dlopen

Case Study: Simulating A Network Bot

slide-87
SLIDE 87

ProFTPD’s memory Malicious payload

Case Study: Simulating A Network Bot

87

dlopen() { } head …… dynamic library list link_map

  • dlopen allows arbitrary computation

– send malicious payload – corrupt link list & call dlopen

  • DOP attack addresses the problems

invalid input no call to dlopen

slide-88
SLIDE 88

ProFTPD’s memory Malicious payload

Case Study: Simulating A Network Bot

88

dlopen() { } head …… dynamic library list link_map

  • dlopen allows arbitrary computation

– send malicious payload – corrupt link list & call dlopen

  • DOP attack addresses the problems

– construct payload in memory invalid input no call to dlopen

(1) Payload prepare MOV MOV

slide-89
SLIDE 89

ProFTPD’s memory Malicious payload

Case Study: Simulating A Network Bot

89

dlopen() { } head …… dynamic library list link_map

  • dlopen allows arbitrary computation

– send malicious payload – corrupt link list & call dlopen

  • DOP attack addresses the problems

– construct payload in memory invalid input no call to dlopen

(1) Payload prepare MOV MOV

slide-90
SLIDE 90

if (flag) { } ProFTPD’s memory Malicious payload

Case Study: Simulating A Network Bot

90

dlopen() { } head …… dynamic library list link_map

  • dlopen allows arbitrary computation

– send malicious payload – corrupt link list & call dlopen

  • DOP attack addresses the problems

– construct payload in memory

– force call to dlopen

invalid input no call to dlopen

(1) Payload prepare MOV MOV

slide-91
SLIDE 91

if (flag) { } ProFTPD’s memory Malicious payload

Case Study: Simulating A Network Bot

91

(2) Trigger MOV STORE dlopen() { } head …… dynamic library list link_map

  • dlopen allows arbitrary computation

– send malicious payload – corrupt link list & call dlopen

  • DOP attack addresses the problems

– construct payload in memory

– force call to dlopen

invalid input no call to dlopen

(1) Payload prepare MOV MOV

slide-92
SLIDE 92

if (flag) { } ProFTPD’s memory Malicious payload

Case Study: Simulating A Network Bot

92

(2) Trigger MOV STORE

> 700 requests

dlopen() { } head …… dynamic library list link_map

  • dlopen allows arbitrary computation

– send malicious payload – corrupt link list & call dlopen

  • DOP attack addresses the problems

– construct payload in memory

– force call to dlopen

invalid input no call to dlopen

(1) Payload prepare MOV MOV

slide-93
SLIDE 93

Case Study: Altering Memory Permissions

  • Defenses based on memory permissions

– DEP: non-writable code – CFI: non-writable jump tags

93

slide-94
SLIDE 94

Case Study: Altering Memory Permissions

  • Defenses based on memory permissions

– DEP: non-writable code – CFI: non-writable jump tags

  • dlopen(): relocation

– change any page permission to writable – update page content – change the permission back

94

slide-95
SLIDE 95

Case Study: Altering Memory Permissions

  • Defenses based on memory permissions

– DEP: non-writable code – CFI: non-writable jump tags

  • dlopen(): relocation

– change any page permission to writable – update page content – change the permission back

  • DOP attacks

– dlopen(code_addr, shellcode)

95

slide-96
SLIDE 96

Case Study: Altering Memory Permissions

  • Defenses based on memory permissions

– DEP: non-writable code – CFI: non-writable jump tags

  • dlopen(): relocation

– change any page permission to writable – update page content – change the permission back

  • DOP attacks

– dlopen(code_addr, shellcode)

  • Code injection is back!

96

slide-97
SLIDE 97

Related Work

97

Techniques Turing Complete? Preserve CFI? Independent

  • f specific

data / funcs? Non-control Data Attacks (Chen et al. 2005)

COOP (Schuster et al. 2015)

 

FlowStitch (Hu et al. 2015)

Printf-Oriented Programming (Carlini et al. 2015)

 

Control Jujustu (Evans et al. 2015)

Data-Oriented Programming

  

slide-98
SLIDE 98

Potential Defenses

  • Memory Safety

– e.g., Cyclone (Jim et al. 2002), CCured (Necula et al. 2002) , SoftBounds+CETS (Nagarakatte et al. 2009, 2010) – high performance overhead (> 100%)

  • Data-flow Integrity

– e.g, DFI (Castro et al. 2006) , kernel DFI (Song et al. 2016)

  • Fined-grained randomization in data space

– e.g., DSR (Bhatkar et al. 2008)

  • Hardware & software fault isolation

– e.g., HDFI (Song et al. 2016) , MPX

98

slide-99
SLIDE 99

Potential Defenses

  • Memory Safety

– e.g., Cyclone (Jim et al. 2002), CCured (Necula et al. 2002) , SoftBounds+CETS (Nagarakatte et al. 2009, 2010) – high performance overhead (> 100%)

  • Data-flow Integrity

– e.g, DFI (Castro et al. 2006) , kernel DFI (Song et al. 2016)

  • Fined-grained randomization in data space

– e.g., DSR (Bhatkar et al. 2008)

  • Hardware & software fault isolation

– e.g., HDFI (Song et al. 2016) , MPX

99

No practical defenses yet !

slide-100
SLIDE 100

Conclusion

100

  • Non-control data attacks can be Turing-complete
slide-101
SLIDE 101

Conclusion

101

  • Non-control data attacks can be Turing-complete
  • Data-Oriented Programming (DOP)

– build expressive non-control data attacks – independent of specific data / functions

slide-102
SLIDE 102

Conclusion

102

  • Non-control data attacks can be Turing-complete
  • Data-Oriented Programming (DOP)

– build expressive non-control data attacks – independent of specific data / functions

  • In real-world programs, DOP can build attacks

– bypass ASLR w/o address leakage – simulate a network bot – enable code injection

slide-103
SLIDE 103

Thanks!

Hong Hu

huhong@comp.nus.edu.sg http://www.comp.nus.edu.sg/~huhong Non-control data attacks are available http://huhong-nus.github.io/advanced-DOP/