Buffer Overflow overflows Defenses and other memory safety - - PowerPoint PPT Presentation

buffer
SMART_READER_LITE
LIVE PREVIEW

Buffer Overflow overflows Defenses and other memory safety - - PowerPoint PPT Presentation

Last time We continued By looking at Buffer Overflow overflows Defenses and other memory safety vulnerabilities Finish overflow attacks & other vulnerabilities Overflow defenses Everything youve always wanted to know about


slide-1
SLIDE 1

Last time

  • Finish overflow attacks & other vulnerabilities
  • Overflow defenses
  • Everything you’ve always wanted to know about

gdb but were too afraid to ask

Buffer

  • verflows

We continued

and other memory safety vulnerabilities

By looking at

Overflow

Defenses

slide-2
SLIDE 2

This time

Required reading:

“StackGuard: Simple Stack Smash Protection for GCC” Optional reading: “Basic Integer Overflows” “Exploiting Format String Vulnerabilities”

Secure


Code

Writing & testing for

Continuing with

Software

Security

http://nob.cs.ucdavis.edu/bishop/secprog/robust.html

slide-3
SLIDE 3

Cat and mouse

slide-4
SLIDE 4

Cat and mouse

  • Defense: Make stack/heap non-executable to prevent

injection of code

slide-5
SLIDE 5

Cat and mouse

  • Defense: Make stack/heap non-executable to prevent

injection of code

  • Attack response: Return to libc
slide-6
SLIDE 6

Cat and mouse

  • Defense: Make stack/heap non-executable to prevent

injection of code

  • Attack response: Return to libc
  • Defense: Hide the address of desired libc code or

return address using ASLR

slide-7
SLIDE 7

Cat and mouse

  • Defense: Make stack/heap non-executable to prevent

injection of code

  • Attack response: Return to libc
  • Defense: Hide the address of desired libc code or

return address using ASLR

  • Attack response: Brute force search (for 32-bit systems)
  • r information leak (format string vulnerability: later today)
slide-8
SLIDE 8

Cat and mouse

  • Defense: Make stack/heap non-executable to prevent

injection of code

  • Attack response: Return to libc
  • Defense: Hide the address of desired libc code or

return address using ASLR

  • Attack response: Brute force search (for 32-bit systems)
  • r information leak (format string vulnerability: later today)
  • Defense: Avoid using libc code entirely and use code in

the program text instead

slide-9
SLIDE 9

Cat and mouse

  • Defense: Make stack/heap non-executable to prevent

injection of code

  • Attack response: Return to libc
  • Defense: Hide the address of desired libc code or

return address using ASLR

  • Attack response: Brute force search (for 32-bit systems)
  • r information leak (format string vulnerability: later today)
  • Defense: Avoid using libc code entirely and use code in

the program text instead

  • Attack response: Construct needed functionality using

return oriented programming (ROP)

slide-10
SLIDE 10

Return oriented programming (ROP)

slide-11
SLIDE 11

Return-oriented Programming

slide-12
SLIDE 12

Return-oriented Programming

  • Introduced by Hovav Shacham in 2007
  • The Geometry of Innocent Flesh on the Bone:

Return-into-libc without Function Calls (on the x86), CCS’07

slide-13
SLIDE 13

Return-oriented Programming

  • Introduced by Hovav Shacham in 2007
  • The Geometry of Innocent Flesh on the Bone:

Return-into-libc without Function Calls (on the x86), CCS’07

  • Idea: rather than use a single (libc) function to run

your shellcode, string together pieces of existing code, called gadgets, to do it instead

slide-14
SLIDE 14

Return-oriented Programming

  • Introduced by Hovav Shacham in 2007
  • The Geometry of Innocent Flesh on the Bone:

Return-into-libc without Function Calls (on the x86), CCS’07

  • Idea: rather than use a single (libc) function to run

your shellcode, string together pieces of existing code, called gadgets, to do it instead

  • Challenges
  • Find the gadgets you need
  • String them together
slide-15
SLIDE 15

Approach

slide-16
SLIDE 16

Approach

  • Gadgets are instruction groups that end

with ret

slide-17
SLIDE 17

Approach

  • Gadgets are instruction groups that end

with ret

  • Stack serves as the code
  • %esp = program counter
  • Gadgets invoked via ret instruction
  • Gadgets get their arguments via pop,

etc.

  • Also on the stack
slide-18
SLIDE 18

Simple example

0xffffffff 0x00 mov ¡%edx, ¡5

equivalent to

%edx

slide-19
SLIDE 19

Simple example

0x17f: ¡pop ¡%edx ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ret 0xffffffff 0x00 Text mov ¡%edx, ¡5

equivalent to

%edx

Gadget

slide-20
SLIDE 20

Simple example

0x17f: ¡pop ¡%edx ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ret 5 0x17f 0xffffffff 0x00 Text mov ¡%edx, ¡5 …

equivalent to

%edx

next ¡ gadget

Gadget “Instructions”

slide-21
SLIDE 21

Simple example

0x17f: ¡pop ¡%edx ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ret 5 0x17f 0xffffffff 0x00 Text mov ¡%edx, ¡5 …

equivalent to

%eip

%edx

next ¡ gadget

%esp

Gadget “Instructions” “program counter”

(ret)

slide-22
SLIDE 22

Simple example

0x17f: ¡pop ¡%edx ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ret 5 0x17f 0xffffffff 0x00 Text mov ¡%edx, ¡5 …

equivalent to

%eip

%edx

next ¡ gadget

%esp (ret)

slide-23
SLIDE 23

Simple example

0x17f: ¡pop ¡%edx ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ret 5 0x17f 0xffffffff 0x00 Text mov ¡%edx, ¡5 …

equivalent to

%eip

%edx

5

next ¡ gadget

%esp (ret)

slide-24
SLIDE 24

Simple example

0x17f: ¡pop ¡%edx ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ret 5 0x17f 0xffffffff 0x00 Text mov ¡%edx, ¡5 …

equivalent to

%eip

%edx

5

next ¡ gadget

%esp (ret)

slide-25
SLIDE 25

Code sequence

0xffffffff 0x00 0x404 … … 5 …

%eax %ebx

… %esp 0x17f: ¡mov ¡%eax, ¡[%esp] ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡mov ¡%ebx, ¡[%esp-­‑8] ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡mov ¡[%ebx], ¡%eax %eip 0x404 Text

slide-26
SLIDE 26

Code sequence

0xffffffff 0x00 0x404 … … 5 …

%eax %ebx

… %esp 0x17f: ¡mov ¡%eax, ¡[%esp] ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡mov ¡%ebx, ¡[%esp-­‑8] ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡mov ¡[%ebx], ¡%eax %eip 0x404 Text 5

slide-27
SLIDE 27

Code sequence

0xffffffff 0x00 0x404 … … 5 …

%eax %ebx

… %esp 0x17f: ¡mov ¡%eax, ¡[%esp] ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡mov ¡%ebx, ¡[%esp-­‑8] ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡mov ¡[%ebx], ¡%eax %eip 0x404 Text 5 0x404

slide-28
SLIDE 28

Code sequence

0xffffffff 0x00 0x404 … … 5 …

%eax %ebx

… %esp 0x17f: ¡mov ¡%eax, ¡[%esp] ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡mov ¡%ebx, ¡[%esp-­‑8] ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡mov ¡[%ebx], ¡%eax %eip 0x404 Text 5 0x404 5

slide-29
SLIDE 29

Equivalent ROP sequence

0xffffffff 0x00 0x404 0x20d 0x21a 5 …

%eax %ebx

… %esp 0x17f: ¡pop ¡%eax ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ret ¡ … ¡ 0x20d: ¡pop ¡%ebx ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ret ¡ … ¡ 0x21a: ¡mov ¡[%ebx], ¡%eax %eip 0x404 Text

slide-30
SLIDE 30

Equivalent ROP sequence

0xffffffff 0x00 0x404 0x20d 0x21a 5 …

%eax %ebx

… %esp 0x17f: ¡pop ¡%eax ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ret ¡ … ¡ 0x20d: ¡pop ¡%ebx ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ret ¡ … ¡ 0x21a: ¡mov ¡[%ebx], ¡%eax %eip 0x404 Text 5

slide-31
SLIDE 31

Equivalent ROP sequence

0xffffffff 0x00 0x404 0x20d 0x21a 5 …

%eax %ebx

… %esp 0x17f: ¡pop ¡%eax ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ret ¡ … ¡ 0x20d: ¡pop ¡%ebx ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ret ¡ … ¡ 0x21a: ¡mov ¡[%ebx], ¡%eax %eip 0x404 Text 5

slide-32
SLIDE 32

Equivalent ROP sequence

0xffffffff 0x00 0x404 0x20d 0x21a 5 …

%eax %ebx

… %esp 0x17f: ¡pop ¡%eax ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ret ¡ … ¡ 0x20d: ¡pop ¡%ebx ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ret ¡ … ¡ 0x21a: ¡mov ¡[%ebx], ¡%eax %eip 0x404 Text 5 0x404

slide-33
SLIDE 33

Equivalent ROP sequence

0xffffffff 0x00 0x404 0x20d 0x21a 5 …

%eax %ebx

… 0x17f: ¡pop ¡%eax ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ret ¡ … ¡ 0x20d: ¡pop ¡%ebx ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ret ¡ … ¡ 0x21a: ¡mov ¡[%ebx], ¡%eax %eip 0x404 Text 5 0x404

slide-34
SLIDE 34

Equivalent ROP sequence

0xffffffff 0x00 0x404 0x20d 0x21a 5 …

%eax %ebx

… 0x17f: ¡pop ¡%eax ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ret ¡ … ¡ 0x20d: ¡pop ¡%ebx ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ret ¡ … ¡ 0x21a: ¡mov ¡[%ebx], ¡%eax %eip 0x404 Text 5 0x404 5

slide-35
SLIDE 35

Image by Dino Dai Zovi

slide-36
SLIDE 36

Whence the gadgets?

slide-37
SLIDE 37

Whence the gadgets?

  • How can we find gadgets to construct an exploit?
slide-38
SLIDE 38

Whence the gadgets?

  • How can we find gadgets to construct an exploit?
  • Automate a search of the target binary for gadgets (look for ret

instructions, work backwards)

  • Cf. https://github.com/0vercl0k/rp
slide-39
SLIDE 39

Whence the gadgets?

  • How can we find gadgets to construct an exploit?
  • Automate a search of the target binary for gadgets (look for ret

instructions, work backwards)

  • Cf. https://github.com/0vercl0k/rp
  • Are there sufficient gadgets to do anything interesting?
slide-40
SLIDE 40

Whence the gadgets?

  • How can we find gadgets to construct an exploit?
  • Automate a search of the target binary for gadgets (look for ret

instructions, work backwards)

  • Cf. https://github.com/0vercl0k/rp
  • Are there sufficient gadgets to do anything interesting?
  • Yes: Shacham found that for significant codebases (e.g.,

libc), gadgets are Turing complete

  • Especially true on x86’s dense instruction set
slide-41
SLIDE 41

Whence the gadgets?

  • How can we find gadgets to construct an exploit?
  • Automate a search of the target binary for gadgets (look for ret

instructions, work backwards)

  • Cf. https://github.com/0vercl0k/rp
  • Are there sufficient gadgets to do anything interesting?
  • Yes: Shacham found that for significant codebases (e.g.,

libc), gadgets are Turing complete

  • Especially true on x86’s dense instruction set
  • Schwartz et al (USENIX Security ’11) have automated

gadget shellcode creation, though not needing/requiring Turing completeness

slide-42
SLIDE 42

Blind ROP

slide-43
SLIDE 43

Blind ROP

  • Defense: Randomizing the location of the code

(by compiling for position independence) on a 64- bit machine makes attacks very difficult

slide-44
SLIDE 44

Blind ROP

  • Defense: Randomizing the location of the code

(by compiling for position independence) on a 64- bit machine makes attacks very difficult

  • Recent, published attacks are often for 32-bit

versions of executables

slide-45
SLIDE 45

Blind ROP

  • Defense: Randomizing the location of the code

(by compiling for position independence) on a 64- bit machine makes attacks very difficult

  • Recent, published attacks are often for 32-bit

versions of executables

  • Attack response: Blind ROP
slide-46
SLIDE 46

Blind ROP

  • Defense: Randomizing the location of the code

(by compiling for position independence) on a 64- bit machine makes attacks very difficult

  • Recent, published attacks are often for 32-bit

versions of executables

  • Attack response: Blind ROP

If server restarts on a crash, but does not re-randomize:

slide-47
SLIDE 47

Blind ROP

  • Defense: Randomizing the location of the code

(by compiling for position independence) on a 64- bit machine makes attacks very difficult

  • Recent, published attacks are often for 32-bit

versions of executables

  • Attack response: Blind ROP

If server restarts on a crash, but does not re-randomize: 1.Read the stack to leak canaries and a return address

slide-48
SLIDE 48

Blind ROP

  • Defense: Randomizing the location of the code

(by compiling for position independence) on a 64- bit machine makes attacks very difficult

  • Recent, published attacks are often for 32-bit

versions of executables

  • Attack response: Blind ROP

If server restarts on a crash, but does not re-randomize: 1.Read the stack to leak canaries and a return address 2.Find gadgets (at run-time) to effect call to write

slide-49
SLIDE 49

Blind ROP

  • Defense: Randomizing the location of the code

(by compiling for position independence) on a 64- bit machine makes attacks very difficult

  • Recent, published attacks are often for 32-bit

versions of executables

  • Attack response: Blind ROP

If server restarts on a crash, but does not re-randomize: 1.Read the stack to leak canaries and a return address 2.Find gadgets (at run-time) to effect call to write 3.Dump binary to find gadgets for shellcode

http://www.scs.stanford.edu/brop/

slide-50
SLIDE 50

Defeat!

  • The blind ROP team was able to completely

automatically, only through remote interactions, develop a remote code exploit for nginx, a popular web server

slide-51
SLIDE 51

Defeat!

  • The blind ROP team was able to completely

automatically, only through remote interactions, develop a remote code exploit for nginx, a popular web server

  • The exploit was carried out on a 64-bit executable

with full stack canaries and randomization

slide-52
SLIDE 52

Defeat!

  • The blind ROP team was able to completely

automatically, only through remote interactions, develop a remote code exploit for nginx, a popular web server

  • The exploit was carried out on a 64-bit executable

with full stack canaries and randomization

  • Conclusion: give an inch, and they take a mile?
slide-53
SLIDE 53

Defeat!

  • The blind ROP team was able to completely

automatically, only through remote interactions, develop a remote code exploit for nginx, a popular web server

  • The exploit was carried out on a 64-bit executable

with full stack canaries and randomization

  • Conclusion: give an inch, and they take a mile?
  • Put another way: Memory safety is really useful!
slide-54
SLIDE 54

void safe() { char buf[80]; fgets(buf, 80, stdin); } void safer() { char buf[80]; fgets(buf, sizeof(buf), stdin); }

slide-55
SLIDE 55

void safe() { char buf[80]; fgets(buf, 80, stdin); } void safer() { char buf[80]; fgets(buf, sizeof(buf), stdin); } void vulnerable() { char buf[80]; if(fgets(buf, sizeof(buf), stdin)==NULL) return; printf(buf); }

slide-56
SLIDE 56

void safe() { char buf[80]; fgets(buf, 80, stdin); } void safer() { char buf[80]; fgets(buf, sizeof(buf), stdin); } void vulnerable() { char buf[80]; if(fgets(buf, sizeof(buf), stdin)==NULL) return; printf(buf); }

slide-57
SLIDE 57

Format string vulnerabilities

slide-58
SLIDE 58

printf format strings

int i = 10; printf(“%d %p\n”, i, &i);

slide-59
SLIDE 59

printf format strings

int i = 10; printf(“%d %p\n”, i, &i);

0xffffffff 0x00000000

&i 10 %eip %ebp &fmt …

slide-60
SLIDE 60

printf’s stack frame

printf format strings

int i = 10; printf(“%d %p\n”, i, &i);

0xffffffff 0x00000000

&i 10 %eip %ebp &fmt …

slide-61
SLIDE 61

caller’s
 stack frame printf’s stack frame

printf format strings

int i = 10; printf(“%d %p\n”, i, &i);

0xffffffff 0x00000000

&i 10 %eip %ebp &fmt …

slide-62
SLIDE 62

caller’s
 stack frame printf’s stack frame

printf format strings

int i = 10; printf(“%d %p\n”, i, &i);

0xffffffff 0x00000000

&i 10 %eip %ebp &fmt …

slide-63
SLIDE 63

caller’s
 stack frame printf’s stack frame

printf format strings

int i = 10; printf(“%d %p\n”, i, &i);

0xffffffff 0x00000000

&i 10 %eip %ebp &fmt …

  • printf takes variable number of arguments
  • printf pays no mind to where the stack frame “ends”
  • It presumes that you called it with (at least) as many arguments as

specified in the format string

slide-64
SLIDE 64

caller’s
 stack frame printf’s stack frame

printf format strings

int i = 10; printf(“%d %p\n”, i, &i);

0xffffffff 0x00000000

&i 10 %eip %ebp &fmt …

  • printf takes variable number of arguments
  • printf pays no mind to where the stack frame “ends”
  • It presumes that you called it with (at least) as many arguments as

specified in the format string

slide-65
SLIDE 65

caller’s
 stack frame printf’s stack frame

printf format strings

int i = 10; printf(“%d %p\n”, i, &i);

0xffffffff 0x00000000

&i 10 %eip %ebp &fmt …

  • printf takes variable number of arguments
  • printf pays no mind to where the stack frame “ends”
  • It presumes that you called it with (at least) as many arguments as

specified in the format string

slide-66
SLIDE 66

caller’s
 stack frame printf’s stack frame

printf format strings

int i = 10; printf(“%d %p\n”, i, &i);

0xffffffff 0x00000000

&i 10 %eip %ebp &fmt …

  • printf takes variable number of arguments
  • printf pays no mind to where the stack frame “ends”
  • It presumes that you called it with (at least) as many arguments as

specified in the format string

slide-67
SLIDE 67

void vulnerable() { char buf[80]; if(fgets(buf, sizeof(buf), stdin)==NULL) return; printf(buf); }

slide-68
SLIDE 68

void vulnerable() { char buf[80]; if(fgets(buf, sizeof(buf), stdin)==NULL) return; printf(buf); }

“%d %x"

slide-69
SLIDE 69

void vulnerable() { char buf[80]; if(fgets(buf, sizeof(buf), stdin)==NULL) return; printf(buf); }

caller’s
 stack frame 0xffffffff 0x00000000

%eip %ebp &fmt …

“%d %x"

slide-70
SLIDE 70

void vulnerable() { char buf[80]; if(fgets(buf, sizeof(buf), stdin)==NULL) return; printf(buf); }

caller’s
 stack frame 0xffffffff 0x00000000

%eip %ebp &fmt …

“%d %x"

slide-71
SLIDE 71

void vulnerable() { char buf[80]; if(fgets(buf, sizeof(buf), stdin)==NULL) return; printf(buf); }

caller’s
 stack frame 0xffffffff 0x00000000

%eip %ebp &fmt …

“%d %x"

slide-72
SLIDE 72

Format string vulnerabilities

slide-73
SLIDE 73

Format string vulnerabilities

  • printf(“100% dml”);
slide-74
SLIDE 74

Format string vulnerabilities

  • printf(“100% dml”);
  • Prints stack entry 4 byes above saved %eip
slide-75
SLIDE 75

Format string vulnerabilities

  • printf(“100% dml”);
  • Prints stack entry 4 byes above saved %eip
  • printf(“%s”);
slide-76
SLIDE 76

Format string vulnerabilities

  • printf(“100% dml”);
  • Prints stack entry 4 byes above saved %eip
  • printf(“%s”);
  • Prints bytes pointed to by that stack entry
slide-77
SLIDE 77

Format string vulnerabilities

  • printf(“100% dml”);
  • Prints stack entry 4 byes above saved %eip
  • printf(“%s”);
  • Prints bytes pointed to by that stack entry
  • printf(“%d %d %d %d …”);
slide-78
SLIDE 78

Format string vulnerabilities

  • printf(“100% dml”);
  • Prints stack entry 4 byes above saved %eip
  • printf(“%s”);
  • Prints bytes pointed to by that stack entry
  • printf(“%d %d %d %d …”);
  • Prints a series of stack entries as integers
slide-79
SLIDE 79

Format string vulnerabilities

  • printf(“100% dml”);
  • Prints stack entry 4 byes above saved %eip
  • printf(“%s”);
  • Prints bytes pointed to by that stack entry
  • printf(“%d %d %d %d …”);
  • Prints a series of stack entries as integers
  • printf(“%08x %08x %08x %08x …”);
slide-80
SLIDE 80

Format string vulnerabilities

  • printf(“100% dml”);
  • Prints stack entry 4 byes above saved %eip
  • printf(“%s”);
  • Prints bytes pointed to by that stack entry
  • printf(“%d %d %d %d …”);
  • Prints a series of stack entries as integers
  • printf(“%08x %08x %08x %08x …”);
  • Same, but nicely formatted hex
slide-81
SLIDE 81

Format string vulnerabilities

  • printf(“100% dml”);
  • Prints stack entry 4 byes above saved %eip
  • printf(“%s”);
  • Prints bytes pointed to by that stack entry
  • printf(“%d %d %d %d …”);
  • Prints a series of stack entries as integers
  • printf(“%08x %08x %08x %08x …”);
  • Same, but nicely formatted hex
  • printf(“100% no way!”)
slide-82
SLIDE 82

Format string vulnerabilities

  • printf(“100% dml”);
  • Prints stack entry 4 byes above saved %eip
  • printf(“%s”);
  • Prints bytes pointed to by that stack entry
  • printf(“%d %d %d %d …”);
  • Prints a series of stack entries as integers
  • printf(“%08x %08x %08x %08x …”);
  • Same, but nicely formatted hex
  • printf(“100% no way!”)
  • WRITES the number 3 to address pointed to by stack entry
slide-83
SLIDE 83

Format string prevalence

0.125 0.25 0.375 0.5 2002 2004 2006 2008 2010 2012 2014

% of vulnerabilities that involve format string bugs

http://web.nvd.nist.gov/view/vuln/statistics

slide-84
SLIDE 84

What’s wrong with this code?

#define BUF_SIZE 16 char buf[BUF_SIZE]; void vulnerable() { int len = read_int_from_network(); char *p = read_string_from_network(); if(len > BUF_SIZE) { printf(“Too large\n”); return; } memcpy(buf, p, len); }

slide-85
SLIDE 85

What’s wrong with this code?

#define BUF_SIZE 16 char buf[BUF_SIZE]; void vulnerable() { int len = read_int_from_network(); char *p = read_string_from_network(); if(len > BUF_SIZE) { printf(“Too large\n”); return; } memcpy(buf, p, len); } void *memcpy(void *dest, const void *src, size_t n);

slide-86
SLIDE 86

What’s wrong with this code?

#define BUF_SIZE 16 char buf[BUF_SIZE]; void vulnerable() { int len = read_int_from_network(); char *p = read_string_from_network(); if(len > BUF_SIZE) { printf(“Too large\n”); return; } memcpy(buf, p, len); } void *memcpy(void *dest, const void *src, size_t n); typedef unsigned int size_t;

slide-87
SLIDE 87

What’s wrong with this code?

#define BUF_SIZE 16 char buf[BUF_SIZE]; void vulnerable() { int len = read_int_from_network(); char *p = read_string_from_network(); if(len > BUF_SIZE) { printf(“Too large\n”); return; } memcpy(buf, p, len); } void *memcpy(void *dest, const void *src, size_t n); typedef unsigned int size_t;

Negative

slide-88
SLIDE 88

What’s wrong with this code?

#define BUF_SIZE 16 char buf[BUF_SIZE]; void vulnerable() { int len = read_int_from_network(); char *p = read_string_from_network(); if(len > BUF_SIZE) { printf(“Too large\n”); return; } memcpy(buf, p, len); } void *memcpy(void *dest, const void *src, size_t n); typedef unsigned int size_t;

Ok Negative

slide-89
SLIDE 89

What’s wrong with this code?

#define BUF_SIZE 16 char buf[BUF_SIZE]; void vulnerable() { int len = read_int_from_network(); char *p = read_string_from_network(); if(len > BUF_SIZE) { printf(“Too large\n”); return; } memcpy(buf, p, len); } void *memcpy(void *dest, const void *src, size_t n); typedef unsigned int size_t;

Ok Negative Implicit cast to unsigned

slide-90
SLIDE 90

Integer overflow vulnerabilities

slide-91
SLIDE 91

What’s wrong with this code?

void vulnerable() { size_t len; char *buf; len = read_int_from_network(); buf = malloc(len + 5); read(fd, buf, len); ... }

slide-92
SLIDE 92

What’s wrong with this code?

void vulnerable() { size_t len; char *buf; len = read_int_from_network(); buf = malloc(len + 5); read(fd, buf, len); ... }

HUGE

slide-93
SLIDE 93

What’s wrong with this code?

void vulnerable() { size_t len; char *buf; len = read_int_from_network(); buf = malloc(len + 5); read(fd, buf, len); ... }

HUGE Wrap-around

slide-94
SLIDE 94

What’s wrong with this code?

void vulnerable() { size_t len; char *buf; len = read_int_from_network(); buf = malloc(len + 5); read(fd, buf, len); ... }

HUGE Wrap-around Takeaway: You have to know the semantics

  • f your programming language to avoid these errors
slide-95
SLIDE 95

Integer overflow prevalence

0.75 1.5 2.25 3 2000 2002 2004 2006 2008 2010 2012 2014

% of vulnerabilities that
 involve integer overflows

http://web.nvd.nist.gov/view/vuln/statistics

slide-96
SLIDE 96

What’s wrong with this code?

int main() { char buf[1024]; ... if(access(argv[1], R_OK) != 0) { printf(“cannot access file\n”); exit(-1); } file = open(argv[1], O_RDONLY); read(file, buf, 1023); close(file); printf(“%s\n”, buf); return 0; }

Suppose that it has higher privilege than the user

slide-97
SLIDE 97

What’s wrong with this code?

int main() { char buf[1024]; ... if(access(argv[1], R_OK) != 0) { printf(“cannot access file\n”); exit(-1); } file = open(argv[1], O_RDONLY); read(file, buf, 1023); close(file); printf(“%s\n”, buf); return 0; }

Suppose that it has higher privilege than the user uid euid

slide-98
SLIDE 98

What’s wrong with this code?

int main() { char buf[1024]; ... if(access(argv[1], R_OK) != 0) { printf(“cannot access file\n”); exit(-1); } file = open(argv[1], O_RDONLY); read(file, buf, 1023); close(file); printf(“%s\n”, buf); return 0; }

Suppose that it has higher privilege than the user ~attacker/mystuff.txt uid euid

slide-99
SLIDE 99

What’s wrong with this code?

int main() { char buf[1024]; ... if(access(argv[1], R_OK) != 0) { printf(“cannot access file\n”); exit(-1); } file = open(argv[1], O_RDONLY); read(file, buf, 1023); close(file); printf(“%s\n”, buf); return 0; }

Suppose that it has higher privilege than the user ~attacker/mystuff.txt uid euid

slide-100
SLIDE 100

What’s wrong with this code?

int main() { char buf[1024]; ... if(access(argv[1], R_OK) != 0) { printf(“cannot access file\n”); exit(-1); } file = open(argv[1], O_RDONLY); read(file, buf, 1023); close(file); printf(“%s\n”, buf); return 0; }

Suppose that it has higher privilege than the user ~attacker/mystuff.txt

ln -s /usr/sensitive ~attacker/mystuff.txt

uid euid

slide-101
SLIDE 101

What’s wrong with this code?

int main() { char buf[1024]; ... if(access(argv[1], R_OK) != 0) { printf(“cannot access file\n”); exit(-1); } file = open(argv[1], O_RDONLY); read(file, buf, 1023); close(file); printf(“%s\n”, buf); return 0; }

Suppose that it has higher privilege than the user ~attacker/mystuff.txt

ln -s /usr/sensitive ~attacker/mystuff.txt

“Time of Check/Time of Use” Problem (TOCTOU) uid euid

slide-102
SLIDE 102

Avoiding TOCTOU

int main() { char buf[1024]; ... if(access(argv[1], R_OK) != 0) { printf(“cannot access file\n”); exit(-1); } file = open(argv[1], O_RDONLY); read(file, buf, 1023); close(file); printf(buf); }

uid euid

slide-103
SLIDE 103

Avoiding TOCTOU

int main() { char buf[1024]; ... if(access(argv[1], R_OK) != 0) { printf(“cannot access file\n”); exit(-1); } file = open(argv[1], O_RDONLY); read(file, buf, 1023); close(file); printf(buf); }

uid euid

slide-104
SLIDE 104

Avoiding TOCTOU

int main() { char buf[1024]; ... if(access(argv[1], R_OK) != 0) { printf(“cannot access file\n”); exit(-1); } file = open(argv[1], O_RDONLY); read(file, buf, 1023); close(file); printf(buf); } euid = geteuid(); uid = getuid(); seteuid(uid); // Drop privileges

uid euid

slide-105
SLIDE 105

Avoiding TOCTOU

int main() { char buf[1024]; ... if(access(argv[1], R_OK) != 0) { printf(“cannot access file\n”); exit(-1); } file = open(argv[1], O_RDONLY); read(file, buf, 1023); close(file); printf(buf); } euid = geteuid(); uid = getuid(); seteuid(uid); // Drop privileges seteuid(euid); // Restore privileges

uid euid

slide-106
SLIDE 106

Memory safety attacks

  • Buffer overflows
  • Can be used to read/write data on stack or heap
  • Can be used to inject code (ultimately root shell)
  • Format string errors
  • Can be used to read/write stack data
  • Integer overflow errors
  • Can be used to change the control flow of a program
  • TOCTOU problem
  • Can be used to raise privileges
slide-107
SLIDE 107

General defenses against memory-safety

slide-108
SLIDE 108

Defensive coding practices

  • Think defensive driving
  • Avoid depending on anyone else around you
  • If someone does something unexpected, you won’t

crash (or worse)

  • It’s about minimizing trust
  • Each module takes responsibility for checking the

validity of all inputs sent to it

  • Even if you “know” your callers will never send a NULL

pointer…

  • …Better to throw an exception (or even exit) than run

malicious code

http://nob.cs.ucdavis.edu/bishop/secprog/robust.html

slide-109
SLIDE 109

How to program defensively

  • Code reviews, real or imagined
  • Organize your code so it is obviously correct
  • Re-write until it would be self-evident to a reviewer
  • Remove the opportunity for programmer mistakes

with better languages and libraries

  • Java performs automatic bounds checking
  • C++ provides a safe std::string class

“Debugging is twice as hard as writing the code in the first

  • place. Therefore, if you write the code as cleverly as possible,

you are, by definition, not smart enough to debug it.

slide-110
SLIDE 110

Secure coding practices

char digit_to_char(int i) { char convert[] = “0123456789”; return convert[i]; }

Think about all potential inputs, no matter how peculiar

slide-111
SLIDE 111

Secure coding practices

char digit_to_char(int i) { char convert[] = “0123456789”; return convert[i]; } char digit_to_char(int i) { char convert[] = “0123456789”; if(i < 0 || i > 9) return ‘?’; return convert[i]; }

Think about all potential inputs, no matter how peculiar

slide-112
SLIDE 112

Secure coding practices

char digit_to_char(int i) { char convert[] = “0123456789”; return convert[i]; } char digit_to_char(int i) { char convert[] = “0123456789”; if(i < 0 || i > 9) return ‘?’; return convert[i]; }

Enforce rule compliance at runtime Think about all potential inputs, no matter how peculiar

slide-113
SLIDE 113

Rule: Use safe string functions

  • Traditional string library routines assume

target buffers have sufficient length

slide-114
SLIDE 114

Rule: Use safe string functions

  • Traditional string library routines assume

target buffers have sufficient length

char str[4]; char buf[10] = “good”; strcpy(str,”hello”); // overflows str strcat(buf,” day to you”); // overflows buf

slide-115
SLIDE 115

Rule: Use safe string functions

  • Traditional string library routines assume

target buffers have sufficient length

char str[4]; char buf[10] = “good”; strcpy(str,”hello”); // overflows str strcat(buf,” day to you”); // overflows buf char str[4]; char buf[10] = “good”; strlcpy(str,”hello”,sizeof(str)); //fails strlcat(buf,” day to you”,sizeof(buf));//fails

  • Safe versions check the destination length
slide-116
SLIDE 116

Rule: Use safe string functions

  • Traditional string library routines assume

target buffers have sufficient length

char str[4]; char buf[10] = “good”; strcpy(str,”hello”); // overflows str strcat(buf,” day to you”); // overflows buf char str[4]; char buf[10] = “good”; strlcpy(str,”hello”,sizeof(str)); //fails strlcat(buf,” day to you”,sizeof(buf));//fails

  • Safe versions check the destination length

Again: new your system’s/language’s semantics

slide-117
SLIDE 117

Replacements

slide-118
SLIDE 118

Replacements

  • … for string-oriented functions
  • strcat ⟹ strlcat
  • strcpy ⟹ strlcpy
  • strncat ⟹ strlcat
  • strncpy ⟹ strlcpy
  • sprintf ⟹ snprintf
  • vsprintf ⟹ vsnprintf
  • gets ⟹ fgets
slide-119
SLIDE 119

Replacements

  • … for string-oriented functions
  • strcat ⟹ strlcat
  • strcpy ⟹ strlcpy
  • strncat ⟹ strlcat
  • strncpy ⟹ strlcpy
  • sprintf ⟹ snprintf
  • vsprintf ⟹ vsnprintf
  • gets ⟹ fgets
  • Microsoft versions different
  • strcpy_s, strcat_s, …
slide-120
SLIDE 120

Replacements

  • … for string-oriented functions
  • strcat ⟹ strlcat
  • strcpy ⟹ strlcpy
  • strncat ⟹ strlcat
  • strncpy ⟹ strlcpy
  • sprintf ⟹ snprintf
  • vsprintf ⟹ vsnprintf
  • gets ⟹ fgets
  • Microsoft versions different
  • strcpy_s, strcat_s, …

Note: None of these in and of themselves are “insecure.”
 They are just commonly misused.

slide-121
SLIDE 121

(Better) Rule: Use safe string library

  • Libraries designed to ensure strings used safely
  • Safety first, despite some performance loss
  • Example: Very Secure FTP (vsftp) string library
  • Another example: C++ std::string safe string library

struct mystr; // impl hidden void str_alloc_text(struct mystr* p_str, const char* p_src); void str_append_str(struct mystr* p_str, const struct mystr* p_other); int str_equal(const struct mystr* p_str1, const struct mystr* p_str2); int str_contains_space(const struct mystr* p_str); …

http://vsftpd.beasts.org/

slide-122
SLIDE 122

Rule: Understand pointer arithmetic

slide-123
SLIDE 123

Rule: Understand pointer arithmetic

int x; int *pi = &x; char *pc = (char*) &x;

slide-124
SLIDE 124

Rule: Understand pointer arithmetic

int x; int *pi = &x; char *pc = (char*) &x; (pi + 1) == (pc + 1) ???

slide-125
SLIDE 125

Rule: Understand pointer arithmetic

int x; int *pi = &x; char *pc = (char*) &x; (pi + 1) == (pc + 1) ???

1 2 3 4 5 6 7 8

x

slide-126
SLIDE 126

Rule: Understand pointer arithmetic

int x; int *pi = &x; char *pc = (char*) &x; (pi + 1) == (pc + 1) ???

1 2 3 4 5 6 7 8

x

slide-127
SLIDE 127

Rule: Understand pointer arithmetic

int x; int *pi = &x; char *pc = (char*) &x; (pi + 1) == (pc + 1) ???

1 2 3 4 5 6 7 8

x

slide-128
SLIDE 128

Rule: Understand pointer arithmetic

  • sizeof() returns number of bytes, but pointer

arithmetic multiplies by the sizeof the type

int buf[SIZE] = { … }; int *buf_ptr = buf; while (!done() && buf_ptr < (buf + sizeof(buf))) { *buf_ptr++ = getnext(); // will overflow } int x; int *pi = &x; char *pc = (char*) &x; (pi + 1) == (pc + 1) ???

1 2 3 4 5 6 7 8

x

slide-129
SLIDE 129

Rule: Understand pointer arithmetic

  • sizeof() returns number of bytes, but pointer

arithmetic multiplies by the sizeof the type

int buf[SIZE] = { … }; int *buf_ptr = buf; while (!done() && buf_ptr < (buf + sizeof(buf))) { *buf_ptr++ = getnext(); // will overflow } while (!done() && buf_ptr < (buf + SIZE)) { *buf_ptr++ = getnext(); // stays in bounds }

  • So, use the right units

int x; int *pi = &x; char *pc = (char*) &x; (pi + 1) == (pc + 1) ???

1 2 3 4 5 6 7 8

x

slide-130
SLIDE 130

Defend dangling pointers

int x = 5; int *p = malloc(sizeof(int)); free(p); int **q = malloc(sizeof(int*)); //reuses p’s space *q = &x; *p = 5; **q = 3; //crash (or worse)!

x: p: q: Stack Heap

?

slide-131
SLIDE 131

Defend dangling pointers

int x = 5; int *p = malloc(sizeof(int)); free(p); int **q = malloc(sizeof(int*)); //reuses p’s space *q = &x; *p = 5; **q = 3; //crash (or worse)!

x: p: q: Stack Heap

?

5

slide-132
SLIDE 132

Defend dangling pointers

int x = 5; int *p = malloc(sizeof(int)); free(p); int **q = malloc(sizeof(int*)); //reuses p’s space *q = &x; *p = 5; **q = 3; //crash (or worse)! ?

x: p: q: Stack Heap

?

5

slide-133
SLIDE 133

Defend dangling pointers

int x = 5; int *p = malloc(sizeof(int)); free(p); int **q = malloc(sizeof(int*)); //reuses p’s space *q = &x; *p = 5; **q = 3; //crash (or worse)!

x: p: q: Stack Heap

?

5

slide-134
SLIDE 134

Defend dangling pointers

int x = 5; int *p = malloc(sizeof(int)); free(p); int **q = malloc(sizeof(int*)); //reuses p’s space *q = &x; *p = 5; **q = 3; //crash (or worse)!

x: p: q: Stack Heap

?

5

?

slide-135
SLIDE 135

Defend dangling pointers

int x = 5; int *p = malloc(sizeof(int)); free(p); int **q = malloc(sizeof(int*)); //reuses p’s space *q = &x; *p = 5; **q = 3; //crash (or worse)!

x: p: q: Stack Heap

?

5

?

¡

slide-136
SLIDE 136

Defend dangling pointers

int x = 5; int *p = malloc(sizeof(int)); free(p); int **q = malloc(sizeof(int*)); //reuses p’s space *q = &x; *p = 5; **q = 3; //crash (or worse)!

x: p: q: Stack Heap

?

5

?

¡ 5

slide-137
SLIDE 137

Defend dangling pointers

int x = 5; int *p = malloc(sizeof(int)); free(p); int **q = malloc(sizeof(int*)); //reuses p’s space *q = &x; *p = 5; **q = 3; //crash (or worse)!

x: p: q: Stack Heap

?

5

?

¡ 5

slide-138
SLIDE 138

Defend dangling pointers

int x = 5; int *p = malloc(sizeof(int)); free(p); int **q = malloc(sizeof(int*)); //reuses p’s space *q = &x; *p = 5; **q = 3; //crash (or worse)!

x: p: q: Stack Heap

?

5

?

¡ 5

slide-139
SLIDE 139

Rule: Use NULL after free

int x = 5; int *p = malloc(sizeof(int)); free(p); p = NULL; //defend against bad deref int **q = malloc(sizeof(int*)); //reuses p’s space *q = &x; *p = 5; //(good) crash **q = 3;

x: p: q: Stack Heap

?

slide-140
SLIDE 140

Rule: Use NULL after free

int x = 5; int *p = malloc(sizeof(int)); free(p); p = NULL; //defend against bad deref int **q = malloc(sizeof(int*)); //reuses p’s space *q = &x; *p = 5; //(good) crash **q = 3;

x: p: q: Stack Heap

?

5

slide-141
SLIDE 141

Rule: Use NULL after free

int x = 5; int *p = malloc(sizeof(int)); free(p); p = NULL; //defend against bad deref int **q = malloc(sizeof(int*)); //reuses p’s space *q = &x; *p = 5; //(good) crash **q = 3; ?

x: p: q: Stack Heap

?

5

slide-142
SLIDE 142

Rule: Use NULL after free

int x = 5; int *p = malloc(sizeof(int)); free(p); p = NULL; //defend against bad deref int **q = malloc(sizeof(int*)); //reuses p’s space *q = &x; *p = 5; //(good) crash **q = 3;

x: p: q: Stack Heap

?

5

slide-143
SLIDE 143

Rule: Use NULL after free

int x = 5; int *p = malloc(sizeof(int)); free(p); p = NULL; //defend against bad deref int **q = malloc(sizeof(int*)); //reuses p’s space *q = &x; *p = 5; //(good) crash **q = 3;

x: p: q: Stack Heap

?

5

slide-144
SLIDE 144

Rule: Use NULL after free

int x = 5; int *p = malloc(sizeof(int)); free(p); p = NULL; //defend against bad deref int **q = malloc(sizeof(int*)); //reuses p’s space *q = &x; *p = 5; //(good) crash **q = 3;

x: p: q: Stack Heap

?

5

?

slide-145
SLIDE 145

Rule: Use NULL after free

int x = 5; int *p = malloc(sizeof(int)); free(p); p = NULL; //defend against bad deref int **q = malloc(sizeof(int*)); //reuses p’s space *q = &x; *p = 5; //(good) crash **q = 3;

x: p: q: Stack Heap

?

5

?

¡

slide-146
SLIDE 146

Rule: Use NULL after free

int x = 5; int *p = malloc(sizeof(int)); free(p); p = NULL; //defend against bad deref int **q = malloc(sizeof(int*)); //reuses p’s space *q = &x; *p = 5; //(good) crash **q = 3;

x: p: q: Stack Heap

?

5

?

¡

slide-147
SLIDE 147

Manage memory properly

  • Common approach in

C: goto chains to avoid duplicated or missed code

  • Like try/finally in

languages like Java

  • Confirm your logic!…

int foo(int arg1, int arg2) { struct foo *pf1, *pf2; int retc = -1; pf1 = malloc(sizeof(struct foo)); if (!isok(arg1)) goto DONE;

pf2 = malloc(sizeof(struct foo)); if (!isok(arg2)) goto FAIL_ARG2; … retc = 0; FAIL_ARG2: free(pf2); //fallthru DONE: free(pf1); return retc; }

slide-148
SLIDE 148

{ . . . hashOut.data = hashes + SSL_MD5_DIGEST_LEN; hashOut.length = SSL_SHA1_DIGEST_LEN; if ((err = SSLFreeBuffer(&hashCtx)) != 0) goto fail; if ((err = ReadyHash(&SSLHashSHA1, &hashCtx)) != 0) goto fail; if ((err = SSLHashSHA1.update(&hashCtx, &clientRandom)) != 0) goto fail; if ((err = SSLHashSHA1.update(&hashCtx, &serverRandom)) != 0) goto fail; if ((err = SSLHashSHA1.update(&hashCtx, &signedParams)) != 0) goto fail; goto fail; if ((err = SSLHashSHA1.final(&hashCtx, &hashOut)) != 0) goto fail; err = sslRawVerify(...); . . . fail:
 SSLFreeBuffer(&hashCtx); return err; }

What’s wrong with this code?

slide-149
SLIDE 149

{ . . . hashOut.data = hashes + SSL_MD5_DIGEST_LEN; hashOut.length = SSL_SHA1_DIGEST_LEN; if ((err = SSLFreeBuffer(&hashCtx)) != 0) goto fail; if ((err = ReadyHash(&SSLHashSHA1, &hashCtx)) != 0) goto fail; if ((err = SSLHashSHA1.update(&hashCtx, &clientRandom)) != 0) goto fail; if ((err = SSLHashSHA1.update(&hashCtx, &serverRandom)) != 0) goto fail; if ((err = SSLHashSHA1.update(&hashCtx, &signedParams)) != 0) goto fail; goto fail; if ((err = SSLHashSHA1.final(&hashCtx, &hashOut)) != 0) goto fail; err = sslRawVerify(...); . . . fail:
 SSLFreeBuffer(&hashCtx); return err; }

What’s wrong with this code?

Basically, this is checking a signature
 (more on this later)

slide-150
SLIDE 150

{ . . . hashOut.data = hashes + SSL_MD5_DIGEST_LEN; hashOut.length = SSL_SHA1_DIGEST_LEN; if ((err = SSLFreeBuffer(&hashCtx)) != 0) goto fail; if ((err = ReadyHash(&SSLHashSHA1, &hashCtx)) != 0) goto fail; if ((err = SSLHashSHA1.update(&hashCtx, &clientRandom)) != 0) goto fail; if ((err = SSLHashSHA1.update(&hashCtx, &serverRandom)) != 0) goto fail; if ((err = SSLHashSHA1.update(&hashCtx, &signedParams)) != 0) goto fail; goto fail; if ((err = SSLHashSHA1.final(&hashCtx, &hashOut)) != 0) goto fail; err = sslRawVerify(...); . . . fail:
 SSLFreeBuffer(&hashCtx); return err; }

What’s wrong with this code?

Basically, this is checking a signature
 (more on this later) Will always jump to ‘fail’

slide-151
SLIDE 151

Rule: Use a safe allocator

  • ASLR challenges exploits by making the base address
  • f libraries unpredictable
  • Challenge heap-based overflows by making the

addresses returned by malloc unpredictable

  • Can have some negative performance impact
  • Example implementations:
  • Windows Fault-Tolerant Heap
  • http://msdn.microsoft.com/en-us/library/windows/desktop/

dd744764(v=vs.85).aspx

  • DieHard (on which fault-tolerant heap is based)
  • http://plasma.cs.umass.edu/emery/diehard.html
slide-152
SLIDE 152

Rule: Favor safe libraries

  • Libraries encapsulate well-thought-out design.

Take advantage!

  • Smart pointers
  • Pointers with only safe operations
  • Lifetimes managed appropriately
  • First in the Boost library, now a C++11 standard
  • Networking: Google protocol buffers, Apache Thrift
  • For dealing with network-transmitted data
  • Ensures input validation, parsing, etc.
  • Efficient
slide-153
SLIDE 153

Defensive coding practices

  • Think defensive driving
  • Avoid depending on anyone else around you
  • If someone does something unexpected, you won’t

crash (or worse)

  • It’s about minimizing trust
  • Each module takes responsibility for checking the

validity of all inputs sent to it

  • Even if you “know” your callers will never send a NULL

pointer…

  • …Better to throw an exception (or even exit) than run

malicious code

http://nob.cs.ucdavis.edu/bishop/secprog/robust.html

slide-154
SLIDE 154

Automated testing techniques

  • Code analysis
  • Static: Many of the bugs we’ve shown could be easily

detected (but we run into the Halting Problem)

  • Dynamic: Run in a VM and look for bad writes (valgrind)
  • Fuzz testing
  • Generate many random inputs, see if the program fails
  • Totally random
  • Start with a valid input file and mutate
  • Structure-driven input generation: take into account the intended

format of the input (e.g., “string int float string”)

  • Typically involves many many inputs (clusterfuzz.google.com)
slide-155
SLIDE 155

Penetration testing

  • Fuzz testing is a form of “penetration testing” (pen

testing)

  • Pen testing assesses security by actively trying to

find explotable vulnerabilities

  • Useful for both attackers and defenders
  • Pen testing is useful at many different levels
  • Testing programs
  • Testing applications
  • Testing a network
  • Testing a server…
slide-156
SLIDE 156

Kinds of fuzzing

slide-157
SLIDE 157

Kinds of fuzzing

  • Black box
  • The tool knows nothing about the program or its input
  • Easy to use and get started, but will explore only

shallow states unless it gets lucky

slide-158
SLIDE 158

Kinds of fuzzing

  • Black box
  • The tool knows nothing about the program or its input
  • Easy to use and get started, but will explore only

shallow states unless it gets lucky

  • Grammar based
  • The tool generates input informed by a grammar
  • More work to use, to produce the grammar, but can go deeper in the

state space

slide-159
SLIDE 159

Kinds of fuzzing

  • Black box
  • The tool knows nothing about the program or its input
  • Easy to use and get started, but will explore only

shallow states unless it gets lucky

  • Grammar based
  • The tool generates input informed by a grammar
  • More work to use, to produce the grammar, but can go deeper in the

state space

  • The tool generates new inputs at least partially informed by the code of

the program being fuzzed

  • Often easy to use, but computationally expensive

White box

slide-160
SLIDE 160

Fuzzing inputs

slide-161
SLIDE 161

Fuzzing inputs

  • Mutation
  • Take a legal input and mutate it, using that as input
slide-162
SLIDE 162

Fuzzing inputs

  • Mutation
  • Take a legal input and mutate it, using that as input
  • Legal input might be human-produced, or automated,

e.g., from a grammar or SMT solver query

  • Mutation might also be forced to adhere to grammar
slide-163
SLIDE 163

Fuzzing inputs

  • Mutation
  • Take a legal input and mutate it, using that as input
  • Legal input might be human-produced, or automated,

e.g., from a grammar or SMT solver query

  • Mutation might also be forced to adhere to grammar
  • Generational
  • Generate input from scratch, e.g., from a grammar
slide-164
SLIDE 164

Fuzzing inputs

  • Mutation
  • Take a legal input and mutate it, using that as input
  • Legal input might be human-produced, or automated,

e.g., from a grammar or SMT solver query

  • Mutation might also be forced to adhere to grammar
  • Generational
  • Generate input from scratch, e.g., from a grammar
  • Combinations
slide-165
SLIDE 165

Fuzzing inputs

  • Mutation
  • Take a legal input and mutate it, using that as input
  • Legal input might be human-produced, or automated,

e.g., from a grammar or SMT solver query

  • Mutation might also be forced to adhere to grammar
  • Generational
  • Generate input from scratch, e.g., from a grammar
  • Combinations
  • Generate initial input, mutateN, generate new inputs, …
slide-166
SLIDE 166

Fuzzing inputs

  • Mutation
  • Take a legal input and mutate it, using that as input
  • Legal input might be human-produced, or automated,

e.g., from a grammar or SMT solver query

  • Mutation might also be forced to adhere to grammar
  • Generational
  • Generate input from scratch, e.g., from a grammar
  • Combinations
  • Generate initial input, mutateN, generate new inputs, …
  • Generate mutations according to grammar
slide-167
SLIDE 167

File-based fuzzing

  • Mutate or generate inputs
  • Run the target program with them
  • See what happens
slide-168
SLIDE 168

File-based fuzzing

  • Mutate or generate inputs
  • Run the target program with them
  • See what happens
XXX XXX XXX XXX y36 XXz mmm
slide-169
SLIDE 169

Examples: Radamsa and Blab

slide-170
SLIDE 170

Examples: Radamsa and Blab

  • Radamsa is a mutation-based, black box fuzzer
  • It mutates inputs that are given, passing them along
slide-171
SLIDE 171

Examples: Radamsa and Blab

  • Radamsa is a mutation-based, black box fuzzer
  • It mutates inputs that are given, passing them along

% echo "1 + (2 + (3 + 4))" | radamsa --seed 12 -n 4

slide-172
SLIDE 172

Examples: Radamsa and Blab

  • Radamsa is a mutation-based, black box fuzzer
  • It mutates inputs that are given, passing them along

% echo "1 + (2 + (3 + 4))" | radamsa --seed 12 -n 4 5!++ (3 + -5)) 1 + (3 + 41907596644) 1 + (-4 + (3 + 4)) 1 + (2 + (3 + 4

slide-173
SLIDE 173

Examples: Radamsa and Blab

  • Radamsa is a mutation-based, black box fuzzer
  • It mutates inputs that are given, passing them along

% echo "1 + (2 + (3 + 4))" | radamsa --seed 12 -n 4 5!++ (3 + -5)) 1 + (3 + 41907596644) 1 + (-4 + (3 + 4)) 1 + (2 + (3 + 4 % echo … | radamsa --seed 12 -n 4 | bc -l

slide-174
SLIDE 174

Examples: Radamsa and Blab

  • Radamsa is a mutation-based, black box fuzzer
  • It mutates inputs that are given, passing them along

% echo "1 + (2 + (3 + 4))" | radamsa --seed 12 -n 4 5!++ (3 + -5)) 1 + (3 + 41907596644) 1 + (-4 + (3 + 4)) 1 + (2 + (3 + 4 % echo … | radamsa --seed 12 -n 4 | bc -l https://code.google.com/p/ouspg/wiki/Radamsa https://code.google.com/p/ouspg/wiki/Blab

  • Blab generates inputs according to a grammar

(grammar-based), specified as regexps and CFGs

slide-175
SLIDE 175

Examples: Radamsa and Blab

  • Radamsa is a mutation-based, black box fuzzer
  • It mutates inputs that are given, passing them along

% echo "1 + (2 + (3 + 4))" | radamsa --seed 12 -n 4 5!++ (3 + -5)) 1 + (3 + 41907596644) 1 + (-4 + (3 + 4)) 1 + (2 + (3 + 4 % echo … | radamsa --seed 12 -n 4 | bc -l https://code.google.com/p/ouspg/wiki/Radamsa https://code.google.com/p/ouspg/wiki/Blab % blab -e '(([wrstp][aeiouy]{1,2}){1,4} 32){5} 10’

  • Blab generates inputs according to a grammar

(grammar-based), specified as regexps and CFGs

slide-176
SLIDE 176

Examples: Radamsa and Blab

  • Radamsa is a mutation-based, black box fuzzer
  • It mutates inputs that are given, passing them along

% echo "1 + (2 + (3 + 4))" | radamsa --seed 12 -n 4 5!++ (3 + -5)) 1 + (3 + 41907596644) 1 + (-4 + (3 + 4)) 1 + (2 + (3 + 4 % echo … | radamsa --seed 12 -n 4 | bc -l https://code.google.com/p/ouspg/wiki/Radamsa https://code.google.com/p/ouspg/wiki/Blab % blab -e '(([wrstp][aeiouy]{1,2}){1,4} 32){5} 10’ soty wypisi tisyro to patu

  • Blab generates inputs according to a grammar

(grammar-based), specified as regexps and CFGs

slide-177
SLIDE 177

Network-based fuzzing

  • Act as 1/2 of a communicating pair
  • Inputs could be produced by replaying previously

recorded interaction, and altering it, or producing it from scratch (e.g., from a protocol grammar)

slide-178
SLIDE 178

Network-based fuzzing

  • Act as 1/2 of a communicating pair
  • Inputs could be produced by replaying previously

recorded interaction, and altering it, or producing it from scratch (e.g., from a protocol grammar)

XXX XXX XXX XXX XXX XXX XXX XXX XXX
slide-179
SLIDE 179

Network-based fuzzing

  • Act as 1/2 of a communicating pair
  • Inputs could be produced by replaying previously

recorded interaction, and altering it, or producing it from scratch (e.g., from a protocol grammar)

XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX y36 XXz mmm XXX XXX XXX XXX y36 XXz mmm
slide-180
SLIDE 180

Network-based fuzzing

  • Act as a “man in the middle”
  • mutating inputs exchanged between parties (perhaps

informed by a grammar)

slide-181
SLIDE 181

Network-based fuzzing

  • Act as a “man in the middle”
  • mutating inputs exchanged between parties (perhaps

informed by a grammar)

XXX y36 XXz mmm XXX XXX XXX
slide-182
SLIDE 182

Network-based fuzzing

  • Act as a “man in the middle”
  • mutating inputs exchanged between parties (perhaps

informed by a grammar)

XXX y36 XXz mmm XXX XXX XXX XXX XXX XXX XXX y36 XXz mmm
slide-183
SLIDE 183

There are many many fuzzers

  • American Fuzzy Lop
  • Mutation-based white-box buzzer
  • SPIKE
  • A library for creating network-based fuzzers
  • Burp Intruder
  • Automates customized attacks against web apps
  • And many more… (BFF, Sulley, …)
slide-184
SLIDE 184

You fuzz, you crash. Then what?

slide-185
SLIDE 185

You fuzz, you crash. Then what?

Try to find the root cause

slide-186
SLIDE 186

You fuzz, you crash. Then what?

Try to find the root cause Is there a smaller input that crashes in the
 same spot? (Make it easier to understand)

slide-187
SLIDE 187

You fuzz, you crash. Then what?

Try to find the root cause Is there a smaller input that crashes in the
 same spot? (Make it easier to understand) Are there multiple crashes that point back
 to the same bug?

slide-188
SLIDE 188

You fuzz, you crash. Then what?

Try to find the root cause Is there a smaller input that crashes in the
 same spot? (Make it easier to understand) Are there multiple crashes that point back
 to the same bug? Determine if this crash represents an
 exploitable vulnerability

slide-189
SLIDE 189

You fuzz, you crash. Then what?

Try to find the root cause Is there a smaller input that crashes in the
 same spot? (Make it easier to understand) Are there multiple crashes that point back
 to the same bug? Determine if this crash represents an
 exploitable vulnerability In particular, is there a buffer overrun?

slide-190
SLIDE 190

Finding memory errors

slide-191
SLIDE 191

Finding memory errors

  • 1. Compile the program with Address Sanitizer

(ASAN)

  • Instruments accesses to arrays to check for
  • verflows, and use-after-free errors
  • https://code.google.com/p/address-sanitizer/
slide-192
SLIDE 192

Finding memory errors

  • 1. Compile the program with Address Sanitizer

(ASAN)

  • Instruments accesses to arrays to check for
  • verflows, and use-after-free errors
  • https://code.google.com/p/address-sanitizer/
  • 2. Fuzz it
slide-193
SLIDE 193

Finding memory errors

  • 1. Compile the program with Address Sanitizer

(ASAN)

  • Instruments accesses to arrays to check for
  • verflows, and use-after-free errors
  • https://code.google.com/p/address-sanitizer/
  • 2. Fuzz it
  • 3. Did the program crash with an ASAN-

signaled error? Then worry about exploitability

slide-194
SLIDE 194

Finding memory errors

  • 1. Compile the program with Address Sanitizer

(ASAN)

  • Instruments accesses to arrays to check for
  • verflows, and use-after-free errors
  • https://code.google.com/p/address-sanitizer/
  • 2. Fuzz it
  • 3. Did the program crash with an ASAN-

signaled error? Then worry about exploitability

  • Similarly, you can compile with other sorts of

error checkers for the purposes of testing

  • E.g., valgrind memcheck http://valgrind.org/
slide-195
SLIDE 195

Defensive coding summary

  • Understand the systems and libraries you use
  • printf(“%n”); !!
  • This is the root cause of most crypto implementation

errors (next section)

  • Assume the worst; code and design defensively
  • Think defensive driving
  • Use pen testing tools to help automate
  • Assume that attackers will; seek to have at least as

much information as they!

slide-196
SLIDE 196

This time

Secure


Code

Writing & testing for

Continued with

Software

Security

  • Return oriented programming
  • Format string & integer overflow vulnerabilities
  • Defenses via good code & automated pen testing
slide-197
SLIDE 197

Next time

Malware

Getting sick with Continuing with

Software

Security

Required reading:

“StackGuard: Simple Stack Smash Protection for GCC” Optional reading: “Basic Integer Overflows” “Exploiting Format String Vulnerabilities”

http://nob.cs.ucdavis.edu/bishop/secprog/robust.html