
Exploit per CVE-2021-21239: bypass della convalida della firma SAML in pysaml2/Redash. Forgia risposte SAML con chiavi pubbliche incorporate per impersonare utenti ed escalare i privilegi tramite provisioning JIT.
Security Assertion Markup Language (SAML) è uno standard aperto per lo scambio di dati di autenticazione e autorizzazione tra parti in un sistema di identità federata. Consente il single sign-on (SSO) tra domini. I componenti chiave sono:
In un flusso SAML tipico, lo SP reindirizza l'utente all'IdP per l'autenticazione. L'IdP restituisce una risposta SAML firmata contenente asserzioni sull'utente (ad esempio, email, nome). Lo SP convalida la firma e provvede o effettua il login dell'utente.
CVE-2021-21239 è una vulnerabilità di bypass della convalida della firma nella libreria pysaml2 (versioni <6.5.0), utilizzata da Redash <=10.1.0 per il SSO SAML. A livello generale, consente a un attaccante di falsificare una risposta SAML con una chiave pubblica incorporata arbitraria, permettendo l'impersonificazione dell'utente e l'escalation dei privilegi tramite provisioning just-in-time (JIT).
La vulnerabilità deriva da come pysaml2 invoca xmlsec1 per verificare le firme SAML. Xmlsec1, per impostazione predefinita, preferisce le chiavi pubbliche incorporate nel <ds:KeyInfo> della risposta SAML rispetto al certificato IdP configurato. Un attaccante può creare una risposta SAML con una coppia di chiavi RSA auto-generata, incorporare la chiave pubblica in <ds:RSAKeyValue> e firmare l'asserzione con la chiave privata. Poiché pysaml2 non limita xmlsec1 a utilizzare solo il certificato IdP fidato, la firma falsificata viene considerata valida, consentendo all'attaccante di accedere come qualsiasi utente (ad esempio, amministratore) e ottenere i massimi privilegi.
A livello di codice, la vulnerabilità esiste in sigver.py di pysaml2 (funzione check_signature). La lista dei comandi xmlsec1 manca dell'opzione --enabled-key-data raw-x509-cert, permettendo a xmlsec1 di utilizzare chiavi incorporate non fidate:
com_list = [
self.xmlsec, '--verify', '--enabled-reference-uris', 'empty,same-doc',
'--pubkey-cert-pem', cert_file_name,
'--id-attr:%s' % id_attr, node_name,
'--node-id', nodeid, '--output', output_file_name, xml_file_name
]
Ciò consente attacchi in cui l'attaccante modifica l'email in <saml:NameID> per impersonare qualsiasi utente, sfruttando il provisioning JIT.
Per testare l'exploit, un'istanza locale di Redash (v10.1.0 o precedente) viene avviata utilizzando Docker Compose. La configurazione prevede la configurazione del SSO SAML con l'IdP di Google:
docker-compose up.REDASH_SAML_LOGIN_ENABLED=true, REDASH_SAML_METADATA_URL=... dall'IdP di Google).Questa configurazione consente di testare la risposta SAML falsificata inviata tramite uno script Python o Burp Suite, verificando l'escalation dei privilegi.
La vulnerabilità sorge perché l'invocazione di xmlsec1 da parte di pysaml2 consente l'uso di chiavi incorporate per la verifica, bypassando il certificato IdP fidato. Un attaccante genera una coppia di chiavi RSA, crea una risposta SAML con la chiave pubblica in <ds:RSAKeyValue>, modifica gli attributi (ad esempio, email verso quella dell'amministratore) e firma l'asserzione. Xmlsec1 verifica utilizzando la chiave incorporata, considerandola valida.
La correzione è stata implementata in pysaml2 v6.5.0 (commit iniziale il 17 gennaio 2021) in src/saml2/sigver.py. La lista dei comandi xmlsec1 è stata aggiornata per includere --enabled-key-data raw-x509-cert, limitando la verifica al certificato IdP configurato:
com_list = [
self.xmlsec, '--verify', '--enabled-reference-uris', 'empty,same-doc',
'--pubkey-cert-pem', cert_file_name,
'--enabled-key-data', 'raw-x509-cert',
'--id-attr:%s' % id_attr, node_name,
'--node-id', nodeid, '--output', output_file_name, xml_file_name
]
Ciò impone la convalida della catena di fiducia, impedendo l'uso di chiavi incorporate. Redash ha risolto il problema aggiornando pysaml2 nelle versioni successive (ad esempio, v11+). Le versioni vulnerabili non utilizzavano --insecure; il bug era l'opzione di restrizione mancante.
Il codice exploit è implementato in cve-2021-21239.py. Questo script Python automatizza il processo di falsificazione di una risposta SAML per sfruttare CVE-2021-21239 in Redash <=10.1.0, consentendo l'impersonificazione dell'utente e l'escalation dei privilegi tramite provisioning JIT. L'exploit prende di mira l'IdP SAML di Google Workspace, ma l'attacco è stato testato con altri IdP (keycloak). Lo script esegue i seguenti passaggi:
email="[email protected]").idpid dall'endpoint di login SAML di Redash se non fornito, garantendo la compatibilità con la configurazione del target.SAMLResponseTemplate.xml) con segnaposto per email, nomi, timestamp e ID asserzione. Vengono generati timestamp UTC dinamici con una finestra di validità di 5 minuti per superare la convalida di Redash.xmlsec per firmare l'elemento <saml:Assertion> con RSA-SHA256, incorporando la chiave pubblica in <ds:RSAKeyValue> per sfruttare la vulnerabilità./saml/callback?org_slug=default).Sfruttare CVE-2021-21239 ha richiesto la creazione di una risposta SAML falsificata che Redash accettasse tramite provisioning JIT. Difficoltà chiave e bypass:
<ds:RSAKeyValue>, firmando con la chiave privata.xmlsec1 funzionavano, ma la libreria Python xmlsec causava discrepanze di digest a causa di problemi di spaziatura/canonicalizzazione. Bypassato serializzando l'XML in una singola riga (etree.tostring(..., pretty_print=False)) prima della firma.NotOnOrAfter troppo futuro causava il rifiuto; bypassato utilizzando timestamp UTC dinamici con validità di 5 minuti.SAMLResponse, causando errori di parsing; bypassato inviando dati grezzi in formato form.Queste sfide evidenziano la necessità di una manipolazione XML precisa e di una corretta configurazione dell'ambiente per sfruttare efficacemente la vulnerabilità. Il codice exploit fornito lo dimostra con successo, falsificando una risposta SAML per impersonare utenti e ottenere accesso.