Exposition mot de passe GMSA Active Directory
Exposition mot de passe GMSA Active Directory : ces découvertes comptent parmi les lacunes les plus lourdes de conséquences qu'EtcSec observe en matière d'hygiène des comptes de service, car le compte exposé est souvent celui que tout le monde pensait sûr par conception. Un compte de service géré en groupe (gMSA, Group Managed Service Account) est la réponse de Microsoft à l'un des plus vieux problèmes d'Active Directory : des mots de passe de comptes de service statiques, connus des humains, qui restent inchangés pendant des années dans des scripts, des tâches planifiées et des fichiers de configuration. Le contrôleur de domaine génère un mot de passe aléatoire de 256 octets et le fait tourner automatiquement — tous les 30 jours par défaut — de sorte qu'aucun administrateur n'a jamais à le saisir ni à le stocker où que ce soit (Microsoft Learn — Manage Group Managed Service Accounts). C'est la promesse, et sur ses propres termes, elle tient.
Ce qui provoque encore cette exposition n'est pas un mot de passe divulgué — c'est une liste de principaux autorisés à le lire qui est trop large. « Personne n'a le mot de passe » ne tient que tant que la liste des entités autorisées à le récupérer reste restreinte, et cette liste est contrôlée par un unique attribut qui se retrouve laissé bien trop permissif, bien plus souvent que les défenseurs ne l'anticipent.
À quoi sert un gMSA
Les services qui s'exécutent de manière identique sur une ferme équilibrée en charge — pools d'applications IIS, tâches planifiées, services Windows — ont besoin d'un principal unique qui se comporte de la même façon sur chaque hôte pour que l'authentification mutuelle Kerberos fonctionne. Un gMSA leur fournit cela sans mot de passe partagé synchronisé manuellement : tout hôte disposant des droits de récupération va chercher le mot de passe actuel directement dans AD via LDAP dès que le service en a besoin (Microsoft Learn).
Pourquoi la liste des droits de lecture crée quand même une exposition
En pratique, cette lacune apparaît de deux façons : un groupe de sécurité créé pour le gMSA est réutilisé pour autre chose sans rapport et accumule silencieusement de nouveaux membres au fil du temps, ou bien le groupe est imbriqué dans un groupe d'administration plus large déjà existant lors de la mise en place, parce que c'était le moyen le plus rapide de faire fonctionner le service. Dans les deux cas, la liste des lecteurs se retrouve plus large que les un ou deux hôtes qui en ont réellement besoin — et contrairement à une vérification classique de groupe à privilèges, cette ACL n'est pas revue au même rythme que l'appartenance aux groupes.
Comment ça fonctionne : PrincipalsAllowedToRetrieveManagedPassword
L'attribut msDS-GroupMSAMembership
Lors de la création d'un gMSA, vous spécifiez quels comptes d'ordinateur ou groupes de sécurité peuvent récupérer son mot de passe :
New-ADServiceAccount -Name svc-app01 -DNSHostName svc-app01.corp.local `
-PrincipalsAllowedToRetrieveManagedPassword "SG-App01-Hosts"
Ce paramètre écrit dans msDS-GroupMSAMembership, un attribut contenant un descripteur de sécurité au format String(NT-Sec-Desc) — une ACL encodée en base64 qui ne peut pas être lue directement. PrincipalsAllowedToRetrieveManagedPassword est le wrapper PowerShell convivial exposé par AD pour le lire et l'écrire (Microsoft Learn — Set-ADServiceAccount) ; les mécanismes bruts de l'attribut sont documentés en détail par DSInternals et la référence gMSA d'InternalAllTheThings.
Quiconque figure dans cette liste peut interroger l'attribut msDS-ManagedPassword, qu'AD calcule à la lecture et renvoie sous forme d'un MSDS-MANAGEDPASSWORD_BLOB contenant le mot de passe actuel en clair. Point crucial : il ne s'agit pas d'une vérification de groupe à privilèges — les Domain Admins n'obtiennent aucun accès implicite. Seuls les principaux explicitement nommés dans msDS-GroupMSAMembership peuvent lire le mot de passe, quels qu'ils soient (DSInternals).
ℹ️ Remarque : c'est exactement pour cette raison que cette faille passe entre les mailles des revues — les administrateurs supposent que l'accès au gMSA suit la logique classique des groupes à privilèges, alors qu'il est en réalité contrôlé par une ACL totalement distincte, que personne n'audite selon son propre calendrier.
Comment la liste devient trop permissive
Il n'existe aucun avertissement natif lorsque PrincipalsAllowedToRetrieveManagedPassword dépasse son périmètre d'origine. Un groupe ajouté « temporairement » pendant une migration, une appartenance imbriquée héritée de la délégation d'une UO parente, ou un groupe d'administration imbriqué ajouté parce qu'il contenait déjà les bons comptes d'ordinateur — chacun de ces cas élargit silencieusement la liste de ceux qui peuvent usurper le compte de service, sans qu'aucun changement correspondant sur l'objet gMSA lui-même n'attire l'attention lors d'une revue de routine. C'est la même classe de problème que celle traitée dans Abus d'ACL et DCSync : une permission dont plus personne ne se souvient l'avoir accordée, toujours valide, toujours exploitable.
La chaîne d'attaque : d'un groupe trop permissif à l'usurpation complète
Un cas réel : le gMSA Citrix dans Domain Admins
L'article de Sean Metcalf sur ADSecurity.org documente un cas concret de ce schéma : un gMSA Citrix, lui-même membre de Domain Admins, avait ses droits de récupération du mot de passe délégués à un groupe appelé « Citrix04 » — qui, après vérification, contenait un compte utilisateur ordinaire. Compromettre ce seul compte utilisateur suffisait à récupérer le mot de passe d'un gMSA équivalent à un Domain Admin (ADSecurity.org — GMSA Security Tip #14).
Lire le mot de passe une fois sur la liste
Une fois qu'un principal figure sur la liste des lecteurs autorisés, extraire le mot de passe ne nécessite aucun exploit — juste une lecture :
# En utilisant les modules AD + DSInternals
$gmsa = Get-ADServiceAccount -Identity "svc-app01" -Properties 'msDS-ManagedPassword'
$blob = ConvertFrom-ADManagedPasswordBlob $gmsa.'msDS-ManagedPassword'
ConvertTo-NTHash -Password $blob.SecureCurrentPassword
Get-ADServiceAccount renvoie le blob, ConvertFrom-ADManagedPasswordBlob (DSInternals) le décode en mots de passe actuel et précédent en clair, et ConvertTo-NTHash dérive le hash NT pour un usage hors ligne (DSInternals). Des outils comme GMSAPasswordReader.exe et gMSADumper.py automatisent la même lecture LDAP à distance, sans jamais toucher l'hôte cible.
Cette relation est exactement ce que l'arête ReadGMSAPassword de BloodHound cartographie : tout utilisateur, groupe ou ordinateur disposant de droits de récupération sur un gMSA. SpecterOps documente trois chemins d'abus une fois cette arête en main — voler ou injecter le jeton du gMSA s'il est déjà connecté sur un hôte autorisé, planifier une tâche ou un service pour s'exécuter en tant que gMSA sur un hôte autorisé, ou récupérer le mot de passe à distance et utiliser le hash NT résultant pour un overpass-the-hash (BloodHound — ReadGMSAPassword). Aucun de ces chemins ne nécessite que la rotation automatique du gMSA échoue — la rotation signifie simplement que l'attaquant relit le mot de passe après chaque cycle, exactement comme le ferait un hôte autorisé.
Détection
Event IDs Windows à corréler
| Indicateur | Event ID | Source | Description |
|---|---|---|---|
| Accès au service d'annuaire sur l'objet gMSA | 4662 | Journal de sécurité du contrôleur de domaine | Enregistré uniquement si une SACL est configurée sur l'objet gMSA ; montre le GUID de la propriété msDS-ManagedPassword accédée et par qui |
| Récupération réussie du mot de passe géré | 2946 | Journal d'événements Directory-Services du DC | « Un appelant a récupéré avec succès le mot de passe d'un compte de service géré en groupe » |
| Échec de récupération du mot de passe géré | 2947 | Journal d'événements Directory-Services du DC | Pendant d'échec de 2946 — un principal non autorisé a tenté une lecture |
| Connexion corrélée | 4624 (Logon_Type 3) | Journal de sécurité du contrôleur de domaine | Connexion réseau autour de l'heure d'un événement 4662/2946 ; relie la lecture à un compte et un hôte source |
Ces Event IDs et l'approche de corrélation (faire correspondre 4662, 2946 et 4624 sur le Logon ID dans une courte fenêtre) sont documentés dans l'article de TrustedSec sur la chasse aux abus de gMSA (TrustedSec — Splunk SPL Queries for Detecting GMSA Attacks). Sans SACL sur l'objet gMSA, l'événement 4662 ne se déclenche jamais — l'audit doit être activé délibérément, objet par objet, un manque qui recoupe les lacunes de configuration de la politique d'audit Active Directory plus larges.
⚠️ Avertissement : les événements 2946/2947 confirment qu'un mot de passe a bien été récupéré, mais ils ne disent pas si le lecteur était attendu. Il faut toujours comparer le compte ou l'hôte à l'origine de l'événement avec la liste PrincipalsAllowedToRetrieveManagedPassword propre au gMSA.
Auditer directement la liste des lecteurs
La détection basée sur les logs ne capture une lecture qu'après coup. Auditez directement et à l'échelle du domaine la liste d'autorisation, plutôt que d'attendre un événement :
Get-ADServiceAccount -Filter * -Properties PrincipalsAllowedToRetrieveManagedPassword |
Select-Object Name, PrincipalsAllowedToRetrieveManagedPassword
Exécutez cette commande sur chaque gMSA du domaine et développez chaque groupe renvoyé — un simple nom de groupe de sécurité peut cacher un compte utilisateur obsolète, un groupe basé sur une UO trop large, ou un groupe à privilèges imbriqué qui n'aurait jamais dû avoir de droits de récupération.
Remédiation
💡 Gain rapide : lancez dès aujourd'hui l'audit Get-ADServiceAccount -Filter * ci-dessus. Il tient en une ligne et fait immédiatement apparaître chaque gMSA dont la liste de lecteurs mérite un second regard.
- Recensez chaque gMSA et ses lecteurs à l'aide de la requête ci-dessus. Développez l'appartenance aux groupes, pas seulement le nom du principal de premier niveau — c'est là que se cache une surprise du type Citrix04.
- Restreignez
PrincipalsAllowedToRetrieveManagedPasswordaux hôtes exacts qui en ont besoin. UtilisezSet-ADServiceAccount -Identity <NomGMSA> -PrincipalsAllowedToRetrieveManagedPassword <groupe-restreint>pour remplacer un groupe trop permissif par un groupe limité aux comptes d'ordinateur exécutant réellement le service (Microsoft Learn — Set-ADServiceAccount). - Vérifiez que rien ne casse avant et après le changement avec
Test-ADServiceAccount -Identity <NomGMSA>sur chaque hôte censé conserver l'accès (Microsoft Learn — Manage Group Managed Service Accounts). - N'imbriquez jamais un groupe lecteur de gMSA dans un groupe d'administration plus large pour gagner du temps lors de la mise en place — c'est exactement ce type d'imbrication qui fait qu'un seul groupe finit par contrôler la récupération du mot de passe de comptes qu'il n'était jamais censé toucher. Voir Imbrication dangereuse de groupes pour comprendre comment l'appartenance transitive crée des chemins que les défenseurs n'anticipent pas.
- Si le gMSA lui-même se trouve dans un groupe à privilèges (Domain Admins ou équivalent), traitez cela comme une découverte distincte et cumulative : des droits de lecture du mot de passe trop larges sur un membre d'un groupe à privilèges est un chemin plus rapide vers Domain Admin que chacun des deux problèmes pris isolément. Ceci est distinct de l'hygiène classique d'appartenance aux groupes à privilèges, traitée dans Comptes privilégiés Active Directory : Protected Users, délégation et lacunes des comptes de service.
- Activez l'audit d'accès au service d'annuaire (SACL) sur les objets gMSA pour que les événements 4662 soient réellement générés pour les comptes qui comptent le plus, plutôt que de découvrir la lacune uniquement lors d'un incident.
Comment EtcSec détecte cela
Le contrôle GMSA_PASSWORD_READERS d'EtcSec signale les objets gMSA dont PrincipalsAllowedToRetrieveManagedPassword inclut un principal plus large que le périmètre d'hôtes attendu — comptes utilisateur, groupes de sécurité génériques, ou appartenances imbriquées qui ne devraient pas pouvoir récupérer le mot de passe. Il est associé à GMSA_OLD_PASSWORD, qui signale les gMSA dont le mot de passe géré n'a pas tourné selon le calendrier prévu, et à DANGEROUS_GROUP_NESTING, qui détecte le schéma d'appartenance transitive généralement à l'origine de ce trop grand périmètre.
ℹ️ Remarque : EtcSec vérifie automatiquement cette vulnérabilité à chaque audit AD. Lancez un audit gratuit pour identifier quels gMSA de votre environnement ont une liste de lecteurs plus large que prévu.
Lecture connexe : Kerberoasting : détection et prévention des attaques de comptes de service couvre l'attaque par SPN à laquelle les gMSA sont largement immunisés (pas de ticket crackable, le mot de passe étant 256 octets de données aléatoires) — un contexte utile pour comprendre pourquoi l'adoption des gMSA ne supprime pas le risque lié aux comptes de service, elle le déplace simplement vers cette ACL. BadSuccessor : escalade de privilèges via les dMSA couvre un chemin d'escalade distinct mais lié, via les comptes de service gérés délégués.
Explorez les pages identité liées à ce sujet

