Buffer overflows
These instructions are a combination of my notes from the PWK course material and notes taken while executing Tib3rius's "Buffer Overflow Prep" room on THM. There are multiple techniques for executing buffer overflows, but all follow the same basic outline. Find what works for you.
General information
Almost all buffer overflow exploits follow a common general flow.
Create a large buffer to trigger the memory overflow
Control EIP by overwriting a return address on the stack by padding a large buffer with an appropriate offset
Include a chosen payload in the buffer prepended by a NOP sled
Choose a correct return address instruction such as JMP ESP in order to redirect the execution flow into the chosen payload
Important memory locations
EAX, EBX, EDX, ESI and EDI are often used as general purpose registers for temporary data storage
EAX (accumulator) - arithmetic and logical functions
EBX (base) - base pointer for memory addresses
ECX (counter) - loop, shift, and rotation counter
EDX (data) - I/O port addressing, multiplication and division
ESI (source index) - pointer addressing of data and source in string copy operations
EDI (destination index) - pointer addressing of data and destination in string copy operations
ESP is the stack pointer and keeps track of the most recently referenced location by storing a pointer
EBP is the base pointer and stores a pointer on top of the stack when a function is called
EIP is the instruction pointer and always points to the next code instruction to be executed
EIP is the primary target during a buffer overflow because it control program flow!
Setup
Immunity Debugger:
Start the application first, then open Immunity Debugger and use File --> Attach to view the applicable process -OR-
Open Immunity Debugger and use File-> Open to start the application
Select the "red arrow" to run the application
Basic commands
F2 - set breakpoint
F7 - Step into a function
F8 - Step over a function
F9 - Run
Mona.py
Set up your working folder with the following command:
Mona is available at: https://github.com/corelan/mona
Fuzzing
The following script will fuzz a program by sending a string of characters that increases by 100 bytes with each iteration. To use, update the IP address, port, and string (line 20) to match the program you are testing.
Replicate the crash
Build a script to replicate the error caused by the fuzzing script.
Locate EIP
Generate a string of characters 400 bytes longer than the length that caused the program to crash while fuzzing.
Insert the generated pattern into the "payload" variable of your script
Restart Immunity Debugger and the program you are testing
Run the exploit script
Note the characters that overwrite EIP
Use pattern_offset.rb to locate the position of the characters in the string
Add the value from pattern offset to the "offset" variable in the script
Set the script's "retn" variable to "BBBB"
Restart Immunity Debugger and the program you are testing
Run the exploit script
EIP should be cleanly overwritten with Bs (42424242)
Check for bad characters
Insert the bad character buffer into the scripts "payload" variable
Restart Immunity Debugger and the program you are testing
Run the exploit script
After the program crashes, right click on "ESP" and "Follow Dump"
Remove characters that cause errors in memory (non-sequential)
Repeat steps 2-5 until there are no errors remaining in ESP
\x00 was already removed from this buffer.
Redirect execution
Next, we want to find a reliable location in memory that contains an JMP ESP (or similar) instruction. This will enable us to redirect the program to our payload at the time of the crash.
Use the mona jmp command to search for jmp (or equivalent). By default, jmp ignores modules with DEP or ASLR.
Select from the list of options and note the memory location
Reverse the location (little endian) and insert the value in the script's "retn" variable (625011af become /xaf/x11/x50/x62)
Generate payload
Next, we generate our reverse shell payload and add it to the exploit. We'll also pad the beginning our the payload with a minimum of 16 NOPs (x90) to provide space in memory for decoding the payload.
Generate shellcode with Metasploit
Pad with NOPs
Add the following to the script's "padding" variable.
Launch exploit
Setup a netcat listener on the attacking machine using the same port identified during the generation of the payload
Launch the exploit
Last updated