Windows 32-Bit Buffer Overflow
SLMail Example
Practice these:
- SLMail - download from exploit-db
- Brainpan - download from vulnhub
Step By Step Scripts
All the scripts are available here as well as at the bottom.
connect.py
Making sure connection and all the operations are successfully performed is crucial as everything will be built on this script/step.
fuzzer.py
Once you’re successfully able to connect to the service, can perform authentication, and quit gracefully, it’s time to fuzz.
getoffset.py
Once the application is fuzzed at X, lets say 2700, bytes, create a unique string of X+200 (or 300) bytes, let’s say 3000 bytes, using msf-pattern_create
like below:
Assign this unique string to the payload variable
Make a note of the address that the EIP was overwriten with, use msf-pattern_offset
to find the offset, like below:
This will provide you with the offset at which the EIP will be written at. If the offset is 2606, then that means from byte 2607 to byte 2610 will determine the EIP address, and the rest will go into ESP.
controleip.py
Next step is to ensure the offset we received is actually right. To do so, we’ll put 4 “B"s from byte 2607 till byte 2610.
If the application crashes with EIP with the address : 42424242
, which is hex for BBBB
, we’ll move on to the next step
badchar.py
Finding bad characters is an iterating process. You will be sending characters from 0x01 to 0xff, and upon countering a character that breaks or is escaped by the application, that character is removed from the character array and the process is repeated. Bad characters aren’t necessarily just the null byte (0x00), newline (\n - 0x0a), and carriage return (\r - 0x0d).
Take a good 20 minutes, sit down, and identify each and every bad character
To know what hex is which character - man ascii
or asciitables website
Finding JMP Pointer
Once all the bad characters are found, we’ll find the JMP ESP pointer from the Immunity Debugger itself using mona. Since I am using SLMail as my example, the bad characters that I will be avoiding are - 0x00 0x0a 0x0d
By executing the above command you will not only find the addresses, without protection mechanisms, that would perform JMP ESP but also ensure that none of the addresses has any of the bad characters in itself.
Please ensure you select an address from the applications’ DLL ONLY, and NOT from OS DLLs. Application DLLs will be constant across operating systems, but we can NOT say the same for OS DLLs.
jmpesp.py
Now that we have our EIP on our hand, let’s see if we actually reach there and that it does go where we want it to.
In the Immunity Debugger, “go to” the address you selected and toggle breakpoint on.
Once we hit the breakpoint, first test is complete. Now let the application continue execution till return to ensure it actually goes in to the ESP.
shelly.py
Now that we found the right address, and verified it. Let’s get a reverse shell. I will be using a stageless shellcode since I have more than enough space to do so.
The above command will generate a shellcode, but in python3 format, which I’m not using for now, so we will remove the “b"s in the front every line and then paste it in our exploit code. By not specifying an encoder, msfvenom will automatically choose one on it’s own, which is good.
EXAM GUIDE
Steps
- Find offset
- Ensure control over EIP at found offset (4 B’s)
- Find bad characters
- Find return address (JMP ESP)
- Ensure EIP overwrite (Breakpoint - F2 - at return address )
- Ensure buffer length for shellcode is good enough
- Get a shell
Commands
cheatsheet.py
Why stageless
- Less the number of exploitation steps, the better
- More control over the shell execution process
- The stager that gets dropped in the staged shell, could be blocked or unable to execute for plethora of reasons unknown to you
- It’s more of a Metasploit thing, which could be one of the reasons it may get blocked
Why staged
- Tried increasing the payload buffer but not enough space to fit a stageless shellcode
Scripts Repo
All the scripts are available here