Fuzzing "Vulnerable Server"

Purpose

Practice fuzzing to find vulnerabilities.

Examine these crashes to determine how easy they will be to exploit.

We will use these tools:

What You Need

WARNING

VulnServer is unsafe to run. The Windows 7 machine will be vulnerable to compromise. I recommend performing this project on virtual machines with NAT networking mode, so no outside attacker can exploit your windows machine.

Preparing the Vulnerable Server

On your Windows 7 machine, open a Web browser and go to

http://sites.google.com/site/lupingreycorner/vulnserver.zip

If that link doesn't work, try this alterative download link.

Save the "vulnserver.zip" file on your desktop.

On your desktop, right-click vulnserver.zip.

Click "Extract All...", Extract.

A "vulnserver" window opens. Double-click vulnserver. The Vulnserver application opens, as shown below.

Turning Off Windows Firewall

On your Windows 7 desktop, click Start.

In the Search box, type FIREWALL

Click "Windows Firewall".

Turn off the firewall for both private and public networks.

Finding your Windows 7 Machine's IP Address

On your Windows 7 Machine, open a Command Prompt. Execute the IPCONFIG command. Find your IP address and make a note of it.

Testing the Server

On your Kali Linux machine, in a Terminal window, execute this command:

Replace the IP address with the IP address of your Windows 7 machine.

nc 192.168.119.130 9999
You should see a banner saying "Welcome to Vulnerable Server!", as shown below.

Type HELP and press Enter. You see a lot of commands. None of these actually do anything useful, but they do take input and process it.

On your Kali Linux machine, in the Terminal window, type EXIT and press Enter to close your connection to Vulnerable Server.

Fuzzing with 'A' Characters

On your Kali Linux machine, in a Terminal window, execute this command:
nano vs-f1
In the nano window, type or paste this code.

Replace the IP address with the IP address of your Windows 7 machine.

#!/usr/bin/python
import socket
server = '192.168.119.130'
sport = 9999

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
connect = s.connect((server, sport))
print s.recv(1024)

print ('Commands: STATS, RTIME, LTIME, SRUN, ' +
   'TRUN, GMON, GDOG, KSTET, GTER, HTER, LTER, KSTAN')
print
cmd = raw_input('Command: ')
l0 = int(raw_input('Start length: '))
l1 = int(raw_input('Stop length: '))
lstep = int(raw_input('Length step: '))

for length in range(l0, l1, lstep):
   print "Sending attack to ", cmd, " A * ", length
   attack = 'A' * length
   s.send((cmd + ' ' + attack + '\r\n'))
   print s.recv(1024)

s.send('EXIT\r\n')
print s.recv(1024)
s.close()

To save the code, type Ctrl+X, then release the keys and press Y, release the keys again, and press Enter.

Execute these commands to make the program executable and run it:

chmod a+x vs-f1

./vs-f1
Enter a command of STATS Try some length values. When I tried it, no length crashed the server, up to 100,000 characters, as shown below.

Continue testing the other commands.

Each time the server crashes, close the Python program with Ctrl+C and restart "Vulnerable Server" on the Windows machine.

I found these crashes:

KSTET at length 70 or longer (but not 60)
GTER at length 150 (but not 140)
HTER at 2100 (but not 2000)
LTER is inconsistent: sending it lengths from 1000 to 10000 with step 1000 leads to crashes sometimes, but not always.

Fuzzing with 253 Characters

Perhaps other characters besides 'A' will lead to more crashes.

n your Kali Linux machine, in a Terminal window, execute this command:

nano vs-f2
In the nano window, type or paste this code.

Replace the IP address with the IP address of your Windows 7 machine.

#!/usr/bin/python
import socket
server = '192.168.119.130'
sport = 9999

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
connect = s.connect((server, sport))
print s.recv(1024)

print "Using test string of 253 characters"
chars = ''
for i in range(1,10):
   chars += chr(i)
for i in range(11,13):
   chars += chr(i)
for i in range(13,255):
   chars += chr(i)

print ('Commands: STATS, RTIME, LTIME, SRUN, ' +
   'TRUN, GMON, GDOG, KSTET, GTER, HTER, LTER, KSTAN')
print
cmd = raw_input('Command: ')
l0 = int(raw_input('Start length: '))
l1 = int(raw_input('Stop length: '))
lstep = int(raw_input('Length step: '))

for length in range(l0, l1, lstep):
   print "Sending attack to ", cmd, " 253chars * ", length
   attack = chars * length
   s.send((cmd + ' ' + attack + '\r\n'))
   print s.recv(1024)

s.send('EXIT\r\n')
print s.recv(1024)
s.close()

To save the code, type Ctrl+X, then release the keys and press Y, release the keys again, and press Enter.

Execute these commands to make the program executable and run it:

chmod a+x vs-f2

./vs-f2
Testing all the commands.

Each time the server crashes, close the Python program with Ctrl+C and restart "Vulnerable Server" on the Windows machine.

I found these crashes:

TRUN at length 8*253 (but not 7*253)
GMON at length 16*253 (but not 15*253)
KSTET at length 1*253
GTER at length 1*253
HTER did not crash at all, up to 90*253
LTER consistently dies at 8*254 but not at 7*253

Fuzzing with Numbers

n your Kali Linux machine, in a Terminal window, execute this command:
nano vs-f3
In the nano window, type or paste this code.

Replace the IP address with the IP address of your Windows 7 machine.

#!/usr/bin/python
import socket
server = '192.168.119.130'
sport = 9999

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
connect = s.connect((server, sport))
print s.recv(1024)

chars = '1234567890'

print ('Commands: STATS, RTIME, LTIME, SRUN, ' +
   'TRUN, GMON, GDOG, KSTET, GTER, HTER, LTER, KSTAN')
print
cmd = raw_input('Command: ')
l0 = int(raw_input('Start length: '))
l1 = int(raw_input('Stop length: '))
lstep = int(raw_input('Length step: '))

for length in range(l0, l1, lstep):
   print "Sending attack to ", cmd, " 10digits * ", length
   attack = chars * length
   s.send((cmd + ' ' + attack + '\r\n'))
   print s.recv(1024)

s.send('EXIT\r\n')
print s.recv(1024)
s.close()

To save the code, type Ctrl+X, then release the keys and press Y, release the keys again, and press Enter.

Execute these commands to make the program executable and run it:

chmod a+x vs-f3

./vs-f3
Testing all the commands.

Each time the server crashes, close the Python program with Ctrl+C and restart "Vulnerable Server" on the Windows machine.

I found these crashes:

KSTET at length 7*10 but not 6*10
GTER at length 15*10 but not 14*10
HTER at length 210*10, but not 200*10
LTER consistently died several times at 620*10 but not at 610*10; but when I tried to repeat it later it became inconsistent again

Summary of Crashes

Here are the 6 crashes I found, with labels for future reference:
KSTET : 70*'A', 1*253, 7*10 (probably all the same)

GTER : 150*'A', 1*253, 15*10 (probably all the same)

HTER : 2100*'A', 210*10 (probably the same)

LTER : Inconsistent results: Sometimes it dies at 8*253 or 620*10

TRUN : 8*253

GMON : 16*253

Examining the KSTET Crash in Immunity

As we've done before, launch "Vulnerable Server" in the Immunity debugger.

Then send 70 'A' characters to KSTET.

Look at the lower left corner of the Immunity window: there was an "Access violation when executing [00000A0D], as shown below:

That looks like a carriage return (0D), line feed (0A) pair in reverse order to me, so I suspect this is the very end of the command line.

Try sending 75 'A' characters.

Now immunity says "Access violation when executing [41414141], as shown below:

So this is a classic buffer overflow exploit; the 'A' characters end up in the EIP.

However, there's not much space to insert attack code. ESP points to a region with only one 'A'.

Let's try a longer attack of 600 'A' characters.

Now immunity says "Access violation when executing [41414141], so we still control the EIP.

Following ESP in the dump, and scrolling back up a few lines in the lower left pane, shows that only a small portion of the 'A' characters made it to ESP, perhaps 80 characters, as shown below:

So this is a SIMPLE STACK OVERFLOW, with SMALL SHELLCODE SPACE

Examining the GTER Crash in Immunity

Launch "Vulnerable Server" in the Immunity debugger.

Then send 150 'A' characters to GTER.

Immunity says "Illegal instruction", and EIP is 0040000C, as shown below:

It's crashed, but it's not obvious that we can control the EIP, because there are no '41' bytes in useful places.

Using 155 'A' characters puts '41414141' in the EIP, as shown below:

Sending 600 'A' characters shows a result much like the KSTET crash: there are only about 80 bytes available near the ESP, as shown below:

Examining the HTER Crash in Immunity

Launch "Vulnerable Server" in the Immunity debugger.

Then send 2100 'A' characters to GTER.

Immunity says "Access violation when executing [AAAAAAAA]", and EIP is AAAAAAAA. The stack points to near the end of a long series of 'AA' bytes, as shown below:

Did the HTER command actually take input in hexadecimal? That would explain why it crashed with numbers and 'A's, but not with the 253-character string.

Send 210 groups of ten digits to GTER.

Now the crash is at EIP = 35343332, and ESP points to a region of digits we injected, as shown below:

So it looks like this crash is a normal buffer overflow if we use digits, but it does something strange with letters.

Examining the LTER Crash in Immunity

Launch "Vulnerable Server" in the Immunity debugger.

Then send 8 groups of 253 characters to LTER.

I did it three times, and got identical results: "Access violation when executing [7271706F]", showing the typical control of EIP, as shown below:

Following ESP in the dump and scrolling the lower left pane up a few rows shows that ESP is pointing to a location near the end of a block of characters we injected, as shown in the image above.

So this looks like a normal buffer overflow, as long as we use the 253-byte string to inject.

Examining the GMON Crash in Immunity

Launch "Vulnerable Server" in the Immunity debugger.

Then send 16 groups of 253 characters to GMON.

Immunity says "Access violation when executing [018B0000]", and EIP is 76428DD2. The stack points to a point about 24 bytes before the input command, as shown in the dump in the lower left pane:

We didn't inject characters into EIP, but we did inject them into EDX--it's now 2A292827. This caused the instruction shown at the top of the left pane to fail, because it's using EDX

MOV DWORD PTR DS:[EDI],EDX

Can we exploit this? Perhaps, if we can use the SEH. Do we control it?

In Immunity, click View, "SEH Chain".

The SEH chain contains characters we injected: EFEEEDEC, as shown below:

This overflow changes EDX and the SEH, and may be exploitable.

Results

Here are 6 crashes I found, with notes.
KSTET : Send 75*'A', control EIP

GTER : 155*'A', control EIP

HTER : 210*'1234567890', control EIP (strange results with 'A')

LTER : 8*253 controls EIP, inconsistent results with ten-digit string

TRUN : 8*253 (analyzed in a previous project, EIP control)

GMON : 16*253 corrupts SEH chain

Sources

Introducing Vulnserver


Posted 6-28-14 1:07 pm by Sam Bowne
Revised 7:58 am 7-1-14