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:
Fuzzing
Don't forget to re-run the binary everytime before you run theexploit.py
script
Create the Fuzzing script:
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:
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
The Finding Bad Characters step in a buffer overflow exploit is critical for ensuring that the payload or shellcode you inject does not get corrupted during transmission or execution.
Certain characters, known as bad characters, can cause problems like truncation, improper parsing, or unintended behavior during the buffer overflow.
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: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
The Finding a Jump Point step in a buffer overflow exploit is crucial after identifying bad characters. Once you have confirmed that your payload can be safely injected into the buffer (without interference from bad characters), the next step is to redirect the program’s execution flow to your payload. This is done by finding a jump point, typically using ROP (Return Oriented Programming) techniques or by overwriting the EIP (Extended Instruction Pointer) with a memory address that points to code that can transfer execution to your shellcode.
⭐ 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:
Copy the generated C code strings and integrate them into your
exploit.py
scriptpayload
variable using the following notation:
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:
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)
In byte order (e.g. \x00\x01\x02) and including the null byte \x00, what were the badchars for OVERFLOW1?
oscp.exe - OVERFLOW2
Answer the questions below:
What is the EIP offset for OVERFLOW2?
1100 bytes (fuzzer)
In byte order (e.g. \x00\x01\x02) and including the null byte \x00, what were the badchars for OVERFLOW2?
oscp.exe - OVERFLOW3
Answer the questions below:
What is the EIP offset for OVERFLOW3?
1700 bytes (fuzzer)
In byte order (e.g. \x00\x01\x02) and including the null byte \x00, what were the badchars for OVERFLOW3?
oscp.exe - OVERFLOW4
Answer the questions below:
What is the EIP offset for OVERFLOW4?
2500 bytes (fuzzer)
In byte order (e.g. \x00\x01\x02) and including the null byte \x00, what were the badchars for OVERFLOW4?
oscp.exe - OVERFLOW5
Answer the questions below:
What is the EIP offset for OVERFLOW5?
800 bytes (fuzzer)
In byte order (e.g. \x00\x01\x02) and including the null byte \x00, what were the badchars for OVERFLOW5?
oscp.exe - OVERFLOW6
Answer the questions below:
What is the EIP offset for OVERFLOW6?
1500 bytes (fuzzer)
In byte order (e.g. \x00\x01\x02) and including the null byte \x00, what were the badchars for OVERFLOW6?
oscp.exe - OVERFLOW7
Answer the questions below:
What is the EIP offset for OVERFLOW7?
1800 bytes (fuzzer)
In byte order (e.g. \x00\x01\x02) and including the null byte \x00, what were the badchars for OVERFLOW7?
oscp.exe - OVERFLOW8
Answer the questions below:
What is the EIP offset for OVERFLOW8?
2200 bytes (fuzzer)
In byte order (e.g. \x00\x01\x02) and including the null byte \x00, what were the badchars for OVERFLOW8?
oscp.exe - OVERFLOW9
Answer the questions below:
What is the EIP offset for OVERFLOW9?
2000 bytes (fuzzer)
In byte order (e.g. \x00\x01\x02) and including the null byte \x00, what were the badchars for OVERFLOW9?
oscp.exe - OVERFLOW10
Answer the questions below:
What is the EIP offset for OVERFLOW10?
1000 bytes (fuzzer)
In byte order (e.g. \x00\x01\x02) and including the null byte \x00, what were the badchars for OVERFLOW10?
Last updated