Introduction

Buffer overflows have been the most common form of security vulnerability in the last 10 years. Buffer overflow attacks make up a substantial portion of all security attacks simply because buffer overflow vulnerabilities are so common and so easy to exploit. Most of the exploits based on buffer overflows aim at forcing the execution of malicious code, mainly in order to provide a root shell to the user.

A buffer overflow occurs when more data are written to a buffer than it can hold. Buffer overflows happen when there is improper validation.

Like it or not, all buffer overflows are a product of poorly constructed software programs. These programs may have multiple deficiencies, such as stack overflows, heap corruption, etc., which are referred to as simply buffer overflows. Programs written in C are particularly susceptible to buffer overflow attacks. Pace and performance were more important design considerations for C than safety. Hence, C allows direct pointer manipulations without any bounds checking. The standard C library includes many functions that are unsafe if they are not used carefully.

Buffer Overflow

To understand buffer overflow attacks, we must first understand what a buffer overflow is. A buffer is an area of memory allocated with a fixed size. It is commonly used as a temporary holding zone when data is transferred between two devices. When user input exceeds the maximum size of the buffer, overwriting the other areas of the memory and corrupting those areas results in buffer overflow.

A common example is an application that asks for a username it expects to be no longer than 8 characters.

boolean rootPriv = false;

char name[8];

cin >> name;

If the user enters a username of more than 8 characters, there is a potential problem if the application tries to store the username in a string buffer of 8 bytes, which can take a maximum of 8 letters.

Types of Buffer Overflow

  • Stack Overflow

    Stack overflows are considered the most common type of error that can be remotely exploitable. Stack overflows are caused by a lack of separation between data and structures that control the data. Of the different types of buffer overflows, stack overflows are considered the easiest to exploit.

  • Heap Overflow

    A heap is a memory area that has been allocated dynamically. Heaps are dynamically created (e.g., new, malloc) and removed (e.g., delete, free).
    Heaps are necessary because the memory size needed by the program is not known in advance or it may require a larger memory than just the stack.

    Heap overflow is basically as same as stack overflow. When a program copies data without checking whether or not it can be stored in the given destination, then the attacker can easily overwrite data and instruction in heap.

  • Off-by-One Errors

    An off-by-one error is a specific type of buffer overflow that occurs when a value is one iteration off what it is expected to be. This can often be due to miscounting the number of times a program should call a specific loop of code. The error may result in rewriting one digit in the return pointer in the stack, which allows a hacker to direct the pointer to an address containing malicious code.

  • Format String Overflow

    A format string attack occurs when a program reads input from the user or from other software and processes the input as a string of one or more commands. If the command that is received differs from that which is expected, such as being longer or shorter than the allocated data space, the program may crash, quit, or make up for the missing information by reading extra data from the stack; allowing the execution of malicious code

Types of Buffer Overflow Attacks

A buffer overflow attack may be of two types. One is remote and another is local. In the case of a remote attack, the attacker uses a network port channel to achieve unauthorized access and tries to get administrator privileges. It is very common today, as the use of Internet spread widely in practice. On the other hand, in a local attack, the attacker gain direct access to the target system, and then enhances his access privilege.

Consequences of Buffer Overflow

  • Availability: Buffer overflows generally lead to crashes. Other attacks leading to lack of availability are possible, including putting the program into an infinite loop.
  • Access control: Buffer overflows often can be used to execute arbitrary code, which is usually outside the scope of a program’s implicit security policy.
  • Other: When the consequence is arbitrary code execution, this can often be used to subvert any other security service.

How to Exploit the Buffer Overflow Vulnerability

To fully exploit the stack buffer overflow vulnerability, we need to solve the following challenging problems:

  • Writing malicious code: The most powerful malicious code is to invoke the shell, so we can run any command we want in that shell.
  • Jumping to the malicious code: To jump to the malicious code that we have injected into the target program’s stack, we need to know the absolute address of the code so that, when the function returns, it will return to our malicious code.
  • Injecting the malicious code: With the buffer overflow vulnerability in the program, we can easily inject malicious code into the memory of the running program.

Shellcode: Shellcode is the code executed when a vulnerability has been exploited.

It is called shellcode because it typically starts a command shell from which the attacker can control the compromised machine. Shellcode is very common in the exploitation of vulnerabilities such as stack and heap-based buffer overflows, as well as format strings attacks. Basically shellcode is a machine code used as the payload in the exploitation of a software bug. From the hacker’s point of view, having accurate and reliable shellcode is a requirement for performing any real-world exploitation of vulnerability. If the shellcode isn’t reliable, the remote application or host could crash.

Examples

  • C program Vulnerable to Buffer Overflow

Below is the C program having buffer overflow vulnerability.

#include<stdio.h>
void main()
{
  char *fname;
  char *lname;
  fname=(char *)malloc(10);
  lname=(char *)malloc(10);
  printf("address of first name:%dn", fname);
  printf("address of last name:%dn", lname);
  printf("Difference between address is :%dn", lname-fname);
  printf("Enter pet name:");
  gets(fname);
  printf("hello %sn",fname);
  system(lname);
  }

The malloc function is used to allocate a certain amount of memory during the execution of a program. The malloc function will request a block of memory from the heap. If the request is granted, the operating system will reserve the requested amount of memory. When a system function is executed, the content in the last name will be executed.

In the above program, we allocate 10 bytes to the first name which is dynamic allocated memory and another 6 additional bytes for malloc call.

We can compile the above program (new.c) as:

We execute the program and get to know that the address between first name and last name is 16 bytes. Then we enter the pet name and the program responds “hello pet name” i.e., John martin. When the user gives the input of less than the 16 digits then the program will execute normally as the function doesn’t goes up to the last name variable.

We again execute the program with a different pet name, i.e., jonathhan lewinters and it responds “hello jonathhan lewinters” and “ers: command not found.” This means the command we are trying to execute is not found in the shell.

In this execution the first 10 bytes are assigned to the first name, 6 bytes are assigned with malloc function and the remaining 3 bytes goes to last name, i.e., “ers.”

Again we execute our program with the same pet name, jonathhan lewinters, but in place of ers we use cat /etc/passwd.

This results in the buffer overflow. This buffer overflow is caused because the gets() function doesn’t limit the length of input. In this way an attacker can exploit the application having a buffer overflow vulnerability to execute a system command. To overcome this kind of problem we can use the fgets(fname,10,stdin) function.

Buffer Overflow Attack in TUGZip 3.5 Using Backtrack

TUGZip 3.5 is prone to the remote buffer-overflow vulnerability because it fails to perform adequate boundary checks on user-supplied data. The vulnerability occurs when handling specially crafted ZIP files. Through this vulnerability, an attacker can exploit this issue to execute arbitrary code with the privileges of the user running the affected application. Failed exploit attempts will result in a denial-of-service condition.

Download TUGZip 3.5 and install the software on a Windows machine. Open the Backtrack machine and start metasploit by using msfconsole command in console.

Search for TUGZip in msf and use exploit TUGZip. If you don’t have this exploit, download it from the resource.

Set reverse TCP as the payload and set LHOST. LHOST is the local host IP address, which means the backtrack machine’s IP address; in my case, it is 192.168.1.11.

Run the exploit. It will create a .zip file. Send that file using some social-engineering method to the victim machine.

Now we need to open a listener so we can listen for the zip connecting back so that we get a session. Create a payload handler on the backtrack machine.

Set reverse TCP as the payload. Set LHOST and run the exploit.

When the victim opens that zip file in TUGZip you will get a meterpreter session opened in backtrack.

Want to learn more?? The InfoSec Institute Reverse Engineering course teaches you everything from reverse engineering malware to discovering vulnerabilities in binaries. These skills are required in order to properly secure an organization from today's ever evolving threats. In this 5 day hands-on course, you will gain the necessary binary analysis skills to discover the true nature of any Windows binary. You will learn how to recognize the high level language constructs (such as branching statements, looping functions and network socket code) critical to performing a thorough and professional reverse engineering analysis of a binary. Some features of this course include:

  • CREA Certification
  • 5 days of Intensive Hands-On Labs
  • Hostile Code & Malware analysis, including: Worms, Viruses, Trojans, Rootkits and Bots
  • Binary obfuscation schemes, used by: Hackers, Trojan writers and copy protection algorithms
  • Learn the methodologies, tools, and manual reversing techniques used real world situations in our reversing lab.

Meterpreter provides an interactive shell that allows you to use extensible features at run time.

A beautiful feature of meterpreter is its ability to remain undetectable by most commonly used intrusion detection systems. Meterpreter also provides ease of multitasking by giving us the ability to create multiple sessions.

Prevention against Buffer Overflow Errors

Buffer overflow vulnerabilities are the result of poor input validation: they enable an attacker to run his input as code in the victim machine. Following are the steps used to prevent (or detect) buffer overflow vulnerabilities.

  • Use safer versions of functions: Safer alternatives are available for all the traditional functions beset by buffer overflows. For instance, strncpy and snprintf are safer than the older strcpy and sprint.
  • Static Techniques: One of the best ways to prevent the exploitation of buffer overflow vulnerabilities is to detect and eliminate them from the source code before the software is put into use. Tools designed to perform automatic source code analysis complement the act of a manual audit by identifying potential security violations, including functions that perform unbounded string copying. Some of the best known tools are its4, RATS, and LCLin.
  • Dynamic run-time checks: In this, an application has restricted access in order to prevent attacks. This method primarily relies on the safety code being preloaded before an application is executed. This preloaded component can either provide safer versions of the standard unsafe functions or it can ensure that return addresses are not overwritten. One example of such a tool is libsafe.
  • Compiler Modifications: If the source code is available, individual programs can have buffer overflow detection automatically added to the program binary through the use of a modified compiler. StackGuard, ProPolice, StackShield, and RAD are such compilers.
  • Stack executes invalidation: Because malicious code (for example, assembly instructions to spawn a root shell) is an input argument to the program, it resides in the stack and not in the code segment. Therefore, the simplest solution is to invalidate the stack’s ability to execute any instructions.

Conclusion

A buffer overflow occurs when more data are written to a buffer than it can hold. The excess data is written to the adjacent memory, overwriting the contents of that location and causing unpredictable results in a program. Buffer overflows happen when there is improper validation. It is considered a bug or weakness in the software. Buffer overflows still account for the largest share of software vulnerabilities. Particularly dangerous is the area of remote exploitable vulnerabilities, where attackers hijack hosts in the Internet to perform criminal activities on behalf of others. The prevention technologies can make exploiting a buffer overflow considerably harder, but no tool can solve completely the problem of buffer overflow.

However, writing secure code is still the best possible solution to these attacks.

References