Pass-the-Hash : s'authentifier avec un hash NTLM jamais cassé
Pourquoi un hash NTLM équivaut au mot de passe, comment fonctionne le pass-the-hash avec Impacket, NetExec et Mimikatz, et les contrôles qui stoppent le mouvement latéral.
La première fois que le pass-the-hash fait tilt, ça ressemble à de la triche. Vous avez extrait un hash d'une machine, vous ne l'avez jamais cassé, et pourtant vous exécutez maintenant des commandes en tant que cet utilisateur sur une autre machine. Aucun clair nulle part dans la chaîne.
Ça marche à cause de ce qu'un hash NTLM est réellement dans le protocole. L'authentification NTLM n'envoie jamais le mot de passe. Le client prouve qu'il connaît le mot de passe en effectuant un calcul défi-réponse clavé sur le hash NT. Le hash est le secret qui intéresse le protocole. Donc si vous détenez le hash, vous pouvez terminer la poignée de main. Le clair n'a aucune importance pour NTLM. Toute l'attaque tient en une phrase : pour l'authentification NTLM, le hash équivaut au mot de passe.
Le faire
Sur une machine d'attaque Linux, Impacket est la voie habituelle. Les outils d'exécution acceptent un flag -hashes sous la forme LMHASH:NTHASH :
psexec.py -hashes aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0 administrator@10.0.0.20
wmiexec.py -hashes :31d6cfe0d16ae931b73c59d7e0c089c0 contoso.local/administrator@10.0.0.20
Ce aad3b435b51404eeaad3b435b51404ee n'est pas le hash LM de l'utilisateur. C'est le hash LM vide, la valeur que LM produit pour un mot de passe nul. Windows moderne ne stocke aucun hash LM, donc les outils se contentent de poser ce remplissage devant les deux-points. Vous pouvez en général passer :NTHASH avec une moitié LM vide, comme le montre la seconde commande.
Pour pulvériser un hash sur tout un sous-réseau, CrackMapExec ou son successeur maintenu NetExec le fait à grande échelle :
nxc smb 10.0.0.0/24 -u administrator -H 31d6cfe0d16ae931b73c59d7e0c089c0
Chaque hôte qui renvoie Pwn3d! est une machine où ce hash est admin local. Sur Windows, Mimikatz le fait en mémoire avec sekurlsa::pth, qui lance un processus dont l'identifiant NTLM est le hash que vous fournissez. Exécutez-le et le nouveau shell s'authentifie sous cette identité auprès de tout ce que NTLM acceptera.
Pourquoi un seul hash se propage aussi loin
La raison pour laquelle le pass-the-hash transforme une seule machine compromise en problème à l'échelle du domaine, c'est le compte administrateur local. Pendant des années, le standard de déploiement était une image golden unique avec un seul mot de passe d'admin local intégré, clonée sur chaque poste. Même mot de passe, même hash NT, sur un millier de machines.
Donc vous éclatez un portable, vous extrayez la SAM locale, vous attrapez le hash NT de l'admin local, et vous possédez désormais toutes les machines bâties à partir de cette image. Vous n'avez jamais touché un contrôleur de domaine et vous n'avez rien cassé. NetExec se contente de parcourir le sous-réseau. C'est la façon de loin la plus courante dont une mission passe d'un seul hôte à "on a tout" en un après-midi.
Quand il faut quand même le casser
Le pass-the-hash n'est pas un passe-partout universel. Il ne marche que là où l'authentification NTLM est acceptée, et il existe de vrais cas où il vous faut le clair malgré tout.
Les services Kerberos uniquement ne prendront pas le hash directement. Soit vous basculez vers l'overpass-the-hash (forger un ticket Kerberos à partir du hash NT), soit vous cassez le mot de passe et vous vous authentifiez normalement.
Les EDR signalent de plus en plus l'outillage classique de pass-the-hash. Le motif d'injection de processus de sekurlsa::pth et le comportement à base de tubes nommés de psexec.py sont bien signaturés. Parfois une connexion discrète avec un vrai mot de passe vaut mieux qu'un hash-pass bruyant qui vous fait isoler.
Et le gros morceau : la réutilisation des mots de passe. Un clair cassé est portable d'une manière qu'un hash n'est pas. Si Sql_Svc!2021 sort d'un hash, vous pouvez l'essayer contre des VPN, des applis web, des tenants cloud, du SSH, dont aucun ne parle NTLM. Donc vous passez quand même les hashs NT dans le mode hashcat 1000 quand vous voulez une portée au-delà de NTLM, même si vous n'avez pas besoin de les casser pour bouger latéralement dans le domaine.
Côté défenseur
La partie inconfortable, c'est qu'on ne peut pas patcher le pass-the-hash pour le faire disparaître. C'est NTLM qui fonctionne comme prévu. Ce que vous pouvez faire, c'est réduire le rayon d'explosion.
Cessez de réutiliser le mot de passe de l'admin local. Microsoft LAPS (ou Windows LAPS) rend aléatoire le mot de passe d'admin local par machine et le fait tourner, donc un hash extrait d'une machine ne vaut rien sur la suivante. Ce seul contrôle casse le chemin de propagation le plus courant.
Mettez vos comptes à forte valeur dans le groupe Protected Users. Ses membres ne peuvent pas utiliser l'authentification NTLM du tout, ce qui veut dire que leurs hashs ne peuvent pas être passés même s'ils fuient.
Désactivez NTLM là où vous le pouvez. Auditer d'abord avec les stratégies Restrict NTLM vous dit ce qui casserait, puis vous resserrez. L'élimination totale est difficile dans un parc plein d'applis héritées, mais chaque service que vous basculez vers Kerberos est un endroit de moins où un hash fonctionne.
Et restreignez qui est admin local et où. Si l'administrateur de domaine ne se connecte jamais sur un poste, ses identifiants ne séjournent jamais dans la mémoire de ce poste pour y être extraits en premier lieu. Mettre en place un modèle administratif en niveaux (tiering) est le correctif structurel ; LAPS et Protected Users sont les contrôles qui vous achètent du temps en attendant d'y arriver.