Posted by: Leap Security
Buffer Overflows or stack smashing are common attack vectors. There are numerous tutorials online on how to perform buffer overflows and the theories behind them, but in this example we’ll dive in a little deeper.
What you’ll need:
- VMware or Virtualbox
- Kali Linux
- Windows OS (I used Windows 7)
- Immunity Debugger
- Vulnerable version of Free Float FTP
- Programming experience
A stack overflow is accomplished when one overwrites the space allocated for the stack. Let’s take a look at simple example. Below we have a program which takes a five digit zip code from a user and places it into an array of five elements. Can you see a problem with this program?
If you were thinking that there was no bound checking you are correct! This program does not validate user input thus allowing a malicious user to input a zip code containing a thousand characters if s/he wishes. Let’s check to see how the stack looks like during the execution of this program. The image below depicts the Stack Example.
For simplicity purposes we have divided the stack into three blocks. The first block will contain the zip code array, the second block will contain the saved frame pointer (ESP), and lastly the return address (EIP). Once the user inputs his/her zip code the character array will be populated as shown below.
Excellent. The program seems to be working thus far. The zip code, 89101, was stored within the zip code array just fine. However, what happens when a user decides to send a thousand characters? Let’s take a look.
Oops! The program has crashed. This happens because the program had no bound checking. If the program were to have implemented input validation and used the strlcpy instead of strcpy function then this could have been avoided.
Now you may be asking yourself, how exactly can someone exploit this? Well, if the user wants to inflict some damage then s/he must find enough space for their payload and make the application point to the payload at the time of the crash. Let’s go through this in detail.
Before we get started, be sure to go through the bullet points below to make sure you’re ready to go:
- Ensure that both of your virtual machine’s (Windows and Kali) network settings are set to internal/host only.
- Install Free Float FTP and Immunity Debugger onto your Windows OS.
Now, let’s move on to the fun stuff. In your Kali VM let’s make a simple proof of concept code to see the crash happen. In this application, the buffer overflow vulnerability is trigged when a user submits 1000 characters to the application. Every application is different and requires fuzzing in order to determine the point of the crash.
Our proof of concept script below submits a thousand letter A’s to the application using the FTP MKD command.
If you do not understand what this program is doing then I highly recommend you visit the python documentation.
After running the proof of concept script we can see that the FTP server registers (specifically ESP, EDI and EIP) within Immunity debugger have changed and are now populated with letter A’s (EIP is populated with 41414141 which is the hex value for letter A). This means we have successfully trigged the buffer overflow vulnerability!
Now that we have overwritten EIP we must find where exactly EIP was overwritten. To do this we will use metasploit’s pattern create and pattern offset scripts. The pattern create script will create a unique string for a given length. We will create a string consisting of 1000 characters and place that into our program’s buffer variable.
Be sure to restart the debugger and FTP application before running the proof of concept script again. Once executed the registers will now be overwritten with the unique pattern. EIP, ESP and EDI should be overwritten. Copy the EIP value (should be 69413269) and use metasploit’s pattern offset to figure out exactly where the location of EIP is at the time of the crash.
Great, we can see that the offset or location for EIP occurs at the 247th byte. Repeat this process for the other registers to obtain their respective offsets.