Buffer Software Security overflows and other memory safety - - PowerPoint PPT Presentation

buffer
SMART_READER_LITE
LIVE PREVIEW

Buffer Software Security overflows and other memory safety - - PowerPoint PPT Presentation

This time We will begin By investigating our 1st section: Buffer Software Security overflows and other memory safety vulnerabilities History Memory layouts Buffer overflow fundamentals Software security Security is a form


slide-1
SLIDE 1

This time

  • History
  • Memory layouts
  • Buffer overflow fundamentals

Buffer

  • verflows

By investigating

and other memory safety vulnerabilities

We will begin

Software

Security

  • ur 1st section:
slide-2
SLIDE 2

Software security

  • Security is a form of dependability
  • Does the code do “what it should”
  • To this end, we follow the software lifecycle
  • Distinguishing factor: an active, malicious attacker
  • Attack model
  • The developer is trusted
  • But the attacker can provide any inputs
  • Malformed strings
  • Malformed packets
  • etc.

What harm could an attacker possibly cause?

slide-3
SLIDE 3

screensaver --prompt=“Don’t unlock plz” Don't unlock plz press ctrl-c to logout Locked by dml

slide-4
SLIDE 4

screensaver --prompt=“Don’t unlock pretty plz” Don't unlock pretty
 plz press ctrl-c to logout Locked by dml

slide-5
SLIDE 5

screensaver --prompt=“Don’t unlock plz␠␠␠\
 ␠␠␠␠␠␠␠␠␠␠␠␠␠␠␠␠␠␠␠␠␠␠␠␠␠␠␠␠␠␠␠␠␠␠␠␠␠␠␠␠␠” Don't unlock plz Locked by dml press ctrl-c to logout

slide-6
SLIDE 6

screensaver —prompt=“Under maintenance;\
 Do not interrupt␠␠␠␠␠␠␠␠␠␠␠␠␠␠␠␠␠␠␠␠␠␠␠␠␠␠␠␠\
 ␠␠␠␠␠␠␠␠␠␠␠␠␠␠␠␠␠␠␠␠␠␠␠␠␠␠␠␠” Under maintenance; Do not interrupt Locked by dml press ctrl-c to logout

slide-7
SLIDE 7

We’re going to focus on C

C is still very popular

http://www.tiobe.com

slide-8
SLIDE 8

We’re going to focus on C

  • Most kernels & OS utilities
  • fingerd
  • X windows server
  • Many high-performance servers
  • Microsoft IIS
  • Microsoft SQL server
  • Many embedded systems
  • Mars rover
  • But the techniques apply more broadly
  • Wiibrew:“Twilight Hack” exploits buffer overflow when saving the

name of Link’s horse, Epona

Many mission critical systems are written in C

slide-9
SLIDE 9

We’re going to focus on C

The harm can be substantial 1988 1999 2000 2001 2002 2003

  • Morris worm
  • Propagated across machines (too aggressively, thanks to a bug)
  • One way it propagated was a buffer overflow attack against a

vulnerable version of fingerd on VAXes

  • Sent a special string to the finger daemon, which caused it to

execute code that created a new worm copy

  • Didn’t check OS: caused Suns running BSD to crash
  • End result: $10-100M in damages, probation, community service
slide-10
SLIDE 10

We’re going to focus on C

The harm can be substantial 1988 1999 2000 2001 2002 2003

  • Morris worm
  • Propagated across machines (too aggressively, thanks to a bug)
  • One way it propagated was a buffer overflow attack against a

vulnerable version of fingerd on VAXes

  • Sent a special string to the finger daemon, which caused it to

execute code that created a new worm copy

  • Didn’t check OS: caused Suns running BSD to crash
  • End result: $10-100M in damages, probation, community service

Robert Morris is now a professor at MIT

slide-11
SLIDE 11

We’re going to focus on C

The harm can be substantial 1988 1999 2000 2001 2002 2003

  • CodeRed
  • Exploited an overflow in the MS-IIS server
  • 300,000 machines infected in 14 hours
slide-12
SLIDE 12

We’re going to focus on C

The harm can be substantial 1988 1999 2000 2001 2002 2003

  • CodeRed
  • Exploited an overflow in the MS-IIS server
  • 300,000 machines infected in 14 hours
slide-13
SLIDE 13

We’re going to focus on C

The harm can be substantial 1988 1999 2000 2001 2002 2003

  • SQL Slammer
  • Exploited an overflow in the MS-SQL server
  • 75,000 machines infected in 10 minutes
slide-14
SLIDE 14
slide-15
SLIDE 15
slide-16
SLIDE 16

GHOST: glibc vulnerability introduced in 2000,


  • nly just announced two days ago
slide-17
SLIDE 17

Buffer overflows are prevalent

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

6 12 18 24 1996 1999 2002 2005 2008 2011 2014 Percent of all vulnerabilities

slide-18
SLIDE 18

Buffer overflows are prevalent

225 450 675 900 1996 1999 2002 2005 2008 2011 2014 Total number of buffer overflow vulnerabilities

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

slide-19
SLIDE 19

This class

slide-20
SLIDE 20

This class E-voting

slide-21
SLIDE 21

This class E-voting Later Later
 



 Later

slide-22
SLIDE 22

Our goals

  • Understand how these attacks work, and how to

defend against them

  • These require knowledge about:
  • The compiler
  • The OS
  • The architecture

Analyzing security requires a whole-systems view

slide-23
SLIDE 23

Memory layout

slide-24
SLIDE 24

Refresher

  • How is program data laid out in memory?
  • What does the stack look like?
  • What effect does calling (and returning from) a

function have on memory?

  • We are focusing on the Linux process model
  • Similar to other operating systems
slide-25
SLIDE 25

All programs are stored in memory

4G

slide-26
SLIDE 26

All programs are stored in memory

4G 0xffffffff 0x00000000

slide-27
SLIDE 27

All programs are stored in memory

4G 0xffffffff 0x00000000 The process’s view

  • f memory is that

it owns all of it

slide-28
SLIDE 28

All programs are stored in memory

4G 0xffffffff 0x00000000 The process’s view

  • f memory is that

it owns all of it In reality, these are virtual addresses; the OS/CPU map them to physical addresses

slide-29
SLIDE 29

The instructions themselves are in memory

Text

4G 0xffffffff 0x00000000

slide-30
SLIDE 30

The instructions themselves are in memory

Text

4G 0xffffffff 0x00000000

0x4bf mov %esp,%ebp 0x4be push %ebp 0x4c1 push %ecx 0x4c2 sub $0x224,%esp ... ...

slide-31
SLIDE 31

Data’s location depends on how it’s created

Text

4G 0xffffffff 0x00000000

slide-32
SLIDE 32

Data’s location depends on how it’s created

Text

4G 0xffffffff 0x00000000

Init’d data

static const int y=10;

slide-33
SLIDE 33

Data’s location depends on how it’s created

Text

4G 0xffffffff 0x00000000

Uninit’d data

static int x;

Init’d data

static const int y=10;

slide-34
SLIDE 34

Data’s location depends on how it’s created

Text

4G 0xffffffff 0x00000000

Uninit’d data

static int x;

Init’d data

static const int y=10;

Known at compile time

slide-35
SLIDE 35

Data’s location depends on how it’s created

Text

4G 0xffffffff 0x00000000

cmdline & env Uninit’d data

static int x;

Init’d data

static const int y=10;

Known at compile time

slide-36
SLIDE 36

Data’s location depends on how it’s created

Text

4G 0xffffffff 0x00000000

cmdline & env Uninit’d data

static int x;

Init’d data

static const int y=10;

Known at compile time Set when
 process starts

slide-37
SLIDE 37

Data’s location depends on how it’s created

Text

4G 0xffffffff 0x00000000

cmdline & env Uninit’d data

static int x;

Init’d data

static const int y=10;

Known at compile time Set when
 process starts

Stack

int f() {
 int x; …

slide-38
SLIDE 38

Data’s location depends on how it’s created

Text

4G 0xffffffff 0x00000000

cmdline & env Uninit’d data

static int x;

Init’d data

static const int y=10;

Known at compile time Set when
 process starts

Heap

malloc(sizeof(long));

Stack

int f() {
 int x; …

slide-39
SLIDE 39

Data’s location depends on how it’s created

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; …

slide-40
SLIDE 40

We are going to focus on runtime attacks

Stack and heap grow in opposite directions

Heap

0xffffffff 0x00000000

Stack

slide-41
SLIDE 41

We are going to focus on runtime attacks

Stack and heap grow in opposite directions Compiler provides instructions that
 adjusts the size of the stack at runtime

Heap

0xffffffff 0x00000000

Stack

slide-42
SLIDE 42

We are going to focus on runtime attacks

Stack and heap grow in opposite directions Compiler provides instructions that
 adjusts the size of the stack at runtime

Heap

0xffffffff 0x00000000

Stack

Stack pointer

slide-43
SLIDE 43

We are going to focus on runtime attacks

Stack and heap grow in opposite directions

push 1
 push 2
 push 3

Compiler provides instructions that
 adjusts the size of the stack at runtime

Heap

0xffffffff 0x00000000

Stack

Stack pointer

slide-44
SLIDE 44

We are going to focus on runtime attacks

Stack and heap grow in opposite directions

push 1
 push 2
 push 3

Compiler provides instructions that
 adjusts the size of the stack at runtime

Heap

0xffffffff 0x00000000

Stack

Stack pointer

slide-45
SLIDE 45

We are going to focus on runtime attacks

Stack and heap grow in opposite directions

push 1
 push 2
 push 3

Compiler provides instructions that
 adjusts the size of the stack at runtime

Heap

0xffffffff 0x00000000

Stack

Stack pointer

slide-46
SLIDE 46

We are going to focus on runtime attacks

Stack and heap grow in opposite directions

push 1
 push 2
 push 3

Compiler provides instructions that
 adjusts the size of the stack at runtime

Heap

0xffffffff 0x00000000

Stack

Stack pointer

1

slide-47
SLIDE 47

We are going to focus on runtime attacks

Stack and heap grow in opposite directions

push 1
 push 2
 push 3

Compiler provides instructions that
 adjusts the size of the stack at runtime

Heap

0xffffffff 0x00000000

Stack

Stack pointer

1

slide-48
SLIDE 48

We are going to focus on runtime attacks

Stack and heap grow in opposite directions

push 1
 push 2
 push 3

Compiler provides instructions that
 adjusts the size of the stack at runtime

Heap

0xffffffff 0x00000000

Stack

Stack pointer

1 2

slide-49
SLIDE 49

We are going to focus on runtime attacks

Stack and heap grow in opposite directions

push 1
 push 2
 push 3

Compiler provides instructions that
 adjusts the size of the stack at runtime

Heap

0xffffffff 0x00000000

Stack

Stack pointer

1 2

slide-50
SLIDE 50

We are going to focus on runtime attacks

Stack and heap grow in opposite directions

push 1
 push 2
 push 3

Compiler provides instructions that
 adjusts the size of the stack at runtime

Heap

0xffffffff 0x00000000

Stack

Stack pointer

1 2 3

slide-51
SLIDE 51

We are going to focus on runtime attacks

Stack and heap grow in opposite directions

push 1
 push 2
 push 3

Compiler provides instructions that
 adjusts the size of the stack at runtime

Heap

0xffffffff 0x00000000

Stack

Stack pointer

1 2 3

return

slide-52
SLIDE 52

We are going to focus on runtime attacks

Stack and heap grow in opposite directions

push 1
 push 2
 push 3

Compiler provides instructions that
 adjusts the size of the stack at runtime

Heap

0xffffffff 0x00000000

Stack

Stack pointer

1 2 3

return

slide-53
SLIDE 53

We are going to focus on runtime attacks

Stack and heap grow in opposite directions

push 1
 push 2
 push 3

Compiler provides instructions that
 adjusts the size of the stack at runtime

Heap

0xffffffff 0x00000000

Stack

Stack pointer

1 2 3

return

{

apportioned by the OS; managed in-process by malloc

slide-54
SLIDE 54

We are going to focus on runtime attacks

Stack and heap grow in opposite directions

push 1
 push 2
 push 3

Compiler provides instructions that
 adjusts the size of the stack at runtime

Heap

0xffffffff 0x00000000

Stack

Stack pointer

1 2 3

return

{

apportioned by the OS; managed in-process by malloc

Focusing on the stack for now

slide-55
SLIDE 55

Stack layout when calling functions

  • What do we do when we call a function?
  • What data need to be stored?
  • Where do they go?
  • How do we return from a function?
  • What data need to be restored?
  • Where do they come from?

Code examples

slide-56
SLIDE 56

Stack layout when calling functions

0xffffffff 0x00000000

caller’s data

void func(char *arg1, int arg2, int arg3) { char loc1[4] int loc2; int loc3; }

slide-57
SLIDE 57

Stack layout when calling functions

0xffffffff 0x00000000

caller’s data arg3 arg2 arg1

Arguments
 pushed in
 reverse order

  • f code

void func(char *arg1, int arg2, int arg3) { char loc1[4] int loc2; int loc3; }

slide-58
SLIDE 58

Stack layout when calling functions

0xffffffff 0x00000000

caller’s data arg3 arg2 arg1 loc1 loc2 …

Arguments
 pushed in
 reverse order

  • f code

Local variables
 pushed in the same order as they appear
 in the code

void func(char *arg1, int arg2, int arg3) { char loc1[4] int loc2; int loc3; }

slide-59
SLIDE 59

Stack layout when calling functions

0xffffffff 0x00000000

caller’s data arg3 arg2 arg1 ??? ??? loc1 loc2 …

Arguments
 pushed in
 reverse order

  • f code

Local variables
 pushed in the same order as they appear
 in the code

void func(char *arg1, int arg2, int arg3) { char loc1[4] int loc2; int loc3; }

slide-60
SLIDE 60

void func(char *arg1, int arg2, int arg3) { char loc1[4] int loc2; int loc3;
 ... loc2++; ... }

0xffffffff 0x00000000

caller’s data arg3 arg2 arg1 ??? ??? loc1 loc2 …

Accessing variables

slide-61
SLIDE 61

void func(char *arg1, int arg2, int arg3) { char loc1[4] int loc2; int loc3;
 ... loc2++; ... }

0xffffffff 0x00000000

caller’s data arg3 arg2 arg1 ??? ??? loc1 loc2 …

Q: Where is (this) loc2?

Accessing variables

slide-62
SLIDE 62

void func(char *arg1, int arg2, int arg3) { char loc1[4] int loc2; int loc3;
 ... loc2++; ... }

0xffffffff 0x00000000

caller’s data arg3 arg2 arg1 ??? ??? loc1 loc2 …

0xbffff323 Q: Where is (this) loc2?

Accessing variables

slide-63
SLIDE 63

void func(char *arg1, int arg2, int arg3) { char loc1[4] int loc2; int loc3;
 ... loc2++; ... }

0xffffffff 0x00000000

caller’s data arg3 arg2 arg1 ??? ??? loc1 loc2 …

0xbffff323 Q: Where is (this) loc2? Undecidable at
 compile time

Accessing variables

slide-64
SLIDE 64

void func(char *arg1, int arg2, int arg3) { char loc1[4] int loc2; int loc3;
 ... loc2++; ... }

0xffffffff 0x00000000

caller’s data arg3 arg2 arg1 ??? ??? loc1 loc2 …

0xbffff323 Q: Where is (this) loc2? Undecidable at
 compile time

  • I don’t know where loc2 is,

Accessing variables

slide-65
SLIDE 65

void func(char *arg1, int arg2, int arg3) { char loc1[4] int loc2; int loc3;
 ... loc2++; ... }

0xffffffff 0x00000000

caller’s data arg3 arg2 arg1 ??? ??? loc1 loc2 …

0xbffff323 Q: Where is (this) loc2? Undecidable at
 compile time

  • I don’t know where loc2 is,
  • and I don’t know how many args

Accessing variables

slide-66
SLIDE 66

void func(char *arg1, int arg2, int arg3) { char loc1[4] int loc2; int loc3;
 ... loc2++; ... }

0xffffffff 0x00000000

caller’s data arg3 arg2 arg1 ??? ??? loc1 loc2 …

0xbffff323 Q: Where is (this) loc2? Undecidable at
 compile time

  • I don’t know where loc2 is,
  • and I don’t know how many args
  • but loc2 is always 8B before “???”s

Accessing variables

slide-67
SLIDE 67

void func(char *arg1, int arg2, int arg3) { char loc1[4] int loc2; int loc3;
 ... loc2++; ... }

0xffffffff 0x00000000

caller’s data arg3 arg2 arg1 ??? ??? loc1 loc2 …

Q: Where is (this) loc2?

  • I don’t know where loc2 is,
  • and I don’t know how many args
  • but loc2 is always 8B before “???”s

Accessing variables

slide-68
SLIDE 68

void func(char *arg1, int arg2, int arg3) { char loc1[4] int loc2; int loc3;
 ... loc2++; ... }

Stack frame
 for this call to func 0xffffffff 0x00000000

caller’s data arg3 arg2 arg1 ??? ??? loc1 loc2 …

Q: Where is (this) loc2?

  • I don’t know where loc2 is,
  • and I don’t know how many args
  • but loc2 is always 8B before “???”s

Accessing variables

slide-69
SLIDE 69

void func(char *arg1, int arg2, int arg3) { char loc1[4] int loc2; int loc3;
 ... loc2++; ... }

Stack frame
 for this call to func 0xffffffff 0x00000000

caller’s data arg3 arg2 arg1 ??? ??? loc1 loc2 …

Q: Where is (this) loc2?

  • I don’t know where loc2 is,
  • and I don’t know how many args
  • but loc2 is always 8B before “???”s

%ebp Frame pointer

Accessing variables

slide-70
SLIDE 70

void func(char *arg1, int arg2, int arg3) { char loc1[4] int loc2; int loc3;
 ... loc2++; ... }

Stack frame
 for this call to func 0xffffffff 0x00000000

caller’s data arg3 arg2 arg1 ??? ??? loc1 loc2 …

Q: Where is (this) loc2?

  • I don’t know where loc2 is,
  • and I don’t know how many args
  • but loc2 is always 8B before “???”s

%ebp A: -8(%ebp) Frame pointer

Accessing variables

slide-71
SLIDE 71

Notation

%ebp A memory address (%ebp) The value at memory address %ebp
 (like dereferencing a pointer)

slide-72
SLIDE 72

Notation

%ebp A memory address (%ebp) The value at memory address %ebp
 (like dereferencing a pointer)

0x00000000 0xffffffff

slide-73
SLIDE 73

Notation

%ebp A memory address (%ebp) The value at memory address %ebp
 (like dereferencing a pointer)

0x00000000 0xffffffff

0xbfff03b8

slide-74
SLIDE 74

Notation

%ebp A memory address (%ebp) The value at memory address %ebp
 (like dereferencing a pointer)

0x00000000 0xffffffff

%ebp

0xbfff03b8 0xbfff03b8

slide-75
SLIDE 75

Notation

%ebp A memory address (%ebp) The value at memory address %ebp
 (like dereferencing a pointer)

0xbfff0720

0x00000000 0xffffffff

%ebp

0xbfff03b8 0xbfff03b8 0xbfff0720

slide-76
SLIDE 76

Notation

%ebp A memory address (%ebp) The value at memory address %ebp
 (like dereferencing a pointer)

0xbfff0720

0x00000000 0xffffffff

%ebp

0xbfff03b8 0xbfff03b8 0xbfff0720

pushl %ebp

slide-77
SLIDE 77

Notation

%ebp A memory address (%ebp) The value at memory address %ebp
 (like dereferencing a pointer)

0xbfff0720

0x00000000 0xffffffff

%ebp

0xbfff03b8

%esp

0xbfff03b8 0xbfff0720

pushl %ebp

slide-78
SLIDE 78

Notation

%ebp A memory address (%ebp) The value at memory address %ebp
 (like dereferencing a pointer)

0xbfff0720

0x00000000 0xffffffff

%ebp

0xbfff03b8

%esp

0xbfff03b8 0xbfff0720

pushl %ebp

slide-79
SLIDE 79

Notation

%ebp A memory address (%ebp) The value at memory address %ebp
 (like dereferencing a pointer)

0xbfff0720

0x00000000 0xffffffff

%ebp

0xbfff03b8

%esp

0xbfff03b8 0xbfff0720

pushl %ebp

slide-80
SLIDE 80

Notation

%ebp A memory address (%ebp) The value at memory address %ebp
 (like dereferencing a pointer)

0xbfff0720

0x00000000 0xffffffff

%ebp

0xbfff03b8

%esp

0xbfff03b8 0xbfff0720

pushl %ebp

0xbfff03b8

slide-81
SLIDE 81

Notation

%ebp A memory address (%ebp) The value at memory address %ebp
 (like dereferencing a pointer)

0xbfff0720

0x00000000 0xffffffff

%ebp

0xbfff03b8

%esp

0xbfff03b8 0xbfff0720

pushl %ebp

0xbfff03b8

movl %esp %ebp /* %ebp = %esp */

slide-82
SLIDE 82

Notation

%ebp A memory address (%ebp) The value at memory address %ebp
 (like dereferencing a pointer)

0xbfff0720

0x00000000 0xffffffff

%ebp

0xbfff03b8

%esp

0xbfff03b8 0xbfff0720

pushl %ebp

0xbfff03b8

movl %esp %ebp /* %ebp = %esp */

slide-83
SLIDE 83

Notation

%ebp A memory address (%ebp) The value at memory address %ebp
 (like dereferencing a pointer)

0xbfff0720

0x00000000 0xffffffff

%ebp

0xbfff03b8

%esp

0xbfff03b8 0xbfff0720

pushl %ebp

0xbfff03b8

movl %esp %ebp /* %ebp = %esp */

0xbfff0200

slide-84
SLIDE 84

Notation

%ebp A memory address (%ebp) The value at memory address %ebp
 (like dereferencing a pointer)

0xbfff0720

0x00000000 0xffffffff

%ebp

0xbfff03b8

%esp

0xbfff03b8 0xbfff0720

pushl %ebp

0xbfff03b8

movl %esp %ebp /* %ebp = %esp */

0xbfff0200 0xbfff0200

slide-85
SLIDE 85

Notation

%ebp A memory address (%ebp) The value at memory address %ebp
 (like dereferencing a pointer)

0xbfff0720

0x00000000 0xffffffff

%ebp

0xbfff03b8

%esp

0xbfff03b8 0xbfff0720

pushl %ebp

0xbfff03b8

movl %esp %ebp /* %ebp = %esp */

0xbfff0200 0xbfff0200 0xbfff03b8

slide-86
SLIDE 86

Stack frame
 for this call to func

Returning from functions

0xffffffff 0x00000000

caller’s data arg3 arg2 arg1 ??? ??? loc1 loc2 …

int main() { ... func(“Hey”, 10, -3); ... }

%ebp

slide-87
SLIDE 87

Stack frame
 for this call to func

Returning from functions

0xffffffff 0x00000000

caller’s data arg3 arg2 arg1 ??? ??? loc1 loc2 …

int main() { ... func(“Hey”, 10, -3); ... }

%ebp

slide-88
SLIDE 88

Stack frame
 for this call to func

Returning from functions

0xffffffff 0x00000000

caller’s data arg3 arg2 arg1 ??? ??? loc1 loc2 …

int main() { ... func(“Hey”, 10, -3); ... }

%ebp %ebp

slide-89
SLIDE 89

Stack frame
 for this call to func

Returning from functions

0xffffffff 0x00000000

caller’s data arg3 arg2 arg1 ??? ??? loc1 loc2 …

int main() { ... func(“Hey”, 10, -3); ... }

%ebp Q: How do we restore %ebp? %ebp

slide-90
SLIDE 90

Stack frame
 for this call to func

Returning from functions

0xffffffff 0x00000000

caller’s data arg3 arg2 arg1 ??? …

int main() { ... func(“Hey”, 10, -3); ... }

Q: How do we restore %ebp? %ebp

slide-91
SLIDE 91

Stack frame
 for this call to func

Returning from functions

0xffffffff 0x00000000

caller’s data arg3 arg2 arg1 ??? …

int main() { ... func(“Hey”, 10, -3); ... }

Q: How do we restore %ebp? %ebp %esp

slide-92
SLIDE 92

Stack frame
 for this call to func

Returning from functions

0xffffffff 0x00000000

caller’s data arg3 arg2 arg1 ??? …

int main() { ... func(“Hey”, 10, -3); ... }

Q: How do we restore %ebp? %ebp

%ebp

  • 1. Push %ebp before locals

%esp

slide-93
SLIDE 93

Stack frame
 for this call to func

Returning from functions

0xffffffff 0x00000000

caller’s data arg3 arg2 arg1 ??? …

int main() { ... func(“Hey”, 10, -3); ... }

%ebp Q: How do we restore %ebp? %ebp

%ebp

  • 1. Push %ebp before locals

%esp

  • 2. Set %ebp to current %esp
slide-94
SLIDE 94

Stack frame
 for this call to func

Returning from functions

0xffffffff 0x00000000

caller’s data arg3 arg2 arg1 ??? …

int main() { ... func(“Hey”, 10, -3); ... }

%ebp Q: How do we restore %ebp? %ebp

%ebp

  • 1. Push %ebp before locals
  • 3. Set %ebp to(%ebp) at return

%esp

  • 2. Set %ebp to current %esp
slide-95
SLIDE 95

Stack frame
 for this call to func

Returning from functions

0xffffffff 0x00000000

caller’s data arg3 arg2 arg1 ???

%ebp

loc1 loc2 …

int main() { ... func(“Hey”, 10, -3); ... }

%ebp %ebp

slide-96
SLIDE 96

Stack frame
 for this call to func

Returning from functions

0xffffffff 0x00000000

caller’s data arg3 arg2 arg1 ???

%ebp

loc1 loc2 …

int main() { ... func(“Hey”, 10, -3); ... }

%ebp Q: How do we resume here? %ebp

slide-97
SLIDE 97

The instructions themselves are in memory

Text

4G 0xffffffff 0x00000000

0x49b movl $0x804..,(%esp) 0x493 movl $0xa,0x4(%esp) 0x4a2 call <func> 0x4a7 mov $0x0,%eax ... ...

slide-98
SLIDE 98

The instructions themselves are in memory

Text

4G 0xffffffff 0x00000000

0x49b movl $0x804..,(%esp) 0x493 movl $0xa,0x4(%esp) 0x4a2 call <func> 0x4a7 mov $0x0,%eax ... ...

%eip

slide-99
SLIDE 99

The instructions themselves are in memory

Text

4G 0xffffffff 0x00000000

0x49b movl $0x804..,(%esp) 0x493 movl $0xa,0x4(%esp) 0x4a2 call <func> 0x4a7 mov $0x0,%eax ... ...

%eip

slide-100
SLIDE 100

The instructions themselves are in memory

Text

4G 0xffffffff 0x00000000

0x49b movl $0x804..,(%esp) 0x493 movl $0xa,0x4(%esp) 0x4a2 call <func> 0x4a7 mov $0x0,%eax ... ...

%eip

slide-101
SLIDE 101

0x5bf mov %esp,%ebp 0x5be push %ebp ... ...

The instructions themselves are in memory

Text

4G 0xffffffff 0x00000000

0x49b movl $0x804..,(%esp) 0x493 movl $0xa,0x4(%esp) 0x4a2 call <func> 0x4a7 mov $0x0,%eax ... ...

%eip

slide-102
SLIDE 102

0x5bf mov %esp,%ebp 0x5be push %ebp ... ...

The instructions themselves are in memory

Text

4G 0xffffffff 0x00000000

0x49b movl $0x804..,(%esp) 0x493 movl $0xa,0x4(%esp) 0x4a2 call <func> 0x4a7 mov $0x0,%eax ... ...

%eip

slide-103
SLIDE 103

0x5bf mov %esp,%ebp 0x5be push %ebp ... ...

The instructions themselves are in memory

Text

4G 0xffffffff 0x00000000

0x49b movl $0x804..,(%esp) 0x493 movl $0xa,0x4(%esp) 0x4a2 call <func> 0x4a7 mov $0x0,%eax ... ...

%eip

slide-104
SLIDE 104

0x5bf mov %esp,%ebp 0x5be push %ebp ... ...

The instructions themselves are in memory

Text

4G 0xffffffff 0x00000000

0x49b movl $0x804..,(%esp) 0x493 movl $0xa,0x4(%esp) 0x4a2 call <func> 0x4a7 mov $0x0,%eax ... ...

%eip

slide-105
SLIDE 105

Stack frame
 for this call to func

Returning from functions

0xffffffff 0x00000000

caller’s data arg3 arg2 arg1 ???

%ebp

loc1 loc2 …

int main() { ... func(“Hey”, 10, -3); ... }

%ebp Q: How do we resume here? %ebp

slide-106
SLIDE 106

Stack frame
 for this call to func

Returning from functions

0xffffffff 0x00000000

caller’s data arg3 arg2 arg1 ???

%ebp

loc1 loc2 …

int main() { ... func(“Hey”, 10, -3); ... }

%ebp Q: How do we resume here? Push next %eip
 before call %ebp

slide-107
SLIDE 107

Stack frame
 for this call to func

Returning from functions

0xffffffff 0x00000000

caller’s data arg3 arg2 arg1 ???

%ebp

loc1 loc2 …

int main() { ... func(“Hey”, 10, -3); ... }

%ebp Q: How do we resume here? Push next %eip
 before call

%eip

%ebp

slide-108
SLIDE 108

Stack frame
 for this call to func

Returning from functions

0xffffffff 0x00000000

caller’s data arg3 arg2 arg1 ???

%ebp

loc1 loc2 …

int main() { ... func(“Hey”, 10, -3); ... }

%ebp Q: How do we resume here? Push next %eip
 before call Set %eip to 4(%ebp) at return

%eip

%ebp

slide-109
SLIDE 109

Stack and functions: Summary

slide-110
SLIDE 110

Stack and functions: Summary

Calling function:

1.Push arguments onto the stack (in reverse) 2.Push the return address, i.e., the address of the instruction you want run after control returns to you: %eip+something 3.Jump to the function’s address

slide-111
SLIDE 111

Stack and functions: Summary

Calling function:

1.Push arguments onto the stack (in reverse) 2.Push the return address, i.e., the address of the instruction you want run after control returns to you: %eip+something 3.Jump to the function’s address

Called function:

4.Push the old frame pointer onto the stack: %ebp 5.Set frame pointer %ebp to where the end of the stack is right now: %esp 6.Push local variables onto the stack; access them as offsets from %ebp

slide-112
SLIDE 112

Stack and functions: Summary

Calling function:

1.Push arguments onto the stack (in reverse) 2.Push the return address, i.e., the address of the instruction you want run after control returns to you: %eip+something 3.Jump to the function’s address

Called function:

4.Push the old frame pointer onto the stack: %ebp 5.Set frame pointer %ebp to where the end of the stack is right now: %esp 6.Push local variables onto the stack; access them as offsets from %ebp

Returning function:

7.Reset the previous stack frame: %ebp = (%ebp) 8.Jump back to return address: %eip = 4(%ebp)

slide-113
SLIDE 113

Buffer overflows

slide-114
SLIDE 114

Buffer overflows from 10,000 ft

  • Buffer =
  • Contiguous set of a given data type
  • Common in C
  • All strings are buffers of char’s
  • Overflow =
  • Put more into the buffer than it can hold
  • Where does the extra data go?
  • Well now that you’re experts in memory layouts…
slide-115
SLIDE 115

A buffer overflow example

void func(char *arg1) { char buffer[4]; strcpy(buffer, arg1); ... } int main() { char *mystr = “AuthMe!”; func(mystr); ... }

slide-116
SLIDE 116

A buffer overflow example

void func(char *arg1) { char buffer[4]; strcpy(buffer, arg1); ... } int main() { char *mystr = “AuthMe!”; func(mystr); ... }

slide-117
SLIDE 117

A buffer overflow example

void func(char *arg1) { char buffer[4]; strcpy(buffer, arg1); ... } int main() { char *mystr = “AuthMe!”; func(mystr); ... }

&arg1

slide-118
SLIDE 118

A buffer overflow example

void func(char *arg1) { char buffer[4]; strcpy(buffer, arg1); ... } int main() { char *mystr = “AuthMe!”; func(mystr); ... }

&arg1 %eip

slide-119
SLIDE 119

A buffer overflow example

void func(char *arg1) { char buffer[4]; strcpy(buffer, arg1); ... } int main() { char *mystr = “AuthMe!”; func(mystr); ... }

&arg1 %ebp %eip

slide-120
SLIDE 120

A buffer overflow example

void func(char *arg1) { char buffer[4]; strcpy(buffer, arg1); ... } int main() { char *mystr = “AuthMe!”; func(mystr); ... }

&arg1

00 00 00 00 buffer

%ebp %eip

slide-121
SLIDE 121

A buffer overflow example

void func(char *arg1) { char buffer[4]; strcpy(buffer, arg1); ... } int main() { char *mystr = “AuthMe!”; func(mystr); ... }

&arg1

00 00 00 00 buffer A u t h

%ebp %eip

slide-122
SLIDE 122

A buffer overflow example

void func(char *arg1) { char buffer[4]; strcpy(buffer, arg1); ... } int main() { char *mystr = “AuthMe!”; func(mystr); ... }

&arg1

00 00 00 00 buffer A u t h M e ! \0

%ebp

4d 65 21 00

%eip

slide-123
SLIDE 123

A buffer overflow example

void func(char *arg1) { char buffer[4]; strcpy(buffer, arg1); ... } int main() { char *mystr = “AuthMe!”; func(mystr); ... }

&arg1

00 00 00 00 buffer A u t h

Upon return, sets %ebp to 0x0021654d

M e ! \0

%ebp

4d 65 21 00

%eip

slide-124
SLIDE 124

A buffer overflow example

void func(char *arg1) { char buffer[4]; strcpy(buffer, arg1); ... } int main() { char *mystr = “AuthMe!”; func(mystr); ... }

&arg1

00 00 00 00 buffer A u t h

Upon return, sets %ebp to 0x0021654d

M e ! \0

%ebp

4d 65 21 00

%eip

SEGFAULT (0x00216551)

slide-125
SLIDE 125

A buffer overflow example

void func(char *arg1) { int authenticated = 0; char buffer[4]; strcpy(buffer, arg1); if(authenticated) { ... } int main() { char *mystr = “AuthMe!”; func(mystr); ... }

slide-126
SLIDE 126

A buffer overflow example

void func(char *arg1) { int authenticated = 0; char buffer[4]; strcpy(buffer, arg1); if(authenticated) { ... } int main() { char *mystr = “AuthMe!”; func(mystr); ... }

slide-127
SLIDE 127

A buffer overflow example

void func(char *arg1) { int authenticated = 0; char buffer[4]; strcpy(buffer, arg1); if(authenticated) { ... } int main() { char *mystr = “AuthMe!”; func(mystr); ... }

&arg1

slide-128
SLIDE 128

A buffer overflow example

void func(char *arg1) { int authenticated = 0; char buffer[4]; strcpy(buffer, arg1); if(authenticated) { ... } int main() { char *mystr = “AuthMe!”; func(mystr); ... }

&arg1 %eip

slide-129
SLIDE 129

A buffer overflow example

void func(char *arg1) { int authenticated = 0; char buffer[4]; strcpy(buffer, arg1); if(authenticated) { ... } int main() { char *mystr = “AuthMe!”; func(mystr); ... }

&arg1 %eip

%ebp

slide-130
SLIDE 130

A buffer overflow example

void func(char *arg1) { int authenticated = 0; char buffer[4]; strcpy(buffer, arg1); if(authenticated) { ... } int main() { char *mystr = “AuthMe!”; func(mystr); ... }

&arg1 %eip

%ebp

00 00 00 00

authenticated

slide-131
SLIDE 131

A buffer overflow example

void func(char *arg1) { int authenticated = 0; char buffer[4]; strcpy(buffer, arg1); if(authenticated) { ... } int main() { char *mystr = “AuthMe!”; func(mystr); ... }

&arg1 %eip

%ebp

00 00 00 00

00 00 00 00 authenticated buffer

slide-132
SLIDE 132

A buffer overflow example

void func(char *arg1) { int authenticated = 0; char buffer[4]; strcpy(buffer, arg1); if(authenticated) { ... } int main() { char *mystr = “AuthMe!”; func(mystr); ... }

&arg1 %eip

%ebp

00 00 00 00

00 00 00 00 authenticated buffer A u t h

slide-133
SLIDE 133

A buffer overflow example

void func(char *arg1) { int authenticated = 0; char buffer[4]; strcpy(buffer, arg1); if(authenticated) { ... } int main() { char *mystr = “AuthMe!”; func(mystr); ... }

&arg1 %eip

%ebp

00 00 00 00

00 00 00 00 authenticated buffer M e ! \0

4d 65 21 00

A u t h

slide-134
SLIDE 134

A buffer overflow example

void func(char *arg1) { int authenticated = 0; char buffer[4]; strcpy(buffer, arg1); if(authenticated) { ... } int main() { char *mystr = “AuthMe!”; func(mystr); ... }

&arg1 %eip

%ebp

00 00 00 00

00 00 00 00 authenticated buffer M e ! \0

4d 65 21 00

A u t h

Code still runs; user now ‘authenticated’

slide-135
SLIDE 135

void vulnerable() { char buf[80]; gets(buf); }

slide-136
SLIDE 136

void vulnerable() { char buf[80]; gets(buf); } void still_vulnerable() { char *buf = malloc(80); gets(buf); }

slide-137
SLIDE 137

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

slide-138
SLIDE 138

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

slide-139
SLIDE 139
slide-140
SLIDE 140

User-supplied strings

  • In these examples, we were providing our own

strings

  • But they come from users in myriad aways
  • Text input
  • Packets
  • Environment variables
  • File input…
slide-141
SLIDE 141

What’s the worst that could happen?

void func(char *arg1) { char buffer[4]; strcpy(buffer, arg1); ... }

&mystr %eip

%ebp

00 00 00 00

buffer

slide-142
SLIDE 142

What’s the worst that could happen?

void func(char *arg1) { char buffer[4]; strcpy(buffer, arg1); ... }

&mystr %eip

%ebp

00 00 00 00

buffer

strcpy will let you write as much as you want (til a ‘\0’)

slide-143
SLIDE 143

What’s the worst that could happen?

void func(char *arg1) { char buffer[4]; strcpy(buffer, arg1); ... }

&mystr %eip

%ebp

00 00 00 00

buffer

strcpy will let you write as much as you want (til a ‘\0’) All ours!

slide-144
SLIDE 144

What’s the worst that could happen?

void func(char *arg1) { char buffer[4]; strcpy(buffer, arg1); ... }

&mystr %eip

%ebp

00 00 00 00

buffer

strcpy will let you write as much as you want (til a ‘\0’) All ours! What could you write to memory to wreak havoc?

slide-145
SLIDE 145

Code injection

slide-146
SLIDE 146

High-level idea

void func(char *arg1) { char buffer[4]; sprintf(buffer, arg1); ... }

&arg1 %eip

%ebp

00 00 00 00

buffer ...

slide-147
SLIDE 147

High-level idea

void func(char *arg1) { char buffer[4]; sprintf(buffer, arg1); ... }

&arg1 %eip

%ebp

00 00 00 00

buffer

(1) Load my own code into memory

Haxx0r c0d3

...

slide-148
SLIDE 148

High-level idea

void func(char *arg1) { char buffer[4]; sprintf(buffer, arg1); ... }

&arg1 %eip

%ebp

00 00 00 00

buffer

(1) Load my own code into memory

Haxx0r c0d3

Text

%eip (2) Somehow get %eip to point to it

...

slide-149
SLIDE 149

High-level idea

void func(char *arg1) { char buffer[4]; sprintf(buffer, arg1); ... }

&arg1 %eip

%ebp

00 00 00 00

buffer

(1) Load my own code into memory

Haxx0r c0d3

Text

%eip (2) Somehow get %eip to point to it

...

slide-150
SLIDE 150

High-level idea

void func(char *arg1) { char buffer[4]; sprintf(buffer, arg1); ... }

&arg1 %eip

%ebp

00 00 00 00

buffer

(1) Load my own code into memory

Haxx0r c0d3

Text

%eip (2) Somehow get %eip to point to it

...

slide-151
SLIDE 151

This is nontrivial

  • Pulling off this attack requires getting a few things

really right (and some things sorta right)

  • Think about what is tricky about the attack
  • The key to defending it will be to make the hard parts

really hard

slide-152
SLIDE 152

Challenge 1

  • It must be the machine code instructions (i.e.,

already compiled and ready to run)

  • We have to be careful in how we construct it:
  • It can’t contain any all-zero bytes
  • Otherwise, sprintf / gets / scanf / … will stop copying
  • How could you write assembly to never contain a full zero

byte?

  • It can’t make use of the loader (we’re injecting)
  • It can’t use the stack (we’re going to smash it)

Loading code into memory

slide-153
SLIDE 153

What kind of code would we want to run?

  • Goal: full-purpose shell
  • The code to launch a shell is called “shell code”
  • It is nontrivial to it in a way that works as injected

code

  • No zeroes, can’t use the stack, no loader dependence
  • There are many out there
  • And competitions to see who can write the smallest
  • Goal: privilege escalation
  • Ideally, they go from guest (or non-user) to root
slide-154
SLIDE 154

Shellcode

#include <stdio.h> int main( ) { char *name[2]; name[0] = “/bin/sh”; name[1] = NULL; execve(name[0], name, NULL); }

slide-155
SLIDE 155

Shellcode

#include <stdio.h> int main( ) { char *name[2]; name[0] = “/bin/sh”; name[1] = NULL; execve(name[0], name, NULL); } xorl %eax, %eax pushl %eax pushl $0x68732f2f pushl $0x6e69622f movl %esp,%ebx pushl %eax ...

Assembly

slide-156
SLIDE 156

Shellcode

#include <stdio.h> int main( ) { char *name[2]; name[0] = “/bin/sh”; name[1] = NULL; execve(name[0], name, NULL); } xorl %eax, %eax pushl %eax pushl $0x68732f2f pushl $0x6e69622f movl %esp,%ebx pushl %eax ...

Assembly

slide-157
SLIDE 157

Shellcode

#include <stdio.h> int main( ) { char *name[2]; name[0] = “/bin/sh”; name[1] = NULL; execve(name[0], name, NULL); } xorl %eax, %eax pushl %eax pushl $0x68732f2f pushl $0x6e69622f movl %esp,%ebx pushl %eax ...

Assembly

“\x31\xc0” “\x50” “\x68””//sh” “\x68””/bin” “\x89\xe3” “\x50” ...

Machine code

slide-158
SLIDE 158

Shellcode

#include <stdio.h> int main( ) { char *name[2]; name[0] = “/bin/sh”; name[1] = NULL; execve(name[0], name, NULL); } xorl %eax, %eax pushl %eax pushl $0x68732f2f pushl $0x6e69622f movl %esp,%ebx pushl %eax ...

Assembly

“\x31\xc0” “\x50” “\x68””//sh” “\x68””/bin” “\x89\xe3” “\x50” ...

Machine code (Part of) your input

slide-159
SLIDE 159

Privilege escalation

  • Permissions later, but for now…
  • Recall that each file has:
  • Permissions: read / write / execute
  • For each of: owner / group / everyone else
  • Consider a service like passwd
  • Owned by root (and needs to do root-y things)
  • But you want any user to be able to run it
slide-160
SLIDE 160

Effective userid

  • Userid = the user who ran the process
  • Effective userid = what is used to determine what

access the process has

  • Consider passwd:
  • getuid() will return you (real userid)
  • seteuid(0) to set the effective userid to root
  • It’s allowed to because root is the owner
  • What is the potential attack?
slide-161
SLIDE 161

Effective userid

  • Userid = the user who ran the process
  • Effective userid = what is used to determine what

access the process has

  • Consider passwd:
  • getuid() will return you (real userid)
  • seteuid(0) to set the effective userid to root
  • It’s allowed to because root is the owner
  • What is the potential attack?

If you can get a root-owned process to run
 setuid(0)/seteuid(0), then you get root permissions

slide-162
SLIDE 162

Challenge 2

  • We can’t insert a “jump into my code” instruction
  • We have to use whatever code is already running

Thoughts?

&arg1 %eip

%ebp

00 00 00 00

buffer ...

\x0f \x3c \x2f ...

Getting our injected code to run

slide-163
SLIDE 163

Challenge 2

  • We can’t insert a “jump into my code” instruction
  • We have to use whatever code is already running

Thoughts?

&arg1 %eip

%ebp

00 00 00 00

buffer

Text

%eip

...

\x0f \x3c \x2f ...

Getting our injected code to run

slide-164
SLIDE 164

Challenge 2

  • We can’t insert a “jump into my code” instruction
  • We have to use whatever code is already running

Thoughts?

&arg1 %eip

%ebp

00 00 00 00

buffer

Text

%eip

...

\x0f \x3c \x2f ...

Getting our injected code to run

slide-165
SLIDE 165

Challenge 2

  • We can’t insert a “jump into my code” instruction
  • We have to use whatever code is already running

Thoughts?

&arg1 %eip

%ebp

00 00 00 00

buffer

Text

%eip

...

\x0f \x3c \x2f ...

Getting our injected code to run

slide-166
SLIDE 166

Stack and functions: Summary

Calling function:

1.Push arguments onto the stack (in reverse) 2.Push the return address, i.e., the address of the instruction you want run after control returns to you: %eip+something 3.Jump to the function’s address

Called function:

4.Push the old frame pointer onto the stack: %ebp 5.Set frame pointer %ebp to where the end of the stack is right now: %esp 6.Push local variables onto the stack; access them as offsets from %ebp

Returning function:

7.Reset the previous stack frame: %ebp = (%ebp) 8.Jump back to return address: %eip = 4(%ebp)

slide-167
SLIDE 167

Hijacking the saved %eip

&arg1 %eip

%ebp

00 00 00 00

buffer

Text

%eip

...

0xbff

%ebp

\x0f \x3c \x2f ...

slide-168
SLIDE 168

Hijacking the saved %eip

&arg1 %eip

%ebp

00 00 00 00

buffer

Text

%eip

...

0xbff

0xbff

%ebp

\x0f \x3c \x2f ...

slide-169
SLIDE 169

Hijacking the saved %eip

&arg1 %eip

%ebp

00 00 00 00

buffer

Text

%eip

...

0xbff

0xbff

%ebp

\x0f \x3c \x2f ...

slide-170
SLIDE 170

Hijacking the saved %eip

&arg1 %eip

%ebp

00 00 00 00

buffer

Text

%eip

...

0xbff

0xbff

But how do we know the address? %ebp

\x0f \x3c \x2f ...

slide-171
SLIDE 171

Hijacking the saved %eip

&arg1 %eip

%ebp

00 00 00 00

buffer

Text

%eip

...

0xbff

0xbff

%ebp

What if we are wrong?

\x0f \x3c \x2f ...

slide-172
SLIDE 172

Hijacking the saved %eip

&arg1 %eip

%ebp

00 00 00 00

buffer

Text

%eip

...

0xbff

0xbff

%ebp

What if we are wrong?

0xbdf

\x0f \x3c \x2f ...

slide-173
SLIDE 173

Hijacking the saved %eip

&arg1 %eip

%ebp

00 00 00 00

buffer

Text

%eip

...

0xbff

0xbff

%ebp

What if we are wrong?

0xbdf

\x0f \x3c \x2f ...

slide-174
SLIDE 174

Hijacking the saved %eip

&arg1 %eip

%ebp

00 00 00 00

buffer

Text

%eip

...

0xbff

0xbff

%ebp

What if we are wrong?

0xbdf

This is most likely data, so the CPU will panic (Invalid Instruction)

\x0f \x3c \x2f ...

slide-175
SLIDE 175

Challenge 3

Finding the return address

slide-176
SLIDE 176

Challenge 3

  • If we don’t have access to the code, we don’t know

how far the buffer is from the saved %ebp Finding the return address

slide-177
SLIDE 177

Challenge 3

  • If we don’t have access to the code, we don’t know

how far the buffer is from the saved %ebp

  • One approach: just try a lot of different values!

Finding the return address

slide-178
SLIDE 178

Challenge 3

  • If we don’t have access to the code, we don’t know

how far the buffer is from the saved %ebp

  • One approach: just try a lot of different values!
  • Worst case scenario: it’s a 32 (or 64) bit memory

space, which means 232 (264) possible answers Finding the return address

slide-179
SLIDE 179

Challenge 3

  • If we don’t have access to the code, we don’t know

how far the buffer is from the saved %ebp

  • One approach: just try a lot of different values!
  • Worst case scenario: it’s a 32 (or 64) bit memory

space, which means 232 (264) possible answers

  • But without address randomization:
  • The stack always starts from the same, fixed address
  • The stack will grow, but usually it doesn’t grow very

deeply (unless the code is heavily recursive)

Finding the return address

slide-180
SLIDE 180

gdb tutorial

slide-181
SLIDE 181

Improving our chances: nop sleds

&arg1 %eip

%ebp

00 00 00 00

buffer

Text

%eip

...

0xbff

0xbff

%ebp

0xbdf

nop is a single-byte instruction (just moves to the next instruction)

\x0f \x3c \x2f ...

slide-182
SLIDE 182

Improving our chances: nop sleds

&arg1 %eip

%ebp

00 00 00 00

buffer

Text

%eip

...

0xbff

0xbff

%ebp

0xbdf

nop nop nop …

nop is a single-byte instruction (just moves to the next instruction)

\x0f \x3c \x2f ...

slide-183
SLIDE 183

Improving our chances: nop sleds

&arg1 %eip

%ebp

00 00 00 00

buffer

Text

%eip

...

0xbff

0xbff

%ebp

0xbdf

nop nop nop …

nop is a single-byte instruction (just moves to the next instruction) Jumping anywhere here will work

\x0f \x3c \x2f ...

slide-184
SLIDE 184

Improving our chances: nop sleds

&arg1 %eip

%ebp

00 00 00 00

buffer

Text

%eip

... 0xbff

%ebp

0xbdf

nop nop nop …

nop is a single-byte instruction (just moves to the next instruction) Jumping anywhere here will work

\x0f \x3c \x2f ...

slide-185
SLIDE 185

Improving our chances: nop sleds

&arg1 %eip

%ebp

00 00 00 00

buffer

Text

%eip

... 0xbff

%ebp

0xbdf

nop nop nop …

nop is a single-byte instruction (just moves to the next instruction) Now we improve our chances


  • f guessing by a factor of #nops

Jumping anywhere here will work

\x0f \x3c \x2f ...

slide-186
SLIDE 186

Putting it all together

&arg1 %eip

%ebp

00 00 00 00

buffer

\x0f \x3c \x2f ...

Text

%eip

... 0xbff

0xbdf

nop nop nop …

nop sled padding good
 guess malicious code

slide-187
SLIDE 187

Putting it all together

&arg1 %eip

%ebp

00 00 00 00

buffer

\x0f \x3c \x2f ...

Text

%eip

... 0xbff

0xbdf

nop nop nop …

nop sled padding good
 guess malicious code But it has to be something;
 we have to start writing wherever
 the input to gets/etc. begins.

slide-188
SLIDE 188

Putting it all together

&arg1 %eip

%ebp

00 00 00 00

buffer

\x0f \x3c \x2f ...

Text

%eip

... 0xbff

0xbdf

nop nop nop …

nop sled padding good
 guess malicious code But it has to be something;
 we have to start writing wherever
 the input to gets/etc. begins.

slide-189
SLIDE 189

Putting it all together

&arg1 %eip

%ebp

00 00 00 00

buffer

\x0f \x3c \x2f ...

Text

%eip

... 0xbff

0xbdf

nop nop nop …

nop sled padding good
 guess malicious code But it has to be something;
 we have to start writing wherever
 the input to gets/etc. begins.

slide-190
SLIDE 190

Next time

Required reading:

“StackGuard: Simple Stack Smash Protection for GCC”

Defenses

More attacks, and Continuing with

Software

Security