Buffer Overflow Mitigation & Recommendation Technique - Part V
- Secure Development Lifecycle (SDLC) - Part VI
Stack Based Buffer Overflow
In Buffer Overflow Exploit - Part 1, I discussed how Stack Based Buffer Overflow works in a brief manner. But now we are going to take a look at it in detail. You can have a look on this diagram to view the pictorial representation of the Stack-Based Buffer Overflow. The first thing that we need to do is send more data that the buffer can handle which overwrites the EIP Address as shown in the following figure.
Figure 1. Sending multiple A’s
Till now we just sent a simple message (i.e. Hello world) to the server now we are going to send 1000 A’s to the server and see how the memory looks. Attach the server with immunity debugger and replace the script with the following code.
Run the code and the output will be the following:
Figure 2. Sending 1000 A’s to the server
Let us take a look at the immunity debugger to see how the memory allocation looks like now.
Figure 3. EIP overwritten
We can see the EIP is overwritten with 41414141. This address is the Hexadecimal representation of “AAAA”. Out of 1000 A’s 4 A’s are in the EIP. There is an access violation trying to execute the code at address 41414141. It is clear that we can control the EIP and replace it with the address we want. Once the vulnerability is known we now need to find the offset on the buffer to know the exact four bytes that overwrite the saved EIP on the stack which lets us control the execution flow. To do that we first need to install the Mona plugin. Mona Plugin could create a random unique pattern which when sent can tell us the exact location (also called offset) of the Address.
Installing & Configuring Mona
Download mona.py. We can simply find it online. Copy mona.py into the Commands folder (inside the Immunity Debugger Application Folder. For me it’s “C:\Program Files (x86)\Immunity Inc\Immunity Debugger\PyCommands” ). You can check if mona.py is working by typing “!Mona” in the command bar of the Immunity Debugger. If everything works, the log window will show the help screen of mona.py.
Next, configure mona.py to store data in a folder other than the default. The default location is the Immunity Debugger application folder, so we create a Folder named “logs” in C drive to set it as a working folder. Just type the following in the command bar.
The above code sets the working folder for mona.py to the folder that we created. Once mona.py is configured we need to create a unique pattern that would tell us the exact position where EIP is being overwritten.
Creating Unique Pattern
We first need to find the offset that could control the EIP. The fastest method to do this is using a feature in Metasploit, called Metasploit pattern. Inside the framework tools folder, we find the scripts pattern_create.rb and pattern_offset.rb. The former creates a string pattern where every three-character sub-string is unique (e.g..: Aa0Aa1Aa2Aa3Aa4). The second script is to calculate the offset once we know which four bytes fits inside the EIP when the program crashes.
To make things easier, mona.py can create a unique cyclic pattern like Metasploit does. To create a cyclic pattern 1000 bytes in length with mona.py, the following command must be typed in the Immunity Debugger command bar.
This command would create a file named pattern.txt in our Working folder i.e. C:\logs\VulnerableServer\pattern.txt with the cyclic pattern inside. The pattern has to be copied into the python code. Now our attacker code looks like:
The next step is again to attach the VulnerableServer.c file to Immunity Debugger and run the attacker’s script. The process again crashes and shows an access violation. The following diagram shows the EIP value overwritten with the pattern.
Figure 4. EIP overwritten with pattern
We need to take a look at the EIP value and take note of the EIP value so that we can find the exact position (offset) to replace it with another address.
Offset of EIP
To figure out the offset to the EIP control bytes, mona.py offers two options:
The first method shows the distance to the four bytes that control EIP, in the log window of Immunity Debugger.
The second method will create the file C:\logs\VulnerableServer\findmsp.txt. The content of the file should look like:
This method gives a lot of Information that should be known to proceed further. We can see that the EIP contains bytes of the normal pattern at the offset of 548 and the ESP points to the cyclic pattern at the offset of 544 just behind the four bytes that control the EIP. This method also informs us the length to store data. As a plus, mona.py offers information about several memory locations that contain the cyclic pattern, and several memory pointers that point directly to the cyclic pattern. We now have the information needed to write an exploit.
We can put the Shellcode just behind the four bytes that control EIP (at offset 548) because we know that the register ESP is pointing directly to this address. So to change the flow control of the process and control the execution. Let us send 548 A’s to the server and send BBBB. Let's see if the EIP is overwritten with BBBB or not. So our new script looks like:
As we run it we will get the following output:
Figure 5. Overwriting EIP with BBBB
But with what address are we going to replace EIP?
In the below figure you can see we have replaced the EIP with the JMP ESP Address of DLL. If you recall, in the first part we discussed the Dll file which we stored in C:\VulnerableServer\Debug\dll.dll. Now we are going to use this dll to get the JMP ESP Address.
Figure 6. Overwriting EIP with JMP ESP
Loading DLL
We now need to put the memory address of an instruction that makes a jump to the address ESP points to into EIP. So we need to find an instruction like jmp esp, call esp, or push esp; ret.
Go to View→ Executable Modules and select the dll file whose SafeSEH and ASLR is set to False. This memory address containing a jmp esp instructions is good to put in EIP and make the flow jump to our Shellcode.
Figure 7. Executable Modules
To find instructions like jmp esp, call esp, or push esp; ret. in memory, we are going to use mona.py again. In the Immunity Debugger command bar, after attaching it to the Vulnerable Server process, we execute:
This command tells mona.py to search for an instruction to jump to ESP inside the process binary and the DLLs loaded in memory on execution time (by default it looks in all DLLs loaded in memory; we can use the -m switch to make it search in DLLs passed as parameters). The result is stored in the file C:\logs\VulnerableServer\jmp.txt. Here is what we need:
Figure 8. Mona JMP Output
Since the DLL injected code will be part of the attacked process' address space, it is possible to jump to the injected code. So we need to search for the command JMP ESP and overwrite the EIP Address with the JMP ESP Address.
Figure 9. Search for Command JMP ESP
We can see the JMP ESP address that we found in the Loaded DLL as below.
Figure 10. Address of JMP ESP
The JMP ESP Address is 610C11DF. We use this address of JMP ESP just after 548 A’s or we can call it junk. This address will point directly to our shellcode. Now lets replace the EIP with the JMP ESP address i.e.(610C11DF).
Note: The EIP address is arranged from backward as it is sent to the stack i.e. \xdf\x11\x0c\x61.
Our code looks like-
Now the last part is to add the Shellcode. Till now we sent a Junk file and the EIP. Now we need to send the Shellcode.
What is Shellcode?
Shellcode is a small piece of code used as the payload in the exploitation of vulnerability. Below is a simple shellcode that is added to the script which opens a message box. You can use and try it. But I will be explaining how a shellcode can be created.
The output of the above will be shown as:
Figure 11. Output of the payload
What should our shellcode do?
There are 2 types of shell- Bind Shell and Reverse Shell. Both of these are explained in Part 1.
Bind Shell-We need to create a shellcode that will open port 4444 in the server and bind it with the shell or command prompt. Thus if we connect to 4444 it would give us the C:/ drive or full access to the victim machine.
Reverse Shell- We need to create a Shellcode that will 4444 in the attacker's machine and listen to the incoming connection from the server. It would also give us access to the victim’s machine.
How to create a Shellcode?
Bind Shell - To create a Bind Shell code, we will open the terminal in Kali Linux and type the following command:
In the above code the payload we are using is windows/shell_bind_tcp. Thus –p is for the payload. We need to bind shell with port 4444 so we set LPORT as 4444. –b is for the bad characters, so we added the most common characters that should not be used. –f is for the output file and c is the language in which we want. It is not necessary to use C you can also use python.
After typing the following in terminal you will get the Shellcode with the removed bad characters. Copy the Shellcode and add it in the python code.
To ensure ESP is not pointing to the Shellcode when the decoder routine is executed, we add an instruction to decrement ESP (sub esp 240h). To obtain the opcodes that represent the instruction, we use a tool from the Metasploit Framework, metasm_shell.rb.
In the following screenshot we see the use of metasm_shell.rb to generate the opcodes we need:
Figure 12. Generate Opcodes
As we can see, if we generate the opcodes of “sub esp,240h” the opcodes generated contain bad characters (0x00). We solve this by adding to esp a negative number: “add esp,-240h”. The “h” in the operation indicates that we are adding 240 in hex, not in decimal. The above output is same in most cases. We first add the move esp and then the Shellcode. So our final Bind Tcp Payload looks like:
Then restart the process and execute the exploit. If all goes right, this is the result on the Windows box:
Figure 13. Bind TCP Output
The TCP port 4444 is listening with the process ID 3444.
To connect to the port 4444, we just simply need to use netcat command i.e.
Every time we would have to manually type it. Just so to automate the process we will be using subprocess to call this command in the terminal. Thus add the following code in the attacker’s script:
After you run the netcat command the output will be:
Figure 14. Gaining Shell Access
You got access to the C drive. You can change the drive and delete, modify and insert anything you want in the victim's machine.
Reverse Shellcode - To create a reverse Tcp Shellcode open Kali Linux and type the following command in the terminal.
It is similar to what we did in bind tcp. Here the LHOST is the attacker’s IP Address. Copy the shellcode generated and paste it in the python code instead of the bind tcp use reverse tcp. The code looks like:
Unlike Bind Tcp, In the reverse tcp, we would not be connecting to the port number instead we would be listening to the port 4444 for the connection from the server. Thus Open the terminal and type the command below:
The above code would start the listener on port 4444. To make these automated write the following command in the attacker’s script.
Note: In Reverse Tcp Attacker’s Ip is used to get reverse connection. LHOST is the Attacker’s Ip.
After executing the netcat command you will see the same output as you saw in the bind Tcp as shown in the following diagram.
Figure 15. Gaining Shell Access
In this part, we performed Stack Based Buffer Overflow. If you are facing any difficulty do let me know. I will help you in every way I can. You can leave the questions in the comment below.
In the next tutorial we will see the SEH Based Buffer overflow.
No comments:
Post a Comment