Although Buffer Overflow is not listed under the “OWASP Top 10”, it doesn’t make this vulnerability any less dangerous than the listed vulnerabilities. It’s mostly utilized by attackers to compromise core software like a web server.
It brings us to the question: what is it and how to mitigate it? It’s not possible to fix buffer overflow problems without understanding it, its risks, and the attack techniques involving it.
What is Buffer Overflow?
Buffer Overflow, also known as “Buffer Overrun”, is an abnormality or mistake in software logic wherein a program writes more-than-possible data to a buffer (a memory location), thus overwriting data to its adjacent memory locations.
What is the result of a buffer overflow? A buffer overflow can corrupt the data in the buffer, crash or hang the application, or even execute malicious code.
So, what is the cause of buffer overflows? They’re mostly caused when an app’s developer implements memory manipulation whiles wrongly assuming the data’s size or its makeup. It may happen if he doesn’t check for buffer’s boundaries, or if he checks for it, he incorrectly uses bounded functions — say strncpy().
The typical programs which are prone to buffer overflow attacks are the ones that depend on external data for their functioning or data properties introduced externally and the ones too complex to get properly debugged and tested.
What is the history of buffer overflows? Buffer overflows were documented and understood as early as October 1972. However, it was not until 1988 that it was exploited or at least it was the first documented exploitation. It was used by Morris worm for spreading to a large number of systems over the web. Advanced users can learn more about the intricacies of Buffer overflow here.
Computer Security Technology Planning Study wrote, “The code performing this function does not check the source and destination addresses properly, permitting portions of the monitor to be overlaid… This can be used to inject code into the monitor that will permit the user to seize control of the machine.” in 1972.
Example of a Buffer Overflow
For example, let’s say two adjacent buffers (#A and #B) can hold 15 characters individually. #A contains “I am buffer #1 ” and #B holds “Hi I am buffer2”. In these examples, the null-termination character is skipped to keep it simple.
Now, if a program needs to write new data to #A — let’s say “Hey I am buffer #1” and it doesn’t check the new data’s size, then it causes a buffer overflow. Why? The new text is 18 characters in size and #A can only hold 15 characters.
So, what happens after the buffer overflow? #A will now hold “Hey I am buffer”, overwriting “ #1” to its adjacent buffer (#B). Then, #B will store “ #1I am buffer2”. As witnessed, #B’s content gets overwritten and damaged, thanks to the data in #A getting overflowed to #B. But it doesn’t look like a security issue, right?
Wrong. In the above example, we talked about non-sensitive data (texts), but if the buffers were holding some crucial data required by the program, it may pose serious security risks. Nonetheless, if the program tries to access the data from #B, it will read corrupted data, which may even cause the program to crash.
How is it Exploited in Attacks?
There are numerous techniques to exploit buffer overflows. They usually differ by the target system architecture or environment, operating system, or memory region. For instance, the exploit for attacking the memory heap differs from the exploit for the call stack. Let’s discuss the two most common techniques.
Heap-based Buffer Overflows
Heap is a dynamically allocated memory, i.e., data is allocated on the heap during the program run. It typically stores program data, so an attacker usually corrupt this data using specific methods to overwrite memory allocation linkage.
The resultant linkage is used to overwrite the program’s function pointer. Thus, the attacker, if successful, is able to run arbitrary code, which may compromise further programs or steal the original program’s data or the user’s data.
Stack-based Buffer Overflows
Stack is a statically allocated memory, i.e., data allocation on the stack is dealt with during the program’s compilation time, unlike as it’s for the heap. An attacker uses stack-based buffer overflows to gain control of the program.
He/she may overflow a local variable storing any crucial data to manipulate the execution of the program. Or, he/she may overflow a return address stored in a stack frame, causing the program to run the code at the new return address. The result: the program runs some malicious code provided by the attacker.
How to Mitigate Buffer Overflows?
Buffer overflows are software development mistakes which can be fixed using some tested tips and tricks. Let’s read about each of them in detail.
1] Opt for a Secure Environment
Though most of the popular app and web servers and web app environments are susceptible to buffer overflow attacks, the ones coded in interpreted languages have an edge. The interpreted languages like Java and Python are less-prone to such attacks with an exception to overflow issues in their interpreters.
The languages known to cause the most buffer overflows are Assembly, C, and C++ — the languages with less support for checking buffers’ boundaries.
Additionally, if your app, website, or web server depends on third-party libraries or software such as Apache, you must opt for safe solutions that address buffer overflows and provide regular updates for patching new vulnerabilities.
2] Update Libraries and Software
Additionally, you must update them regularly to mitigate any known and patched buffer overflow vulnerabilities. Also, if your app depends on any libraries (say a graphics library), you must update them too and deliver patches regularly.
Moreover, it’s always a good idea to subscribe to the bug reports or developer updates of the libraries or software you’re using in your apps or websites. They help you to keep an eye on the latest security advisories from their developers.
3] Do Regular Vulnerability Scans
You should perform vulnerability scans using reputed vulnerability scanners to search buffer overflow bugs in your custom libraries, web apps and servers, and software products. Then, you must fix those vulnerabilities and distribute as well as install the related fixes to avoid attacks using those buffer overflow bugs.
Some of the free or open-source solutions are Golismero, w3af, and OWASP ZAP. Also, there are many commercial solutions with varied proprietary features. Do you want to try one? Techworld hosts a large list of vulnerability scanners.
4] Implement Protective Solutions
There are security solutions that help you to search and prohibit most known buffer overflow attacks targeted toward stacks. The popular solutions include Libsafe, ProPolice, StackGuard, and Data Execution Prevention (DEP).
Then, there are numerous protective measures availed by CPUs and OSs like a bit named NX (“No eXecute”) or XD (“eXecute Disabled”) is used to mark crucial pages (like the heap or stack) as readable and writable but inexecutable.
Finally, you should implement a deep packet inspector — a network analyzer that reads and analyzes every incoming network packet. It scans the packets to detect buffer overflow attacks and block them to protect your systems.
That’s all about buffer overflow and how it’s exploited by attackers. Did you find this post helpful in understanding buffer overflow? Post a comment below.