Chapter 6 Buffer Overflow Buffer Overflow Buffer Overflow

Chapter 6 Buffer Overflow

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); } Example void trouble () { int a = 32; char line[128]; gets(line); }](http://slidetodoc.com/presentation_image_h2/19a1a41cbd4b106912111cddea3b9f53/image-3.jpg)
Example void trouble () { int a = 32; char line[128]; gets(line); }

Buffer Over Attack line a return address

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 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(“%sn”, 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(“%sn”, 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 = ‘ ’; break; } *word = c; word++; } }
![strncpy() and strncat() pitfalls • The size incorrectly specified – char s 1[S 1_SIZE], strncpy() and strncat() pitfalls • The size incorrectly specified – char s 1[S 1_SIZE],](http://slidetodoc.com/presentation_image_h2/19a1a41cbd4b106912111cddea3b9f53/image-17.jpg)
strncpy() and strncat() pitfalls • The size incorrectly specified – char s 1[S 1_SIZE], s 2[S 2_SIZE] – strncpy (s 1, s 2, S 2_SIZE) – strncat (s 1, s 2, S 1_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, 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() • Safe. Str library
- Slides: 25