OSCP Buffer Overflow Guide (Windows)
A walkthrough of the process to create a buffer overflow in windows in preperation for OSCP. This guide should be used with the walkthrough youtube video: https://www.youtube.com/watch?v=tUWCmpxWYdo
1. Play with the Program
First and foremost we should play with the application, see how it works. how many inputs it takes, is there a command we have to enter before we get to our overflow command, etc.
Make sure the program is running in immunity and connect to it with nc:
2. Crash Replication
This step is finding a reliable way of crashing the application. This will usually be sending a string of A's, this can be done manually or writing a small python program.
If we want to automatically fuzz with increments of 100 we can use the following:
Fuzz.py (default script will send increments of 100)
Once we know the number for a crash, we can now create our exploit and update the code with what we know.
Creating exploit.py
Make sure to add any prefix commands, remove or add s.send and s.recv to mimic what we sent through netcat to the application.
Create this python code and fill in all the blanks. edit the code with the correct IP and port and change the exploit code part to send and receive what the application is expecting to send and receive up until our buffer. Running our code we should get a reliable crash of the application every time we run it. only then should we move on.
Once we have a reliable crash we can move on to finding the offset.
3. Finding the Offset
To find the offset we send a unique string of characters to the program and look at the value of the EIP register, We can then use this value to find the offset.
First we generate a unique string:
Kali:
Web:
Once we have created the unique string. We send this to the program. At the point of crash we can then copy the value from EIP and calculate the offset.
in kali:
4. Controlling EIP
Now we have the offset we can change our python code to double check that we are controlling EIP. So we send the offset number of 'A's, we then send 4 'B's (these should appear in EIP) and lastly we send the remainder of our PoC crash (3000) as C's, as this is where our payload will go later on.
We can also try increasing the number of C's to give us more room for our payload. We need a minimum of 350 characters for a Remote Access Trojan
5. Finding Bad Characters
To find the bad characters we need to send a string from \x00 all the way to \xFF. \x00 is a null byte, and is usually always a bad character.
Python Program to generate bad chars:
Output:
To adjust our python program we can add the string to the badchars variable and uncomment it. we can then change the fuzz variable to the following:
We can now send this string to the program in place of the shell code. Once the program has crashed we can follow "ESP in dump" and view the hexdump. Going through each value we should be able to determine if there are any bad characters due to it missing or changing subsequent values.
We then keep a note of these bad characters, remove them from the string and run it again until all bad characters have been discovered.
6. Redirecting Execution
Once we have discovered all the bad characters the next step is to tell the program to execute our payload. Replacing our B's with the address of ESP will not work as these address values change every time the program crashes or is reset.
So we need to find a "JMP ESP" command hard coded within the program or .dll to use. Using this instruction will redirect EIP to our payload located in ESP.
To find jmp esp commands run the following:
This command searches for JMP commands pointing to ESP. The reason we list the bad characters is because we do not want these characters appearing in the address of the jmp command as it will corrupt our python code.
If the green text window with the script output does not appear click Window > log data to view the results We also want to make sure our address has ASLR set to false
7.Endianness
So how does this affect us?
If we have an address of 0x625011AF
if we convert it to Little Endian it will look like: \xAF\x11\x50\x62
And if we convert it to Big Endian it will look like: \x62\x50\x11\xAF
Once we have added the address into our return pointer in python we can then run the program and set a breakpoint (F2 in immunity) on our address(ctrl + g to search for the address in immunity). Running our exploit will stop the program on our address and we can then follow the steps (F7 in immunity) to make sure our return address stored in EIP directs us to our payload (which should be in ESP :)
8. Creating Payload
Once we are sure that our code is working and redirecting execution to our payload. we can then go ahead and create our payload to grant us a reverse shell. kali:
msfvenom: metasploit payload generator
-p: type of payload
LHOST: Local IP address
LPORT: local port
-a: architecture of target system
--platform: Operating system of target
-b: bad chars
-e: encoder (used to bypass antivirus)
-f: format of output (py = python output)
9. NOPS
So our final buffer should look something like:
buffer: Variable name
prefix: instruction for program
" ": space
fuzz: lots of A's (offset amount)
retrn: return address (jmp esp)
padding: NOPS to allow payload to decode
buf: shellcode for reverse shell
10.TROUBLESHOOTING
Check IP address - You may be pointing at your dev machine instead of the target you are trying to exploit
Make sure we are using the right payload in msfvenom for the target
Make sure to use correct port, sometimes firewalls will block port 4444 for example so we may want to use a common port such as 443
Is you Edianness correct?
Check Encoder (using one might be an issue) - x86/shikata_ga_nai
Verify Shellcode space. We need at least 351 bytes available to us for shellcode space after our jump to esp.
Last updated
Was this helpful?