Buffers are memory storage regions that temporarily hold data while it is being transferred from one location to another. These buffers typically live in RAM memory. Most modern hard drives take advantage of buffering to efficiently access data. Buffer is also widely used in online video streaming and buffers are frequently used in online video streaming to prevent interruption. When a video is streamed, the video player downloads and stores perhaps 20% of the video at a time in a buffer and then streams from that buffer.
A buffer overflow (or buffer overrun) occurs when the volume of data exceeds the storage capacity of the memory buffer. As a result, the program attempting to write the data to the buffer overwrites adjacent memory locations. In other words, when more data (than was originally allocated to be stored) gets placed by a program or system process, the extra data overflows. It causes some of that data to leak out into other buffers. For example, a buffer for log-in credentials may be designed to expect username and password inputs of 8 bytes, so if a transaction involves an input of 10 bytes (that is, 2 bytes more than expected), the program may write the excess data past the buffer boundary.
There are four type buffer overflow:
- Stack-based buffer overflow: These buffer overflows are more common, and leverage stack memory that only exists during the execution time of a function.
- Heap-based buffer overflow: These buffer overflows involve flooding the memory space allocated for a program beyond memory used for current runtime operations.
- Integer overflow attack: An arithmetic operation results in an integer (whole number) that is too large for the integer type meant to store it.
- Unicode overflow: A unicode overflow creates a buffer overflow by inserting unicode characters into an input that expect ASCII characters. (Read more about ASCII Codes here)
How Do Attackers Exploit Buffer Overflows?
Exploiting the behavior of a buffer overflow is a well-known security exploit. Attackers exploit buffer overflow issues by overwriting the memory of an application. This changes the execution path of the program, triggering a response that damages files or exposes private information. In fact, in a buffer-overflow attack, the extra data sometimes holds specific instructions for actions intended by a hacker or malicious user. By sending suitably crafted user inputs to a vulnerable application, attackers can force the application to execute arbitrary code to take control of the machine or crash the system.
If the overwritten part in memory contains a pointer (an object that points to another place in memory) the attacker’s code could replace that code with another pointer that points to an exploit payload. This can transfer control of the whole program over to the attacker’s code.
Programming languages commonly associated with buffer overflows include C and C++, which provide no built-in protection against accessing or overwriting data in any part of memory and do not automatically check that data written to an array (the built-in buffer type) is within the boundaries of that array. Buffer overflow vulnerabilities are caused by programmer mistakes that are easy to understand but much harder to avoid and protect against. Windows, Mac OSX, and Linux all contain code written in one or both of these languages. More modern languages like Java, PERL, and C# have built-in features that help reduce the chances of buffer overflow, but cannot prevent it altogether.
How to Prevent Buffer Overflows?
Developers can protect against buffer overflow vulnerabilities via security measures in their code, or by using languages that offer built-in protection. Three common protections are:
- Address space randomization (ASLR): Randomly rearranges the address space locations of key data areas of a process. Buffer overflow attacks need to know the locality of executable code, and randomizing address spaces makes this virtually impossible. In such a case, when malicious code is placed in a buffer, the attacker cannot predict its address.
- Data execution prevention: Flags certain areas of memory as non-executable or executable, which stops an attack from running code in a non-executable region.
- Structured exception handler overwrite protection (SEHOP): It helps stop malicious code from attacking Structured Exception Handling (SEH), a built-in system for managing hardware and software exceptions. It thus prevents an attacker from being able to make use of the SEH overwrite exploitation technique.
- Having up-to-date security patches: Deploy security patches as soon as they become available.