Windows Stack Based Buffer Overflow
Buffer overflow are mainly use to remotely exploit (or locally) applications in order to execute shellcodes, like reverse or bind shells. Its pretty intimidating for a new comers in this awesome field but with enough time and determination you will be able to learn fast and you will be able to exploit applications.
For this training I will use a windows 7 system VMware image that you can download here. Note, you can use VirtualBox but it’s VirtualBox.
Moreover, I will use inside the windows 7 machine:
- Python 2,7;
- A debugger called Immunity Debugger;
- A really (REALLY) useful python script known as mona.py and
- The vulnerable application LabF nfsAxe 3.7 FTP Client
My attacking machine is a Kali Linux system that you can download in the Kali Linux website here.
In this post I will try to do my best to be understand by the majority. If you want a more complete tutorial written by an expert, about Stack Based Buffer Overflow, I highly suggest you to read this post from the CORELAN website.
Before beginning this tutorial, a quick overview of how the exploit work. The FTP client will connect as anonymous in our malicious FTP server and then we will send the exploit. So, you need to install your own virtual windows system, all the required tools (listed upper) and to have a connection between your virtual windows system and you attacking system.
The first thing that we need to do when we have an application and we want to exploit it it’s to throw different length of strings in each place we can inject data in order to, hopefully, make it, the application, crash. That’s what we called fuzzing. Note, you can do it manually or you can automate it with tools or your own scripts.
For example, for our first try we will send five hundred ‘A’s (\x41 in hexadecimal) to our client when he connect to our malicious python server. The following Python script gonna be used.
We start our malicious server and we use the FTP client to connect to our malicious server.
The FTP client should look like that, we have our five hundred ‘A’s.
After few tries, where each time we increase the number of ‘A’ we send to the FTP client, we can find that the FTP client crash with 4000 ‘A’. We can update our python script and try it.
OK, application successfully crashed. Now, let’s make crash this application when attached to the debugger.
To attach a process to Immunity Debugger: File -> Attach
Then we have to continue the execution of the application by pressing the F9 key. Finally, the application should look like that at the moment of the crash.
At this point, we need to talk a look at what is the EIP and the ESP registers.
The EIP register is the Extended Instruction Pointer. EIP is the most important thing in stack based exploit because he allow use to control the execution flow of the application. With him (EIP) we can deflect into our malicious code the normal execution of the application, for example.
The ESP register is the Extended Stack Pointer. Primarily used for hunting bad-chars (later in the post) he serves as an indirect memory operand pointing to the top of the stack at any time. When you add something on the stack his value decreases and when you remove something his value increases because LIFO (Last In First Out).
So, your work now is to find where EIP is overwrite in order to later control the execution flow. For that, we will create and use a cyclic pattern.
A cyclic pattern is: “a string that contains unique patterns. Using this pattern [..] we can see how big the buffer should be to write exactly into EIP.”
-CORELAN – https://www.corelan.be/index.php/2009/07/19/exploit-writing-tutorial-part-1-stack-based-overflows/
Two way can be used, one with Metasploit exploits tools and one with mona.py. Both will be use and explains in this post.
Pattern creation with Metasploit
The pattern_create.rb tool from the Metasploit framework can be used to create our cyclic pattern.
We can update our exploit with this pattern.
Now if we replicate the crash we will find which pattern overwrite EIP.
As we can see, EIP is overwritten by: 38714337. Now, we can use the other Metasploit tool, pattern_offset.rb, to find after how many bytes we overwrite EIP.
Seemingly, after 2063 bytes we overwrite EIP.
Pattern creation with mona.py
Same process here but instead of using Metasploit we will use the mona.py script. First, we set your working directory (where you want).
Now, we create our cyclic pattern.
We can copy/past the Hex chain of the created file in order to update our exploit and then, make crash once again the application. At the moment of the crash instead of using the pettern_offset.rb tool we can use another command from mona.py, that will find where EIP is overwritten with a cyclic pattern.
Once again, EIP is overwritten after 2063 bytes.
Finally, we can update our exploit.
Our next step is to find which characters are not allow or. Sometimes, all characters are usable and sometimes your have more than five/six characters that will made fail your exploit. Please note, the ‘\x00’ characters, also know as the null terminator is never allow and must be remove in any cases. This part of exploit development is really important and may be responsible of the failure of our work.
The first thing that we can do is to generate a variable with all possible characters (except ‘\x00’).
We update our exploit in order to find which characters in this list change.
After the crash we can right click on the ESP register and then click on the Follow in Dump option in order to see the content of the dump after the EIP offset.
As we can see after the ‘\x0a’ characters something goes wrong and break our string of bad-chars. So, we can say that the ‘\x0a’ characters is a bad characters and we need to avoid it for later. We have two way to find bad-chars, manually, or with mona.py. In the first case we did it manually, now we will see how to did it with mona.py.
Let’s update the bytearray.bin file and our exploit.
We make crash the application and then we use the compare command of mona.py to compare bytes in a file, in our case the previously created and updated bytearray.bin file, and a sequence of bytes at given address.
The second and the last bad-chars is ‘\x0d’.
For this exploit we found only two unusable characters but as says previously sometimes we need to repeat this process more then five/six times. Finally we can update our exploit and notes these badchars.
Controlling the execution flow
So, now, we need to find a way to control the execution flow and to redirect the application into our malicious code. For that we need to find an address where we can execute a JMP ESP (hexadecimal = ‘\xff\xe4’), CALL ESP (hexadecimal = ‘\xff\xd4’) or, a more esoteric one, a PUSH ESP; RET (hexadecimal = ‘\x54\xc3’) instruction.
Mona.py will help us to search in each imported modules the desired instruction. However, the address of the instructions must be subject to different restrictions such as:
- The address must be bad-chars free and
- The address must be in a module with DEP (Data Execution Prevention) and ASLR (Address Space Layout Randomization) unused.
Note, for a compatibility between different windows version you should find an address in a non OS module. First we search which module are without DEP, ASLR and non native OS module.
We can search for a PUSH ESP; RET instruction with the find command of mona.py, in this three modules and who don’t contain our previously discovered bad-chars.
Fortunately for us, the 0x6809d408 address can be use, so we can update our exploit and change the ‘\x42’s with this address.
Now, before making one more time the application crash we have to put a breakpoint at this address.We have to: click on the Go to address in Disassembler button -> enter the address -> press F2 to set the breakpoint.
After the crash, we will reach the breakpoint.
Finally, if we hit two times the F8 key (Step over), to execute the PUSH ESP and the RET instruction, we will redirect the execution of the program right after EIP.
Shellcode creation and execution
We successfully found a way to redirect the execution flow of the application into a place where we have enough space to store and execute our malicious code a.k.a shellcode.
We can easily create a reverse shell with the msfvenom tool from the Metasploit Framework. Note, we have to specify our bad-chars to msfvenom (with the -b flag).
We can add the shellcode into our exploit.
We set a listener in order to receive our reverse shell.
Let’s put a breakpoint in the same address as previously in order to see our shellcode.
Finally, we press the F9 key to run the program and we gain a shell!
You can find and download the final version of this exploit here.