• If you are citizen of an European Union member nation, you may not use this service unless you are at least 16 years old.

View
 

Buffer Overflow

Page history last edited by Robert Auger 9 years, 6 months ago

Project: WASC Threat Classification

Threat Type: Attack

Reference ID: WASC-7

 

Buffer Overflow

A Buffer Overflow is a flaw that occurs when more data is written to a block of memory, or buffer, than the buffer is allocated to hold. Exploiting a buffer overflow allows an attacker to modify portions of the target process’ address space. This ability can be used for a number of purposes, including the following:

 

  • Control the process execution
  • Crash the process
  • Modify internal variables

 

The attacker’s goal is almost always to control the target process’ execution. This is accomplished by identifying a function pointer in memory that can be modified, directly or indirectly, using the overflow. When such a pointer is used by the program to direct program execution through a jump or call instruction, the attacker-supplied instruction location will be used, thereby allowing the attacker to control the process.

 

In many cases, the function pointer is modified to reference a location where the attacker has placed assembled machine-specific instructions. These instructions are commonly referred to as shellcode, in reference to the fact that attackers often wish to spawn a command-line environment, or shell, in the context of the running process.

 

Buffer overflows are most often associated with software written in the C and C++ programming languages due to their widespread use and ability to perform direct memory manipulation with common programming constructs. It should be emphasized, however, that buffer overflows can exist in any programming environment where direct memory manipulation is allowed, whether through flaws in the compiler, runtime libraries, or features of the language itself.

 

Types of Buffer Overflows

Buffer Overflows can be categorized according to the location of the buffer in question, a key consideration when formulating an exploit. The two main types are Stack-Based Overflow and Heap-Based Overflow. Buffers can be located in other areas of process memory, though such flaws are not as common.

 

Stack-Based Overflow

The "stack" refers to a memory structure used to organize data associated with function calls, including function parameters, function-local variables, and management information such as frame and instruction pointers. The details of the stack layout are defined by the computer architecture and by the function calling convention used.

 

In a stack-based overflow, the buffer in question is allocated on the stack. The following code illustrates a stack-based overflow.

 

void bad_function(char *input)
{
char dest_buffer[32];
 
strcpy(dest_buffer, input);
printf("The first command-line argument is %s.\n", dest_buffer);
}
 
int main(int argc, char *argv[])
{
 
if (argc > 1)
{
bad_function(argv[1]);  
}
else
{
printf("No command-line argument was given.\n");
}
 
return 0;
}

 

Example 1 – A C program with a stack-based buffer overflow

 

In this example, the first command-line argument, argv[1], is passed to bad_function. Here, it is copied to dest_buffer, which has a size of 32 bytes allocated on the stack. If the command-line argument is greater than 31 bytes in length, then the length of the string plus its null terminator will exceed the size of dest_buffer. The exact behavior at this point is undefined. In practice, it will depend on the compiler used and the contents of the command-line argument; suffice it to say that a string of 40 "A" characters will almost certainly crash the process.

 

The canonical exploit for a stack-based buffer overflow on the IA32 platform is to overwrite the calling function’s return pointer. This value is located after function local variables on the stack and stores the location of the calling function’s instruction pointer. When this value is modified, it allows the attacker to set any location in memory as the active instruction once the currently-executing function returns.

 

Heap-Based Overflow

The "heap" refers to a memory structure used to manage dynamic memory. Programmers often use the heap to allocate memory whose size is not known at compile-time, where the amount of memory required is too large to fit on the stack, or where the memory is intended to be used across function calls.

 

In a heap-based overflow, the buffer in question is allocated on the heap. The following code illustrates a heap-based overflow.

 

int main(int argc, char *argv[])
{
char *dest_buffer;
 
dest_buffer = (char *) malloc(32);
 
if (NULL == dest_buffer)
return -1;
 
if (argc > 1)
{
strcpy(dest_buffer, argv[1]);
printf("The first command-line argument is %s.\n", dest_buffer);
}
else
{
printf("No command-line argument was given.\n");
}
 
free(dest_buffer);
 
return 0;
}

 

 

Example 2 – A C program with a heap-based buffer overflow

 

The goal of the exploit in a heap-based overflow is similar to that of a stack-based overflow: identify data after the overflowed buffer that can be used to control program execution. The canonical exploit for heap overflows is to manipulate heap data structures such that subsequent calls to memory management functions such as malloc or free cause attacker-supplied data to be written to an attacker-supplied location. This capability is then used to overwrite a commonly-used function pointer, giving the attacker control once that pointer is used to direct execution. It should be noted that this exploit scenario assumes a heap manager that stores such structures along with the allocated data, which is not always the case.

 

Integer Operations and Buffer Overflows

Buffer overflows are often the result of problems with integer operations, specifically with integer overflows, underflows, and issues with casting between integer types. More details of such attacks can be found in the Integer Overflow section.

 

Buffer Overflow Defenses

The easiest way to address buffer overflows is to avoid them in the first place. Higher-level languages such as Java, C#, and scripting languages do not encourage low-level memory access during common operations like using strings. These are safer alternatives to C and C++.

 

If language choice is not an option, and C or C++ must be used, it is best to avoid dangerous APIs whose use often leads to buffer overflows. Instead, libraries or classes explicitly created to perform string and other memory operations in a secure fashion should be used.

 

Runtime Protections Against Buffer Overflows

It should also be noted that many runtime protections exist for buffer overflows. Such protections include:

 

  • The use of canaries, or values whose modification can be detected, that signal when a stack buffer overflow occurs
  • The use of "no execute" protections for memory locations that limit the ability of attacker-supplied shellcode to be executed
  • The use of address layout randomization to prevent the use of function pointers typically located in a well-known location
  • The use of heap management structures that do not store heap management metadata alongside heap data

 

Runtime protection measures should be considered defense-in-depth actions that make buffer overflows more difficult, but not impossible, to exploit. It is highly recommended that all buffer overflows be addressed by fixing the code where they originate.

 

References

 

General Reference

"Intel 64 and IA-32 Architectures Software Developer's Manual"

[1] http://download.intel.com/design/processor/manuals/253665.pdf

 

Buffer Overflow

"Smashing the Stack for Fun and Profit", By Aleph One - Phrack 49

[2] http://www.phrack.com/issues.html?issue=49&id=14#article

 

"w00w00 on Heap Overflows" By Matt Conover and w00w00 Security Team.

[3] http://www.w00w00.org/files/articles/heaptut.txt

 

"The Shellcoder's Handbook, 2ed." By Anley, C., Heasman, J., Linder, F., & Richarte, G.

[4] Wiley Press

 

"The Art of Software Security Assessment", By Dowd, M., McDonald, J., & Schuh, J.

[5] Addison Wesley Professional Press

 

"CWE-119: Failure to Constrain Operations within the Bounds of a Memory Buffer"

[6] http://cwe.mitre.org/data/definitions/119.html

 
Protecting Against "strlcpy and strlcat - Consistent, Safe, String Copy and Concatenation.", By Miller, T. C., & de Raadt, T.

[7] http://www.tw.openbsd.org/papers/ven05-deraadt/index.html

 

"Using the Strsafe.h Functions."

[8] http://msdn.microsoft.com/en-us/library/ms647466.aspx

 

"Security Development Lifecycle (SDL) Banned Function Calls" by Howard, M.

[9] http://msdn.microsoft.com/en-us/library/bb288454.aspx

 

"StackGuard: Automatic Adaptive Detection and Prevention of Buffer-Overflow Attacks.", by Cowan, C., Pu, C., Maier, D., Walpole, J., Bakke, P., Beattie, S., et al.

[10] Proceedings of the 7th USENIX Security Symposium. San Antonio, TX.

 

"Windows Vista ISV Security" By Howard, M., & Thomlinson, M.

[11] http://msdn.microsoft.com/en-us/library/bb430720.aspx

 

Related Attacks

"Integer Overflows", WASC Threat Classification

[12] http://projects.webappsec.org/Integer-Overflows

 

"Format String Attack", WASC Threat Classification

[13] http://projects.webappsec.org/Format-String

 

Comments (0)

You don't have permission to comment on this page.