Writing the Exploit for the Discovered Vulnerability
In exploit development, the execution flow of the vulnerable application depends on the return address of the stack pointer, if you cannot get hold of the stack pointer, all your efforts will be useless.
Finding Pointers
To find the exact value of where the EIP register is overwritten with the 1000 “A”, or the buffer value of 1000 bytes we have sent, is called “Determining the offset”.
To find the EIP offset, we need to go back to Metasploit to help us. Let’s quickly generate some set patterns with Metasploit and do the same fuzzing but, this time, we will send some set patterns instead of 1000 “A”s and then will again use Metasploit to find the offset for us.
Creating a pattern with Metasploit.
We will now use this pattern and fuzz the server again. Once successfully fuzzed, the EIP value will have four bytes from this pattern of 1000 bytes.
At this stage, our fuzzer will now look like what is shown below. And you can see that we are now sending the pattern we have just created, instead of sending 1000 “A”s.
Let’s run the fuzzer and notice the EIP value.
EIP value is now “34684133”. We will take this value and now be able to find the exact value of the offset where our EIP is getting over written. For this we will copy this value and use Metasploit to find the offset value for us, as shown below.
We have used the Metasploit pattern_offset script, as shown above, to find the offset. The offset value it shows is 221, which means that EIP will be overwritten after exactly 221 bytes of buffer data.
Let’s work on our fuzzer now and start working towards the exploit development phase.
Our exploit code now should look like what is shown below.
We have created a buffer of size 221. After that, we have EIP with 4 bytes and this holds 4 “C”s and next we have ESP of size 500 which is 500 “B”s. If the exploit works well, we should have 4 “C”s written to EIP and ESP should have “B”s as data.
We will now run the exploit and see the results.
Something is wrong here, as we can only see that EIP has “42434343”, which means “BCCC”. Hhowever, we programmed our exploit to write 4 “C”s in EIP register, but we lost one byte somewhere while the buffer overflowed. It’s not a big issue as we only lost the one byte and it can be easily fixed by setting the offset size to 222. Let’s recode and re-exploit to see the results. Our exploit will now look like what is shown below.
We have set the buffer size to 222 and then sent EIP and ESP. Let’s re-exploit and see the results in Immunity Debugger.
Here you go, we now have EIP successfully over written with 4 “C”s, which means you now have complete control over the application and vulnerability is successfully discovered. But the exploit is still incomplete.
Calculating Space
What we have to find next are two key things. Ffirstly, we need to ensure the return address, i.e. the pointer, to the ESP register where we will keep our actual code and not just dummy data. Secondly, we need to ensure the total space we have for our shellcode.
To calculate the total space manually, let’s do some calculation.
We first send the 1000 bytes to generate the errors in the application, hence everything should happen within this 1000 bytes of space. Hhowever, out of this 1000 bytes, we use 222 bytes for the offset, so 1000-222= 778, but out of 778, 4 bytes are gone for EIP so we are left with 774 space with our shellcode.
But we don’t know where our stack is starting from, which means we need to ensure that we are not using any bytes while writing our shellcode into the ESP.
Let’s have a quick look at the stack data we have after controlling the EIP register.
We will simply write the shellcode as:
“1abcdefjhijkl2abcdefjhijkl3abcdefjhijkl4abcdefjhijkl5abcdefjhijkl6abcdefjhijkl” and the results in the Immunity Debugger.
At this stage, our exploit code should look like what is shown below.
Once exploited with the above exploit, Immunity Debugger shows the following results.
This shows that our stack highlighted in the above figure is starting from “hij..” instead of our “1ab..”, which means that we lost some 8 bytes. To ensure that we don’t use any bytes of our actual shellcode, we will put some pre-shellcode to ensure that our actual shellcode is not damaged. Our exploit will now look like what is shown below.
We have set pre-shellcode of 8 bytes data, which is 8 “C”s, and then we will be sending the actual shellcode. Let’s exploit and see the results to ensure that we are not losing any bytes of our shellcode now.
Great, you can now see that our shellcode is fitted exactly as we coded as you can see that our ESP is now starting from “1abcd..”
Controlling EIP
So far, we have been saying that you are controlling EIP but what do we mean when we use the term “Controlling EIP”? At this stage, controlling EIP means that you fully own the flow of application with your shellcode.
What we have so far:
• We know EIP offset
• We know space available for our shellcode
• We know 8 bytes needs to be in pre-shellcode
What we don’t have yet:
• Actual Shellcode
• Location of the ESP pointer
So, let’s first generate the shellcode very easily with the Metasploit help, as shown below. We will use the shell_bind TCP to port 9988. You can generate this shellcode with Metasploit very easily. The shellcode is shown below.
Our exploit should look like what is shown below after using this shellcode.
We now have a shellcode, which opens a port 9988, and allows us to connect back to the victim machine to get the shell successfully, once executed. But we don’t have the pointer to this shellcode, which is the pointer to ESP.
Writing PoC
Without the return address of ESP, your exploit code is nothing but just a piece of software code. To make it a real proof of the concept, you need to have the return address so that you can prove that you have exploited the vulnerability and that it results in something you wanted to do with the exploitation. So without return address of ESP pointer, your whole effort ends up in nothing! Now,the question is how to find this. So far, we have been using Metasploit for assisting us in exploitdevelopment. Metasploit does have the power to find the ESP return address but it has its own limitation. We will use Mona.py to do the job for us.
To make it happen, simply use the following command, as shown below, and select any of the return addresses Mona.py gives you in return. However, do ensure that you run this command once you overwrite the ESP.
You can see that Mona.py has found 54 pointers for us. Use any of these and pack the EIP value with any one of these. We will use the pointer value as shown in the below snapshot.
To fix the value into the EIP register is very easy; break the value and reverse it, as shown below, to save in the variable called myeip
Connecting to the port 9988 to get the shell and you can see port 9988 is now open