Charlie Clark

Mentre aiutavo Andrew Schwartz con il suo post su Kerberos FAST (che contiene ulteriori informazioni su cos'è e come funziona FAST, quindi dategli una lettura), ho notato qualcosa di interessante. Le AS-REQ per gli account macchina non sono blindate. L'armatura di Kerberos è descritta da Microsoft:

L'armatura di Kerberos utilizza un ticket-granting ticket (TGT) per il dispositivo per proteggere gli scambi di servizi di autenticazione con il KDC, quindi lo scambio di servizi di autenticazione del computer non è blindato. Il TGT dell'utente viene utilizzato per proteggere i suoi scambi di TGS con il KDC.

Mi sono chiesto se fosse possibile richiedere i ticket di servizio (ST) al servizio di autenticazione (AS). La possibilità di richiedere ST al SA ha diverse conseguenze, tra cui nuovi percorsi di attacco, aggiramento del rilevamento e potenziale indebolimento dei controlli di sicurezza. Tutti i problemi discussi in questo post sono stati segnalati a Microsoft e sono stati "considerati di progettazione"(Figura 1).

Lettura correlata

Riassunto di Kerberos

Innanzitutto, ecco una panoramica di alto livello del tipico flusso Kerberos(Figura 2, tratta da ADSecurity):

  1. Un account richiede un TGT al controller di dominio (DC).
  2. Il DC risponde con un TGT, che ha la sua chiave di sessione.
  3. Il TGT e la sua chiave di sessione vengono utilizzati per richiedere un ticket di servizio (ST) al DC.
  4. Il DC risponde con un ST, che ha la sua chiave di sessione.
  5. L'ST e la sua chiave di sessione vengono utilizzati per l'autenticazione nei confronti del servizio finale.
  6. Il servizio finale concede o vieta l'accesso.
Figura 2. Flusso tipico di Kerberos (AD Security), che illustra i passaggi dell'elenco precedente
Figura 2. Flusso tipico di Kerberos (ADSecurity)

Il fatto che per ogni ticket venga emessa una chiave di sessione è una caratteristica importante per la ricerca che segue. Questa chiave di sessione viene restituita all'account richiedente all'interno di una sezione crittografata della risposta; la chiave di crittografia è già nota al richiedente.

Ad esempio, la chiave di sessione TGT è memorizzata all'interno di una sezione crittografata con la chiave utilizzata per dimostrare l'identità del richiedente quando richiede un TGT. Questa chiave è normalmente la chiave a lungo termine (hash della password) dell'account. Tuttavia, nel caso della crittografia a chiave pubblica per l'autenticazione iniziale (PKINIT) nel protocollo Kerberos, la chiave è derivata dal certificato. La chiave di sessione ST è memorizzata all'interno di una sezione crittografata con la chiave di sessione TGT.

La chiave di sessione del ticket è necessaria per utilizzare il ticket nel passaggio successivo del flusso Kerberos.

Una richiesta Kerberos ha due sezioni principali:

  • padata (dati di pre-autenticazione)
  • req-body (corpo della richiesta)

Il corpo della richiesta viene inviato per lo più in chiaro e contiene diverse informazioni:

  • kdc-options: varie opzioni
  • cname: nome dell'account richiedente (facoltativo)
  • regno: nome di dominio
  • sname: nome del service principal (SPN) per il ticket risultante (opzionale)
  • da: ora a partire dalla quale il cliente vuole che il biglietto sia valido (opzionale)
  • till: tempo fino al quale il cliente vuole che il biglietto sia valido
  • rtime: il tempo di rinnovo richiesto (opzionale)
  • nonce: numero casuale
  • etype: elenco dei tipi di crittografia supportati dal client
  • indirizzi: elenco di indirizzi del client richiedente (opzionale)
  • enc-authorization-data: varie sezioni di dati di autorizzazione, crittografati con la chiave di sessione solitamente utilizzata per i privilegi locali (facoltativo)
  • additional-tickets: elenco dei biglietti necessari per la richiesta (facoltativo)

Una risposta Kerberos è composta da diverse sezioni e contiene una parte crittografata:

  • pvno: numero di versione
  • msg-type: tipo di messaggio (11 AS, 13 TGS)
  • padata: dati di pre-autenticazione (opzionale)
  • crealm: nome di dominio del cliente
  • cname: nome del conto richiedente
  • ticket: biglietto risultante
  • enc-part: dati crittografati per l'utilizzo da parte del client

Il problema dei ticket di servizio richiesti da AS

La parte del flusso Kerberos su cui si concentra questo post è AS-REQ/AS-REP, che di solito viene utilizzata per richiedere un TGT. Nelle operazioni normali, un AS-REQ ha uno dei due valori nel campo sname all'interno del req-body:

  • krbtgt/domain.local: utilizzato per richiedere un TGT iniziale
  • kadmin/changepw: usato per richiedere un ticket di breve durata, che può essere usato per reimpostare le password usando un messaggio KRB-PRIV (definito in RFC 3244)

Ho notato che con Kerberos Flexible Authentication Secure Tunneling (FAST) applicato, gli account macchina inviavano ancora i loro AS-REQ non blindati. Mi sono chiesto se un AS-REQ potesse essere usato per richiedere direttamente un ST, piuttosto che un TGT. Questo mi ha spinto a modificare Rubeus per determinare se specificando un altro SPN all'interno del nome di un AS-REQ il DC avrebbe risposto con un ST per quell'SPN. La risposta è stata affermativa(Figura 3).

Figura 3. Schermata di un AS richiesto da ST
Figura 3. Ticket di servizio richiesto al SA

Utilizzando un account macchina, posso richiedere un ST senza utilizzare l'armatura quando viene applicato il FAST. Cos'altro è possibile fare?

Nuovi modi per Kerberoast

Kerberoasting, scoperto da Tim Medin, è un metodo per recuperare la password in chiaro o l'hash NT di un account di servizio, generalmente un account utente con un SPN. Kerberoasting è possibile perché una parte di un ST è crittografata con la chiave a lungo termine dell'account di servizio (hash della password). Estraendo la parte crittografata del ticket, è possibile formare un hash da varie password in chiaro e tentare di decifrare la parte crittografata. Se la decrittazione ha successo, l'hash utilizzato è la chiave a lungo termine usata per criptare il biglietto. Questa chiave può essere utilizzata per autenticarsi come account del servizio.

Inoltre, qualsiasi account può richiedere un ST per qualsiasi servizio. Pertanto, per eseguire l'attacco è necessaria la capacità di autenticarsi ad Active Directory (AD). Almeno, questo era vero in passato.

Kerberoasting senza pre-autenticazione

Innanzitutto, ho provato a utilizzare un account che non richiedeva la pre-autenticazione(DONT_REQ_PREAUTH) per richiedere un ST. Quando un account non richiede la pre-autenticazione per autenticarsi, è possibile richiedere un TGT senza richiedere i dati di pre-autenticazione, che sono crittografati con una qualche forma di credenziale (ad esempio, hash della password, certificato). Se un attaccante non ha ottenuto una credenziale valida per un account, non è possibile generare una pre-autenticazione valida. Se la pre-autenticazione non è richiesta, questo non è un problema.

Quando un ticket viene richiesto senza pre-autenticazione, il risultato include comunque una parte crittografata. Questa parte crittografata è cifrata con la chiave di credenziale usata per l'autenticazione e contiene la chiave di sessione per il ticket incluso nella risposta. Si tratta dei dati crittografati utilizzati nell'attacco ASREPRoast di Will Schroeder. Il TGT risultante è utilizzabile solo con l'accesso alla chiave dell'account richiedente, poiché è necessaria la chiave di sessione del TGT.

Tuttavia, per Kerberoasting, l'accesso alla chiave di sessione non è necessario. È necessario solo l'ST risultante o, più precisamente, la parte crittografata dell'ST, che non è protetta dalla chiave dell'account richiedente. Pertanto, se un account è configurato in modo da non richiedere la pre-autenticazione, è possibile effettuare Kerberoast senza alcuna credenziale. Questo metodo di Kerberoasting è stato implementato in Rubeus in questa PR.

Dimostrazione

Poiché non è ancora stato ottenuto l'accesso a un account valido, non è possibile interrogare LDAP. È invece necessario un elenco di potenziali account di servizio. Una precedente ricerca di Arseniy Sharoglazov mostra che gli ST possono essere richiesti utilizzando solo il nome utente dell'account di servizio, invece di richiedere l'SPN effettivo, molto utile per questa ricerca.

Un elenco di nomi utente può essere generato in diversi modi, tra cui l'enumerazione degli utenti utilizzando sessioni nulle su un DC, la generazione di un elenco di nomi utente utilizzando informazioni open-source (OSINT) o indovinando i nomi utente potenziali. Qualsiasi elenco di nomi utente potenziali può essere facilmente verificato inviando un AS-REQ senza pre-autenticazione. Un nome utente valido che richiede la pre-autenticazione riceve un errore KDC_ERR_PREAUTH_REQUIRED(Figura 4).

Figura 4. Schermata che mostra un AS-REQ senza pre-autenticazione per un nome utente valido che richiede pre-autenticazione
Figura 4. L'utente richiede la pre-autorizzazione

Un nome utente valido che non richiede la pre-autenticazione riceve un TGT(Figura 5).

Figura 5. Schermata che mostra la risposta per un utente che non richiede la pre-autenticazione
Figura 5. L'utente non richiede la pre-autorizzazione

Un nome utente non valido riceve un errore KDC_ERR_C_PRINCIPAL_UNKNOWN (Figura 6).

Figura 6. Risposta per un nome utente non valido
Figura 6. L'utente non esiste

A scopo dimostrativo, è stato generato un elenco usando una sessione nulla sul DC, utilizzando il metodo di ciclaggio RID di enum4linux-ng(-R), come mostra la Figura 7.

Figura 7. Schermata che mostra l'elenco generato
Figura 7. Ciclo RID di enum4linux-ng

Utilizzando questo elenco di nomi utente, è facile determinare gli account che non richiedono la pre-autenticazione in AD (Figura 8).

Figura 8. Output di una scansione per gli account che non richiedono la pre-autenticazione
Figura 8. Scansione degli account che non richiedono la pre-autenticazione

Si noti che le AS-REQ senza pre-autenticazione non vengono registrate come evento Windows, a meno che l'account non richieda la pre-autenticazione.

Con l'elenco dei nomi utente e il nome utente di un account che non richiede la pre-autenticazione, è possibile lanciare l'attacco(Figura 9).

Figura 9. Schermata che mostra Kerberoasting senza pre-autenticazione
Figura 9. Kerberoasting senza pre-autorizzazione

Il risultato ottenuto può essere utilizzato per tentare di decifrare le password offline.

Prova di concetto: Arrosto nel mezzo

Un'altra conseguenza interessante è la possibilità di Kerberoast da una posizione Man-in-the-Middle (MitM). Questo tipo di attacco non è generalmente possibile con le TGS-REQ perché il campo cksum opzionale dell'autenticatore all'interno dell'AP-REQ protegge il req-body della richiesta ed è spesso incluso dai client Kerberos Windows autentici. Pertanto, la modifica del nome di un TGS-REQ senza aggiornare il checksum all'interno dell'autenticatore invalida il checksum dell'autenticatore e restituisce un errore KRB_AP_ERR_MODIFIED. Questo non è un problema per le AS-REQ, perché il corpo della req, e di conseguenza il campo sname, non sono protetti.

Testando questo approccio, ho scoperto che le AS-REQ possono essere riprodotte più volte. Un aggressore deve catturare un solo AS-REQ per inviare molti AS-REQ con valori di nome diversi.

Dimostrazione

Per dimostrare questo approccio, ho scritto un proof of concept (POC) approssimativo. Questo POC, RoastInTheMiddle, implementa uno spoof ARP tra i DC e i sistemi vittima per eseguire un attacco MitM. Il POC fa passare il traffico mentre ascolta le AS-REQ. Quando viene trovato un AS-REQ, il POC esegue un Kerberoast. Il POC non è pronto per l'attacco, ma dimostra che un attacco è possibile.

Per prima cosa, il POC avvia quattro thread, uno sniffer, un ARP spoofer, un ri-assemblatore (per le richieste suddivise in più pacchetti) e il roaster(Figura 10).

Figura 10. Schermata che mostra l'avvio del RoastInTheMiddle POC
Figura 10. Avvio di RoastInTheMiddle

Quando vede un AS-REQ, il POC inizia a cercare di effettuare il Kerberoast dell'elenco fornito, che può contenere nomi utente o SPN(Figura 11).

Figura 11. Schermata che mostra il POC Kerberoasting
Figura 11. Arrosto nel mezzo della torrefazione

Come mostra la Figura 11, questo tentativo fa sì che tutti gli ST ricevuti vengano emessi in formato hashcat, pronti per il cracking offline delle password.

La capacità di MitM AS-REQ, quindi di modificarli e riprodurli, potrebbe essere utile anche per sviluppare altri attacchi. Ho tentato di modificare le opzioni di kdc per includere l'opzione proxiable che risulta in un ticket con il flag proxiable impostato. Tuttavia, non sono riuscito a trovare un percorso di attacco che utilizzasse quel ticket e quel flag. Questo comportamento potrebbe anche consentire l'uso di altri account per eseguire un Kerberoast, permettendo agli aggressori di evitare di bruciare un account compromesso.

Miglioramenti

Sono possibili alcuni miglioramenti per questo processo. In primo luogo, è possibile forzare un AS-REQ da un TGS-REQ intercettandolo e rispondendo con un errore KRB_AP_ERR_BAD_INTEGRITY. In questo modo si costringe il client a riautenticarsi inviando un AS-REQ.

Dovrebbe essere possibile eseguire questo attacco anche utilizzando l'iniezione del server dei nomi DHCPv6 (come mitm6 di Dirk-jan Mollema o Inveigh di Kevin Robertson), rispondendo alle query DNS SRV per il servizio LDAP e quindi gestendo la successiva connessione LDAP.

Il supporto per la modifica degli etipi all'interno della richiesta consente attacchi di downgrade del tipo di crittografia quando l'ambiente lo consente, come descritto da Will Schroeder qui.

Infine, il POC richiede l'installazione di Npcap sul sistema che esegue il POC (che utilizza sharppcap), principalmente per lo spoofing ARP. Se si sceglie la strada dell'IPv6 o si implementano le risposte ARP utilizzando i socket raw, si può eliminare questa dipendenza.

Bypassare i rilevamenti

Molti rilevamenti Kerberos si basano su eventi 4769(È stato richiesto un ticket di servizio Kerberos). Tuttavia, la richiesta di un ticket di servizio tramite un AS-REQ non produce 4769 eventi, ma piuttosto 4768 eventi(È stato richiesto un ticket di autenticazione Kerberos (TGT)).

La Figura 12 mostra un evento 4768 quando viene richiesto un ST tramite un AS-REQ.

Figura 12. Immagine dell'evento 4768
Figura 12. Evento 4768 per un ticket di servizio

Pertanto, gli aggressori che utilizzano questo metodo possono facilmente eludere molti rilevamenti che si basano su 4769 eventi.

Altre conseguenze dei ticket di servizio richiesti da AS

Sebbene non sia riuscito a richiedere i biglietti S4U2self all'AS, gli ST recuperati dall'AS sono privi del Ticket Checksum (introdotto per proteggere i biglietti S4U2self dall'attacco bronze bit di Jake Karnes).

Infine, un ST richiesto al TGS viene generalmente restituito con un PAC(Figura 13).

Figura 13. Schermata della richiesta di ST (con PAC) da parte del TGS
Figura 13. Richiesta di un ST con un PAC al TGS

È possibile richiedere un ST senza PAC al TGS, ma per farlo è necessario modificare il bit NO_AUTH_DATA_REQUIRED dei conti di servizio nell'attributo useraccountcontrol(Figura 14).

Figura 14. Output che mostra l'attributo
Figura 14. attributo useraccountcontrol per DSC1 e pgreen

Quando è presente questa configurazione, l'ST restituito manca di un PAC, come dimostra la differenza di dimensioni del biglietto restituito(Figura 15).

Figura 15. Schermata di richiesta ST (senza PAC) da parte del TGS
Figura 15. Richiesta di un ST senza PAC al TGS

Un ST senza PAC può essere richiesto al SA semplicemente impostando la sezione dati PA-PAC-OPTIONS PA su false, aggiungendo lo switch /nopac a Rubeus(Figura 16).

Figura 16. Output che mostra la richiesta di ST (senza PAC) da parte del SA
Figura 16. Richiesta di un ST senza PAC da parte del SA

Questo approccio potrebbe essere utilizzato in alternativa alla creazione di biglietti d'argento, richiedendo un ST senza PAC, quindi iniettando un altro PAC includendolo nella sezione enc-authorization-data della richiesta. Potrebbe anche fornire altri potenziali percorsi di attacco.

Rilevamento dei ticket di servizio richiesti dagli AS

Poiché sembra che Microsoft non ritenga questi problemi degni di essere risolti, l'unica opzione è il rilevamento all'interno dell'organizzazione. Come mostrato in precedenza, quando viene richiesto un ST dal SA, viene registrato l'evento 4768(Figura 17).

Figura 17. Schermata dell'evento 4768
Figura 17. Evento 4768 per un ticket di servizio

In questo caso, si può notare che il Nome servizio e l'ID servizio non sono krbtgt. Tutti i ticket autentici richiesti dal SA, compresi i ticket kadmin/changepw, hanno un Nome servizio e un ID servizio di krbtgt(Figura 18).

Figura 18. Schermata che mostra il normale evento 4768
Figura 18. Evento normale 4768

Il controllo del traffico di rete per le AS-REQ che non sono per il krbtgt/dominio o kadmin/changepw dovrebbe rilevare anche queste richieste(Figura 19).

Figura 19. Schermata della richiesta AS-REQ ST in Wireshark
Figura 19. Richiesta AS-REQ ST in Wireshark

Questa ricerca, insieme alla risposta di Microsoft, dimostra la necessità di un monitoraggio continuo e di misure di hardening adeguate. La capacità di eludere i rilevamenti attuali e di eseguire attacchi efficaci, come Kerberoasting, da una posizione non autenticata è un problema serio che non deve essere ignorato. La ricerca qui descritta potrebbe portare a nuovi attacchi, mettendo potenzialmente a rischio le organizzazioni.

Assicuratevi che siano presenti dei rilevamenti quando vengono effettuati questi tipi di richieste di ticket.

Ringraziamenti

Vorrei ringraziare le seguenti persone per il loro contributo a questa ricerca:

Cronologia

  • 25 maggio 2022: Segnalato al MSRC
  • 27 maggio 2022: MSRC ha cambiato lo stato in Revisione/Ripro.
  • 13 luglio 2022: MSRC ha risposto che il comportamento è stato "progettato".
  • 27 settembre 2022: divulgazione al pubblico

Maggiori informazioni da Semperis Research