Montiors is a hard rated machine on HackTheBox created by TheCyberGeek. To get user we exploit an LFI vulnerability in a wordpress plugin to discover another vhost. The cacti application running there is vulnerable to SQLI which we can leverage to RCE and a reverse shell. Having a foothold we will find a service configuration exposing a shell script which contains the password of the user marcus.
To obtain root we will first exploit an insecure deserilization vulnerability in Apache OFBiz running on tomcat to get a shell on a docker container. There we discover the cap_sys_module capability is enabled which lets us load our own kernel module. Compromising ring 0 we get code excution on the host, which leads to another reverse shell as root on monitors. There were also two unintended paths which made the whole machine rather quick and easy. These were patched rather quickly after release, but we will still look into both of them.
User
Nmap
We start our enumeration of as usual with a nmap scan against all ports on our target and follow it up with a script and version detection scan against the discovered open ports to get a better picture of our target.
All ports
1 |
|
Script and version
1 |
|
Monitors.htb
Wordpress
Adding monitors.htb to our /etc/hosts we visit it in our browser of choice where we are greeted by a wordpress blog.
Knowing the running cms, we dig deeper into it using wpscan with the enumeration flag where we select all-plugins. We also choose plugins-detection mode of passive to look for linked plugins.
1 |
|
The scan discovers the wp-with-spitz plugin. Looking it up on google, we quickly find a LFI/RFI vulnerability in the plugin with a PoC on Exploit-DB. Testing the PoC in burp, we can identify that the vulnerability is indeed present on the box.
From here on there were two possible ways to user with one of them being patched by now. We will cover both, starting with the intended route.
LFI
Since wordpress often stores database credentials in cleartext in the wp-config.php file this is an interesting point for us to start. Going up a few directories we are able to retrieve it with a set off credentials.
Heading to the wordpress login we see that the password doesn’t fit to the username admin. Since there is more on the machine than just worpress the next step for us is to retrieve as many files from the target with the LFI as possible. For this we use a short python script with the LFI wordlists from the Seclists repo merged and cleaned.
lfi.py
1 |
|
We create the exfil directory in our current working directory, put the wordlist there aswell and run the fuzzer. After a while the script finishes, leaving us with a lot more information about the system we just have to sort through.
1 |
|
Looking at the \etc\apache2\sites-available\000-default.conf, which is the default apache file to define virtual hosts we can identify another v-host cacti-admin.monitors.htb.
000-default.conf
1 |
|
Cacti SQLI to RCE
We add it aswell to our /etc/hosts file and pay the page a visit. It turns out to be the login page of a cacti monitoring software installation.
With the earlier found password BestAdministrator@2020! we can log in as the admin user. As a first step we enumerate the version of the installation to be 1.2.12.
This version is vulneraby to CVE-2020-14295 and following the PoC we can leverage the SQLI to RCE in multiple steps. First we write the payload in the settings table with a first request.
Then we set up our ncat listener.
1 |
|
Finally we reindex the database with another http request and trigger our payload.
This results in a reverse shell as www-data, which we upgrade with python and fix the terminal size.
1 |
|
www-data => marcus
On the machine there is a custom service defined in /etc/systemd/system/cacti-backup.service, which reveals a script in the home directory of marcus.
1 |
|
Taking a look at the script we find a config password VerticalEdge2020.
1 |
|
Using this password we can now log into marcus account via ssh and grab the user flag.
1 |
|
Unintended User
Up to a half day after release there was also an unintended way to get to the user which let’s us bypass the cacti-admin.monitors.htb vhost.
Going back to our extracted files from the LFI fuzz there is also an \etc\crontab, which reveals the same backup service running.
1 |
|
From there it is pretty much the same steps we took before, shown here using burp.
First we get the service in the systemd directory.
After that you could grab the backup.sh in marcus’s home directory and ssh into the machine.
Root
The root part had also two possible ways for about half a day. We will again dig first into the intended method and then look into the unintended method afterwards.
Tomcat
Listing all open ports we can see that localhost is listening on port 8443.
1 |
|
To take a close look at it we forward it to our local machine. To enter the the ssh console in the connection we press ~C as the first input and forward the port to 8443 on our machine.
1 |
|
Looking at the forwarded port we see a tomcat application running with version 9.0.31.
Since there is not much we see yet, we use ffuf to enumerate additional directories.
1 |
|
Going over to /content there is a login page of an OFBiz installation which also leaks the version running.
insecure deserializtion
The installation is vulnerable to CVE-2020-9496. The exploit abuses insecure java deserialization in a XML-RPC request.
We will use the msf module linux/http/apache_ofbiz_deserialization to exploit this.
The exploit sends a XML-RPC POST request with a ysoresial generated ROME payload to the /webtools/control/xmlrpc endpoint, where it get’s deserialized resulting in RCE.
1 |
|
Selecting the module we set ForceExploit true to bypass the checks, set the srvport to a free, bindable port on our machine, set RHOSTS to 127.0.0.1 and set RPORT to the port we forwarded to. We then set LHOST to our vpn ip and LPORT to the port we want to listen on to catch the shell. We also set DisablePayloadHandler to true to catch it ourselves and set PAYLOAD to linux/x64/shell_reverse_tcp.
Confirming all options are correct and our netcat listener is up, we run the exploit.
1 |
|
1 |
|
After catching the reverse shell we upgrade it like we did before and fix the size again.
1 |
|
Kernel module from docker
Being in a docker environment we list the capabilites as part of our enumeration
1 |
|
As it turns out we have the cap_sys_module capability which means we can load a module into the kernel, thus giving us arbitray code excution in ring 0.
Following this blogpost we can create our own kernel module to send us a reverse shell as root. Adapting the code to our ip and the makefile to our filename we upload both to the docker.
grem.c
1 |
|
Makefile
1 |
|
The necessary parts of the kernel to make our module have however been disabled. Lucky for us the needed .deb packes are in the root of the machine.
1 |
|
First we need to set the path for dpkg to install them.
1 |
|
Afterwards we install both packages with dpkg.
1 |
|
With all conditions met we can now finally make our kernel module.
1 |
|
This gives use the grem.ko module which we now can install. Before we do that we setup our listener.
1 |
|
And upon installing it we recieve a reverseshell as root on the host system.
1 |
|
1 |
|
Unintended root overlayfs
There was another way to get root on the machine but only in the vip+ network, which was quickly patched after the release. The machine wasn’t patched on this network against CVE-2021-3493.
Compiling the exploit locally and transfering it to the machine you got a quick root by simply running it.
1 |
|
1 |
|
1 |
|












