🏢Active DirectoryGroupsPasswordPermissions

Esposizione password GMSA Active Directory: quando la rotazione automatica non è un confine di sicurezza

Le password gMSA ruotano automaticamente perché nessun essere umano debba mai conoscerle — ma l'attributo msDS-GroupMSAMembership che regola chi può leggere quella password viene spesso lasciato troppo permissivo, offrendo agli attaccanti un percorso diretto di impersonazione.

Younes AZABARDi Younes AZABAR10 min di lettura
Esposizione password GMSA Active Directory: quando la rotazione automatica non è un confine di sicurezza

Esposizione password GMSA Active Directory

Esposizione password GMSA Active Directory: questi risultati sono tra le lacune più gravi che EtcSec osserva nell'igiene degli account di servizio, perché l'account esposto è spesso quello che tutti davano per sicuro per progettazione. Un account di servizio gestito di gruppo (gMSA, Group Managed Service Account) è la soluzione Microsoft a uno dei problemi più vecchi di Active Directory: password di account di servizio statiche, note agli esseri umani, che restano invariate per anni in script, attività pianificate e file di configurazione. Il controller di dominio genera una password casuale di 256 byte e la ruota automaticamente — ogni 30 giorni per impostazione predefinita — così nessun amministratore deve mai digitarla o memorizzarla da qualche parte (Microsoft Learn — Manage Group Managed Service Accounts). Questa è la promessa, e nei suoi stessi termini regge.

Ciò che continua a causare questa esposizione non è una password trapelata — è un elenco di principal autorizzati a leggerla troppo ampio. «Nessuno ha la password» vale solo finché l'elenco di chi può recuperarla resta ristretto, e quell'elenco è controllato da un unico attributo che viene lasciato troppo permissivo molto più spesso di quanto i difensori si aspettino.

A cosa serve un gMSA

I servizi che vengono eseguiti in modo identico su una farm bilanciata — pool di applicazioni IIS, attività pianificate, servizi Windows — hanno bisogno di un unico principal che si comporti allo stesso modo su ogni host perché l'autenticazione reciproca Kerberos funzioni. Un gMSA fornisce questo senza una password condivisa sincronizzata manualmente: qualsiasi host con diritti di recupero preleva la password corrente direttamente da AD via LDAP ogni volta che il servizio ne ha bisogno (Microsoft Learn).

Perché l'elenco dei diritti di lettura crea comunque esposizione

Nella pratica la lacuna si manifesta in due modi: un gruppo di sicurezza creato per il gMSA viene riutilizzato per qualcosa di non correlato e accumula silenziosamente nuovi membri nel tempo, oppure il gruppo viene annidato all'interno di un gruppo amministrativo più ampio già esistente durante la configurazione, perché era il modo più rapido per far funzionare il servizio. In entrambi i casi l'elenco dei lettori resta più ampio degli uno o due host che ne hanno realmente bisogno — e, a differenza di una normale verifica sui gruppi privilegiati, questa ACL non viene rivista con la stessa cadenza dell'appartenenza ai gruppi.

Come funziona: PrincipalsAllowedToRetrieveManagedPassword

L'attributo msDS-GroupMSAMembership

Quando si crea un gMSA, si specifica quali account computer o gruppi di sicurezza possono recuperarne la password:

New-ADServiceAccount -Name svc-app01 -DNSHostName svc-app01.corp.local `
  -PrincipalsAllowedToRetrieveManagedPassword "SG-App01-Hosts"

Quel parametro scrive in msDS-GroupMSAMembership, un attributo che contiene un descrittore di sicurezza in formato String(NT-Sec-Desc) — una ACL codificata in base64 che non può essere letta direttamente. PrincipalsAllowedToRetrieveManagedPassword è il wrapper PowerShell semplificato che AD espone per leggerlo e scriverlo (Microsoft Learn — Set-ADServiceAccount); i meccanismi grezzi dell'attributo sono documentati in dettaglio da DSInternals e dal riferimento gMSA di InternalAllTheThings.

Chiunque sia elencato lì può interrogare l'attributo msDS-ManagedPassword, che AD calcola in lettura e restituisce come un MSDS-MANAGEDPASSWORD_BLOB contenente la password corrente in chiaro. Un punto cruciale: non si tratta di una verifica su gruppo privilegiato — i Domain Admins non ottengono alcun accesso implicito. Solo i principal esplicitamente indicati in msDS-GroupMSAMembership possono leggere la password, chiunque essi siano (DSInternals).

ℹ️

ℹ️ Nota: è esattamente per questo motivo che il problema sfugge alle revisioni — gli amministratori presumono che l'accesso al gMSA segua la normale logica dei gruppi privilegiati, mentre in realtà è regolato da una ACL completamente separata che nessuno controlla secondo un proprio calendario.

Come l'elenco diventa troppo ampio

Non esiste alcun avviso integrato quando PrincipalsAllowedToRetrieveManagedPassword cresce oltre il suo perimetro originario. Un gruppo aggiunto «temporaneamente» durante una migrazione, un'appartenenza annidata ereditata dalla delega di una OU superiore, o un gruppo amministrativo annidato aggiunto perché conteneva già gli account computer giusti — ognuno di questi casi amplia silenziosamente chi può impersonare l'account di servizio, senza alcuna modifica corrispondente sull'oggetto gMSA stesso che attiri l'attenzione durante una revisione di routine. È la stessa classe di problema trattata in Abuso di ACL e DCSync: un permesso che nessuno ricorda di aver concesso, ancora valido, ancora sfruttabile.

La catena di attacco: da un gruppo troppo ampio all'impersonazione completa

Un caso reale: il gMSA Citrix nei Domain Admins

L'analisi di Sean Metcalf su ADSecurity.org documenta un caso concreto di questo schema: un gMSA Citrix, esso stesso membro di Domain Admins, aveva i propri diritti di recupero della password delegati a un gruppo chiamato «Citrix04» — che, una volta verificato, conteneva un normale account utente. Compromettere quell'unico account utente è bastato per recuperare la password di un gMSA equivalente a un Domain Admin (ADSecurity.org — GMSA Security Tip #14).

Leggere la password una volta nell'elenco

Una volta che un principal è nell'elenco dei lettori autorizzati, estrarre la password non richiede alcun exploit — solo una lettura:

# Usando i moduli AD + DSInternals
$gmsa = Get-ADServiceAccount -Identity "svc-app01" -Properties 'msDS-ManagedPassword'
$blob = ConvertFrom-ADManagedPasswordBlob $gmsa.'msDS-ManagedPassword'
ConvertTo-NTHash -Password $blob.SecureCurrentPassword

Get-ADServiceAccount restituisce il blob, ConvertFrom-ADManagedPasswordBlob (DSInternals) lo decodifica nelle password attuale e precedente in chiaro, e ConvertTo-NTHash deriva l'hash NT per un uso offline (DSInternals). Strumenti come GMSAPasswordReader.exe e gMSADumper.py automatizzano la stessa lettura LDAP da remoto, senza mai toccare l'host di destinazione.

Questa relazione è esattamente ciò che l'edge ReadGMSAPassword di BloodHound mappa: qualsiasi utente, gruppo o computer con diritti di recupero su un gMSA. SpecterOps documenta tre percorsi di abuso una volta ottenuto quell'edge — rubare o iniettare il token del gMSA se è già connesso su un host autorizzato, pianificare un'attività o un servizio da eseguire come il gMSA su un host autorizzato, oppure recuperare la password da remoto e usare l'hash NT risultante per un overpass-the-hash (BloodHound — ReadGMSAPassword). Nessuno di questi percorsi richiede che la rotazione automatica del gMSA fallisca — la rotazione significa solo che l'attaccante rilegge la password dopo ogni ciclo, esattamente come farebbe un host autorizzato.

Rilevamento

Event ID di Windows da correlare

IndicatoreEvent IDOrigineDescrizione
Accesso al servizio di directory sull'oggetto gMSA4662Log di sicurezza del controller di dominioRegistrato solo se sull'oggetto gMSA è configurata una SACL; mostra il GUID della proprietà msDS-ManagedPassword a cui si è avuto accesso e da chi
Recupero riuscito della password gestita2946Log eventi Directory-Services del DC«Un chiamante ha recuperato con successo la password di un account di servizio gestito di gruppo»
Recupero non riuscito della password gestita2947Log eventi Directory-Services del DCControparte di fallimento del 2946 — un principal non autorizzato ha tentato una lettura
Accesso correlato4624 (Logon_Type 3)Log di sicurezza del controller di dominioAccesso di rete intorno all'orario di un evento 4662/2946; collega la lettura a un account e a un host di origine

Questi Event ID e l'approccio di correlazione (far corrispondere 4662, 2946 e 4624 sul Logon ID in una finestra breve) sono documentati nell'analisi di TrustedSec sulla caccia agli abusi gMSA (TrustedSec — Splunk SPL Queries for Detecting GMSA Attacks). Senza una SACL sull'oggetto gMSA, l'evento 4662 non si attiva mai — l'audit deve essere attivato deliberatamente, oggetto per oggetto, una lacuna che si sovrappone alle più ampie lacune di configurazione dei criteri di controllo di Active Directory.

⚠️

⚠️ Avviso: gli eventi 2946/2947 confermano che una password è stata recuperata, ma non dicono se il lettore fosse atteso. Bisogna sempre confrontare l'account o l'host che ha generato l'evento con l'elenco PrincipalsAllowedToRetrieveManagedPassword proprio del gMSA.

Controllare direttamente l'elenco dei lettori

Il rilevamento basato sui log intercetta una lettura solo dopo che è avvenuta. Effettuate un controllo diretto e a livello di dominio dell'elenco di autorizzazione, invece di attendere un evento:

Get-ADServiceAccount -Filter * -Properties PrincipalsAllowedToRetrieveManagedPassword |
  Select-Object Name, PrincipalsAllowedToRetrieveManagedPassword

Eseguite questo comando su ogni gMSA del dominio ed espandete ogni gruppo restituito — un semplice nome di gruppo di sicurezza può nascondere un account utente obsoleto, un gruppo basato su una OU troppo ampio, o un gruppo privilegiato annidato che non avrebbe mai dovuto avere diritti di recupero.

Correzione

💡

💡 Vittoria rapida: eseguite oggi stesso l'audit Get-ADServiceAccount -Filter * sopra riportato. Richiede una sola riga e mostra immediatamente ogni gMSA il cui elenco di lettori merita un secondo sguardo.

  1. Censite ogni gMSA e i suoi lettori usando la query sopra riportata. Espandete l'appartenenza ai gruppi, non solo il nome del principal di primo livello — è lì che si nasconde una sorpresa in stile Citrix04.
  2. Restringete PrincipalsAllowedToRetrieveManagedPassword agli host esatti che ne hanno bisogno. Usate Set-ADServiceAccount -Identity <NomeGMSA> -PrincipalsAllowedToRetrieveManagedPassword <gruppo-ristretto> per sostituire un gruppo troppo ampio con uno limitato agli account computer che eseguono davvero il servizio (Microsoft Learn — Set-ADServiceAccount).
  3. Verificate che nulla si rompa prima e dopo la modifica con Test-ADServiceAccount -Identity <NomeGMSA> su ogni host che deve mantenere l'accesso (Microsoft Learn — Manage Group Managed Service Accounts).
  4. Non annidate mai un gruppo lettore di gMSA dentro un gruppo amministrativo più ampio per risparmiare un passaggio durante la configurazione — è esattamente questo tipo di annidamento a far sì che un singolo gruppo finisca per controllare il recupero della password di account che non avrebbe mai dovuto toccare. Vedi Annidamento pericoloso dei gruppi per capire come l'appartenenza transitiva crei percorsi che i difensori non si aspettano.
  5. Se il gMSA stesso si trova in un gruppo privilegiato (Domain Admins o equivalente), trattatelo come un risultato distinto e cumulativo: diritti di lettura della password troppo ampi su un membro di un gruppo privilegiato rappresentano un percorso più rapido verso Domain Admin rispetto a ciascuno dei due problemi preso singolarmente. Questo è distinto dalla normale igiene di appartenenza ai gruppi privilegiati, trattata in Account privilegiati di Active Directory: Protected Users, delega e lacune degli account di servizio.
  6. Attivate l'audit di accesso al servizio di directory (SACL) sugli oggetti gMSA in modo che gli eventi 4662 vengano effettivamente generati per gli account che contano di più, invece di scoprire la lacuna solo durante un incidente.

Come EtcSec rileva questo problema

Il controllo GMSA_PASSWORD_READERS di EtcSec segnala gli oggetti gMSA il cui PrincipalsAllowedToRetrieveManagedPassword include un principal più ampio del perimetro di host previsto — account utente, gruppi di sicurezza generici, o appartenenze annidate che non dovrebbero poter recuperare la password. È abbinato a GMSA_OLD_PASSWORD, che segnala i gMSA la cui password gestita non ha ruotato secondo la pianificazione, e a DANGEROUS_GROUP_NESTING, che rileva lo schema di appartenenza transitiva solitamente all'origine di questo eccesso di perimetro.

ℹ️

ℹ️ Nota: EtcSec verifica automaticamente questa vulnerabilità a ogni audit AD. Eseguite un audit gratuito per scoprire quali gMSA del vostro ambiente hanno un elenco di lettori più ampio del previsto.

Lettura correlata: Kerberoasting: rilevamento e prevenzione degli attacchi agli account di servizio copre l'attacco basato su SPN a cui i gMSA sono in gran parte immuni (nessun ticket craccabile, dato che la password è composta da 256 byte di dati casuali) — un contesto utile per capire perché l'adozione dei gMSA non elimina il rischio legato agli account di servizio, ma lo sposta semplicemente su questa ACL. BadSuccessor: escalation di privilegi tramite i dMSA copre un percorso di escalation distinto ma correlato, tramite gli account di servizio gestiti delegati.

Esplora le pagine di identity security collegate a questo tema