Successfully reported this slideshow.

04 - I love my OS, he protects me (sometimes, in specific circumstances)

0

Share

Loading in …3
×
1 of 36
1 of 36

04 - I love my OS, he protects me (sometimes, in specific circumstances)

0

Share

Description

* Into GNU/Linux OS, compiler and loader protections
* ASLR
* DEP
* Canary
* Fortify source
* RELRO
* PIE

Transcript

  1. 1. I love my OS He protects me (sometimes, in specific circumstances) Alex Moneger Security Engineer He protects me (sometimes, in specific circumstances)
  2. 2. Making exploit writers life harder  Refresher on standard buffer overflow: 1. Requires a fixed address to jump to 2. Requires execution on a data segment 3. Requires capability of overwriting SEIP 4. Alternatively, can require capability to overwrite a stack function pointer 5. In case of string functions (strcpy, strcat, gets, …) a null byte cannot be present in the exploit string, otherwise it is considered as a string terminator.  That’s quite a few constraints © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 2
  3. 3. Address Space Layout Randomization © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 3
  4. 4. The fixed address problem  What about making the memory layout unpredictable?  Randomize the stack, heap, mmap, …  Enter Address Space Layout Randomization (ASLR)  Each run of a program presents a different memory layout © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 4
  5. 5. Test program ASLR cisco@kali:~/src/seccon/ch4$ pygmentize -g aslr.c #define _GNU_SOURCE /* for RTLD_NEXT */ #include <dlfcn.h> #include <stdio.h> #include <stdlib.h> #include <string.h> char *rodata = "ABCD"; char data[4+1] = "ABCD"; int main(int argc, char **argv) { printf("Stack base address: %pn", argv); char *heap = malloc(sizeof(int)); printf("Heap base address: %pn", heap); void (*memcpy_addr)(int) = dlsym(RTLD_NEXT, "memcpy"); printf("Memcpy libc address: %pn", memcpy_addr); unsigned int text; __asm__("call dummy;" "dummy: pop %%eax;" "mov %%eax, %0;":"=r"(text)); printf("Code section address: %pn", text); printf("Data section address: %pn", data); printf("RO data section address: %pn", rodata); free(heap); } cisco@kali:~/src/seccon/ch4$ cc aslr.c -o aslr -ldl © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 5
  6. 6. No ASLR  Addresses are predictable at each program run: cisco@kali:~/src/seccon/ch4$ sudo sysctl -w kernel.randomize_va_space=0 kernel.randomize_va_space = 0 cisco@kali:~/src/seccon/ch4$ ./aslr | head -n 3 Stack base address: 0xbffff7b4 Heap base address: 0x804a008 Memcpy libc address: 0xb7f749a0 cisco@kali:~/src/seccon/ch4$ ./aslr | head -n 3 Stack base address: 0xbffff7b4 Heap base address: 0x804a008 Memcpy libc address: 0xb7f749a0 © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 6
  7. 7. A bit of ASLR  Stack and dyn libs are randomized  Heap is predictable: cisco@kali:~/src/seccon/ch4$ sudo sysctl -w kernel.randomize_va_space=1 kernel.randomize_va_space = 1 cisco@kali:~/src/seccon/ch4$ ./aslr | head -n 3 Stack base address: 0xbf9c64c4 Heap base address: 0x804a008 Memcpy libc address: 0xb77039a0 cisco@kali:~/src/seccon/ch4$ ./aslr | head -n 3 Stack base address: 0xbf97b804 Heap base address: 0x804a008 Memcpy libc address: 0xb77429a0 © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 7
  8. 8. Full ASLR  Heap, stack and dynlibs addresses randomized  Default since 2.6.12 kernels (2005): cisco@kali:~/src/seccon/ch4$ sudo sysctl -w kernel.randomize_va_space=2 kernel.randomize_va_space = 2 cisco@kali:~/src/seccon/ch4$ ./aslr | head -n 3 Stack base address: 0xbfca1924 Heap base address: 0x8bea008 Memcpy libc address: 0xb77489a0 cisco@kali:~/src/seccon/ch4$ ./aslr | head -n 3 Stack base address: 0xbf9880c4 Heap base address: 0x80c2008 Memcpy libc address: 0xb776b9a0  Notice anything? © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 8
  9. 9. Is stack really random? cisco@kali:~/src/seccon/ch4$ ./aslr | head -n 1 | awk -F ':' '{print $2}' | tr -d " n" | python -c "import sys; print bin(int(sys.stdin.read(),16))" 0b10111111110000011101100101110100 cisco@kali:~/src/seccon/ch4$ ./aslr | head -n 1 | awk -F ':' '{print $2}' | tr -d " n" | python -c "import sys; print bin(int(sys.stdin.read(),16))" 0b10111111101000010111000101010100 cisco@kali:~/src/seccon/ch4$ ./aslr | head -n 1 | awk -F ':' '{print $2}' | tr -d " n" | python -c "import sys; print bin(int(sys.stdin.read(),16))" 0b10111111111011000111001101100100  19 bits, not bad.  2**19 = 524288 tries => difficult bruteforce  But… © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 9
  10. 10. RandOOOOhhhhm  Memory alignments make this harder: cisco@kali:~/src/seccon/ch4$ pygmentize -g linux_aslr.c unsigned long arch_align_stack(unsigned long sp) { if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space) sp -= get_random_int() % 8192; return sp & ~0xf;  So only 8192 possibilities (13 bits)  That’s not too bad. } © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 10
  11. 11. Is mmap really random? cisco@kali:~/src/seccon/ch4$ ./aslr | head -n 3 | tail -n 1 | awk -F ':' '{print $2}' | tr -d " n" | python -c "import sys; print bin(int(sys.stdin.read(),16))" 0b10110111011010110010100110100000 cisco@kali:~/src/seccon/ch4$ ./aslr | head -n 3 | tail -n 1 | awk -F ':' '{print $2}' | tr -d " n" | python -c "import sys; print bin(int(sys.stdin.read(),16))" 0b10110111011100100011100110100000 cisco@kali:~/src/seccon/ch4$ ./aslr | head -n 3 | tail -n 1 | awk -F ':' '{print $2}' | tr -d " n" | python -c "import sys; print bin(int(sys.stdin.read(),16))" 0b10110111011010010000100110100000  Mmap = 9 bits of entropy  2**9 = 512, that’s not that many tries… Can we do less  From mmap.c: “* 8 bits of randomness in 32bit mmaps” = 256 tries © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 11
  12. 12. Better ASLR?  PaX (integrated in GRSec) provides better ASLR  Exec-shield on RHEL provides better ASLR  Preventing repeated “exec” of programs segfaulting is important. Requires GRSec  64 bits helps a lot, but is not perfect. More entropy to play with, but same page size alignment constraints © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 12
  13. 13. What is happening?  Damn, where is my shellcode in memory?  Shellcode address is changing all the time Too short Shellcode Junk SC Add ress Too far Too far back © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 13
  14. 14. Data Execution Prevention aka X^W © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 14
  15. 15. Code Vs Data again  Code never needs to write itself. Why is the code segment writable?  Data never needs to execute. Why are the data segments executable?  Idea is to have 2 sets of permissions for memory: RW and RE  Data is RW, code is RE  Let’s enforce this in hardware and software © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 15
  16. 16. DEP Support  Support for DEP introduced in kernel 2.6.8 (2004)  Enabled by default on PAE and 64 bit  Exec-shield adds software DEP on 32 bits  Enable it in BIOS and that’s it © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 16
  17. 17. Is my program DEP enabled? cisco@kali:~/src/seccon/ch4$ readelf -l aslr | egrep "LOAD|STACK" LOAD 0x000000 0x08048000 0x08048000 0x00798 0x00798 R E 0x1000 LOAD 0x000798 0x08049798 0x08049798 0x00140 0x00144 RW 0x1000 GNU_STACK 0x000000 0x00000000 0x00000000 0x00000 0x00000 RW 0x4  What happens if I execute my shellcode on the stack? cisco@kali:~/src/seccon/ch4$ cc ../ch3/ch3.c -fno-stack-protector -z execstack -U_FORTIFY_SOURCE -o ch3 cisco@kali:~/src/seccon/ch4$ invoke ch3.py $ exit cisco@kali:~/src/seccon/ch4$ cc ../ch3/ch3.c -fno-stack-protector -U_FORTIFY_SOURCE -o ch3 cisco@kali:~/src/seccon/ch4$ invoke ch3.py Segmentation fault cisco@kali:~/src/seccon/ch4$ dmesg | tail -n 1 [709828.604691] ch3[30982]: segfault at bffffc8c ip bffffc8c sp bffffd00 error 15 cisco@kali:~/src/seccon/ch4$ pygmentize -g ch3.py | grep ret | head -n 1 ret_addr = 0xbffffc8c © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 17
  18. 18. What is happening?  When landing on your shellcode, OS checks memory permissions  No X bit set, kill execution Shellcode Junk SC Add ress X bit Set? © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 18
  19. 19. I love birds. Can I have a canary? © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 19
  20. 20. What’s a canary?  Buffer overflow takes control by overwriting SEIP  Let’s detect SEIP overwrites  What if we put some random data before SEIP and check it before returning?  That’s a canary, a small random cookie placed in local storage and checked at function return time © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 20
  21. 21. Where’s the canary?  Canary is protecting the top of the stack  Canary is generally 24 bits of randomness + a null byte  If mismatch on function return, exit: SEIP SEBP Canary Buf 80484b2: 8b 55 f4 mov edx,DWORD PTR [ebp-0xc] 80484b5: 65 33 15 14 00 00 00 xor edx,DWORD PTR gs:0x14 80484bc: 74 05 je 80484c3 <vuln+0x57> 80484be: e8 7d fe ff ff call 8048340 <__stack_chk_fail@plt> © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 21
  22. 22. A naïve example implementation cisco@kali:~/src/seccon/ch4$ pygmentize -g manual_canary.c | grep 'func' -A 18 int func(char *arg) { struct locals { char buf[0x64]; int canary; }; struct locals vars; vars.canary = 0x12345678; strcpy(vars.buf, arg); if (vars.canary != 0x12345678) { printf("BoF detected!!! Exiting...n"); exit(1); } return 0x5; } cisco@kali:~/src/seccon/ch4$ ./manual_canary $(python -c 'print "A"*128') BoF detected!!! Exiting... cisco@kali:~/src/seccon/ch4$ echo $? 1 © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 22
  23. 23. Runtime time!  What does this look like in gdb? cisco@kali:~/src/seccon/ch4$ gdb manual_canary Reading symbols from /home/cisco/src/seccon/ch4/manual_canary...(no debugging symbols found)...done. gdb$ break *0x8048499 Breakpoint 1 at 0x8048499 gdb$ r Breakpoint 1, 0x08048499 in func () gdb$ x/w $ebp + 0x4 0xbffff6bc: 0x080484e0 gdb$ x/12w $ebp -0x10 0xbffff6a8: 0xbffff6d8 0x12345678 0x00000001 0xbffff784 0xbffff6b8: 0xbffff6d8 0x080484e0 0x00000000 0xb7ff0590 0xbffff6c8: 0x0804850b 0xb7fbeff4 0x08048500 0x00000000  We protect SEIP © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 23
  24. 24. What happens if I overwrite the canary?  Try our standard exploit: cisco@kali:~/src/seccon/ch4$ cc ../ch3/ch3.c -fno-stack-protector -z execstack -U_FORTIFY_SOURCE -o ch3 cisco@kali:~/src/seccon/ch4$ invoke ch3.py $ exit cisco@kali:~/src/seccon/ch4$ cc ../ch3/ch3.c -fstack-protector -z execstack -U_FORTIFY_SOURCE -o ch3 cisco@kali:~/src/seccon/ch4$ invoke ch3.py *** stack smashing detected ***: /home/cisco/src/seccon/ch4/ch3 terminated © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 24
  25. 25. What is happening?  The buffer overflow overwrites SEIP but also the canary  Canary check fails, execution stops Shellcode Junk SC Add ress Canary OK? STOP!!! can ary © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 25
  26. 26. Fortify source © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 26
  27. 27. What it does  Replaces unsafe functions with safe ones, when size can be determined at compile time  String functions (strcpy,…)  Memory functions (memcpy,…)  Formatting functions (sprintf, …)  Works for static stack buffers, and malloced heap buffers  Comes from exec-shield project © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 27
  28. 28. How to enable it  Compile with the _FORTIFY SOURCE macro (see man 7 feature_test_macros) cisco@kali:~/src/seccon/ch4$ cc ../ch3/ch3.c -fno-stack-protector -z execstack -U_FORTIFY_SOURCE -O1 -g -Wall -o ch3 cisco@kali:~/src/seccon/ch4$ invoke ch3.py $ exit cisco@kali:~/src/seccon/ch4$ cc ../ch3/ch3.c -fno-stack-protector -z execstack -D_FORTIFY_SOURCE=2 -O1 -g - Wall -o ch3 cisco@kali:~/src/seccon/ch4$ invoke ch3.py *** buffer overflow detected ***: /home/dahtah/src/seccon/ch4/ch3 terminated © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 28
  29. 29. Under the hood  Compiler knows the size of the buffer. Changes the call to unsafe functions to equivalent safe ones cisco@kali:~/src/seccon/ch4$ objdump -d -j .text -M intel ch3 | grep -i 'vuln>:' -A 17 0804843c <vuln>: 804843c: 57 push edi 804843d: 81 ec 88 00 00 00 sub esp,0x88 8048443: 8d 7c 24 1c lea edi,[esp+0x1c] 8048447: b9 19 00 00 00 mov ecx,0x19 804844c: b8 00 00 00 00 mov eax,0x0 8048451: f3 ab rep stos DWORD PTR es:[edi],eax 8048453: c7 44 24 08 64 00 00 mov DWORD PTR [esp+0x8],0x64 804845a: 00 804845b: 8b 84 24 90 00 00 00 mov eax,DWORD PTR [esp+0x90] 8048462: 89 44 24 04 mov DWORD PTR [esp+0x4],eax 8048466: 8d 44 24 1c lea eax,[esp+0x1c] 804846a: 89 04 24 mov DWORD PTR [esp],eax 804846d: e8 ce fe ff ff call 8048340 <__strcpy_chk@plt> 8048472: b8 01 00 00 00 mov eax,0x1 8048477: 81 c4 88 00 00 00 add esp,0x88 804847d: 5f pop edi 804847e: c3 ret © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 29
  30. 30. Left overs © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 30
  31. 31. ASCII Armor  BoFs based on strings can’t have a null byte  Let’s map anything executable into the lower portion of memory  Addresses will have there MSB set to 0, providing the null byte protection  Only on RHEL/Centos/Fedora  Extremely effective on 64 bits OS $ /bin/ls /proc/self/maps 00101000-00116000 r-xp 00000000 03:01 319365 /lib/ld-2.3.2.so 00116000-00117000 rw-p 00014000 03:01 319365 /lib/ld-2.3.2.so 00117000-0024a000 r-xp 00000000 03:01 319439 /lib/libc-2.3.2.so 0024a000-0024e000 rw-p 00132000 03:01 319439 /lib/libc-2.3.2.so © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 31
  32. 32. Position independent code (PIE)  Loadable segments are also randomized (Full ASLR)  Combined with previous protections, renders attacks close to impossible  More on this when we talk about ELF and introduce ROP © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 32
  33. 33. Take away © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 33
  34. 34. Compilation cisco@kali:~/src/seccon/ch4$ cc ../ch3/ch3.c -fstack-protector -D_FORTIFY_SOURCE=2 -Wl,-z,relro,-z,now -fpie –pie -Wall -o ch3  Not all these options work depending on the dependancies  Know what it exposes to when you turn something off  You have no excuse to make an attackers life easier  Even with all protections enabled, exploitation is still possible © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 34
  35. 35. Exercise time © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 35
  36. 36. oo//o/  Compile ch3 program with various options. Take time to understand the protections in place  Try to exploit the example program in the canary section. What is wrong with it?  Disable all protections except one. Can you find a way around it?  Enable Full ASLR. Can you find any non randomized memory zones? © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 36

Description

* Into GNU/Linux OS, compiler and loader protections
* ASLR
* DEP
* Canary
* Fortify source
* RELRO
* PIE

Transcript

  1. 1. I love my OS He protects me (sometimes, in specific circumstances) Alex Moneger Security Engineer He protects me (sometimes, in specific circumstances)
  2. 2. Making exploit writers life harder  Refresher on standard buffer overflow: 1. Requires a fixed address to jump to 2. Requires execution on a data segment 3. Requires capability of overwriting SEIP 4. Alternatively, can require capability to overwrite a stack function pointer 5. In case of string functions (strcpy, strcat, gets, …) a null byte cannot be present in the exploit string, otherwise it is considered as a string terminator.  That’s quite a few constraints © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 2
  3. 3. Address Space Layout Randomization © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 3
  4. 4. The fixed address problem  What about making the memory layout unpredictable?  Randomize the stack, heap, mmap, …  Enter Address Space Layout Randomization (ASLR)  Each run of a program presents a different memory layout © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 4
  5. 5. Test program ASLR cisco@kali:~/src/seccon/ch4$ pygmentize -g aslr.c #define _GNU_SOURCE /* for RTLD_NEXT */ #include <dlfcn.h> #include <stdio.h> #include <stdlib.h> #include <string.h> char *rodata = "ABCD"; char data[4+1] = "ABCD"; int main(int argc, char **argv) { printf("Stack base address: %pn", argv); char *heap = malloc(sizeof(int)); printf("Heap base address: %pn", heap); void (*memcpy_addr)(int) = dlsym(RTLD_NEXT, "memcpy"); printf("Memcpy libc address: %pn", memcpy_addr); unsigned int text; __asm__("call dummy;" "dummy: pop %%eax;" "mov %%eax, %0;":"=r"(text)); printf("Code section address: %pn", text); printf("Data section address: %pn", data); printf("RO data section address: %pn", rodata); free(heap); } cisco@kali:~/src/seccon/ch4$ cc aslr.c -o aslr -ldl © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 5
  6. 6. No ASLR  Addresses are predictable at each program run: cisco@kali:~/src/seccon/ch4$ sudo sysctl -w kernel.randomize_va_space=0 kernel.randomize_va_space = 0 cisco@kali:~/src/seccon/ch4$ ./aslr | head -n 3 Stack base address: 0xbffff7b4 Heap base address: 0x804a008 Memcpy libc address: 0xb7f749a0 cisco@kali:~/src/seccon/ch4$ ./aslr | head -n 3 Stack base address: 0xbffff7b4 Heap base address: 0x804a008 Memcpy libc address: 0xb7f749a0 © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 6
  7. 7. A bit of ASLR  Stack and dyn libs are randomized  Heap is predictable: cisco@kali:~/src/seccon/ch4$ sudo sysctl -w kernel.randomize_va_space=1 kernel.randomize_va_space = 1 cisco@kali:~/src/seccon/ch4$ ./aslr | head -n 3 Stack base address: 0xbf9c64c4 Heap base address: 0x804a008 Memcpy libc address: 0xb77039a0 cisco@kali:~/src/seccon/ch4$ ./aslr | head -n 3 Stack base address: 0xbf97b804 Heap base address: 0x804a008 Memcpy libc address: 0xb77429a0 © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 7
  8. 8. Full ASLR  Heap, stack and dynlibs addresses randomized  Default since 2.6.12 kernels (2005): cisco@kali:~/src/seccon/ch4$ sudo sysctl -w kernel.randomize_va_space=2 kernel.randomize_va_space = 2 cisco@kali:~/src/seccon/ch4$ ./aslr | head -n 3 Stack base address: 0xbfca1924 Heap base address: 0x8bea008 Memcpy libc address: 0xb77489a0 cisco@kali:~/src/seccon/ch4$ ./aslr | head -n 3 Stack base address: 0xbf9880c4 Heap base address: 0x80c2008 Memcpy libc address: 0xb776b9a0  Notice anything? © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 8
  9. 9. Is stack really random? cisco@kali:~/src/seccon/ch4$ ./aslr | head -n 1 | awk -F ':' '{print $2}' | tr -d " n" | python -c "import sys; print bin(int(sys.stdin.read(),16))" 0b10111111110000011101100101110100 cisco@kali:~/src/seccon/ch4$ ./aslr | head -n 1 | awk -F ':' '{print $2}' | tr -d " n" | python -c "import sys; print bin(int(sys.stdin.read(),16))" 0b10111111101000010111000101010100 cisco@kali:~/src/seccon/ch4$ ./aslr | head -n 1 | awk -F ':' '{print $2}' | tr -d " n" | python -c "import sys; print bin(int(sys.stdin.read(),16))" 0b10111111111011000111001101100100  19 bits, not bad.  2**19 = 524288 tries => difficult bruteforce  But… © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 9
  10. 10. RandOOOOhhhhm  Memory alignments make this harder: cisco@kali:~/src/seccon/ch4$ pygmentize -g linux_aslr.c unsigned long arch_align_stack(unsigned long sp) { if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space) sp -= get_random_int() % 8192; return sp & ~0xf;  So only 8192 possibilities (13 bits)  That’s not too bad. } © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 10
  11. 11. Is mmap really random? cisco@kali:~/src/seccon/ch4$ ./aslr | head -n 3 | tail -n 1 | awk -F ':' '{print $2}' | tr -d " n" | python -c "import sys; print bin(int(sys.stdin.read(),16))" 0b10110111011010110010100110100000 cisco@kali:~/src/seccon/ch4$ ./aslr | head -n 3 | tail -n 1 | awk -F ':' '{print $2}' | tr -d " n" | python -c "import sys; print bin(int(sys.stdin.read(),16))" 0b10110111011100100011100110100000 cisco@kali:~/src/seccon/ch4$ ./aslr | head -n 3 | tail -n 1 | awk -F ':' '{print $2}' | tr -d " n" | python -c "import sys; print bin(int(sys.stdin.read(),16))" 0b10110111011010010000100110100000  Mmap = 9 bits of entropy  2**9 = 512, that’s not that many tries… Can we do less  From mmap.c: “* 8 bits of randomness in 32bit mmaps” = 256 tries © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 11
  12. 12. Better ASLR?  PaX (integrated in GRSec) provides better ASLR  Exec-shield on RHEL provides better ASLR  Preventing repeated “exec” of programs segfaulting is important. Requires GRSec  64 bits helps a lot, but is not perfect. More entropy to play with, but same page size alignment constraints © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 12
  13. 13. What is happening?  Damn, where is my shellcode in memory?  Shellcode address is changing all the time Too short Shellcode Junk SC Add ress Too far Too far back © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 13
  14. 14. Data Execution Prevention aka X^W © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 14
  15. 15. Code Vs Data again  Code never needs to write itself. Why is the code segment writable?  Data never needs to execute. Why are the data segments executable?  Idea is to have 2 sets of permissions for memory: RW and RE  Data is RW, code is RE  Let’s enforce this in hardware and software © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 15
  16. 16. DEP Support  Support for DEP introduced in kernel 2.6.8 (2004)  Enabled by default on PAE and 64 bit  Exec-shield adds software DEP on 32 bits  Enable it in BIOS and that’s it © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 16
  17. 17. Is my program DEP enabled? cisco@kali:~/src/seccon/ch4$ readelf -l aslr | egrep "LOAD|STACK" LOAD 0x000000 0x08048000 0x08048000 0x00798 0x00798 R E 0x1000 LOAD 0x000798 0x08049798 0x08049798 0x00140 0x00144 RW 0x1000 GNU_STACK 0x000000 0x00000000 0x00000000 0x00000 0x00000 RW 0x4  What happens if I execute my shellcode on the stack? cisco@kali:~/src/seccon/ch4$ cc ../ch3/ch3.c -fno-stack-protector -z execstack -U_FORTIFY_SOURCE -o ch3 cisco@kali:~/src/seccon/ch4$ invoke ch3.py $ exit cisco@kali:~/src/seccon/ch4$ cc ../ch3/ch3.c -fno-stack-protector -U_FORTIFY_SOURCE -o ch3 cisco@kali:~/src/seccon/ch4$ invoke ch3.py Segmentation fault cisco@kali:~/src/seccon/ch4$ dmesg | tail -n 1 [709828.604691] ch3[30982]: segfault at bffffc8c ip bffffc8c sp bffffd00 error 15 cisco@kali:~/src/seccon/ch4$ pygmentize -g ch3.py | grep ret | head -n 1 ret_addr = 0xbffffc8c © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 17
  18. 18. What is happening?  When landing on your shellcode, OS checks memory permissions  No X bit set, kill execution Shellcode Junk SC Add ress X bit Set? © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 18
  19. 19. I love birds. Can I have a canary? © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 19
  20. 20. What’s a canary?  Buffer overflow takes control by overwriting SEIP  Let’s detect SEIP overwrites  What if we put some random data before SEIP and check it before returning?  That’s a canary, a small random cookie placed in local storage and checked at function return time © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 20
  21. 21. Where’s the canary?  Canary is protecting the top of the stack  Canary is generally 24 bits of randomness + a null byte  If mismatch on function return, exit: SEIP SEBP Canary Buf 80484b2: 8b 55 f4 mov edx,DWORD PTR [ebp-0xc] 80484b5: 65 33 15 14 00 00 00 xor edx,DWORD PTR gs:0x14 80484bc: 74 05 je 80484c3 <vuln+0x57> 80484be: e8 7d fe ff ff call 8048340 <__stack_chk_fail@plt> © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 21
  22. 22. A naïve example implementation cisco@kali:~/src/seccon/ch4$ pygmentize -g manual_canary.c | grep 'func' -A 18 int func(char *arg) { struct locals { char buf[0x64]; int canary; }; struct locals vars; vars.canary = 0x12345678; strcpy(vars.buf, arg); if (vars.canary != 0x12345678) { printf("BoF detected!!! Exiting...n"); exit(1); } return 0x5; } cisco@kali:~/src/seccon/ch4$ ./manual_canary $(python -c 'print "A"*128') BoF detected!!! Exiting... cisco@kali:~/src/seccon/ch4$ echo $? 1 © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 22
  23. 23. Runtime time!  What does this look like in gdb? cisco@kali:~/src/seccon/ch4$ gdb manual_canary Reading symbols from /home/cisco/src/seccon/ch4/manual_canary...(no debugging symbols found)...done. gdb$ break *0x8048499 Breakpoint 1 at 0x8048499 gdb$ r Breakpoint 1, 0x08048499 in func () gdb$ x/w $ebp + 0x4 0xbffff6bc: 0x080484e0 gdb$ x/12w $ebp -0x10 0xbffff6a8: 0xbffff6d8 0x12345678 0x00000001 0xbffff784 0xbffff6b8: 0xbffff6d8 0x080484e0 0x00000000 0xb7ff0590 0xbffff6c8: 0x0804850b 0xb7fbeff4 0x08048500 0x00000000  We protect SEIP © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 23
  24. 24. What happens if I overwrite the canary?  Try our standard exploit: cisco@kali:~/src/seccon/ch4$ cc ../ch3/ch3.c -fno-stack-protector -z execstack -U_FORTIFY_SOURCE -o ch3 cisco@kali:~/src/seccon/ch4$ invoke ch3.py $ exit cisco@kali:~/src/seccon/ch4$ cc ../ch3/ch3.c -fstack-protector -z execstack -U_FORTIFY_SOURCE -o ch3 cisco@kali:~/src/seccon/ch4$ invoke ch3.py *** stack smashing detected ***: /home/cisco/src/seccon/ch4/ch3 terminated © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 24
  25. 25. What is happening?  The buffer overflow overwrites SEIP but also the canary  Canary check fails, execution stops Shellcode Junk SC Add ress Canary OK? STOP!!! can ary © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 25
  26. 26. Fortify source © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 26
  27. 27. What it does  Replaces unsafe functions with safe ones, when size can be determined at compile time  String functions (strcpy,…)  Memory functions (memcpy,…)  Formatting functions (sprintf, …)  Works for static stack buffers, and malloced heap buffers  Comes from exec-shield project © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 27
  28. 28. How to enable it  Compile with the _FORTIFY SOURCE macro (see man 7 feature_test_macros) cisco@kali:~/src/seccon/ch4$ cc ../ch3/ch3.c -fno-stack-protector -z execstack -U_FORTIFY_SOURCE -O1 -g -Wall -o ch3 cisco@kali:~/src/seccon/ch4$ invoke ch3.py $ exit cisco@kali:~/src/seccon/ch4$ cc ../ch3/ch3.c -fno-stack-protector -z execstack -D_FORTIFY_SOURCE=2 -O1 -g - Wall -o ch3 cisco@kali:~/src/seccon/ch4$ invoke ch3.py *** buffer overflow detected ***: /home/dahtah/src/seccon/ch4/ch3 terminated © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 28
  29. 29. Under the hood  Compiler knows the size of the buffer. Changes the call to unsafe functions to equivalent safe ones cisco@kali:~/src/seccon/ch4$ objdump -d -j .text -M intel ch3 | grep -i 'vuln>:' -A 17 0804843c <vuln>: 804843c: 57 push edi 804843d: 81 ec 88 00 00 00 sub esp,0x88 8048443: 8d 7c 24 1c lea edi,[esp+0x1c] 8048447: b9 19 00 00 00 mov ecx,0x19 804844c: b8 00 00 00 00 mov eax,0x0 8048451: f3 ab rep stos DWORD PTR es:[edi],eax 8048453: c7 44 24 08 64 00 00 mov DWORD PTR [esp+0x8],0x64 804845a: 00 804845b: 8b 84 24 90 00 00 00 mov eax,DWORD PTR [esp+0x90] 8048462: 89 44 24 04 mov DWORD PTR [esp+0x4],eax 8048466: 8d 44 24 1c lea eax,[esp+0x1c] 804846a: 89 04 24 mov DWORD PTR [esp],eax 804846d: e8 ce fe ff ff call 8048340 <__strcpy_chk@plt> 8048472: b8 01 00 00 00 mov eax,0x1 8048477: 81 c4 88 00 00 00 add esp,0x88 804847d: 5f pop edi 804847e: c3 ret © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 29
  30. 30. Left overs © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 30
  31. 31. ASCII Armor  BoFs based on strings can’t have a null byte  Let’s map anything executable into the lower portion of memory  Addresses will have there MSB set to 0, providing the null byte protection  Only on RHEL/Centos/Fedora  Extremely effective on 64 bits OS $ /bin/ls /proc/self/maps 00101000-00116000 r-xp 00000000 03:01 319365 /lib/ld-2.3.2.so 00116000-00117000 rw-p 00014000 03:01 319365 /lib/ld-2.3.2.so 00117000-0024a000 r-xp 00000000 03:01 319439 /lib/libc-2.3.2.so 0024a000-0024e000 rw-p 00132000 03:01 319439 /lib/libc-2.3.2.so © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 31
  32. 32. Position independent code (PIE)  Loadable segments are also randomized (Full ASLR)  Combined with previous protections, renders attacks close to impossible  More on this when we talk about ELF and introduce ROP © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 32
  33. 33. Take away © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 33
  34. 34. Compilation cisco@kali:~/src/seccon/ch4$ cc ../ch3/ch3.c -fstack-protector -D_FORTIFY_SOURCE=2 -Wl,-z,relro,-z,now -fpie –pie -Wall -o ch3  Not all these options work depending on the dependancies  Know what it exposes to when you turn something off  You have no excuse to make an attackers life easier  Even with all protections enabled, exploitation is still possible © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 34
  35. 35. Exercise time © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 35
  36. 36. oo//o/  Compile ch3 program with various options. Take time to understand the protections in place  Try to exploit the example program in the canary section. What is wrong with it?  Disable all protections except one. Can you find a way around it?  Enable Full ASLR. Can you find any non randomized memory zones? © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 36

More Related Content

Related Books

Free with a 30 day trial from Scribd

See all

×