Ce qu'est réellement un hash NTLM
NTLM est le MD4 d'un mot de passe en UTF-16LE : non salé, rapide, équivalent au mot de passe. Différence avec NetNTLMv2, où il réside, et le rôle de la taille.
Le mot « NTLM » est collé sur trois choses différentes qui ne se comportent pas du tout pareil, et la confusion bloque les gens pendant des heures. Fixons d'abord ce qu'est le hash lui-même.
NTLM est le MD4 du mot de passe, point
Un hash NTLM se calcule en prenant le mot de passe de l'utilisateur, en l'encodant en UTF-16 little-endian, puis en le passant une fois dans MD4. C'est tout l'algorithme. Pas de sel. Pas de nombre d'itérations. Pas de facteur de travail. La sortie fait 32 caractères hexadécimaux.
Relisez, car toutes les conséquences en découlent. Pas de sel, donc deux utilisateurs avec le même mot de passe ont le hash identique, et les consultations précalculées fonctionnent. Pas d'itération, donc c'est foudroyant de rapidité sur GPU, comparable au débit du MD5 brut, des dizaines de milliards par seconde. Et il est calculé directement depuis le mot de passe sans rien d'autre mélangé, ce qui le rend équivalent au mot de passe : posséder le hash vaut opérationnellement posséder le mot de passe pour l'authentification Windows. Cette dernière propriété est la plus importante, et nous y reviendrons.
NetNTLMv1/v2 est une tout autre chose
Voici le piège. NetNTLMv1 et NetNTLMv2 ne sont pas le hash stocké. Ce sont des blobs d'authentification défi-réponse échangés sur le réseau pendant une négociation SMB ou HTTP. Le serveur envoie un défi, le client le combine avec une fonction à clé du hash NTLM, et la réponse repart. Ce que vous capturez sur le fil avec Responder ou un relais SMB, c'est cette réponse, pas le hash NTLM lui-même.
Les différences pratiques sont totales. Un blob NetNTLMv2 inclut un défi serveur, un défi client et des horodatages, donc il est long et clairement pas en 32 hexa. Vous ne pouvez pas faire de pass-the-hash avec un NetNTLMv2 capturé ; vous pouvez seulement tenter de le casser hors ligne pour récupérer le mot de passe, puis l'utiliser. Le casser est aussi plus lent à cause de la construction à clé. Les gens disent sans cesse « j'ai dumpé des hash NTLM » alors qu'ils ont capturé des réponses NetNTLMv2, puis s'étonnent que -m 1000 rejette l'entrée. Format différent, mode différent, attaque différente.
Le hash NTLM stocké est -m 1000. NetNTLMv2 est -m 5600. NetNTLMv1 est -m 5500. Ne les mélangez pas.
Où résident les hash NTLM stockés
Sur un poste Windows autonome, les hash NTLM se trouvent dans la ruche SAM, protégée par le SYSKEY/bootkey. Sur un contrôleur de domaine, ils résident dans NTDS.dit, la base Active Directory, une entrée par compte de domaine. Et à l'exécution, on peut les extraire de la mémoire du processus LSASS, ce que visent les outils comme Mimikatz et la famille sekurlsa.
Chaque emplacement implique un accès différent. SAM signifie admin local sur un poste. NTDS.dit signifie compromission d'un contrôleur de domaine ou un droit DCSync. LSASS signifie exécution de code en tant que SYSTEM sur un hôte vivant. Savoir de quelle source vient un hash vous dit comment il a été obtenu et ce que vous pouvez en faire ensuite.
Une chaîne de 32 hexa ne dit rien à elle seule
NTLM fait 32 caractères hexadécimaux. MD5 aussi. Le MD4 de n'importe quoi aussi. Impossible de les distinguer à l'œil. C'est le cas typique où la détection de format par la forme échoue et où il faut désambiguïser par la source.
Si la valeur sort de secretsdump.py contre un DC, ou d'un dump LSASS, c'est du NTLM et vous le cassez avec -m 1000. Si elle sort d'une colonne de base de données d'une appli web, c'est bien plus probablement du MD5 en -m 0. Mêmes 32 caractères, mode différent, et donner du NTLM à -m 0 ne cassera tout simplement rien. Dans le doute, suivez comment trouver le bon mode hashcat et appuyez-vous sur la provenance plutôt que sur l'apparence.
Pass-the-hash : pourquoi le hash est le trophée
Parce que NTLM est équivalent au mot de passe, vous n'avez souvent pas besoin de le casser du tout. Le protocole d'authentification NTLM prouve la connaissance du hash, pas du clair, donc vous pouvez vous authentifier en présentant directement le hash. C'est le pass-the-hash, et c'est pourquoi un hash NTLM extrait est un identifiant à part entière. Ne le cassez que si vous voulez le clair pour le réutiliser ailleurs ou étayer un argumentaire sur la complexité des mots de passe dans le rapport.
LM, le fantôme hérité
Les systèmes anciens stockaient aussi un hash LM à côté du NTLM. LM est encore plus faible : il met le mot de passe en majuscules, le complète à 14 caractères, le coupe en deux moitiés de 7 octets et chiffre chacune en DES indépendamment. Ces deux moitiés se cassent quasi instantanément avec -m 3000, et récupérer les deux donne le mot de passe en majuscules, d'où la vraie casse n'est qu'un petit saut. LM devrait être désactivé partout désormais, mais NoLMHash n'est pas universellement positionné sur les parcs hérités, donc on en trouve encore. Si vous voyez une moitié aad3b435... dans un dump, c'est la sentinelle de LM vide indiquant que le stockage LM était désactivé pour ce compte.
Ce que les défenseurs doivent faire
Vous ne pouvez pas saler NTLM ni le ralentir. Le protocole est ce qu'il est, et Microsoft ne fait que commencer à le retirer. Tout le fardeau défensif retombe donc sur la longueur du mot de passe. Non salé plus rapide signifie qu'un mot de passe faible est récupéré en quelques secondes et qu'un mot de passe réutilisé casse tous les comptes qui le partagent. Un mot de passe de 9 caractères est perdu ; une longue phrase de passe pousse la force brute hors de portée, même aux vitesses GPU de NTLM.
Imposez de longs minimums, tuez le stockage LM avec NoLMHash, protégez LSASS avec Credential Guard, surveillez les DCSync, et avancez vers Kerberos et la dépréciation de NTLM là où votre parc le permet. Le hash lui-même ne sera jamais solide. Votre seul levier est de rendre l'entrée trop grande pour être devinée.