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 |
|