250 likes | 433 Views
Buffer Overflow. Chapter 6. Buffer Overflow. Buffer Overflow occurs when the program overwrites data outside the bounds of allocated memory It was one of the first exploited security issues (Morris 1988) Many buffer overflow problems are related to string manipulations
E N D
Buffer Overflow Chapter 6
Buffer Overflow • Buffer Overflow occurs when the program overwrites data outside the bounds of allocated memory • It was one of the first exploited security issues (Morris 1988) • Many buffer overflow problems are related to string manipulations • In the year 2000, 50% of CERT warnings were related to buffer overflow. • Any language like C and C++ that does not enforce memory safety and type safety is a potential risk to buffer overflow.
Example void trouble () { int a = 32; char line[128]; gets(line); }
Buffer Over Attack return address a line return address a line return address a line
Buffer Allocation Strategies • Static • Use a fixed size allocation. Alter the program behavior if the data does not fit or truncate the data. • Buffer overflow mistakes can be checked by automated tools or humans. • Dynaminc • Resize the buffer as needed • More difficult to check for code problems. • Mixing static and dynamic allocation can cause problems.
Static Allocation Example #define BUFSIZE 1024 #define SUCCESS 0 int main(int argc, char **argv) { char str[BUFSIZE]; int len; len = snprintf(str, BUFSIZE, “%S(%d)”, argv[0], argc); printf(“%s\n”, str); if (len >= BUFSIZE) { printf(“length truncated (from %d)\n”, len); } return SUCCESS; }
Dynamic Allocation Example #define BUFSIZE 1024 #define SUCCESS 0 int main(int argc, char **argv) { char *str; int len; if ((str = (char *)malloc(BUFSIZE)) == NULL) { return -1; } len = snprintf(str, BUFSIZE, “%S(%d)”, argv[0], argc); if (len >= BUFSIZE) { free(str); if ((str = (char *)malloc(len + 1)) == NULL) { return -1; } snprintf(str, len+1, “%S(%d)”, argv[0], argc); } printf(“%s\n”, str); free(str); str = NULL; return SUCCESS; }
Dynamic Allocation • Issues • More difficult to manage. • Can introduce memory leaks • Use-after-free • Double free • Solutions • Enforce Null-After-Free • Tracking buffer sizes
Tracking Buffer Sizes • C and C++ do not track buffer sizes • Programmers have to do it on their own • Some languages track buffer sizes. • Errors in tracking buffer sizes could lead to buffer overflow conditions
Unsafe String functions • gets() • scanf() • strcpy() • sprintf()
gets() and friends • gets() reads input stream into a buffer until a new line is found. • Very dangerous function and it should be avoided. • To use gets() you must be 100% sure you trust the input. • C++ >> operator repeated the same mistake as gets().
scanf() and friends • %s specifier in the format string can cause a buffer overflow condition. • scanf() can be used safely if the format specifier properly bounds the amount of data to be read.
strcpy() and friends • strcpy() copies one buffer to another until a null character is found. • If source buffer is larger than destination or source is not null terminated buffer overflow condition may occur.
sprintf() and friends • To avoid buffer overflow the destination buffer must be large enough to accommodate the combination of all source arguments. • %s can be a variable string length and can cause buffer overflow. • Bounded format string can make sprintf() safer to use.
Risk of reimplementation • Programmers should be careful not to duplicate the same mistakes made in the dangerous standard C functions. • Implementation of similar functions can be harder to detect.
Example of reimplementaion void get_word(char *word) { int c; while (isspace(c = getchar())) {} while (c = getchar()) { if (c == -1) { break; } if (isspace(c)) { *word = ‘\0’; break; } *word = c; word++; } }
strncpy() and strncat() pitfalls • The size incorrectly specified • char s1[S1_SIZE], s2[S2_SIZE] • strncpy (s1, s2, S2_SIZE) • strncat (s1, s2, S1_SIZE) • strncpy does not always null terminate the destination. • strncat destination and source must be terminated.
Truncation Errors • A truncation after copying a buffer can cause unpredictable problems. • Some examples • Check access control on a file then copy the file to another smaller buffer. The new buffer points to another file. • Check the validity of a host name then copy to a smaller buffer. New buffer now contains a new hostname.
Maintaining null terminator • Many libc functions rely on the null char at the end of a string. • Examples: strlen, strcpy, strncpy, strncat • Some functions that are designed to operate on memory blocks may not null terminate a string • Examples: fread(), recvmsg(), strncpy() • Programmers must ensure strings are null terminated to avoid runtime errors and buffer overflows. • Catching errors due to failure of null terminating a string is very difficult and may not be possible until the program is running in production. • One way to ensure strings are terminated is to explicitly add a null char at the end of a buffer.
Character Sets • Today several character sets exist and are used for input and output. • ISO-8859-1, UTF-8, UTF-16 and UTF-32 are some of the most commonly used. • ISO-8859-1 and UTF-32 are fixed-width encoding. • UTF-16 and UTF-8 are variable-width encoding. • New type wchar_t was introduced to handle other character sets.
Characters and buffer overflow • Mismatch between the string length and the number of bytes in the buffer can cause buffer overflow issues. • Operation that expects bounds in bytes is passed bound in characters or vice-versa • Functions that convert from one encoding to another magnify the problem.
Format Strings • When a variable string is passed as a format string to a function that can cause a format string vulnerability. while (fgets(buf, sizeof buf, f)) { lreply(200, buf) ... } void lreply(int n, char *fmt, ... ) { char buf[BUFSIZ]; ... vsnprintf(buf, sizeof buf, fmt, ap); ... }
Format Strings • Most format string vulnerabilities are caused by misuse of functions that require a format string • Example: printf(str) instead of printf (“%s”, str) • Read data from the stack by passing formatting characters • Use %n directive to write arbitrary positions in memory.
Preventing Format String exploits • Always pass a static format string • If static string is too restrictive choose from a list of format strings • If a format string must be read from input perform input validation.
Better String Classes and Libraries • std::string class in STL • Microsoft CString in ATL/MFC • Vstr library • Designed to work with readv() and writev() • SafeStr library