Craniocerebral injury; brainpan style

It would come to no surprise to most of you that I am addicted to boot2root challenges. Every day I learn something new, and every day I become more and more inspired and passionate about the infosec landscape.

Recently I took part in my first boot2root CTF, VulnHub’s Sokar challenge. Having completed the challenge (the write-up will be published once the competition is over), I find myself in a place of limbo. It is another week before the challenge ends and the results are announced, and there is also the second CrikeyCon conference coming up in a weeks time. It feels like Christmas to me and I cannot sleep due to all the excitement, so I need something to help pass the time. Sounds to me like a good excuse to fire up another boot2root challenge and continue wandering along this learning curve.

Introducing brainpan 1, by @superkojiman.

After attempting various hacking challenges, I was inspired to come up with my own. Brainpan is my attempt at a vulnerable virtual machine. Your goal is to break in and get root access.

With introductions over, let’s get to work!

Netdiscover:

Nmap:

We’ll start by checking out if anything responds on port 9999:

Entering ‘password’ gives us an “ACCESS DENIED” message and the program exits. No problems, we’ll come back to this.

Let’s take a look at what is listening on port 10000.

A web server of some form. Let’s take a closer look in a browser.

safe_coding_10000

Nothing overly exciting there. If you have read any of my previous writeups you’ll know what time it is. WFuzz! Come on down!

We don’t need to be prompted here… let’s take a look at what is in the bin directory.

brainpan-exe

A windows executable; that’s something different. It’s time for a game of choose your own adventure!! Do we take a further look at what’s behind door number 9999, or door number 10000? And the winner is…. 10000. Ok, let’s download the brainpain.exe binary and take a look.

Firstly, is the file a true PE executable or does it have a hidden surprise?

Ok. A standard windows executable. Next, let’s give it a once over with the ever reliable strings tool.

Nice! A couple of things stand out here for me:

  • This brainpan.exe looks the same as our listening process on port 9999
  • Line 14: shitstorm – This looks like the password to me
  • Line 65: strcpy – Possible buffer overflow attack vector

Obviously, we should try the possible password shitstorm.

ACCESS GRANTED, and then a return. Hmm… How about we check out the strcpy function. Whilst there is Evan’s Debugger and Ollydbg (executed via wine) available for linux, I choose to use Immunity Debugger in a windows environment for ‘windozy’ type tasks. I also use Corelan Team’s Immunity Debugger pycommand mona.py addon. If you would like to support my learning and my site, feel free to buy me a copy of IDA Pro if you wish :)

Disclaimer: For those of you that already know how to perform a simple strcpy buffer overflow, you can quickly step over the next section as it will be quite lengthy and ‘user-friendly’ per se. I have chosen to include plenty of fuzzing code and details for each step so that anyone new to this type of attack vector can easily learn and hopefully understand the process.

Time to use my trusty quick fuzzer to see if we can get our input to cause a segfault. This is a bit of code I use often and amend with shellcode and registers as we progress. Simple, but effective.

Time to run brainpan.exe and attach to the process with Immunity Debugger. With the process listening on our windows machine, let’s throw our 1000 fuzzing A’s (\x41) at port 9999 and see if we get a segfault.

segfault

BAM! We caused the segfault we wanted, and as you can see we have successfully overwritten eip with our fuzzy A’s. Time to take control and have some fun.

Next step, how many bytes do we need to fill our buffer with in order to get us to eip? As in my previous writeups, I like to use Metasploit’s pattern tools for this activity. Let’s create a pattern to start with.

We’ll add this to our fuzzing script, replacing our junk of A’s with the pattern output.

Next. Restart the brainpan.exe process, re-attach to the process, and send the fuzzing script to the listener.

segfault2

Once again, we have overwritten eip successfully. Take note of the instruction pointer address 35724134, and we’ll push that into Metasploit’s pattern offset tool, which will give us the number of bytes we need to send to our buffer in order to control eip.

Great! We know we need exactly 524 bytes of ‘junk’ to get us to eip. Let’s edit our fuzzer accordingly and see if we can successfully overwrite eip with some B’s (\x42). Re-run, re-attach, and launch fuzzer.

segfault3

Voila! As you can see, we’ve successfully overwritten eip with our 4 bytes of B’s. So what’s next? Next, we want to see if we can put our own code into esp. If we can put code into esp, we will look for a function call named jmp esp, tell eip to point at esp, thus giving us the ability to execute our malicious code stored in esp. Let’s edit our fuzzer to include a stack of C’s (\x43) in esp and see if we have space for our potential shellcode.

segfault4

As you can see above, we have successfully filled esp with our large number of C’s, which lets us know we have some area available to put our shellcode. Let’s see if we can find the address of a jmp esp function. In Immunity Debugger, use ctrl-f and enter the search jmp esp. As you can see below the address of our first jmp esp is 311712F3.

jmp_esp_addr

Next step, let’s generate some shellcode to test that our proof-of-concept (PoC) actually works. As the box we are testing our PoC against is a windoZe machine, we’ll generate a simple windows reverse shell using msfvenom.

Next, let’s put it all together. Our payload is going to look like this: {junk} {jmp esp address} {nops + shellcode}

Start up the brainpan.exe process, create our netcat listener on port 443, and let’s test out our PoC code.

Good stuff…. we have a reverse TCP connection to our windows machine. Time to create a linux reverse shell.

Update the PoC script with the victim host’s IP address and updated shellcode, create a new netcat listener on port 443, and execute accordingly.

Success! We now have a low privileged shell on our victim machine. Let’s continue.

We’ll take a look in the home directory to see if there is anything interesting…. nope. The only thing noticeable is that there is a script which restarts the web service should it die, as well as the root of the web service running on port 10000.

Do we have any special permissions we can use with sudo?

anansi_util with NOPASSWD? Interesting. Let’s take a closer look.

The - manual [command] part stands out immediatley. Let’s see if we can run a [command] with root privileges.

W00T!!!!! We are root! The binary allow us to query a manpage as root, and as such we can use man’s built in ability to run commands inline, such as !/bin/sh in the above output.

brain cells

Let’s grab the flag!

Thanks @superkojiman for an enjoyable boot2root. I’ll definitely have a go at Brainpan 2.

VulnHub, as always, thank you for providing such an awesome resource for us all. Good Karma coming your way.

Until next time, tight lines and may you pop shells often.