NTLM est un des protocoles utilisés dans les mécanismes d'authentification des environnements Windows. Il est encore très présent malgré le fait que Microsoft essaye de le pousser vers la sortie au profit de Kerberos.
En effet, de nombreuses vulnérabilités sont présentes au sein de ce protocole. Nous allons nous intéresser dans cet article à celles de sa première version : NTLMv1.
Les attaques décrites dans cette série d'articles seront effectuées dans un environnement à jour, avec tous les patches de sécurité installés sur les clients comme sur les serveurs/contrôleurs de domaine (au 13/06/2025, date d'écriture de cet article). Nous partirons, bien sûr, du principe que les administrateurs ont activé les réponses NTLMv1 sur les contrôleurs de domaine puisque c'est le sujet de l'article (notre expérience en pentest interne nous montre que ça n'est pas si rare que ça pourrait en avoir l'air).
Nous commencerons par une rapide explication du fonctionnement du protocole.
Ensuite, nous aborderons le sujet du relais NTLM, puis nous continuerons avec les différences entre les versions 1 et 2 du protocole.
Dans l'article suivant, nous mettrons en place une série d'attaques permises par la version 1 du protocole.
Enfin, dans le dernier article, nous parlerons des remédiations et de comment limiter l'impact de leurs mises en place.
Le protocole NTLM
Qu'est-ce que NTLM
Dans un environnement Active Directory NTLM peut être utilisé pour la phase d'authentification pour de nombreux protocoles. On le retrouve le plus souvent lors de l'utilisation de LDAP, SMB ou encore HTTP.
L'authentification via le protocole NTLM est relativement simple à expliquer puisqu’elle se limite à 3 requêtes :
NEGOCIATE
C'est la première requête. Le client demande à s'authentifier auprès du serveur. Il lui fournit son nom d'utilisateur.
CHALLENGE
La réponse du serveur à NEGOCIATE. Celui-ci génère et fournit dans la requête, une chaine de 16 caractères hexadécimaux appelés "challenge".
AUTHENTICATE
Dernière requête. Le client calcule la réponse NTLM en utilisant le challenge envoyé par le serveur et un dérivé du mot de passe de l'utilisateur (son secret).
Des schémas expliquant le mécanisme d'authentification du protocole NTLM sont disponibles à peu près partout sur internet mais pour une question de droit d'auteur, nous allons en utiliser un nouveau qui ressemblera à tous les autres :

Pour résumer rapidement, voici comment tout ça fonctionne :
• NEGOCIATE : demande d'authentification du client
• CHALLENGE : réponse du serveur avec le challenge
• AUTHENTICATE : calcul et envoi de la réponse NTLM
Validation
Le serveur doit maintenant vérifier que la réponse apportée par le client est correcte et si c'est le cas, il accepte l'authentification. Pour ça il doit être en possession du challenge utilisé ainsi que du secret du client.
Pour le challenge c'est facile, c'est lui qui l'a généré. Pour le secret, il existe deux possibilités :
Le serveur connait le secret :
C'est le cas pour une authentification avec un utilisateur local au serveur ou vers un contrôleur de domaine.
Le serveur est en mesure de calculer lui-même la réponse NTLM (secret + challenge). Il la compare alors avec celle envoyée par le client, si elles sont identiques : bravo, l'utilisateur a prouvé qu'il était en procession de son secret, il peut s'authentifier. Sinon, l'authentification est refusée.

Le serveur NE connait PAS le secret:
Dans ce cas, si nous sommes dans unenvironnement Active Directory, le serveur va demander à quelqu'un qui connaitle secret de l'utilisateur de valider l'authentification : un contrôleur dedomaine (DC).
Le serveur va donc envoyer au contrôleur de domaine le challenge qu'il avait généré pour le client, le nom de l'utilisateur qui essaye de s'authentifier ainsi que la réponse NTLM que ce dernier a apportée. Cette étape constitue la requête NETLOGON.
Avec ces informations, le contrôleur de domaine est en mesure de calculer la réponse NTLM et ainsi de vérifier la validité de celle renvoyée par le client. Il répondra finalement au serveur en l'informant de la réussite ou nom de l'authentification.
On va reprendre le schéma précédent en y ajoutant ces nouvelles étapes pour que ça soit plus clair :

Les explications ci-dessus sont en fait un résumé de ce qui se passe lors de l'authentification. Un excellent article en langue française, écrit par Pixis explique en détail le fonctionnement de NTLM. On vous le conseille, c'est très bien expliqué.
Le relais NTLM
La grande majorité des attaques liées à NTLM nécessitent que l'attaquant relaie des requêtes d'authentification. Nous allons voir ici pourquoi et comment ça marche.
Théorie
Si l'attaquant est en mesure de recevoir une requête NEGOCIATE émise depuis un véritable client (par exemple en se positionnant en man-in-the-middle), il lui sera possible de relayer cette requête vers la machine de son choix afin de s'authentifier au nom du client légitime.
Pour résumer, l'attaquant joue simplement le rôle de passe-plat jusqu'à la fin de l'authentification.

Petite explication :
1. Le client envoie la requête NEGOCIATE vers l'attaquant qui la transmet telle quelle au serveur ciblé. L'authentification est initiée.
2. Le serveur génère et envoie le challenge à la machine de l'attaquant qui le relai vers le client légitime.
3. Le client calcule la réponse NTLM à l'aide du mot de passe de son utilisateur et une nouvelle fois, l'envoie vers l'attaquant qui transmet au serveur.
4. Le serveur valide l'authentification qui, de son point de vue, provient de l'attaquant.
5. L'attaquant est maintenant authentifié auprès du serveur en tant que l'utilisateur du client.
Tout au long des échanges, l'attaquant joue donc le rôle de serveur (du point de vue du client) et de client (du point de vue du serveur cible).
Si par exemple il s'agissait d'une authentification permettant l'accès au serveur via SMB, l'attaquant serait alors en mesure de parcourir les répertoires lisibles par l'utilisateur légitime dont il a usurpé la connexion.
Enfin c'est le cas uniquement si la signature des échanges n'a pas été négociée ...
Signature
Qu'est-ce que c'est
La signature des échanges est un mécanisme de sécurité qui peut être négocié entre le client et le serveur pendant l'authentification. Son rôle est d'assurer aux deux parties que chacune d'entre elles est bien qui elle prétend être.
Elle s'applique sur la session, c'est-à-dire sur tous les échanges qui ont lieu après l'authentification (par exemple lors du listage ou du parcours des répertoires d'un partage SMB).
Si la signature a été négociée, chaque requête de la session devra contenir une signature qui est dérivée du secret de l'utilisateur et du contenu de ladite requête. La signature ne peut donc être valide que si l'émetteur de la requête connait le secret de l'utilisateur.
De ce fait, même si un attaquant a réussi la phase d'authentification grâce à une attaque par relai, il ne sera pas en mesure de signer les messages de la session. Le serveur rejettera donc la suite de la communication.
Négociation
Suivant les protocoles utilisés, la signature peut se négocier de différente façon. Sans entrer dans les détails, il faut retenir qu'il s'agit d'un drapeau défini, ou non, par les deux parties.
Si tout le monde est d'accord, on signe. Dans les faits c'est un peu plus complexe puisque suivant la valeur des différents drapeaux, la signature peut être obligatoire ("require") ou optionnelle ("enable").
Dans le cas où elle est obligatoire, si une des deux parties n'est pas en mesure de signer, alors la communication ne se poursuit pas.
Si elle est optionnelle, on continue sans signature.
Le drapeau définissant si la signature a été négociée est Negociate Always Signing.

Retenez simplement que si signature il y a, les attaques se basant sur le relai deviennent impossibles.
Altération
Comme nous l'avons vu, toutes les requêtes de la phase d'authentification passent par l'attaquant.
Si on ajoute à cela le fait que la négociation de la mise en place de la signature se fait justement pendant cette phase, alors pourquoi ne pas simplement altérer les requêtes pour négocier le fait de ne PAS signer la session?
Et bien c'est possible, du moins dans certains cas.
Si aucune des deux parties ne requiert la négociation (celle-ci est donc optionnelle), alors on va pouvoir changer les drapeaux pour signifier au client et au serveur qu'on ne souhaite pas signer la session qui suit.
Nous en reparlerons dans le chapitre suivant.
Les deux versions de NTLM
Le protocole NTLM connait actuellement deux versions. La version 2 apporte son lot de sécurités, notamment dans le contenu de la requête AUTHENTICATE. Nous allons en décrire quelques-unes dans les lignes qui suivent.
Dans ce chapitre, on va un peu parler de cryptographie (sans entrer dans les détails). Retenez simplement ce qu'est un hash NT : il s'agit du hash MD4 du mot de passe de l'utilisateur. Pour simplifier, c'est un dérivé de son mot de passe.
Calcul de la réponse NTLM - mécanisme de chiffrement
Comme décrit plus haut, le hash NT de l'utilisateur est utilisé dans le mécanisme de calcul de la réponse au challenge, envoyé par le serveur (AUTHENTICATE). Sans trop entrer dans les détails, voici les différences notables qu'il existe dans ce calcul pour les deux versions de NTLM.
En version 1, la réponse au challenge est calculée en utilisant un chiffrement de type DES (Data Encryption Standard). DES est un algorithme de chiffrement par bloc, dont la faiblesse et la facilité de cassage sont maintenant reconnues.
Ainsi, le Hash NT est utilisé comme clé pour chiffrer le challenge, via l'algorithme DES :

Voici concrètement à quoi ça ressemble dans la requête AUTHENTICATE :

DES étant un algorithme très faible, la récupération du mot de passe de l'utilisateur par le cassage de la réponse est tout à fait envisageable, mais nous y reviendrons dans l’article sur les attaques.
La version 2 utilise quant à elle un algorithme de type HMAC basé sur MD5, qui présente une sécurité bien plus robuste face aux tentatives de cassage par brute force.
Il reste cependant possible de mettre en œuvre des attaques de cassage par dictionnaires, mais cela demandera beaucoup plus de temps qu'avec la version 1.
Voici comment est calculée la réponse pour NTLMv2:

Ce qui, une fois les variables remplacées, donne :

Alors comme ça, c'est sûr, on n’y comprend pas forcément grand-chose mais on peut déjà remarquer une plus grande complexité dans ce calcul que dans celui de la version 1, via l'utilisation de plus de paramètres (on y reviendra plus tard) et surtout la présence de plusieurs fois l'utilisation de HMAC.
Le contenu d'AUTHENTICATE pour la version 2 :

On remarque que bien plus de données sont disponibles dans cette réponse que dans celle présentée plus haut. On va s'y intéresser, c'est la suite de cet article.
Le détail des calculs présentés ici est disponible dans la documentation Microsoft pour NTLM v1 et NTLM v2
Note : nous ne nous sommes intéressés ici qu'à l'utilisation de hash NT. Un hash LM peut également être utilisé mais cette pratique est plus que déconseillée puisque les mécanismes de chiffrement en jeu sont, dans ce cas, encore plus faible. Il devient plus que trivial de casser les mots de passe lors de son utilisation.
Contenu de la réponse
Nous avons pu voir précédemment que le contenu des réponses NTLM n'est pas du tout le même suivant la version du protocole.
Pour NTLMv1, c'est facile, c'est juste le résultat d'un chiffrement DES. Les données présentes dans la réponse NTLMv2 sont bien plus intéressantes car elles ajoutent quelques mécanismes de sécurité.
Reprenons le contenu de la requête AUTHENTICATE en version 2 :

On remarque toute une série d'attributs qui n'étaient pas présents dans la réponse NTLMv1. Il s'agit des AV Pairs (Attribut/Value Pairs).
Ils contiennent des informations permettant de sécuriser et d'identifier la requête (noms DNS/NETBIOS du serveur cible et de son domaine). Nous verrons par la suite pourquoi ils sont importants.
Message Integrity Code (MIC)
Une des sécurités mises en place sur le protocole NTLM est l'ajout d'un contrôle d'intégrité sur la requête AUTHENTICATE.
Sa fonction est de vérifier que le contenu de cette requête n'a pas été modifié. Ce rôle est rempli par le MIC.
Comme pour la signature, un drapeau indique s'il doit être utilisé. Il s'agit de "Negociate Sign" (oui, ça ressemble au drapeau gérant la signature de session mais ça n'est pas le même).

Le MIC est calculé en reprenant, entre autre, le contenu de la réponse NTLM.

Reprenons l'attaque par relai vue plus haut.
On a dit qu'il était possible d'altérer les requêtes du processus d'authentification en changeant les drapeaux négociant la signature, pour désactiver cette dernière.
Cette technique devient impossible si le MIC est en place puisque si nous changeons le contenu de la réponse (en modifiant un drapeau), alors la valeur du MIC ne correspondra plus à celle indiquée dans la requête.
Mais qu'est-ce qui nous empêche de changer la valeur du MIC?
Pour NTLMv2, ça n'est pas possible.
Pour le comprendre, on va entrer plus en détail dans le calcul du MIC.
Comme indiqué précédemment, le calcul du MIC prend en compte le contenu de la réponse NTLM et en particulier le NTProof.
Petit rappel :

On remarque qu'il est calculé, entre autres à partir du Hash NT du secret de l'utilisateur, que nous ne possédons pas. Il n'est donc pas possible de fournir un MIC correct. Le serveur rejettera l'authentification.
Et si on changeait la valeur des drapeaux pour faire croire au serveur que le client ne veut pas utiliser le MIC?
Toujours à cause du contenu de la réponse, en NTLMv2 ça n'est pas possible.
Vous vous rappelez des AV PAIRS? L'un d'entre eux, nommé sobrement "Flags", indique si le MIC a été négocié. S'il est défini à 2, alors le MIC est utilisé.

Cette valeur est contenue dans le calcul du MIC puisqu’intégrée à la réponse NTLMv2. Impossible donc de la modifier sans altérer le MIC.
En NTLMv1, par contre, aucune indication de ce type n'est présente dans la réponse puisqu'on a vu qu'il s'agit uniquement du chiffrement du challenge du serveur, avec le hash NT de l'utilisateur.
Rien ne nous empêche donc de changer les drapeaux et retirer le MIC de la réponse AUTHENTICATE. Sans MIC, on est également en mesure de modifier arbitrairement toute la requête et, par exemple, retirer la négociation de la signature.
Ainsi, en NTLMv1, si aucune des deux parties n'oblige l'utilisation de la signature, les attaques par relais aboutiront.
Gardez en tête que, à l'exception des contrôleurs de domaine, le comportement par défaut des machines Windows (serveurs ou non) est de proposer la signature sans l'obliger. On commence donc à comprendre pourquoi NTLMv1 est si dangereux.
On va maintenant pouvoir passer de la théorie à la pratique et se convaincre définitivement que l'utilisation de NTLMv1 dans un système d'information devrait être prohibée.
Accrochez-vous, le FUN commence dans le prochain article
Bibliographie et sources :
• https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-nlmp/c0250a97-2940-40c7-82fb-20d208c71e96
• https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-nlmp/5e550938-91d4-459f-b67d-75d70009e3f3
• https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-nlmp/83f5e789-660d-4781-8491-5f8c6641f75e
• https://beta.hackndo.com/ntlm-relay/
• https://medium.com/@petergombos/lm-ntlm-net-ntlmv2-oh-my-a9b235c58ed4
• https://www.calcomsoftware.com/why-ntlmv1-will-always-be-vulnerable-to-ntlm-relay-attacks/
• https://securityboulevard.com/2022/08/ntlmv1-vs-ntlmv2-digging-into-an-ntlm-downgrade-attack/