Vulnserver Buffer Overflow — TRUN
What I will be outlining in this post is how to find and exploit a buffer overflow vulnerability in the vulnserver application.
What is vulnserver?
Windows based threaded TCP server application that is designed to be exploited. http://www.thegreycorner.com/2010/12/introducing-vulnserver.html
Tools used
- Immunity debugger
- Spike
- nmap
- Netcat
- monapy
- Microsoft Code
So to start off I ran the application on a Windows 10 host and scanned the Victim with nmap to identify the port being used by the application. The default port used by vulnserver is 9999.
Next thing to to is establish a connection to vulnserver over port 9999 and see what the application presents back to us.
nc -nv 192.168.173.130 9999
So the application asks us to input the HELP option. So I did this and noticed that the TRUN command is available to us. And I wanted to start playing with it. To validate that it takes data we just insert some random string,
Let’s attach the application to immunity debugger before we start fuzzing the function.
Then I created a spike script with the below code:
s_readline();
s_string("TRUN ");
s_string_variable("COMMAND");The
Then I ran the fuzzing script against the application:
generic_send_tcp 192.168.173.130 9999 buff.spk 0 0
So after a small while the a application crashes and a few things happened.
When I ran the program again I saw the following popup appear. 4 bytes of A’s shown in it’s hex value as “41414141”. The EAX has also been changed starting with the TRUN :/./ command followed by the string of A’s leading into the ESP and EIP.
At this point it starts looking good for a potential buffer overflow. I could have continued using spike to find the exact offset of where the application breaks but I decided to start building the python script used for exploiting the flaw.
Typically with a buffer overflow I will start off with some form of skeleton code and build the exploit from there on. The below script replicated the original crash that spike caused.
Now that we have replicated the crash with our python script. We need to identify the 4 bytes that have overwritten the EIP register. So first off I generated a random string with monapy and replaced the buffer with the generated value.
The below code is the new exploit script that I used, with the replaced buffer string:
After running the updated python script the EIP was replaced to 6F43376F.
There are usually two ways that I would go about identifying the offset that of the string that overwrites the EIP. First one is pattern_offset which is a metasploit tool:
And the second is with monapy.
With this information we want to verify that the offset found is the correct one. So what I did was to update the python script to the following:
What this did was verify the offset is correct. Now we can see that the EIP has been overwritten with 4 b’s as “42424242” and that the C’s are present in the buffer directly after the 4 bytes of b’s. This means that we can place the shellcode after the 4 bytes of b’s. However this can only happen once we have eliminated the bad characters.
To eliminate all the bad characters you can use mona to generate all possible characters from \x00 to \xFF. I always take out the null byte “\x00” before starting the process because its usually a bad character.
To generate the characters:
!mona bytearray
Then I updated the script to include bad characters and store them in the buffer variable.
From the above updated script we can see that \x00 was the only bad character. So we don’t need to do anything else in this case:
The next part of the process is to find an address that contains a JMP ESP. I decided to use the dll that ships with the application called essfunc.dll.
!mona jmp -r esp -m “essfunc.dll”
I used the first address for the next part of the python script “0x625011af”. When you look at the protection features it does not have any, so this would be an easy target… Using msfvenom I generated the shellcode needed to exploit the vulnerability and gain a remote shell. In the msfvenom command below we are binding a tcp shell over port 4444 (not specified — you can specify this) and using the application we are exploiting with the thread parameter then specifying the null byte character.
msfvenom -p windows/shell_bind_tcp EXITFUNC=thread -b "\x00" -f c
After this I added some new parts to the python script
- The JMP ESP from the DLL identified
- A nopsled before the shellcode (24 NOP instructions)
Time to see the shell connection