Sécurité de l’Active Directory : les mots de passe dans la description des objets utilisateur
Sommaire
I. Présentation
Dans cet article, nous allons nous intéresser à une mauvaise pratique encore très présente au sein des équipes d'administration et des annuaires Active Directory : le stockage de mots de passe dans l'attribut "description" des objets utilisateurs.
Nous allons voir en quoi cette pratique est dangereuse pour le domaine et pourquoi son existence et ses impacts sont souvent méconnus. Également, nous nous intéresserons de façon très pratique à la manière dont attaquants et défenseurs peuvent détecter et exploiter cette faille au sein d'un Active Directory.
Enfin, nous verrons quelles sont les bonnes pratiques et les difficultés de détection, aussi bien lors de l'introduction de la vulnérabilité dans l'Active Directory que lors de son exploitation par un attaquant.
II. Mot de passe dans l'attribut description : quels risques ?
Lorsque l'on administre un système d'information et un domaine, nous avons accès à des outils, interfaces et serveurs auquel personne d'autres n'a accès dans l'entreprise. Ainsi, il est aisé de croire que nous seul avons accès aux différentes informations que nous manipulons : ce n'est pas tout à fait vrai.
Au sein de l'Active Directory, tous les objets ont de nombreux attributs, techniques et métier. Le "dn", "sAMAccountName", les attributs relatifs aux groupes, aux mots de passe, etc. L'attribut "description" en fait partie, il s'agit d'un simple champ texte permettant d'indiquer des informations sur l'objet créé :
Plutôt pratique lorsque l'on souhaite, par exemple, se rappeler pour quel service ce compte a été créé, quel est le nom complet du propriétaire lorsque l'on crée des objets non nominatifs ("XR-23-OP"), etc.
Lorsque l'on combine ces deux constats, les administrateurs peuvent penser que la description peut aussi permettre de stocker les mots de passe des comptes dont ils ne se serviront pas tous les jours ou que plusieurs membres de l'équipe sont susceptibles de manipuler (comptes "communs" ou de services par exemple). Dès lors, quoi de plus pratique que d'établir une convention implicite : "si tu cherches le mot de passe de ce compte, il est dans sa description AD" ?
Cependant, il est souvent oublié que la quasi-totalité des attributs de tous les objets sont lisibles par tous les comptes authentifiés de l'Active Directory (utilisateurs, ordinateurs, etc.). C'est ainsi que fonctionne l'Active Directory et il en va de son bon fonctionnement. Si vous avez déjà parcouru mon cours sur BloodHound, vous verrez que cela permet d'aller très loin dans la découverte d'un domaine et même d'y découvrir des chemins d'attaque complets.
Pour l'attribut "description" par exemple, il pourrait très bien être utilisé par une application de tchat interne se reposant sur l'annuaire pour afficher la description de l'utilisateur avec lequel vous discutez. Il faut donc bien que cet attribut soit accessible en lecture.
Cette mauvaise pratique, très commune d'après mon expérience en tant qu'auditeur cybersécurité et pentester, est souvent exploitée par les attaquants ayant déjà un accès authentifié au domaine afin de compromettre rapidement d'autres comptes. Ce type d'attaque dispose même d'un TTP dans le framework MITRE ATT&CK, qui référence les principales techniques d'attaque (T1552 - Unsecured Credentials) :
III. Point de vue de l'attaquant
A. Depuis Linux
À présent, nous allons voir comment un attaquant disposant d'un accès authentifié au domaine (mode opératoire "boite grise"), peut récupérer les descriptions des objets utilisateurs du domaine depuis un poste Linux. De nombreux outils offensifs ont été développés, notamment en Python et bash, pour les OS Linux.
- Utilisation de ldapsearch
L'outil le plus simple pour commencer est bien sur "ldapsearch", un client plutôt classique et légitime pour discuter avec le service LDAP :
ldapsearch -H ldap://it-connect.tech -x -b 'dc=it-connect,dc=tech' -D [email protected] -w 'Abcd1234' description
Ici, nous obtenons rapidement toutes les descriptions de tous les utilisateurs C'est un début (plutôt verbeux), cherchons maintenant des mots de passe.
D'après mon expérience, certains caractères sont spécifiques à la présence de mots de passe et rarement présents dans des descriptions textuelles simples, c'est notamment le cas du ":" et du "=". C'est aussi le cas de certains mots comme "mdp", "pass" ou "mot de passe".
Nous pouvons ajouter des filtres, bien que ce soit quelque peu fastidieux via "ldapsearch" :
ldapsearch -H ldap://it-connect.tech -x -b 'dc=it-connect,dc=tech' -D [email protected] -w 'Abcd1234' '(&(
objectClass=User) (|(description=**=)(description=*:*)(description=*mdp*) (description=*pass*) (description=*mot de passe*)))' description
Voici un exemple de résultat obtenu :
Le résultat est un peu verbeux, mais tout à fait exploitable.
- Utilisation de netexec
Nous pouvons également utiliser "netexec" (anciennement "crackmapexec"), qui dispose d'un module fait pour ce type de recherche.
netexec ldap 192.168.56.102 -u mmartin -p 'Abcd1234' -d it-connect.tech -M user-desc
Nous utilisons ici le module "user-desc" de "netexec", celui-ci va tout d'abord nous ressortir toutes les descriptions des objets utilisateurs contenant le mot de "pass".
Comme vous pouvez le voir dans la dernière ligne de la sortie, "netexec" va également sauvegarder toutes les descriptions des utilisateurs dans un fichier de log, dans lequel nous pourrons faire nos propres recherches, exemple :
- Utilisation de Cypher
Enfin, si vous avez utilisé "SharpHound.exe" pour extraire les données de l'Active Directory et que vous les avez importées dans BloodHound, voici une requête "Cypher" à utiliser dans la base "Neo4j" pour avoir une recherche équivalente à celles faites précédemment :
MATCH (u:User)
WHERE u.description CONTAINS "="
OR u.description CONTAINS ":"
OR u.description CONTAINS "mdp"
OR u.description CONTAINS "pass"
OR u.description CONTAINS "mot de passe"
RETURN u.samaccountname,u.description
Voici un exemple de résultat obtenu :
Si vous souhaitez apprendre à utiliser BloodHound, n'hésitez pas à consulter mon cours sur le sujet :
B. Depuis un poste Windows
Nous allons à présent voir comment récupérer ces informations en tant qu'attaquant sur un poste Windows, intégré ou non au domaine : la différence n'est pas très importante lorsque l'on dispose d'un compte de domaine valide.
Utilisons pour cela "PowerView" de la suite PowerSploit, un ensemble de scripts PowerShell offensifs (un peu l'équivalent de la librairie "impacket" sous Linux) :
Get-Netuser | Select -Property UserPrincipalName,description
Voici un exemple de résultat attendu :
Là aussi, nous récupérons facilement les descriptions utilisateurs et pouvons appliquer des filtres de recherche :
Get-NetUser |Select -Property UserPrincipalName,description | Where-Object {$_.description -like "*pass*"}
Nous venons de voir que sous Linux comme sous Windows, la récupération des descriptions des objets de l'Active Directory est triviale et même réalisable avec des outils natifs et non "offensifs" ("ldapsearch"). Il faut également savoir que si votre Active Directory est affecté par certaines mauvaises configurations, ces informations peuvent aussi être récupérées sans authentification, par exemple, en cas d'accès anonyme autorisé au service LDAP de l'Active Directory.
IV. Point de vue du défenseur
A. Identifier les mots de passe dans les descriptions
Si vous êtes en charge de l'administration du domaine et avez accès au contrôleur de domaine. La première bonne pratique est déjà de constater si des mots de passe sont présents dans la description de vos objets. Vous pouvez ouvrir la console "Utilisateurs et ordinateurs Active Directory" et trouver la description des objets dans l'affichage central :
Pour trouver et modifier la description d'un objet, il faut faire un clic droit "Propriétés" sur l'objet en question, puis se rendre sur "Général" :
Vous pouvez faire la même opération en PowerShell avec la cmdlet "Get-ADUser", issue du module "Active Directory". Une première requête va nous afficher toutes les descriptions utilisateurs non vides :
Get-ADUser -Filter {description -like '*'} -Properties samaccountname, description | Select-Object samaccountname, description
L'intérêt ici est que nous récupérons toutes les valeurs d'un seul coup. Voici le résultat attendu :
Comme l'attaquant, nous pouvons appliquer des filtres sur certains caractères ou mots caractéristiques de la présence de mots de passe :
Get-ADUser -filter {description -like '=' -or description -like 'pass' -or description -like '*mdp*' -or description -like '*mot de passe*'} -Properties samaccountname, description | Select-Object samaccountname,description
Voici un résultat possible :
Il s'agit là déjà d'une bonne base de recherche. Si vous souhaitez aller plus loin et être sûr qu'aucun mot de passe n'est présent, il faudra parcourir les données affichées manuellement.
Nous nous limitons aux utilisateurs ici, mais cela vaut peut-être également le coup de chercher dans les descriptions d'autres types d'objets ? Également, maintenant que vous avez ces quelques commandes sous la main, pourquoi ne pas planifier un contrôle régulier du contenu des attributs "description" des objets de l'Active Directory ? Afin de mettre en place cette sécurisation dans la durée.
B. Correctif et bonnes pratiques de sécurité
Nous allons à présent voir comment corriger cette faiblesse si vous la découvrez sur votre domaine. Dans un premier temps, il convient de savoir s'il est légitime de stocker ce mot de passe, doit-il être utilisé par plusieurs personnes (cas d'un compte de service) ? Si c'est le cas, il est recommandé de stocker ce mot de passe dans un coffre-fort numérique, partagé avec votre équipe si besoin est. Ensuite, la correction en elle-même est plutôt simple : Modifier la description.
Via l'interface graphique, il suffit de faire un clic droit "Propriétés" et de modifié la valeur de l'attribut "description", tel que montré plus haut :
Il est également possible de le faire via PowerShell, en utilisant la CmdLet "Set-ADUser" du module "Active Directory" :
Set-ADUser Topdesk -Description $null
Vous pourrez immédiatement contrôler le résultat de "Set-ADUser" avec la CmdLet "Get-ADUser" :
Pour être très pointilleux, vous pouvez même remplacer le contenu de la description par "Description supprimée par XXX le XX/XX/XXXX". Ainsi, il n'y aura pas de mauvaise surprise pour votre collègue qui a l'habitude de récupérer ce mot de passe à cet endroit, et il pourra venir vous demander où est ce fameux mot de passe à présent :).
- Évoquons à présent les bonnes pratiques concernant le stockage des mots de passe :
Les mots de passe ne doivent jamais être stockés de manière non sécurisée (chiffrée) et sur des supports, physiques ou numériques, accessibles à tous (même chiffrés).
Lorsque le besoin de partager des mots de passe est présent (cas pour un compte de service, susceptibles d'être géré par plusieurs personnes), il est recommandé d'utiliser des coffres-forts de mots de passe. KeePass est une bonne option, mais peut être limité en ce qui concerne le partage d'information, son usage est d'ordinaire plutôt personnel. Des solutions existent pour le partage de mot de passe, on peut notamment citer le projet Bitwarden qui permet de gérer les permissions et journaliser les accès aux mots de passe (vous pouvez auto-héberger Bitwarden).
Lorsqu'il s'agit de mots de passe de compte utilisateur (dans le sens utilisateur humain du système d'information) : l'administrateur n'a pas à le connaitre, ce mot de passe n'a donc rien à faire dans un attribut quel qu'il soit.
La bonne pratique d'assignation des mots de passe utilisateur consiste à paramétrer un mot de passe (aléatoire et différent à chaque utilisateur) à un compte, et de cocher la case "L'utilisateur doit changer ce mot de passe à la prochaine ouverture de session". L'utilisateur pourra alors paramétrer un mot de passe qui lui est propre ensuite.
Si le besoin d'invoquer un argument d'autorité se fait sentir, nous pouvons toujours rappeler la directive n°11 du guide d'hygiène informatique de l'ANSSI :
Il est également recommandé de changer les mots de passe des comptes concernés. En effet, les mots de passe ayant été exposés "publiquement" par le passé, n'importe qui peut les avoir récupérés et donc continuer de les utiliser. Sans parler de la présence de cette information dans d'éventuels backups de la base NTDS, export des données de l'AD (BloodHound, PingCastle), etc.
Enfin, il convient également sensibiliser et former les administrateurs aux bonnes pratiques de sécurité et risques liés au stockage non sécurisé des mots de passe :
- Identifiant de la remédiation dans le framework MITRE ATT&CK : M1017 - User Training
- Directive n°1 du guide d'hygiène de l'ANSSI : Former les équipes opérationnelles à la sécurité des systèmes d’information
Les simulations de cyberattaques, telles que les tests d'intrusion ou les opérations Red Team, offrent également une opportunité de mettre en lumière de manière très factuelle les mauvaises pratiques en matière de sécurité. Elles permettent de mesurer concrètement l'impact de ces pratiques sur la sécurité du système d'information et, par extension, sur la résilience de l'entreprise. Cela permet aussi parfois de bousculer certaines certitudes en incitant à une ouverture d'esprit et à une révision des positions figées.
C. Possibilité de détection de l'attaque
Nous allons à présent nous intéresser aux possibilités de détection de l'exploitation de cette vulnérabilité ou de son introduction au sein de l'Active Directory via les journaux d'évènements. Concernant la détection, et sur un Active Directory disposant des règles d'audit par défaut, les choses se compliquent quelque peu.
Pour étudier les évènements produits lors de la récupération des descriptions, j'effectue 10 fois de suite une récupération de la description des 2500 utilisateurs de mon Active Directory depuis un poste Linux, histoire de générer un beau volume de requêtes :
Voici le volume de logs produits durant le temps de l'attaque, que je visualise dans ElasticSearch :
59 évènements, ce qui est plutôt faible au regard du nombre d'éléments récupérés et en sachant que mon Active Directory est dans un lab vide, et non dans un vrai SI avec de l'activité. Si j'interroge ELK sur les top évènements générés, voici ce qu'il en ressort :
Voici la description des principaux évènements :
- 4624 : An account was successfully logged on.
- 4634 : An account was logged off
- 4776 : The computer attempted to validate the credentials for an account.
Pour faire simple : aucun évènement n'est journalisé mis à part l'ouverture et la fermeture d'une session. Autrement dit, cette opération passe totalement inaperçue.
Autre point potentiellement intéressant, nous pouvons tenter de voir si les journaux d'évènement peuvent nous aider à détecter l'introduction de la vulnérabilité sur le domaine par un administrateur. Autrement dit, pouvons-nous avoir un évènement/une alerte lorsqu'un utilisateur est créé ou modifié avec une description contenant des caractères/mots caractéristiques d'un mot de passe ?
Lors de la création d'un utilisateur, l'eventID 4720 A user account was created est journalisé, voici son contenu (vue ElasticSearch) :
Lors de la modification d'un utilisateur existant et de l'insertion d'un mot de passe dans sa description, l'eventID 4738 A user account was changed est journalisé, voici son contenu (vue ElasticSearch):
Vous ne voyez pas l'attribut description ? C'est normal, il n'est pas journalisé. Autrement dit, nous sommes à nouveau dans le noir et il est impossible de mettre en place une règle de détection basée sur le contenu du champ "description".
Nous venons de voir que l'objectif de détection parait difficile à atteindre, tant lors d'une "exploitation" (récupération des attributs) et que lors de l'introduction de la vulnérabilité sur le domaine. La seule option qu'il nous reste est donc la réalisation d'audits réguliers, manuels ou scriptés, permettant de chercher des mots de passe dans l'attribut "description" des utilisateurs.
Pour répondre à ce besoin, je vous propose un script PowerShell qui peut être utilisé dans le cadre d'une tâche planifiée déclenchée par un évènement 4738 :
Ce script va, lors de sa première exécution, créer une "archive" : un fichier XML contenant les GUID des utilisateurs et le hash de leur description. Lors des exécutions suivantes, les utilisateurs et descriptions seront récupérés auprès de l'Active Directory, comparés à l'archive créée précédemment et les différences de hash découverts (donc, une modification de la description) entrainerons une journalisation du login utilisateur ainsi que de sa description.
Si l'utilisateur n'existait pas dans l'archive précédente (cas d'une création), sa description sera journalisée également. Enfin, une nouvelle archive sera créée et remplacera la précédente, prête pour la prochaine analyse. Le script créera un évènement ID 1000 dans le journal "Application" :
Voici par exemple une requête KQL (pour ElasticSearch) permettant de chercher quelques mots de clés dans les "event.code 10000" :
event.code:10000 and (winlog.event_data.param2: *pass* or winlog.event_data.param2: *mot de passe* or winlog.event_data.param2: *pwd*)
Et enfin un exemple de détection d'un mot de passe dans une description grâce aux évènements créés par ce script dans ElasticSearch :
- Identifiant de la remédiation dans le framework MITRE ATT&CK : M1047 - Audit
Si vous connaissez d'autres options, eventID ou moyens de détection concernant cette faiblesse et son exploitation, n'hésitez pas à le signaler dans les commentaires de cet article !
V. Conclusion
Nous avons dans cet article fait le tour de la question concernant la présence de mots de passe dans l'attribut "description" des utilisateurs du domaine. Nous avons notamment vu pourquoi cette faiblesse pouvait être présente sur un domaine, comment elle pouvait être exploitée et corrigée. Également, nous avons vu que la détection de l'attaque en question n'est pas aisée, contrairement au contrôle de sa présence au sein de l'Active Directory. Cela va donc dans le sens d'un contrôle régulier de cet attribut et de la sensibilisation des administrateurs sur les bonnes pratiques de stockage des mots de passe.
N'hésitez pas à donner votre avis dans les commentaires ou sur notre Discord !
Bonjour,
Pour la gestion des mots de passe : LockPass est une solution (payante) certifié par l’ANSSI.