Buffer OverFlow


Published on

Published in: Technology
1 Like
  • Be the first to comment

No Downloads
Total views
On SlideShare
From Embeds
Number of Embeds
Embeds 0
No embeds

No notes for slide

Buffer OverFlow

  1. 1. Buffer Over-run
  2. 2. Introduction <ul><li>What is Buffer Overrun? </li></ul><ul><ul><li>Buffer Over-run refers to problem where we can make program to use more than allotted ‘buffer’. </li></ul></ul><ul><ul><li>All buffer overruns cannot be exploited as security vulnerability. </li></ul></ul><ul><li>What it could lead to? </li></ul><ul><ul><li>Buffer overflows can be triggered by inputs that are designed to execute code, or alter the way the program operates. </li></ul></ul><ul><ul><li>You get an access violation (AV). </li></ul></ul><ul><ul><li>Your site becomes unstable. </li></ul></ul><ul><ul><li>The attacker injects code into your application, executes it, and makes everyone an administrator of your site. </li></ul></ul>
  3. 3. The π Program <ul><li>int main(int argc, char* argv[]) </li></ul><ul><li>{ </li></ul><ul><li>char buff[1024]; </li></ul><ul><li>if (strcmp (argv[1], &quot;3.1415926&quot;) == 0) { </li></ul><ul><li>strcpy (buff, argv[2]); </li></ul><ul><li>printf (&quot;thanks, %sn&quot;, buff); </li></ul><ul><li>} </li></ul><ul><li>else { </li></ul><ul><li>strcpy(buff, argv[1]); </li></ul><ul><li>printf(&quot;sorry, %s is not correct.n&quot;, buff); </li></ul><ul><li>} </li></ul><ul><li>} </li></ul>Buffer Overflow #1 Buffer Overflow #2
  4. 4. Types of Buffer Overrun <ul><li>Stack Overruns </li></ul><ul><li>Heap Overruns </li></ul><ul><li>Array Indexing Errors </li></ul><ul><li>Format String </li></ul><ul><li>Unicode and ANSI Buffer size mismatch </li></ul>
  5. 5. Stack Overrun <ul><li>Occurs when a buffer declared on the stack is overwritten by copying data lager than buffer. </li></ul><ul><li>This can be exploited, by modifying return address (ESP) in stack. </li></ul>Local Var1 Param1 Local Var2 ESP Arg1 If we can change this return to desired address. Then execution after returning from this function, Execution would continue from modified address
  6. 6. Stack Overflow Example <ul><li>Sample Execution for argument “Hello”– </li></ul><ul><li>foo = 00401000 </li></ul><ul><li>bar = 00401045 </li></ul><ul><li>Stack: </li></ul><ul><ul><li>6C6C6548  Hello </li></ul></ul><ul><ul><li>0000006F </li></ul></ul><ul><ul><li>7FFDF000 </li></ul></ul><ul><ul><li>0012FF80 </li></ul></ul><ul><ul><li>0040108A  Return Address of foo </li></ul></ul><ul><ul><li>00410EDE </li></ul></ul><ul><li>Execution for argument “ABCDEFGHIJKLMNOPx45x10x40”– </li></ul><ul><li>foo = 00401000 </li></ul><ul><li>bar = 00401045 </li></ul><ul><li>Stack: </li></ul><ul><li>44434241 </li></ul><ul><li>48474645 </li></ul><ul><li>4C4B4A49 </li></ul><ul><li>504F4E4D </li></ul><ul><li>00401045  Return address changed to bar() </li></ul><ul><li>00410ECA </li></ul><ul><li>Hacked!! </li></ul><ul><li>void foo (const char *input) </li></ul><ul><li>{ </li></ul><ul><li>char buf[10]; </li></ul><ul><li>strcpy(buf, input); </li></ul><ul><li>printf(“Stack:%p %p %p %p %p %p} </li></ul><ul><li>} </li></ul><ul><li>void bar(){ </li></ul><ul><li>printf(“Hacked!!’); </li></ul><ul><li>} </li></ul><ul><li>int main(int argc, char* argv[]) </li></ul><ul><li>{ </li></ul><ul><ul><li>…… </li></ul></ul><ul><ul><li>printf(“foo = %p”,foo); </li></ul></ul><ul><ul><li>printf(“bar = %p”,bar); </li></ul></ul><ul><ul><li>foo(argv[1]); </li></ul></ul><ul><ul><li>…… </li></ul></ul><ul><li>} </li></ul>
  7. 7. Stack Overrun <ul><li>Off-by-One – </li></ul><ul><ul><li>Programming error, which boundary while handling buffers. </li></ul></ul><ul><ul><li>void foo(char *in) </li></ul></ul><ul><ul><li>{ </li></ul></ul><ul><ul><li>char buff[64]; </li></ul></ul><ul><ul><li>strcpy(buff,in,sizeof(buff)); </li></ul></ul><ul><ul><li>buff[sizeof(buff)] = “0”;  Off-by-one </li></ul></ul><ul><ul><li>} </li></ul></ul><ul><li>To improve security , Intel in Itanium Processor(ia64) starts storing return address in Register. This make it difficult to exploit Stack Overrun on IA64, but not impossible. </li></ul><ul><li>Stack Overruns are usually discovered by attackers by using fuzzers </li></ul>
  8. 8. Stack BOs at Work <ul><li>void func(char *p, int i) </li></ul><ul><li>{ </li></ul><ul><ul><li>int j = 0; </li></ul></ul><ul><ul><li>CFoo foo; </li></ul></ul><ul><ul><li>int (*fp)(char *, int) = &func; </li></ul></ul><ul><ul><li>char b[128]; </li></ul></ul><ul><ul><li>strcpy(b,p); </li></ul></ul><ul><li>} </li></ul>
  9. 9. Heap Overruns <ul><li>Occurs by copying data lager than buffer size, for a buffer whose memory is allotted from heap (using malloc family functions). </li></ul><ul><li>Difficult to exploit as compared to Stack Overruns, as no program execution register can be modified. </li></ul>
  10. 10. Heap Overrun Example <ul><li>void foo(char *input1, char *input2) </li></ul><ul><li>{ </li></ul><ul><li>char *buff,buff2; </li></ul><ul><li>buff = (char*)malloc(16); </li></ul><ul><li>buff2= (char*)malloc(16); </li></ul><ul><li>strcpy(buff,input1); </li></ul><ul><li>strcpy(buff2,input2); </li></ul><ul><li>printf(“input 1 = %sn input 2 = %sn”, buff, buff2); </li></ul><ul><li>free(buff); free(buff2); </li></ul><ul><li>} </li></ul><ul><li>void bar(){ </li></ul><ul><li>printf(“Hacked!!’); </li></ul><ul><li>} </li></ul><ul><li>int main(int argc, char* argv[]) </li></ul><ul><li>{ </li></ul><ul><ul><li>char arg1[], arg2[]; // map to input </li></ul></ul><ul><ul><li>printf(“bar = %p”,bar); </li></ul></ul><ul><ul><li>foo(arg1,arg2); </li></ul></ul><ul><ul><li>…… </li></ul></ul><ul><li>} </li></ul><ul><li>Sample Execution for argument “Hello Temp”– </li></ul><ul><li>bar = 41414141 </li></ul><ul><li>input 1 = Hello </li></ul><ul><li>Input 2 = Temp </li></ul><ul><li>Now change parameter to “DDDDDDDDDDDDDCCC Temp”- </li></ul><ul><li>bar = 41414141 </li></ul><ul><li>Warning Message = Memory “0x44434343” could not be read </li></ul><ul><li>With debugger, we can get to know that return address in stack while calling foo() is saved at 0x41424344 </li></ul><ul><li>Now change parameter to “DDDDDDDDDDDDABCD AAAA”- </li></ul><ul><li>bar = 41414141 </li></ul><ul><li>input 1 = Hello </li></ul><ul><li>Input 2 = AAAA </li></ul><ul><li>Hacked!!! </li></ul>
  11. 11. Array Indexing Errors <ul><li>Manipulation can be done easily by passing non-valid index, which points to memory out of range of allocated array memory. </li></ul><ul><li>Ex. Char Array defined as arr[10]. </li></ul><ul><ul><li>char arr[10]; </li></ul></ul><ul><ul><li>SetValue(index i, value x) </li></ul></ul><ul><ul><li>{ </li></ul></ul><ul><ul><li>arr[i] = x; </li></ul></ul><ul><ul><li>} </li></ul></ul><ul><li>Any of these operation would modify memory not allocated for buffer – </li></ul><ul><ul><li>SetValue(-20,’x’) => Arr[-20] = ‘x’ </li></ul></ul><ul><ul><li>SetValue(26,’x’) => Arr[26] = ‘x’ </li></ul></ul><ul><li>Variant – Truncation error. Where due to truncation of value, unexpected may happen. E.g.- </li></ul><ul><ul><li>On a UNIX system ID of super user is ‘0’. Network File System Daemon accepts user id as integer, check with non-zero and then truncate to unsigned short. </li></ul></ul><ul><ul><li>So user with ID ‘10000’, on truncation would become ‘0’ </li></ul></ul>
  12. 12. Format String Bugs <ul><li>The Format String exploit occurs in functions which expects variable number of inputs. E.g. – printf. </li></ul><ul><li>This problem arises because there isn’t any realistic way for a function which takes variable number of arguments to determine how many arguments where passed to it. Sample functions – printf, sprintf, fprintf </li></ul><ul><li>If a Format String has parameter , like %x, is inserted into the posted data, the string is parsed by the Format Function, and the conversion specified in the parameters is executed. The Format Function is expecting more arguments as input, and if these arguments are not supplied, the function could read or write the stack. </li></ul>
  13. 13. Format String Attack <ul><li>int main (int argc, char **argv) </li></ul><ul><li>{ </li></ul><ul><li>char buf [100]; </li></ul><ul><li>int x = 1 ; </li></ul><ul><li>snprintf(buf, sizeof buf, argv [1] ) ; </li></ul><ul><li>buf [ sizeof(buf) -1 ] = 0 ; </li></ul><ul><li>printf ( “Buffer size is: (%d) nData </li></ul><ul><li>input:%sn” , strlen (buf) , buf ) ; </li></ul><ul><li>printf ( “X equals: %d/ in </li></ul><ul><li>hex: %#xnMemory address for x: (%p) </li></ul><ul><li>n” , x, x, &x) ; </li></ul><ul><li>return 0 ; </li></ul><ul><li>} </li></ul><ul><li>./test.exe “aaaa” </li></ul><ul><li>Buffer size is (4) </li></ul><ul><li>Data input : aaaa </li></ul><ul><li>X equals: 1/ in hex: 0x1 </li></ul><ul><li>Memory address for x (0xbffff73c) </li></ul><ul><li>./test.exe “aaaa %x %x” </li></ul><ul><li>Buffer size is (15) </li></ul><ul><li>Data input : aaaa 1 61616161 </li></ul><ul><li>X equals: 1/ in hex: 0x1 </li></ul><ul><li>Memory address for x (0xbffff73c) </li></ul>
  14. 14. Unicode and ANSI Buffer Size Mismatches <ul><li>Buffer overrun during conversion of Unicode and ANSI is very common problem on Windows. </li></ul><ul><li>Reason for conversion is due to variable bytes representation of characters in Unicode. </li></ul>
  15. 15. Arithmetic Overflow / Underflow Does it Look Familiar? <ul><li>Algorithm(A[0..N-1], value) </li></ul><ul><li>{ </li></ul><ul><li>low = 0 </li></ul><ul><li>high = N - 1 </li></ul><ul><li>while (low <= high) </li></ul><ul><li>{ </li></ul><ul><li>mid = (low + high) / 2 </li></ul><ul><li>if (A[mid] > value) </li></ul><ul><li>high = mid - 1 </li></ul><ul><li>else if (A[mid] < value) </li></ul><ul><li>low = mid + 1 </li></ul><ul><li>else </li></ul><ul><li>return mid // found </li></ul><ul><li>} </li></ul><ul><li>return -1 // not found </li></ul><ul><li>} </li></ul>
  16. 16. The ‘n’-function are safe? Right?! Be extra cautious when using ‘n’ functions! // Example #1 (code verifies pszSrc is <= 50 chars) #define MAX (50) char *pszDest = malloc(sizeof(pszSrc)); strncpy(pszDest,pszSrc,MAX); sizeof is 4-bytes, not 50 String not null-terminated if len(pszSrc) >= MAX // Example #2 #define MAX (50) char szDest[MAX]; strncpy(szDest,pszSrc,MAX); // Example #3 #define MAX (50) char szDest[MAX]; strncpy(szDest,pszSrc,strlen(pszSrc)); Wrong buffer size!
  17. 17. Preventing Buffer Overrun <ul><li>Do not write user input to arbitrary location in memory. </li></ul><ul><li>Special care while doing string operations in code. </li></ul><ul><li>Choice of programming language. E.g. C++ STL provides in-built memory handling and checks. </li></ul><ul><li>Avoid standard library functions which are not bounds checked, such as gets , scanf and strcpy . </li></ul><ul><li>Use Strsafe.h </li></ul><ul><li>Use GS Flags while compilation. </li></ul>
  18. 18. <ul><li>Questions? </li></ul>