Upload
christal-hubbard
View
222
Download
3
Embed Size (px)
Citation preview
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);
}
Buffer Over Attack
line areturnaddress
line areturnaddress
line areturnaddress
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 0int 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 0int 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