Buffer Overflow CS0 Buffer Overflow – "Data gone wild" Background Summary: Buffer overflow occurs when data is input or written beyond the allocated bounds of an object, causing a program crash or creating a vulnerability that attackers might exploit. Description: A buffer overflow occurs when data is written beyond the boundaries of a fixed length buffer overwriting adjacent memory locations which may include other buffers, variables and program flow data. Considered the “nuclear bomb” of the software industry, the buffer overflow is one of the most persistent security vulnerabilities and frequently used attacks. Risk – How can it Happen? : Writing outside the bounds of a block of allocated memory can corrupt data, crash the program, or cause the execution of malicious code. C++ is particularly vulnerable to buffer overflow. Example of Occurrence: Buffer overflow vulnerabilities were exploited by the the first major attack on the Internet. known as the Morris worm, this attack infected more than 60,000 machines and shut down much of the Internet for several days in 1988. Carolyn Duffy Marsan Morris Worm Turns 20: Look what it's Done Network World, October 30, 2008 http://www.networkworld.com/news/2008/103008-morris-worm.html?page=1 How can I avoid buffer overflow problems? Make sure you have enough space: Before copying data to a fixed size block, make sure it is large enough to hold the data that you are going to copy. If it is not large enough, do not copy more data than your available space can hold. If your program is not able to continue properly after filling the available space, you may have to find some way to recover from the error. Validate indices: If you have an integer variable, verify that it is within the proper bounds before you use it as an index to an array. This validation is particularly important for any values that might have been provided as user input or other untrusted input, such as information that might be read from a file or from a network connection. Laboratory/Homework Assignment: 1. Type in the following program. Compile and run. © 2009, Towson University Buffer Overflow CS0 #include <iostream> using namespace std; int main() { int importantData = 1; int buffer[10]; for (int i = 0; i < 30; i++) buffer[i] = 7; cout << "after buffer overflow: " << endl; cout << "importantData = " << importantData << endl; return 0; } What happened? Why? Fix the error and re-run The exact details of what will happen may differ from one operating system to the next. On a Windows XP computer, this program led to the following output: after buffer overflow: importantData = 7 5 [main] 5156 _cygtls::handle_exceptions: 297847 [main] 5156 open_stackdumpfile: Dumping 505834 [main] 5156 _cygtls::handle_exceptions: 707085 [main] 5156 _cygtls::handle_exceptions: corrupted stack) Exception: STATUS_ACCESS_VIOLATION stack trace to ex1.exe.stackdump Exception: STATUS_ACCESS_VIOLATION Error while dumping state (probably This happens because the buffer array 10 items, numbered from 0-9, but the loop will attempt to assign 30 values. This causes a buffer overflow, which leads to data being written to locations outside of the buffer array. Some of this data changes other neighbor values, including modifying the importantData variable. Important data regarding the program flow is also modified, leading to the error messages. To fix the problem, change the upper index of the loop to ensure that it does not go beyond the end of the loop. Specifically, change the for loop to start for (int i =0; i < 10; i++) 2. Consider this program: #include <iostream> using namespace std; int main() { int tests[10]; int test; int count; cout << "How many numbers? "; cin >> count; for (int i =0 ; i < count; i++) { V © 2009, Towson University Buffer Overflow CS0 cout << "Please type a number: "; cin >> test; tests[i]= test; V 0 <=i <10; } return 0; } 1. Complete the following checklist for this program. 2. The V indicates where the potential buffer could occur. How could we prevent this? The vulnerability occurs because we don’t verify that i is greater than or equal to 0 and less than 10. This can happen if count >9 or count < 0. We can prevent this by making sure that count is never less than zero or greater than 10. This can be done in one of two ways: 1. Requiring the user input to specify a values between 0 and 10, repeating the request if out-of-range values are given? 2. Modifying the requested value to be equal to 10 if the user types a number greater than 10, or zero if the user’s input value is less than 0. 3. Revise the program to eliminate potential buffer overflow problems. #include <iostream> using namespace std; int main() { int tests[10]; int test; int count =-1; while (count < 0 || count >10) { cout << "How many numbers (Must be >=0 and <= 10) ? "; cin >> count; } for (int i =0 ; i < count; i++) { cout << "Please type a number: "; cin >> test; tests[i]= test; } return 0; } 4. Turn in program (marked after completing checklist), output, and questions. © 2009, Towson University Buffer Overflow CS0 Security Checklist: Security Checklist Vulnerability Buffer Overflow Course CS0 Task – Check each line of code Completed 1. Finding Arrays: 1.1 Underline each array declaration 1.2. For each array, underline all subsequent references 2. Index Variables – legal range for an array of size n is 0 <= i < n 2.1 For each underlined access that uses a variable as an index, write the legal range next to it. 2.2 For each index marked in 2.1, underline all occurrences of that variable. 2.3. Mark with a V any assignments, inputs or operations that may modify these index variables. Does your code verify that these operations will result in an index value that is within the appropriate bounds? If not, you may have a vulnerability. Shaded areas indicate vulnerabilities! Discussion 1. Describe the buffer overflow problem. A buffer overflow occurs when a program attempts to access a value that is outside of the specified data buffer. The most common occurrence of this vulnerability involves trying to access an element that is beyond the bounds of an array. Attempting to write to the 15 position in a 10item array, for example, would cause a buffer overflow. 2. Give three real life examples of buffer overflow attacks (research on the web). 1. 2. 3. The 1998 Morris Internet Worm 2001 Code Red Worm – Microsoft Internet Information Services 2003 SQL Slammer – Microsoft SQL Server 2000 Source: http://en.wikipedia.org/wiki/Buffer_overflow 3. What can result from a buffer overflow? The potential impact of a buffer overflow will largely depend on the programming language. Some languages, such as Java, automatically identify situations that would lead to buffer overflows. These languages will generally indicate an error by throwing an exception, which the program should handle appropriately. If exceptions are not handled, the program will terminate. C, C++, and other similar languages do not stop programs from writing outside the bounds of a buffer. Programs written in these languages can write data beyond the bounds of a buffer, often without any obvious problems. However, this out-of-bounds data can also corrupt the values of variables, change the © 2009, Towson University Buffer Overflow CS0 state of the program so as to make continued execution impossible, and create vulnerabilities that attackers might use to take control of computers. 4. Provide three different examples of code that may lead to a buffer overflow. 1. int vals [10]; vals[375] = 4; 2. int vals[10]; for (int i = 0; i < 30; i++) { vals[i] = i*i; } 3. int vals[10]; int vals2[30]; for (int i = 0; i < 10; i++) { vals[i] = i*i; } int k =0; for (int j=0; j <5; j++) { for (int m = 0; m <10; m++) { vals2[k] = vals[m]; k++; } } 5. How can you prevent a buffer overflow from occurring in your program? 1. Make sure you have enough space: allocate buffers that are large enough to complete your tasks. 2. Check index values: before using an integer or a variable to either retrieve a value from an array or store a value to an array, verify that it is within the appropriate range. Don’t forget that arrays are zero-indexed: if an array has 10 elements, all indices must be greater than or equal to zero, and less than or equal to 9. 3. Beware of code that copies items from one array to another: this sort of code has been involved in many real buffer overflow vulnerabilities. © 2009, Towson University