Buffer Overflows and Countermeasures
In computer security and programming, a buffer overflow, or buffer overrun, is an anomalous condition where a course of action attempts to store data beyond the boundaries of a fixed-length buffer. The consequence is that the additional data overwrites nearby memory locations. The overwritten data may include other buffers, variables and program flow data, and may consequence in inconsistent program behavior, a memory access exception, program termination (a crash), incorrect results or especially if deliberately caused by a malicious usera possible breach of system security.
Programming languages C and C++ are most commonly associated with buffer overflows, because they provide no built-in protection against accessing or overwriting data in any part of memory and do not check that data written to an range (the built-in buffer kind) is within the boundaries of that range.
A buffer overflow occurs when data written to a buffer, due to insufficient bounds checking, corrupts data values in memory addresses nearby to the allocated buffer. Most commonly this occurs when copying strings of characters from one buffer to another.
Buffer overflows can be triggered by inputs specifically designed to execute malicious code or to make the program function in an unintended way. As such, buffer overflows cause many software vulnerabilities and form the basis of many exploits. Sufficient bounds checking by the programmer, the compiler or the runtime can prevent buffer overflows.
Types of Buffer overflows:
In generic form there are basically two types of buffer overflows
o Stack based buffer overflows
o Heap based buffer overflows
Stack based buffer overflows:
In software, a stack buffer overflow occurs when a program writes to a memory address on the program’s call stack outside of the intended data structure; usually a fixed length buffer. Stack buffer overflow bugs are caused when a program writes more data to a buffer located on the stack than there was truly allocated for that buffer. This almost always results in corruption of nearby data on the stack, and in situations where the overflow was triggered by mistake, will often cause the program to crash or function incorrectly. This kind of overflow is part of the more general class of programming bugs known as buffer overflows. If the affected program is running with special privileges, or accepts data from un trusted network hosts (e.g. a web server) then the bug is a possible security vulnerability. If the stack buffer is filled with data supplied from an un trusted user then that user can corrupt the stack in such a way as to inject executable code into the running program and take control of the time of action. This is one of the oldest and more reliable methods for black hats to gain unauthorized access to a computer.
Heap based buffer overflows:
A heap overflow is a kind of buffer overflow that occurs in the heap data area. Memory on the heap is dynamically allocated by the application at run-time and typically contains program data.
A technically inclined and malicious user may adventure stack-based buffer overflows to manipulate the program in one of several ways:
o By overwriting a local variable that is near the buffer in memory on the stack to change the behavior of the program which may assistance the attacker.
o By overwriting the return address in a stack frame. Once the function returns, execution will begin again at the return address as stated by the attacker, usually a user input filled buffer.
o By overwriting a function pointer, or exception handler, which is afterward executed.
With a method called “Trampolining”, if the address of the user-supplied data is unknown, but the location is stored in a register, then the return address can be overwritten with the address of an opcode which will cause execution to jump to the user supplied data. If the location is stored in a register R, then a jump to the location containing the opcode for a jump R, call R or similar instruction, will cause execution of user supplied data. The locations of appropriate opcodes, or bytes in memory, can be found in DLLs or the executable itself. However the address of the opcode typically cannot contain any null characters and the locations of these opcodes can vary between applications and versions of the operating system. The Metasploit Project is one such database of appropriate opcodes, though only those found in the Windows operating system are listed.
A buffer overflow occurring in the heap data area is referred to as a heap overflow and is exploitable in a different manner to that of stack-based overflows. Memory on the heap is dynamically allocated by the application at run-time and typically contains program data. Exploitation is performed by corrupting this data in specific ways to cause the application to overwrite internal structures such as connected list pointers. The canonical heap overflow technique overwrites dynamic memory allocation linkage (such as malloc meta data) and uses the resulting pointer exchange to overwrite a program function pointer.
Various techniques have been used to detect or prevent buffer overflows, with various tradeoffs. The most reliable way to avoid or prevent buffer overflows is to use automatic protection at the language level. This sort of protection, however, cannot be applied to legacy code, and often technical, business, or cultural constraints call for a unprotected language. Following are the choices or methods to avoid buffer overflows.
1. Choice of cure programming languages like java, .Net
2. Use of safe libraries
3. Executable space protection
4. Address space layout randomization
5. thorough packet inspection
6. Parameter sanitization