Inglorious Astar

Auditer les mots de passe de ses utilisateurs

Hackez vos mots de passe avant que ce soit un pirate qui le fasse

Public cible :
Sysadmin
-
Temps de lecture :
15
min

Dans votre domaine Windows, il y a des utilisateurs.
Parmi ces utilisateurs, il y a Fred qui vient de Toulouse et dont le mot de passe est "Toulouse31!" (on ne peut pas lui reprocher de ne pas respecter les critères de complexité : minuscules, majuscules, chiffres, ponctuation) ;
Il y a ext_technisave, le compte de votre infogérant, dont le mot de passe est TechniS@ve2018 ;
Il y a print_cantine, un compte de service qui existe depuis bien avant votre entrée dans la boite, dont le mot de passe est "cantine".

Peut être que vous vous êtes reconnus dans cette description ou peut être que vous avez pensé « Diable que sais-je des mots de passe de mes utilisateurs moi ? ».

En tant qu'admin système ou RSSI, vous savez ce que vous demandez à vos utilisateurs (mot de passe long, avec des majuscules, chiffres, ponctuation, etc.) mais vous ne savez pas comment ils le respectent. Cet angle mort de la sécurité est une vraie source de faiblesse, partagée par de nombreuses entreprises (on pourrait dire "toutes" sans faire une grosse erreur).

Pourquoi auditer les mots de passe ?

Si vous possédez un service avec authentification exposé sur Internet (Email, VPN, SSH, etc.) et que l'utilisateur test a le mot de passe test, vous risquez de vous retrouver avec du monde chez vous.
Un pirate pourrait aussi avoir obtenu un accès initial dans votre réseau (pièce jointe malveillante, F5 BigIP non à jour, etc.) et vouloir trouver le mot de passe Administrateur du domaine pour pouvoir aller faire le zouave sur tous les postes et serveurs. Donc si le mot de passe de cet Administrateur est bonjour, le réseau ne va pas passer des moments Nutella.

Mais il n'y a pas que l'Administrateur du domaine qui est concerné. Vous avez souvent d'autres comptes qui ont des droits d'administration : le compte de l'antivirus, le compte de l'outil de sauvegarde, etc. Il suffit qu'un seul d'entre eux ait un mot de passe trop prédictible (hum hum veeam:veeam) et c'est le drame.

Et, finalement, même les comptes qui n'ont pas de droits d'administration peuvent faire des choses intéressantes : accéder à des fichiers sensibles sur les partages ou même remplacer des fichiers par des malwares pour piéger d'autres utilisateurs, accéder à des outils internes (paye, dépot de code, ERP) et effacer/modifier leur contenu, ouvrir des sessions distantes sur d'autres machines pour y déposer des malware, etc.

Lors des audits de sécurité internes, c'est souvent la découverte d'un seul compte avec un mot de passe faible (le légendaire stagiaire:stagiaire) qui permet d'attraper un fil rouge dont le bout est la compromission de tout le réseau. Et inversement, il est très rare de tomber sur un réseau où il n'y a AUCUN mot de passe faible.
De ce fait, la plupart des audits internes se soldent par un élégant "RISQUE CRITIQUE" en première page.

Mais si les mots de passe des utilisateurs étaient régulièrement testés (et modifiés lorsqu'ils sont trop faibles), les intrusions se passeraient moins docilement pour les auditeurs et les pirates.
Nous recommandons, dans nos rapports d'audit, d'effectuer un test annuel de robustesse des mots de passe de l'AD.
Mais force est de constater que l'outillage à disposition des RSSI et Admins Systèmes, pour cette tâche, est famélique.
Qu'à ne cela tienne, nous en avons donc fait un !

Comment auditer les mots de passe

On distingue deux types d'attaques contre les mots de passe.

  • Les attaques en ligne où pour chaque essai d'un mot de passe le pirate doit envoyer une requête à votre serveur et attendre de savoir si sa tentative a abouti ou échoué. On peut raisonnablement estimer que 100-1000 essais par seconde est l'ordre de grandeur de cette attaque.
  • Les attaques hors ligne où le pirate possède un indice lui permettant de savoir si le mot de passe qu'il essaye est le bon ou non, sans avoir à interroger le serveur d'authentification (l'ordre de grandeur est alors d'environ 1 milliard d'essais par seconde).

Ce fameux indice, vous le savez peut être, est le résultat d'une fonction de hachage, appelé empreinte (ou hash en anglais). L'attaquant peut prendre plein de mots de passe possibles, les donner en entrée à cette fonction de hachage et si l'empreinte produite est identique à celle du bon mot de passe, c'est qu'il a trouvé le bon mot de passe.

Vous êtes peut être déjà familier des fonctions de hachage (MD5, SHA-1, SHA256, bcrypt, ...). Leur propriété fondamentale est d'être non-inversibles : si je vous donne une entrée, vous pouvez calculer son empreinte en quelques millisecondes, mais si je vous donne une empreinte, vous ne pouvez pas en déduire son entrée. L'empreinte 1817ac59c84467458e3f16fcbdd2ae28 ne laisse transparaître aucune indication sur ce qu'était son entrée. Mais c'est quand même un indice inestimable pour un pirate : pour chaque entrée qu'il soupçonne d'être la bonne, il peut en calculer l'empreinte en quelques millisecondes et voir si elle correspond à 1817ac59c84467458e3f16fcbdd2ae28.
C'est ainsi que fonctionnent les attaques hors ligne.

Active Directory ne stocke pas directement les mots de passe des utilisateurs, il en stocke les empreintes. Ainsi, si quelqu'un accède à sa base de données, les mots de passe des utilisateurs ne sont pas directement exposés (l'attaquant doit réussir une attaque hors ligne contre chacun d'eux). 
Mais stocker les empreintes permet quand même à l'AD de vérifier l'authentification d'un utilisateur. En effet, si l'utilisateur marcel est associé à l'empreinte ed417b63f16b1e6265a4ef92e78bbab2 dans la base de l'AD et qu'un utilisateur prétend s'authentifier sur le compte de marcel avec le mot de passe "brouette", l'AD a simplement à calculer l'empreinte de "brouette" (quelques ms) et à vérifier si elle correspond bien à ed417b63f16b1e6265a4ef92e78bbab2.
Dans un environnement Active Directory, il y a malheureusement de nombreuses actions où l'empreinte d'un mot de passe est exposée : obtention d'un ticket kerberos, accès à un partage distant, mise en cache des comptes sur une machine, ... C'est pour cela qu'on recommande de tester la robustesse des mots de passe utilisateurs face à une attaque hors ligne. D'une part cela respect le principe de Kerckhoffs en traitant le pire des cas. D'autre part, en ayant évalué la robustesse face à une attaque hors ligne, on peut en déduire celle face à une attaque en ligne (l'inverse n'est pas possible).

L'outil Lestat d'A*

Prérequis

Pour réaliser cet audit vous aurez besoin :

  • d'un compte administrateur du domaine
  • d'un poste Linux ou Windows avec python installé dessus et un accès Internet
  • d'installer les packages python impacket et ldapdomaindump et click (pip install ldapdomaindump impacket click)
  • de la suite Lestat

Récupérer la base des mots de passe

La première étape est de récupérer la base des hash des mots de passe de vos utilisateurs.

Pour faire simple, la base des utilisateurs de l'AD c'est la base des comptes locaux des contrôleurs du domaine. Cette base des comptes locaux, sous n'importe quel système Windows, est matérialisée par 3 fichiers sous C:\Windows\System32\config\ :

  • SAM
  • SYSTEM
  • SECURITY

Le hic est que leur accès est verrouillé pendant que le système est en fonctionnement.

Nous allons voir plusieurs alternatives pour les exporter.

Depuis les sauvegardes

Vos contrôleurs de domaine sont vraisemblablement sauvegardés (si ce n'est pas le cas vous êtes plutôt mal). Une solution simple est d'aller piocher ces 3 fichiers dans une sauvegarde via l'interface de votre outil. La plupart des grosses solutions commerciales (Veeam, ...) permettent d'explorer le système de fichiers des images de sauvegarde.
Par exemple, via la fonctionnalité qui permet de restaurer des fichiers spécifiques à l'endroit de votre choix. Vous pouvez ainsi restaurer la version la plus récente de ces 3 fichiers dans le répertoire personnel de votre utilisateur. Ces fichiers restaurés ne seront pas verrouillés par le système.
C'est la meilleure solution car elle ne risque pas d'être bloquée par votre EDR ou votre antivirus.

Une fois les 3 fichiers récupérés, il faut en extraire la base des hash. L'outil python secretsdump de la suite impacket va nous le permettre simplement :

secretsdump.py LOCAL -sam SAM -security SECURITY -system SYSTEM -outputfile hashes.txt

Via le Volume Shadow Copy

Volume Shadow Copy Service (VSS) est une fonctionnalité intégrée à Windows qui permet de restaurer votre système à un état antérieur.

L'utilitaire vssadmin permet d'utiliser ce service en ligne de commande.
Vous pouvez créer une shadow copy du disque C puis la monter comme un disque :

vssadmin create shadow /for=C:
mklink /d c:\shadowcopy \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy?\

Ensuite il ne vous reste qu'à vous rendre dans C:\shadowcopy\Windows\System32\config\ et à copier les 3 fichiers qui nous intéressent.

Le désavantage de cette solution est qu'elle fait souvent sonner les EDR/AV. Donc vous ne pourrez peut être pas l'utiliser.

Si vous avez réussi de cette manière, il faut également en extraire la bse des hash :

secretsdump.py LOCAL -sam SAM -security SECURITY -system SYSTEM -outputfile hashes.txt

Vis un export du NTDS.dit

Le fichier NTDS.dit contient toute la base de l'AD (notamment les utilisateurs). Il se trouve normalement sous C:\Windows\ntds\ntds.dit. Mais son accès est également protégé.

Il existe une commande permettant de réaliser un export de ce fichier :

ntdsutil "ac i ntds" "ifm" "create full c:\copy-ntds" quit quit

Vous n'avez qu'à vous rendre dans le répertoire C:\copy-ntds et à récupérer les fichiers NTDS.dit et SYSTEM qui s'y trouvent.

Utilisez l'outil secretsdump pour extraire la base des hash de ces deux fichiers :

secretsdump.py LOCAL -ntds NTDS.dit -system SYSTEM -outputfile hashes.txt

Ici aussi l'opération peut être bloquée par un EDR/AV.

Via l'utilitaire secretsdump

L'outil secretsdump peut aussi être utilisé à distance (avec un compte admin du domaine) pour effectuer automatiquement les opérations de récupération :

secretsdump.py <DOMAIN>/<USER>@<DC_IP> p <PASSWORD> -outputfile hashes.txt

Ici aussi l'opération peut être bloquée par un EDR/AV.

Quelque soit la manière dont vous avez obtenu le fichier hashes.txt, pensez bien à supprimer complètement les fichiers intermédiaires que vous avez pu créer sur le DC. Ils contiennent des informations critiques et ne doivent donc pas être exposés.

Récupérer la base des utilisateurs

Vous allez peut être vous dire que si on a les fichiers SAM, SYSTEM et SECURITY on a déjà tout ce qu'il nous faut niveau base des utilisateurs. Pas tout à fait. Ce qui va nous intéresser ce sont aussi les attributs de ces comptes dans Active Directory : est-ce qu'il sont désactivés, à quels groupes ils appartiennent, ...

Pour cela, il existe un outil qui produit un résultat très facilement exploitable : ldapdomaindump. C'est un outil python, qui peut donc être utilisé aussi bien sur Linux que sur Windows. Il s'utilise à l'aide d'un compte du domaine :

ldapdomaindump -u <DOMAIN>\\<USER> -p <PASSWORD> --no-html --no-json ldap://<DC_IP>:389

Il produira plusieurs fichiers décrivant la base Active Directory. Celui qui nous intéresse est domain_users.grep.

Cracker les hash

Bien, maintenant nous avons tout le nécessaire pour se lancer dans l'audit de la robustesse de ces hash.

Nous nous concentrerons sur les hash au format NTLM (abrégé NT). Mais il peut être pertinent de vérifier que vous n'avez pas des hash dans l'ancien format LM (LanMan), auquel cas tous les mots de passe de vos utilisateurs sont à risque, même ceux qui ont été choisis de manière sécurisée.
Pour le vérifier, vous pouvez ouvrir le fichier hashes.txt et regarder les lignes qui ont la forme : 
nom d'utilisateur (éventuellement précédé du nom du domaine) : un numéro d'utilisateur : une suite de 32 caractères hexadécimaux : une autre suite de 32 caractères hexadécimaux :::.
Par exemple :

mydomain\myuser:1530:aad3b435b51404eeaad3b435b51404ee:ad38316b9d8a9f6dd210d806d5877bcf:::

La première suite de 32 caractères hexadécimaux correspond aux hash LM et la seconde aux hash NT. La première doit toujours valoir aad3b435b51404eeaad3b435b51404ee qui correspond à un mot de passe vide. Si vous repérez une exception, ça signifie que le mot de passe est aussi stocké en version LanMan (ce qui est une vulnérabilité). Pour corriger le problème, suivez cette procédure.

La méthode simple et rapide

Il y a un moyen assez simple d'avoir une bonne idée de la robustesse générale des mots de passe, c'est de comparer les hash avec la base du site HIBP.
L'outil LennieTheLeaker.py de la suite Lestat va nous y aider. Pour chaque hash de notre base il va requêter l'API de HIPB et vérifier si le hash en question est compromis ou non.

L'avantage est que c'est très rapide (le plus long c'est de télécharger la base).
Le désavantage c'est que ça ne nous révélera pas les mots de passe : on saura seulement que le hash de tel utilisateur correspond à un mot de passe compromis, sans connaître ce mot de passe. Donc on ne pourra pas faire d'éducation ciblée en identifiant les motifs faibles que nos employés utilisent lorsqu'ils créent leur mot de passe.
Mais ça permet de répondre assez vite à la question : quelle proportion de mes comptes utilisateurs est exposée au password stuffing ?

La commande a exécuter est la suivante :

python LennieTheLeaker.py hashes.txt -w RESULT.txt

On peut s'inquiéter du fait de devoir communiquer nos hash au site HIPB. Après tout, je veux connaître mes mots de passe vulnérables mais je ne veux pas qu'un tiers (le site HIPB) les connaisse aussi.
Ils ont bien conçu leur API pour minimiser ce problème. En fait on ne va pas interroger l'API en lui demandant directement "est-ce que le hash a523a8c091767efbd9e83f72c389e7e5 est compromis ?", auquel cas on lui révèlerait toute notre base de hash. On va lui demander : "donne moi tous les hash compromis que tu connais qui commencent par a523a" et on va vérifier si le hash a523a8c091767efbd9e83e72c389e7e5 est présent dans la réponse. Donc HIPB sait que l'un de nos utilisateurs possède un hash qui commence par a523a mais il ingore la suite. Or comme il reste 27 caractères hexadécimaux à deviner, il lui faudrait en moyenne 162 000 000 000 000 000 000 000 000 000 000 essais pour trouver le bon. Et inversement, le fait d'avoir précisé les 5 premiers caractères nous évite de chercher dans toute la base de HIPB pour chaque requête, ce qui serait trop volumineux.
Néanmoins si vous ne voulez exposer aucune information, l'outil fournit un moyen de télécharger la base en local (attention c'est très long) :

python LennieTheLeaker.py hashes.txt -db HIPB.txt -w RESULT.txt
[*] Parsing hashes file ...
[+] Parsing completed. 381 users detected with 331 unique NTLM hashes
[*] Checking local HaveIBeenPwned database for leaked passwords ...
[!] "HIPB.txt" file does not exist. Would you like to download the HIBP database ? It takes a long time
[y/n] : y
[*] Downloading HIPB database ...
 [------------------------------------]    0%  1d 08:04:31

La méthode simple et bourrine

Une autre façon de faire (ou bien une façon complémentaire) est de simplement utiliser un outil de force brute pour tester tous les mots de passe possible (depuis le mot de passe "a" jusqu'au mot de passe "zzzzzzzzzzzzzzzzzzz").

Pour cela, vous pouvez utiliser l'outil john-the-ripper :

john --format=nt --fork=<nombre de CPU> hashes.txt

Je vous conseille de vous équiper d'une machine avec un minimum de puissance quand même (pour un octocore, mettez donc --fork=8).

L'idée est de laisser tourner l'outil pendant le plus de temps possible (3 jours par exemple). Quand vous estimez que l'effort est représentatif de ce que pourrait y passer un adversaire, vous coupez l'outil (CTRL+C) et vous générez un fichier de résultat :

john --format=nt --show hashes.txt > RESULT.txt

Vous pouvez utiliser un autre outil de craquage de mot de passe bien sûr (comme hashcat) tant qu'à la fin vous pouvez exporter son résultat dans un format où chaque ligne est de la forme user:password.

La méthode sioux

Les vrais pirates ne s'embêtent plus vraiment à faire de la force brute. Ils utilisent des dictionnaires (wordlist) de mots de passe probables :

  • Le top des mots de passe les plus courants
  • Les dérivés du nom de l'entreprise (Astar -> 4st4r, A$tar, Astar123!, ...)
  • Les dérivés du nom d'utilisateur (admin -> adm1n, Admin123!, ...)
  • Les prénoms communs (Nicolas, ...) et leurs dérivés (Nicol4s, Nicola$, NICO1997, ...)
  • Les lieux communs (Thailande, NewYork, ...) et leurs dérivés (Thailande2003, tHAILAND123, ...)
  • etc.

Vous pouvez utiliser l'outil MikeTheMangler de la suite Lestat pour générer des wordlist qui dérivent le nom de la société ou des utilisateurs. 
Par exemple, si vous êtes l'entreprise Airbus, vous pouvez générer des mots de passe probables basés sur des mots clés en les séparant par des virgules :

python MikeTheMangler.py --comb 1 Airbus,avion,A380
avion
Airbusavion
A380Airbus
A380
avionA380
A380avion
AirbusA380
avionAirbus
Airbus

Et vous pouvez y ajouter tout un tas de variations (majuscules, leet, ponctuation, nombres, ...) :

python MikeTheMangler.py --nick 0 --case 1 --leet 1 --num 1 --punc 1 --pref 0 --comb 1 Airbus,avion,A380
4irbus4vion2!
av1onA1rbus_0
a380airbus2
4vion01
Airbusavi0n_01
Airbu$_7
AirbusA380_0
a3802!
airbusavi0n2!
airbusa3802!
avi0nAirbus5
av!on1
airbusa3807
avionAirbu501!
A!rbus_7
avionairbus
avi0n7!
av1onA1rbus01!
...

N'hésitez pas à explorer les options avec python MikeTheMangler.py --help. Et notamment à utiliser les listes de prénoms et de lieux que nous avons construites.

Chaque fois que vous avez généré une liste, vous pouvez utiliser john-the-ripper pour voir si elle permet de craquer de nouveaux hash :

john --format=nt --wordlist=<MALISTE> hashes.txt

Et à la fin vous exportez la liste de tous les hash craqués, d'un seul coup :

john --format=nt --show hashes.txt > RESULT.txt
Idéalement, nous vous encourageons à d'abord appliquer la stratégie avec les wordlist, puis la force brute, puis enfin les mots de passe fuités.

Analyser les mots de passe craqués

Nous disposons maintenant d'un fichier RESULT.txt qui contient les mots de passe craqués et du fichier domain_users.grep.

C'est là que Lestat va enfin vous automatiser sérieusement les choses. Vous pouvez générer toute l'analyse avec la simple commande suivante :

python LesterTheLooter.py RESULT.txt domain_users.grep

Cela produit un fichier excel Lestat.xlsx avec 3 feuillets :

  • La liste des comptes craqués avec les groupes associés à chaque utilisateur, la capacité de filtrer les comptes désactivés, une estimation de la robustesse, ...
  • La liste des groupes compromis d'après les comptes craqués
  • Les statistiques de robustesse : pourcentage de comptes compromis, motifs les plus présents, ...

Il est également possible d'exporter en CSV ou juste sur la sortie standard.

Vue utilisateurs

Le premier feuillet du fichier excel liste les comptes craqués :

Pour chaque compte craqué, il est stipulé :

  • son nom
  • le mot de passe craqué
  • si le compte est désactivé ou non
  • la date de la dernière connexion
  • la date du dernier changement de mot de passe
  • le nombre de groupes auquel le compte appartient
  • la liste de ces groupes
  • si le compte est sensible ou non (surligné en rouge si c'est un admin du domaine ou équivalent et en orange s'il est suspecté d'être sensible)
  • le temps nécessaire pour craquer le mot de passe dans une attaque en ligne (environ 100 essais par seconde)
  • la raison de la faiblesse du mot de passe : dérivé du login, dérivé du nom de l'entreprise, leaké, présent dans la liste du top 1 million des mots de passe les plus courants, ...
  • la description du compte

PS : pour anticiper votre question, oui je me suis assuré que le blur était résistant aux outils d'IA permettant de déflouter

Vue groupes

Le deuxième feuillet liste les groupes compromis :

Pour chaque groupe il est stipulé :

  • son nom
  • le nombre de comptes compromis appartenant à ce groupe
  • la sensibilité du groupe (si c'est un groupe admin du domaine ou équivalent, il est surligné en rouge, s'il est suspecté d'être sensible, il est surligné en orange)
  • la résistance à une attaque en ligne (équivalent à la résistance la plus faible parmi les comptes compromis qui en font partie)
  • la liste des comptes actifs qui en font partie (s'il n'y a aucun compte actif, la ligne est grisée)
  • la liste des comptes désactivés qui en font partie

Vue stats

Le dernier feuillet fournit des statistiques brutes (cachées dans l'images ci-dessous) et des graphiques permettant d'identifier les pratiques à risque dans l'entreprise. 
Les statistiques portent sur deux groupes : celui de tous les comptes et celui des comptes activés seulement :

Les statistiques fournies comprennent :

  • La proportion de comptes craqués par rapport à la totalité des comptes
  • Le nombre de mots de passe uniques compromis (plusieurs utilisateurs peuvent avoir le même mot de passe)
  • Le nombre de comptes critiques (admin du domaine) et sensibles compromis
  • La répartition des mots de passe craqués par longueur
  • La répartition des mots de passe craqués par charset (minuscules, majuscules, chiffres, ponctuations)
  • Le top 10 des mots de passe les plus fréquents parmi ceux craqués
  • Le top 10 des motifs les plus fréquents parmi les mots de passe craqués (par exemple s'il y a les mots de passe Airbus!, Airbus123, Airbu$, ... le motif "airbus" sera détecté comme transverse à tous ceux là)
  • La répartition des mots de passe par résistance aux attaques en ligne (secondes, minutes, heures, jours, ...). Les mots de passe non craqués sont considérés comme ayant une résistance de l'ordre de l'année
  • La répartition des mots de passe craqués d'après la raison de leur faiblesse (dérivé du login, dérivé du nom de l'entreprise, commun, leaké, ...)

Ces éléments peuvent vous aider à identifier des mauvaises pratiques répandues chez les utilisateurs et à mieux cibler les campagne de sensibilisation/éducation.
Retrouvez nos recommandations sur les bonnes pratiques concernant les mots de passe (probablement pas tout à fait celles que vous auriez pensées).

L'outil évolue régulièrement et gagnera en simplicité avec le temps. N'hésitez pas à nous faire part de vos retours dessus : contact@astar.org.

David SORIA
-
2024-01-09

Nos autres articles