Grafana is a data visualization and monitoring platform that listens on TCP port 3000 by default.
It stores users, dashboards, data sources and other internal information in a relational database. SQLite is used by default, although MySQL and PostgreSQL are also supported.
Sensitive data source settings, including passwords, tokens and private keys, are encrypted before being stored inside the secure_json_data column.
Data Source Secret Decryption
Workflow
Suppose that a File Disclosure vulnerability allows arbitrary files to be retrieved from a server running Grafana.
In a package-based installation, the most relevant files are usually:
The configuration files may disclose the secret_key used to protect data source secrets, while grafana.db may contain their encrypted values.
For a Prometheus data source using Basic Authentication, the username is normally stored in basic_auth_user and the encrypted password appears as basicAuthPassword inside secure_json_data.
The attack therefore consists of obtaining the effective secret_key, extracting the encrypted value from the database and decrypting it locally.
The value fromdefaults.iniis only the default. An active value ingrafana.inior theGF_SECURITY_SECRET_KEYenvironment variable takes precedence.
Theadmin_passwordsetting only defines the initial administrator password during the first Grafana startup. It does not necessarily contain the current password.
Requirements
Arbitrary file-read access to the Grafana configuration and database files
A Grafana installation using SQLite as its database backend
The effectivesecret_keyused by the same Grafana instance
An encrypted secret stored in thedata_source.secure_json_datacolumn
Grafana 9.0 and later use envelope encryption by default. In those versions, thesecret_keyalone may not be sufficient and legacy decryptors may fail.
Abuse
Extracting the Grafana Files
Use the discovered File Disclosure primitive to retrieve the following resources:
id name type url basic_auth basic_auth_user secure_json_data1 Prometheus prometheus http://localhost:9090 1 prometheus {"basicAuthPassword":"<ENCRYPTED_VALUE>"}
The script contains Grafana’s historical default key hardcoded in the grafanaIni_secretKey variable. Replace it with the value extracted from the target:
sed -i 's/SW2YcwTIb9zpOOhoPsMm/<SECRET_KEY>/' decrypt.py
Decrypting the Data Source Password
Run the decryptor and provide the extracted basicAuthPassword value:
python3 decrypt.py
Command Output
? Enter the datasource password: <ENCRYPTED_VALUE>[*] grafanaIni_secretKey= <SECRET_KEY>[*] DataSourcePassword= <ENCRYPTED_VALUE>[*] plainText= <PLAINTEXT_PASSWORD>
The recovered value is the password used by Grafana to authenticate against the Prometheus data source. It is not necessarily a Grafana user or administrator password.