🏢Active DirectoryPasswordConfig

Mot de passe en clair et chiffrement réversible Active Directory : le piège de l'attribut userPassword expliqué

Deux réglages Active Directory peuvent laisser des mots de passe récupérables en clair : l'attribut userPassword et le flag UAC de chiffrement réversible. Voici comment détecter et corriger les deux.

Younes AZABARPar Younes AZABAR11 min de lecture
Mot de passe en clair et chiffrement réversible Active Directory : le piège de l'attribut userPassword expliqué

Le problème du mot de passe en clair et chiffrement réversible Active Directory

Mot de passe en clair et chiffrement réversible Active Directory : cette exposition fait partie des rares mauvaises configurations qui court-circuitent entièrement le déroulé habituel d'un attaquant — pas de hash à casser, pas de ticket à relayer, juste un mot de passe littéral posé dans l'annuaire, contrairement à un hash NT volé et réutilisé via Pass-the-Hash. Active Directory est conçu pour ne jamais stocker de copie utilisable d'un mot de passe : chaque valeur unicodePwd est hachée à sens unique (hash NT, et clés Kerberos long terme) avant d'atteindre la base, et l'attribut lui-même ne peut pas être relu via LDAP. La documentation du protocole MS-SAMR de Microsoft est explicite sur le seul cas qui casse cette garantie : le stockage du mot de passe en clair pour un objet n'est configuré que lorsque la valeur Effective-PasswordReversibleEncryptionEnabled du compte est positionnée, ou lorsque son attribut userAccountControl contient le bit ENCRYPTED_TEXT_PWD_ALLOWED (0x0080) — après quoi la prochaine définition ou modification de mot de passe écrit une copie déchiffrable dans supplementalCredentials.

Cet article couvre deux modes de défaillance distincts, au niveau attribut, qui se terminent tous deux par un attaquant en possession d'un identifiant en clair utilisable directement issu de l'annuaire :

  • L'attribut LDAP historique userPassword, que certains environnements peuplent directement avec une chaîne littérale.
  • Le flag de chiffrement réversible sur userAccountControl, qui indique à chaque contrôleur de domaine de conserver une copie déchiffrable du mot de passe en plus des hashes habituels.

Les deux sont classés Critiques dans le catalogue d'audit d'etc-collector (PASSWORD_CLEARTEXT_STORAGE, REVERSIBLE_ENCRYPTION) car compromettre l'un ou l'autre donne à un attaquant le mot de passe littéral, pas seulement un hash à casser ou à relayer. Cette distinction compte opérationnellement : un hash cassé ou une session relayée peuvent être contenus en faisant tourner un identifiant et en revoyant ce qu'il a touché, mais un mot de passe en clair récupéré est souvent réutilisé ailleurs — comptes personnels, autres systèmes, autres domaines — donc le rayon d'impact de l'une ou l'autre exposition s'étend bien au-delà de l'objet AD où elle a été trouvée.

⚠️

⚠️ Avertissement : ceci est un mécanisme différent des identifiants en clair WDigest (qui expose des mots de passe en mémoire LSASS sur un hôte compromis) et des mots de passe laissés dans les champs description d'AD (métadonnées en texte libre, pas un attribut de stockage de mot de passe). Les deux mécanismes ci-dessous vivent dans la logique de gestion des mots de passe propre à l'annuaire, pas dans un canal annexe.

Comment ça fonctionne

L'attribut userPassword

userPassword est un attribut LDAP standard (défini en dehors du schéma Microsoft, dans les standards d'annuaire dérivés de la RFC 4519) qu'Active Directory reconnaît aussi sous certaines conditions. Selon MS-ADTS §3.1.1.3.1.5.2, AD ne laisse les clients écrire et utiliser userPassword pour définir le mot de passe d'un compte que lorsque :

  • le DC fonctionne en tant qu'AD LDS, ou
  • le DC est AD DS, le niveau fonctionnel du domaine est Windows Server 2003 ou supérieur, et
  • l'heuristique fUserPwdSupport dans l'attribut dSHeuristics est activée.

Quand cette heuristique est désactivée (le défaut pour AD DS), userPassword est simplement un attribut ordinaire, non indexé, sans sémantique particulière — ce qui est exactement le piège : de nombreux administrateurs et scripts de provisioning (outils de migration LDAP, jobs de synchronisation RH, intégrations Unix/LDAP historiques) écrivent encore une chaîne de mot de passe littérale dans userPassword par habitude ou par besoin d'interopérabilité. Contrairement à unicodePwd, cet attribut est lisible par quiconque dispose de droits de lecture générique sur l'objet, donc une simple recherche LDAP (userPassword=*) peut extraire chaque valeur en clair qui y a jamais été écrite — aucune élévation de privilèges requise, aucun cassage de hash, rien à relayer.

ldapsearch -x -H ldap://dc01.corp.local -D "[email protected]" -W \
  -b "DC=corp,DC=local" "(userPassword=*)" sAMAccountName userPassword

Le flag UAC de chiffrement réversible

Le second mécanisme est le bit ENCRYPTED_TEXT_PWD_ALLOWED (décimal 128 / hex 0x0080) dans userAccountControl, exposé sur l'objet utilisateur comme l'attribut ms-DS-User-Encrypted-Text-Password-Allowed et, dans le module PowerShell AD, comme la propriété de compte AllowReversiblePasswordEncryption. Le positionner n'écrit pas lui-même un mot de passe en clair — cela change ce qui se passe à la prochaine définition ou modification de mot de passe : AD stocke le nouveau mot de passe dans supplementalCredentials sous une forme déchiffrable avec la propre clé de chiffrement du domaine, en plus des hashes habituels.

Ce flag existe pour supporter des protocoles d'authentification historiques qui ont besoin du mot de passe réel pour calculer un challenge-response, le plus souvent CHAP pour RADIUS/IAS dial-up et VPN, ainsi que les anciens déploiements IIS Digest Authentication. La documentation Microsoft sur la politique de sécurité est sans détour sur le compromis : l'activer « revient essentiellement à stocker des versions en clair des mots de passe », et cela ne devrait jamais être activé à l'échelle du domaine sauf si une application en a réellement besoin.

Si un domaine a besoin de cela pour un petit ensemble de comptes de service historiques, en restreindre la portée compte : une Fine-Grained Password Policy (Password Settings Object) peut positionner msDS-PasswordReversibleEncryptionEnabled uniquement sur l'OU ou le groupe qui en a besoin, plutôt que de basculer le réglage « Stocker les mots de passe en utilisant un chiffrement réversible » dans la Default Domain Policy pour tous les comptes du domaine.

🚨 Danger : MITRE ATT&CK T1556.005 documente ceci comme une technique adverse active, pas seulement comme une mauvaise configuration historique : avec suffisamment de droits, un attaquant peut exécuter Set-ADUser -AllowReversiblePasswordEncryption $true contre un compte cible, attendre (ou forcer) une réinitialisation de mot de passe, puis récupérer le mot de passe en clair depuis le prochain identifiant stocké du compte — transformant un simple droit d'écriture en porte dérobée permanente de collecte d'identifiants qui survit à la rotation des mots de passe.

Pourquoi cela apparaît encore dans les environnements modernes

Aucun des deux mécanismes n'est une relique qui n'affecte que les domaines de l'ère Windows 2000. userPassword réapparaît chaque fois qu'une organisation fait tourner un outillage de synchronisation d'identité conçu à l'origine pour OpenLDAP ou un autre annuaire RFC-4519, pointé vers Active Directory sans ajustement — le job de synchronisation écrit le champ qu'il a été conçu pour écrire, et rien dans AD ne l'en empêche si dSHeuristics l'autorise. Le chiffrement réversible réapparaît de la même manière : un boîtier RADIUS, un concentrateur VPN historique, ou une vieille application intranet utilisant IIS Digest Authentication est configuré une fois, la politique à l'échelle du domaine est basculée pour que ça fonctionne, et le réglage survit tranquillement à l'application qui en avait besoin — souvent pendant des années, sur tous les comptes du domaine, longtemps après que quiconque se souvienne pourquoi il est là.

Les deux cas partagent la même cause racine : le réglage est un interrupteur à l'échelle du domaine ou de l'objet, mais le besoin réel est presque toujours étroit — une application, une intégration, un protocole historique. Rien ne force une revue quand la dépendance disparaît, donc l'exposition persiste comme pure dette technique jusqu'à ce qu'un audit, ou un attaquant, la trouve. Elle mérite sa place sur la même liste de surveillance que les mauvaises configurations de sécurité Active Directory les plus courantes qui survivent des années après leur justification d'origine.

Détection

IndicateurEvent IDSourceDescription
Attribut userPassword peupléRequête LDAP(userPassword=*) retourne un objet ; l'attribut est lisible sans détour, aucune élévation de privilèges nécessaire
dSHeuristics autorise les écritures userPasswordRequête LDAP sur le Configuration NCLe caractère fUserPwdSupport dans CN=Directory Service,CN=Windows NT,CN=Services,CN=Configuration,... n'est pas 0/2
userAccountControl a le bit 128 positionné4738Journal d'événements de sécurité (DC)Les changements « User Account Control » listent Encrypted Text Password Allowed ; se déclenche aussi en 4720 lors de la création d'un compte avec le flag déjà positionné
Le compte a AllowReversiblePasswordEncryption = TrueAD PowerShell / filtre LDAP bitwiseExposition permanente, indépendante du moment où le flag a été positionné
# Comptes avec chiffrement réversible actuellement activé
Get-ADUser -Filter {AllowReversiblePasswordEncryption -eq $true} `
  -Properties AllowReversiblePasswordEncryption, PasswordLastSet |
  Select-Object SamAccountName, PasswordLastSet

# Filtre LDAP bitwise-AND équivalent (matching-rule OID 1.2.840.113556.1.4.803)
Get-ADUser -LDAPFilter "(userAccountControl:1.2.840.113556.1.4.803:=128)" `
  -Properties userAccountControl | Select-Object SamAccountName
💡

💡 Astuce : Get-ADUser -Filter {AllowReversiblePasswordEncryption -eq $true} ne montre que l'état actuel. Alertez aussi sur l'Event ID 4738, pour qu'un basculement de flag sur un compte privilégié soit détecté à l'instant où il se produit — pas des semaines plus tard lors du prochain cycle d'audit.

Pour userPassword, comme il s'agit d'un attribut générique qu'AD n'indexe pas ni ne protège spécialement par défaut, un balayage LDAP planifié pour (userPassword=*) sur tout le domaine est le seul moyen fiable de le détecter ; il n'existe pas d'événement de sécurité dédié pour l'écriture sur cet attribut, donc les réaudits périodiques comptent autant que le balayage initial.

Remédiation

💡

💡 Solution rapide : désactivez « Stocker les mots de passe en utilisant un chiffrement réversible » dans la Default Domain Policy sauf si vous pouvez nommer l'application historique spécifique qui l'exige.

  1. Auditez avant de toucher à quoi que ce soit. Exécutez les deux requêtes ci-dessus sur tout le domaine et enregistrez chaque résultat — basculer le flag ou vider userPassword force un changement de mot de passe pour ce compte, donc planifiez la rotation avec les propriétaires de compte au préalable.
  2. Désactivez le chiffrement réversible à l'échelle du domaine via la stratégie de groupe (Configuration ordinateur > Stratégies > Paramètres Windows > Paramètres de sécurité > Stratégies de comptes > Stratégie de mot de passe > « Stocker les mots de passe en utilisant un chiffrement réversible » = Désactivé), sauf en cas de dépendance CHAP/RADIUS ou IIS Digest Authentication historique spécifique.
  3. Si une dépendance légitime existe, cantonnez-la avec une Fine-Grained Password Policy (msDS-PasswordReversibleEncryptionEnabled) appliquée uniquement à l'OU ou au groupe qui fait tourner cette application — jamais à l'échelle du domaine.
  4. Videz toute valeur userPassword trouvée, et repositionnez fUserPwdSupport à désactivé dans dSHeuristics sauf si le DC fait intentionnellement tourner AD LDS ou qu'une intégration documentée en a besoin.
  5. Forcez une réinitialisation de mot de passe pour chaque compte concerné. Désactiver le flag ou vider l'attribut ne supprime pas rétroactivement le matériel d'identifiant déjà écrit dans supplementalCredentials — seul le prochain changement de mot de passe le fait.
  6. Verrouillez l'accès en écriture à userAccountControl et userPassword pour les utilisateurs standards ; les deux ne devraient être modifiables que par l'administration d'identité tier-0, et toute attribution GenericAll/GenericWrite qui les atteint mérite le même niveau de scrutin qu'un chemin vers Domain Admin.
  7. Câblez l'Event ID 4738 dans votre SIEM avec une alerte sur l'apparition de Encrypted Text Password Allowed dans la liste des attributs modifiés, au minimum scopée sur les comptes privilégiés et de service, et relancez les balayages LDAP selon un calendrier récurrent plutôt que de traiter ceci comme un nettoyage ponctuel.
  8. Documentez toute exception restante. Si une application historique a réellement encore besoin du chiffrement réversible, enregistrez le propriétaire, la date de revue et le plan de décommissionnement — une exception non documentée est indiscernable d'une exception passée inaperçue lors du prochain audit.

Comment EtcSec détecte cela

Le catalogue d'audit d'EtcSec suit les deux mécanismes comme des vérifications distinctes, de sévérité Critique : PASSWORD_CLEARTEXT_STORAGE signale tout objet où userPassword porte une valeur, et REVERSIBLE_ENCRYPTION signale tout compte avec AllowReversiblePasswordEncryption (le bit UAC ENCRYPTED_TEXT_PWD_ALLOWED) activé. Les deux se trouvent dans la catégorie Password aux côtés de contrôles liés comme la conformité de la politique de mot de passe et les secrets cPassword GPO SYSVOL — ensemble, ils couvrent la poignée de façons dont un annuaire peut finir par détenir un mot de passe qu'un attaquant n'a même pas besoin de casser.

ℹ️

ℹ️ Remarque : EtcSec vérifie automatiquement cette vulnérabilité lors de chaque audit AD. Lancez un audit gratuit pour vérifier que votre environnement n'expose aucun des deux flags.

Explorez les pages identité liées à ce sujet