Jake Hildreth Consulente capo per la sicurezza

Nella mia recente ricerca, ho dato un’occhiata distratta ai documenti di progettazione dell’Infrastruttura a Chiave Pubblica (PKI) di Microsoft e alle RFC correlate (in particolare la RFC 4556), nel tentativo di trovare un metodo affidabile per elevare i privilegi da un normale utente con privilegi limitati a qualsiasi account arbitrario, senza configurazioni errate. (Sì, è così che trascorro il mio tempo libero. Queste cose sono importanti per me e per le persone con cui lavoro quando elaboriamo piani di preparazione alle minacce informatiche.)

Purtroppo, nonostante abbia cercato in aree simili, non ho trovato traccia dell’attacco Certighost nella documentazione, sebbene si tratti di una vulnerabilità nota dei Servizi certificati di Active Directory (AD CS).

In realtà, non ho trovato alcun metodo per l'escalation dei privilegi.

Tuttavia, ho individuato un metodo di persistenza post-exploit basato su un errore di configurazione che, pur non essendo affascinante come Certighost, è quasi altrettanto inquietante.

  • Non richiede l'accesso alla chiave privata di un'autorità di certificazione (un prerequisito per un attacco di tipo "Golden Certificate" o " Golden Ticket ").
  • Ciò va contro le linee guida comunemente diffuse su come riottenere l'accesso agli account compromessi.
  • A differenza di Certighost, questa vulnerabilità non verrà corretta, poiché si basa su una configurazione documentata da Microsoft e pensata per i test e la risoluzione dei problemi.

Se sei responsabile della prevenzione e della gestione delle violazioni dei sistemi di gestione delle identità nel tuo ambiente, ti consigliamo di tenere d’occhio questa notizia.

Oggi vi presenterò gli “Zombie Certificates”, ovvero certificati di autenticazione che non si possono eliminare!

“Chi è?” Il processo di autenticazione PKINIT

In un tipico ambiente Active Directory (AD), la forma principale di credenziale di autenticazione è la ben nota combinazione di nome utente e password. Il nome utente rappresenta un’affermazione relativa alla propria identità; la password verifica tale affermazione.

Tuttavia, AD supporta anche l’uso di certificati a chiave pubblica come credenziali di autenticazione, spesso sotto forma di smart card. Questo processo di autenticazione basato su certificati è denominato “Crittografia a chiave pubblica per l’autenticazione iniziale” ( Public Key Cryptography for Initial Authentication), noto anche come PKINIT. L’implementazione di PKINIT da parte di Microsoft è descritta in modo esaustivo in MS-PKCA, ma in sintesi, invece di crittografare i ticket relativi all’autenticazione (AS-REP/AS-REQ) con la propria password, si utilizza una chiave privata, controllata dall’utente, per crittografare tali ticket.

Esaminando attentamente la sezione 6.3.3 della RFC 5280, ho trovato la definizione fornita dall’algoritmo di ciò che accade quando un verificatore non è in grado di determinare lo stato di revoca:

Dopo aver elaborato tali CRL, se lo stato di revoca non è ancora stato determinato, restituire lo stato del certificato (cert_status) come UNDETERMINED.

“Ti conosco?” PKINIT in Active Directory

Quando si tenta di autenticarsi in AD con un certificato tramite PKINIT, si interagisce con un controller di dominio (DC) che funge da centro di distribuzione delle chiavi Kerberos (KDC). Durante il processo PKINIT, il KDC verifica se il certificato in uso è attualmente valido ai fini dell'autenticazione.

Il KDC verifica diversi attributi del certificato prima di confermare l’identità del soggetto, tra cui (ma non solo):

  • Emittente: il KDC deve considerare attendibile l'Autorità di Certificazione (CA) che ha emesso il certificato. Se il KDC non considera attendibile l'emittente del certificato, non potrai accedere.
  • Uso previsto: i certificati contengono informazioni che spiegano come possono essere utilizzati (maggiori dettagli in seguito). Se provi ad autenticarti con un certificato destinato alla firma del codice, non riuscirai ad accedere.
  • Periodo di validità: se oggi provi ad autenticarti con un certificato che non sarà valido fino al 20X6, non potrai accedere. E se oggi provi ad autenticarti con un certificato scaduto nel 1666, non potrai accedere.
  • Stato di revoca: un emittente può revocare un certificato inserendolo in un elenco di certificati revocati (CRL). Se provi a utilizzare un certificato presente in un CRL, molto probabilmente — come avrai intuito — non riuscirai ad accedere.

Ma quest'ultimo punto è un po' complicato…

Cosa succede se la CRL non è disponibile? Dopotutto, le CRL vengono solitamente pubblicate come URL HTTP su server web, e i server web non garantiscono quasi mai un’operatività continua.

Come abbiamo già visto, le RFC sono chiare su questo punto. Quando una CRL non è disponibile, il KDC dovrebbe contrassegnare lo stato di revoca del certificato come UNDETERMINED. Ciò che non risulta altrettanto chiaro dalle RFC e dalla documentazione Microsoft è il significato di UNDETERMINED nel contesto del processo PKINIT.


Affrontare l'ignoto

Durante la creazione dei rilevamenti ESC16 per Fabbro e Fabbro 2 (strumenti della comunità open source disponibili su GitHub), ho scoperto il DisableExtensionList configurazione delle autorità di certificazione (CA) di AD Certificate Services (AD CS). Estensioni sono brevi note aggiunte a un certificato che spiegano a quale scopo serve il certificato e come può e deve essere utilizzato.

Su un server AD CS CA, il DisableExtensionList L'impostazione viene utilizzata per prevenire l'aggiunta di estensioni specifiche ai certificati emessi da un'autorità di certificazione (CA). In genere, questo elenco rimane vuoto, ma è possibile aggiungere estensioni all'elenco (e quindi rimuoverle dai certificati emessi) a scopo di test, per migliorare la compatibilità, per aumentare la sicurezza e così via.

Una delle estensioni che vengono solitamente aggiunte a un certificato è l'estensione CRL Distribution Point (CDP), nota anche come OID 2.5.29.31. L'estensione CDP indica a un KDC (o a qualsiasi altro soggetto incaricato della verifica) esattamente dove trovare lo stato di revoca di un certificato.

Domanda: Cosa succede se aggiungo l'estensione CDP al DisableExtensionList? Un'autorità di certificazione AD CS emetterebbe un certificato senza l'estensione CDP?

Risposta: A quanto pare… sì! Quando l’OID 2.5.29.31 esiste nel DisableExtensionList, ogni certificato emesso dall'autorità di certificazione (CA) non presenta l'estensione CDP, poiché Figura 1 spettacoli.

Figura 1: Un certificato tipico e un certificato privo dell'estensione CDP

E ora la domanda più importante: potrei utilizzare un certificato senza estensione CDP per eseguire correttamente PKINIT?

Purtroppo no.

Durante il processo PKINIT, il KDC tenta di verificare lo stato di revoca del certificato presentato. Senza l’estensione CDP, il KDC non sa dove verificare lo stato del certificato. Risponde con KDC_REVOCATION_UNKNOWN, e la richiesta di autenticazione viene respinta. Il certificato non è più valido… per ora.

Questa risposta di tipo “fail-closed” è quella predefinita per AD, ma tale comportamento non è immutabile.


Ignorare l'ignoto

Man mano che approfondivo la questione, mi sono reso conto che Microsoft aveva già preso in considerazione il problema dell'inaccessibilità delle CRL e aveva creato un valore di registro per gestirlo: UseCachedCRLOnlyAndIgnoreRevocationUnknownErrors. Come suggerisce il nome del valore, quando UseCachedCRLOnlyAndIgnoreRevocationUnknownErrors è impostato su 1, le CRL memorizzate nella cache vengono utilizzate per verificare lo stato di revoca (meglio di niente!) e gli errori relativi a revoche sconosciute vengono ignorati.

A quel punto mi sono chiesto: se questo valore del registro fosse impostato e riuscissi a provocare un errore sconosciuto, PKINIT andrebbe a buon fine?

Caro lettore, sono allo stesso tempo molto triste ed estremamente entusiasta di comunicarti che la risposta è un sonoro SÌ.

È sufficiente modificare un singolo valore del registro per far passare l'intero processo PKINIT dalla modalità "fail-closed" a quella "fail-open".

Figura 2: Sei un “Good Cert” o un “Bad Cert”?

Questo comportamento mi turba profondamente. Ma è anche del tutto logico. Secondo la documentazione fornita da vari produttori (tra cui Microsoft), questo valore del Registro di sistema può essere utilizzato per allentare i controlli di sicurezza in situazioni quali i test e la risoluzione dei problemi.

Non è destinato a un uso permanente. In effetti, indica al KDC di lasciare il cancello sbloccato per qualsiasi entità che non sia in grado di dimostrare di essere effettivamente inattiva.


Nascondere l'ignoto

Esiste un effetto collaterale interessante e inaspettato associato a un certificato privo dell'estensione CDP: può essere revocato e aggiunto alla CRL di un'autorità di certificazione (CA) come qualsiasi altro certificato, ma la sua inclusione nell'elenco è sostanzialmente priva di significato.

Immaginate il CRL come un cimitero e ogni voce di revoca come una lapide. Il certificato "zombie" ha una lapide con il proprio nome, ma il certificato non riporta alcuna indicazione su come raggiungere il cimitero, quindi nessuno va mai a controllare.

Sembra morto, ma non lo è. È un certificato zombie!

Ciò rappresenta un vero e proprio problema durante la gestione di un incidente. A volte, nel corso di tale gestione, è necessario reimpostare o revocare tutte le credenziali associate a un account compromesso, comprese le password e tutti i certificati di autenticazione.

Cosa succede quando non è effettivamente possibile revocare un certificato di autenticazione?


Adattare i componenti per garantire una persistenza invisibile

A questo punto della mia ricerca, avevo osservato alcuni comportamenti diversi:

  1. È possibile creare certificati di autenticazione senza un'estensione CDP.
  2. È impossibile verificare lo stato di revoca di un certificato privo dell'estensione CDP.
  3. Senza un'estensione CDP, un certificato può apparire come revocato alla CA e ai suoi amministratori, ma tale apparenza è priva di significato se non è possibile verificare lo stato di revoca.
  4. Se un verificatore non riesce a verificare lo stato di revoca di un certificato (per qualsiasi motivo), lo stato del certificato è “sconosciuto”, non “revocato” né “valido”.
  5. Per impostazione predefinita, l'implementazione di PKINIT da parte di Microsoft rifiuta i certificati con uno stato di revoca sconosciuto.
  6. Il comportamento predefinito "fail-closed" può essere modificato in "fail-open" modificando un singolo valore del Registro di sistema.

C'erano tutti i pezzi. Dovevo solo smettere di cercare di farli camminare.

Ho passato davvero troppo tempo a cercare di mettere insieme questi elementi comportamentali per formare una catena completa di escalation dei privilegi, ma alla fine ho rinunciato. Mi sembrava proprio impossibile. Senza accesso amministrativo all’host della CA o al servizio CA, è impossibile modificare DisableExtensionList. Modifica del UseCachedCRLOnlyAndIgnoreRevocationUnknownErrors La modifica di un valore del Registro di sistema sui DC richiede in genere l'appartenenza al gruppo BUILTIN\Administrators (BA) del dominio. Nessuna delle due operazioni è possibile senza autorizzazioni e privilegi preesistenti.

Ma cosa succederebbe se smettessi di concentrarmi sulle ESC (tecniche di escalation) e iniziassi invece a pensare alle PERSIST (tecniche di persistenza)?

Nel white paper del 2021 di SpecterOps intitolato “Certified Pre-Owned”, gli autori hanno elencato diverse opzioni per la persistenza a livello di dominio, utente e macchina basate su AD CS. La persistenza non è così accattivante come l’escalation e raramente viene messa in evidenza in un tipico test di penetrazione. Tuttavia, gli aggressori utilizzano la persistenza per riottenere l’accesso a un ambiente che hanno precedentemente compromesso.

È un aspetto importante da tenere in considerazione!


Il quadro d'insieme: come gli hacker creano i certificati zombie

Quando ho cambiato prospettiva, passando dal pensiero “Devo trovare un nuovo ESC!” a “Anche PERSIST fa paura!”, il quadro mi è apparso più chiaro e, francamente, mi ha spaventato un po’. Immaginate che un malintenzionato compia i seguenti passaggi:

  1. Ottengono un accesso altamente privilegiato al tuo ambiente AD: BA, amministratori di dominio (DA) o amministratori aziendali (EA). (Questo passaggio è volutamente molto approssimativo. Fattene una ragione!)
  2. L'autore dell'attacco verifica che nella foresta sia presente un'infrastruttura a chiave pubblica (PKI) di AD CS e che questa supporti PKINIT, controllando la presenza di una o più autorità di certificazione (CA) nella foresta NtAuthCertificates oggetto.
  3. Utilizzando RemoteRegistry o modificando direttamente il Registro di sistema, l'autore dell'attacco imposta il UseCachedCRLOnlyAndIgnoreRevocationUnknownErrors valore a 1 su uno o più DC.
  4. Aggiungono l'OID 2.5.29.31 a un CA DisableExtensionList, tramite certutil.exe oppure la modifica diretta del registro di sistema dell'host CA.
  5. L'autore dell'attacco richiede un certificato di autenticazione per un utente di cui ha il controllo, probabilmente l'account BA/DA/EA che sta utilizzando in quel momento.
  6. Confermano che lo “Zombie Certificate” funziona con PKINIT.

In un ambiente tipico, le fasi di ricognizione, modifica del registro, richiesta di certificati e convalida PKINIT di questo attacco possono essere automatizzate tramite script ed eseguite in pochi secondi, poiché molti di questi elementi sono ben noti o estremamente facili da individuare utilizzando i binari integrati e i file .NET non necessari presenti su ogni computer Windows moderno.

A meno che non si mettano in relazione eventi provenienti da diversi flussi in un unico insieme di indicatori, semplicemente non ci si accorgerà che questo attacco sta avvenendo.

Tuttavia, immaginiamo che i nostri valorosi difensori si accorgano dell’intrusione e adottino rapidamente le misure necessarie per contenerla. Essi:

  • Terminare tutte le sessioni di accesso attive dall'account compromesso
  • Reimpostare la password AD dell'account compromesso
  • Revocare i certificati di autenticazione dell'account compromesso
  • Fai qualcos’altro… Non faccio parte del team IR di Semperis, quindi mi affido alla loro esperienza…

Nonostante queste misure, l'autore dell'attacco può utilizzare il certificato "zombie" richiesto al punto 6 sopra riportato per eseguire PKINIT e riottenere l'accesso all'account che controllava in precedenza.

In che modo? Poiché lo stato di revoca del certificato è sconosciuto e l'autore dell'attacco ha modificato il processo PKINIT in modo che adotti un comportamento "fail-open" quando lo stato di revoca è sconosciuto.


E la cosa diventa ancora più inquietante: la rianimazione degli zombie

La risposta dell'IR che ho descritto sopra era volutamente incompleta: l'account compromesso avrebbe dovuto essere disattivato e sostituito completamente con un nuovo account. Tuttavia, nella confusione che caratterizza un incidente, alcune misure correttive possono sfuggire.

Il contenimento incompleto è una realtà!

Tuttavia, un hacker più lungimirante avrebbe potuto apportare alcune modifiche alla propria procedura per rendere il proprio accesso ancora più persistente. Anziché utilizzare un modello preesistente per richiedere un certificato di autenticazione per l'account che aveva compromesso, l'hacker avrebbe potuto:

  • Crea un nuovo modello che includa l'errore di configurazione ESC1
  • Utilizza il modello ESC1 per richiedere un certificato che includa il SAN di un altro account privilegiato

Ora, se l'utente inizialmente compromesso venisse disabilitato o eliminato, l'autore dell'attacco manterrebbe comunque il controllo dell'account con privilegi incluso nel SAN.

Questo zombie ha un secondo battito cardiaco. Se uccidi l’ospite, continua a camminare assumendo un’altra identità.

Nota a margine: esistono diversi altri metodi subdoli per rendere questo attacco ancora più furtivo, ma in coscienza non posso descriverli in dettaglio in questa sede.


Come individuare i certificati "zombie"

Come si fa a capire se si è in preda a un'infestazione di zombie? Si comincia dal cervello.

Il “cervello” di uno “Zombie Certificate” è il UseCachedCRLOnlyAndIgnoreRevocationUnknownErrors valore del Registro di sistema. Controlla ogni controller di dominio nella tua foresta e tutte le foreste di fiducia. Il percorso completo del registro è:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Kdc\UseCachedCRLOnly AndIgnoreRevocationUnknownErrors

Se un DC ha questo valore impostato su 1, consideralo un indicatore certo di manomissione fino a prova contraria. Procedi con le seguenti azioni:

  • Verificare la presenza di certificati di autenticazione rilasciati a utenti con privilegi, anche se risultano revocati.
  • Individua tutti i certificati di autenticazione che includono il SAN di un utente privilegiato, indipendentemente dallo stato (abilitato/disabilitato) del richiedente.
  • Controlla ogni CA DisableExtensionList eseguendo il seguente comando: certutil -config <CA-HOST-FQDN\CAName> -getreg policy\DisableExtensionList

Se viene visualizzato il seguente output, significa che è cambiato qualcosa che non avrebbe dovuto cambiare:

Figura 3: L'aggressore si trova all'interno della casa

Come uccidere lo zombie

Il valore del registro è il vero colpo decisivo. Un certificato "zombie" è pericoloso solo finché almeno un DC accetta uno stato di revoca sconosciuto. Elimina prima quella condizione.

  1. Su ogni DC interessato, eliminare UseCachedCRLOnlyAndIgnoreRevocationUnknownErrors e riavviare il Kerberos Key Distribution Center. In questo modo si ripristina immediatamente il comportamento "fail-closed". PKINIT rifiuterà qualsiasi certificato il cui stato di revoca non possa essere confermato.
  2. Rimuovi OID 2.5.29.31 dalla CA DisableExtensionList. I nuovi certificati includeranno nuovamente l'estensione CDP.
    Un punto fondamentale: I certificati già emessi senza estensione CDP sono definitivamente immuni alla revoca, indipendentemente da quanto riportato nella CRL dell’autorità di certificazione. La voce di revoca esiste, ma nessun verificatore potrà mai individuarla poiché il certificato non contiene alcun riferimento alla CRL. Questi certificati non presentano alcun rischio una volta risolto il problema del registro, ma devono essere individuati e sostituiti.
  3. Individuare tutti i certificati emessi nel periodo in cui DisableExtensionList contenevano l'OID CDP. Revocarli tutti. Una volta corretto il valore del registro, sono già praticamente inattivi, ma la revoca esplicita chiude il ciclo e crea una traccia di audit.
  4. Imporre la nuova registrazione per tutti gli account interessati, in particolare quelli con privilegi. Emettere nuovi certificati che includano un’estensione CDP valida.

Prevenire la prossima epidemia

Uccidere lo zombie attivo non basta. Devi fermare quello successivo.

  • Monitorare il registro di sistema di ogni controller di dominio considerato affidabile. Avviso in caso di modifiche a UseCachedCRLOnlyAndIgnoreRevocationUnknownErrors in tutti i centri di distribuzione. Qualsiasi valore diverso da absent o 0 dovrebbe dare luogo a un'indagine immediata.
  • Audit DisableExtensionList secondo un programma prestabilito. Dovrebbe essere vuoto su ogni CA della tua foresta. Puoi controllare direttamente il percorso del Registro di sistema oppure eseguire una query tramite certutil: certutil -config <CA-HOST-FQDN\CAName> -getreg policy\DisableExtensionList
    Consiglio da esperto: Il Piattaforma Semperis Lightning può monitorare il registro di sistema al posto tuo!
  • Utilizza Locksmith 2. Sia Locksmith che Locksmith 2 includono il rilevamento dell'errore di configurazione DisableExtensionList. Eseguili regolarmente nell'ambito dei controlli di integrità di AD CS.

Affinché si verifichi un’epidemia di “certificati zombie”, devono sussistere contemporaneamente due condizioni:

  • Un CA che emette certificati senza estensione CDP
  • Almeno un DC che entra in stato di "fail-open" a causa di uno stato di revoca sconosciuto

Se si elimina una delle due condizioni, l'attacco fallisce. Se si eliminano entrambe, si ottiene una PKI molto più sicura.


Aspettatevi che gli zombie tornino a risorgere… e tenetevi pronti

I "certificati zombie" non sono un caso limite puramente teorico. Si basano interamente su funzionalità Microsoft documentate e intenzionali.

Nessun CVE risolverà il problema. Non è prevista alcuna patch. L'attacco funziona perché gli amministratori devono occasionalmente allentare i controlli di revoca — e gli aggressori possono sfruttare proprio questa flessibilità.

La buona notizia è che i prerequisiti sono notevoli. Un aggressore ha bisogno di un accesso con privilegi elevati prima che tutto ciò sia possibile, il che significa che una corretta gestione dei privilegi è fondamentale. La cattiva notizia è che, una volta soddisfatti tali prerequisiti, l’attacco è rapido, automatizzabile tramite script e sfugge alla maggior parte delle procedure standard di risposta agli incidenti (IR).

Se nel proprio ambiente si utilizza AD CS, controllare il valore del Registro di sistema e il DisableExtensionList su ogni CA oggi. Se ne trovi uno dei due in modo inaspettato, c'è un problema che vale la pena approfondire. Se li trovi entrambi insieme, potresti già avere uno zombie che vaga nella tua foresta.

Se avete bisogno di assistenza per individuare i certificati "zombie", contattate Semperis. I nostri esperti di risposta agli incidenti si occupano di queste cose ogni giorno e sono a vostra disposizione per aiutarvi.

Esclusione di responsabilità

Questo contenuto è fornito solo a scopo educativo e informativo. Il suo scopo è quello di promuovere la consapevolezza e la correzione responsabile delle vulnerabilità di sicurezza che possono esistere sui sistemi di cui si è proprietari o che si è autorizzati a testare. È severamente vietato l'uso non autorizzato di queste informazioni per scopi malevoli, sfruttamento o accesso illegale. Semperis non approva né condona alcuna attività illegale e declina ogni responsabilità derivante dall'uso improprio del materiale. Inoltre, Semperis non garantisce l'accuratezza o la completezza dei contenuti e non si assume alcuna responsabilità per eventuali danni derivanti dal loro utilizzo.


Scopri di più su come prevenire ed eliminare la persistenza in Active Directory e Entra ID