Reprenons l’échange NTLMSSP que nous avions décortiqué dans l’article sur la lecture d’un NTLMSSP dans Wireshark, et posons-lui une seule question: qu’est-ce qui, dans cette suite de trois messages, empêche un tiers de la rejouer ailleurs? Nous allons suivre le message de négociation jusqu’au Type 3, repérer le drapeau exact qui décide du sort d’un relais, et voir où la signature SMB, le MIC et la protection étendue viennent se placer dans la trame. Le but n’est pas de relayer quoi que ce soit mais de comprendre, au niveau du champ, pourquoi certaines sessions tiennent et d’autres non.
Le relais NTLM, pour rappel, c’est l’attaquant qui se place au milieu. Il prend les messages NTLM que la victime lui envoie et les repousse tels quels vers une cible, en se faisant passer pour elle, sans jamais avoir besoin de son mot de passe. Toute la défense consiste à lier ces messages à quelque chose que l’attaquant ne peut pas reproduire, et c’est ce lien que nous allons chercher champ par champ.
Le drapeau qui décide: NTLMSSP_NEGOTIATE_SIGN
Tout se joue très tôt, dans le message de négociation (Type 1) et dans la réponse du serveur. Les deux parties s’y annoncent une liste de capacités sous forme de bits dans un champ NegotiateFlags. Nous allons nous arrêter sur un seul de ces bits.
Dirk-jan Mollema l’a très bien expliqué: la différence entre l’authentification NTLM en SMB et en HTTP tient aux drapeaux négociés par défaut
, et le drapeau problématique est NTLMSSP_NEGOTIATE_SIGN (0x00000010), documenté dans la section 2.2.2.5 de MS-NLMP
. SMB le positionne par défaut, HTTP non. Quand ce bit est présent et honoré, les deux parties dérivent une clé de session et signent les messages qui suivent. L’attaquant qui relaie n’a jamais eu cette clé, donc toute opération signée qu’il envoie est rejetée et la session s’effondre dès la première.
D’où la question évidente, et c’est là que l’ancienne faiblesse apparaît: ce champ de drapeaux n’est pas lui-même protégé dans les versions anciennes du protocole. Rien n’empêchait, historiquement, de retirer le bit de signature en transit. L’attaquant intercepte, efface NEGOTIATE_SIGN, et la session relayée se retrouve non signée alors que la victime croyait signer. Ce procédé a un nom, « drop the MIC », et nous allons voir comment les protections suivantes le ferment.
Nous retrouvons ces valeurs dans [MS-NLMP] et dans n’importe quel décodeur:
| Drapeau | Valeur | Rôle |
|---|---|---|
| NTLMSSP_NEGOTIATE_SIGN | 0x00000010 | Demande la capacité de signature (clé de session dérivée) |
| NTLMSSP_NEGOTIATE_SEAL | 0x00000020 | Demande le chiffrement |
| NTLMSSP_NEGOTIATE_ALWAYS_SIGN | 0x00008000 | Signature « dummy » même sans clé négociée |
Attention: ALWAYS_SIGN n’est pas SIGN. Le premier impose la présence d’un bloc de signature sur tous les messages, le second déclenche réellement la négociation de la clé qui sert à signer. C’est le second qui gêne un relais.
MIC et channel binding: lier les trois messages, lier le canal
La parade à « drop the MIC » se trouve dans le Type 3, enfoui dans la réponse NTLMv2 qui est elle-même scellée par le mot de passe de la victime. Deux structures y vivent, dans la liste d’AV_PAIR.
Nous commençons par MsvAvFlags (AvId 0x0006). Quand son bit 0x00000002 est positionné, [MS-NLMP] indique que le client fournit un MIC dans le message d’authentification. Le MIC est un HMAC-MD5 calculé sur la concaténation des trois messages NTLM (Négociation, Challenge, Authentification) avec la clé de session exportée. Comme la victime a annoncé, dans une partie signée par son mot de passe, qu’elle a bien joint un MIC, l’attaquant ne peut plus retirer ce MIC ni retoucher les drapeaux sans que la cible s’en aperçoive. Les trois messages sont soudés ensemble.
La seconde est MsvAvChannelBindings (AvId 0x000A). Elle contient un haché MD5 de 16 octets de la structure de channel bindings; une valeur toute à zéro signale l’absence de binding. Pour un service TLS, cette structure transporte le haché du certificat d’extrémité du serveur, au sens de la RFC 5929 (tls-server-end-point). C’est le cœur de la protection étendue pour l’authentification, l’EPA. Un serveur HTTPS qui exige l’EPA compare le haché présenté à celui de son propre certificat et rejette l’authentification s’ils diffèrent. L’authentification NTLM est alors collée au canal TLS que le client voit. Si l’attaquant termine le TLS de son côté puis relaie vers une autre cible, les certificats ne correspondent pas, et l’authentification tombe.
Ce qu’on voit dans Wireshark, session signée contre non signée
Sur une maquette à deux serveurs (domaine test.local, srv01 et srv02), la différence se lit directement dans la négociation SMB2. Nous filtrons sur smb2 et nous ouvrons le Negotiate Protocol Response du serveur. Le champ Security mode porte deux bits:
Security mode: 0x03
.... ...1 = Signing enabled: True
.... ..1. = Signing required: TrueQuand Signing required vaut True, le serveur refuse toute session non signée. La victime et la cible dérivent une clé de session à partir de la clé de session NTLM, et chaque message SMB2 suivant porte une signature dans son en-tête (champ Signature de 16 octets, non nul). L’attaquant qui relaie n’a jamais eu la clé: il ne peut pas produire cette signature, la cible rejette la première requête utile avec STATUS_ACCESS_DENIED.
Si nous refaisons la capture sur une session non signée, nous voyons le champ Signature rester à zéro et le Security mode ne montre que Signing enabled. C’est là, et seulement là, qu’un relais SMB « classique » aboutit. Sur un contrôleur de domaine, la question ne se pose pas: la signature y est exigée par défaut, comme sur les clients Windows 11 24H2.
Pour les mêmes raisons détaillées dans l’article NTLMSSP, pensez à décocher la validation de signature dans Wireshark si vous voulez inspecter le contenu sans que l’analyseur ne marque les paquets en erreur.
Comment un attaquant obtient l’authentification, et jusqu’où ça va
Un relais ne sert à rien sans une authentification entrante. L’attaquant la provoque, et c’est tout le rôle des techniques de coercition que nous allons regarder maintenant. PetitPotam abuse l’interface MS-EFSRPC (Encrypting File System Remote Protocol) pour forcer une machine à s’authentifier vers un hôte choisi; Coercer, de p0dalirius, regroupe plusieurs interfaces (MS-RPRN le « PrinterBug », MS-EFSRPC, MS-DFSNM, MS-FSRVP, etc…) dans un seul outil qui commence par énumérer ce qui répond sur la cible avant de déclencher. La mécanique est documentée, elle vise un pipe nommé, et la machine ciblée part s’authentifier là où l’UNC pointe.
Une fois l’authentification coercée captée, le rayon d’impact dépend de ce vers quoi on peut la pousser. Relayée vers LDAP, elle permet d’écrire des attributs (délégation, RBCD). Relayée vers AD CS en HTTP (le scénario ESC8), elle obtient un certificat au nom du compte machine, et un certificat ne se révoque pas d’un claquement de doigts. Relayée vers SMB sur un serveur sans signature, elle exécute dans le contexte du compte relayé. L’attaquant repart avec une session déjà authentifiée, qui ressemble trait pour trait à une connexion légitime, et par certains côtés c’est pire qu’un mot de passe volé.
C’est ce qui rend la détection difficile. Un relais réussi n’a rien d’une anomalie évidente: une session SMB s’ouvre, un compte machine se connecte quelque part, tout cela arrive tous les jours. Nous devons chercher le signal ailleurs. Un chercheur le résume bien: voir le service EFS passer à l’état « running » (event 7036 du gestionnaire de services) puis, dans la seconde, des connexions entrantes vers le pipe \PIPE\efsrpc depuis une source inhabituelle, voilà un signal combiné solide. Du côté partage, l’event 5145 journalise l’accès réseau aux pipes lsarpc ou efsrpc. Et un décalage entre le nom de poste annoncé dans le Type 3 et l’adresse source réelle de la connexion trahit souvent une authentification qui ne vient pas d’où elle prétend.
Durcir, et une nuance récente qui remet la signature sur la table
Nous pouvons déduire les parades de ce que nous avons vu dans la trame. Exiger la signature SMB côté serveur (Signing required, pas seulement enabled) ferme le relais SMB non signé. Exiger l’EPA sur les services TLS (AD CS en premier, les endpoints LDAPS, Exchange) lie l’authentification au canal. Réduire la surface de coercition en filtrant les interfaces RPC avec netsh rpc filter, et en bloquant l’EFSRPC là où il n’a rien à faire. Et plus en amont, retirer NTLM là où Kerberos suffit.
Nous devons encore parler de la réflexion. CVE-2025-33073, la « Reflective Kerberos Relay Attack » découverte par RedTeam Pentesting, a montré qu’une machine pouvait être coercée à s’authentifier contre elle-même et finir en NT AUTHORITY\SYSTEM, sur tout hôte de domaine qui n’exige pas la signature SMB. Microsoft l’a corrigée au Patch Tuesday du 10 juin 2025. La leçon de fond restait: la signature SMB reste le mur.
Et puis ce mur a pris une fissure. Oui, il semble qu’il y ait une technique en ce moment qui permette de faire du relais même si le Signing est activé. Je renvoie au write-up de Lydéric Lefebvre sur blackfield.ch et à son PoC reauthx, un fork de krbrelayx avec un seul drapeau en plus, --reauth-bypass. L’idée tient en une phrase, et elle est gênante: quand une session SMB se ré-authentifie, le serveur réutilise la première clé de signature et ne vérifie pas que le nouvel utilisateur correspond à l’ancien. La session relayée peut alors être signée avec une clé que l’attaquant contrôle, bien qu’il n’ait jamais connu la clé de l’identité relayée. L’auteur le dit lui-même sans emphase: contourner la signature ne compromet rien à lui seul, la signature SMB reste nécessaire, mais elle ne suffit plus contre ce détournement sur les hôtes qui n’imposent pas une identité cohérente à la ré-authentification. Je pense que c’est la nuance à garder en tête, plus que le nom du PoC. Les contributions associées rattachent le comportement à la ré-utilisation de clé de session à travers une ré-authentification cross-user (MS-SMB2 3.3.5.5.2), avec un correctif côté éditeur. À l’heure où j’écris ces lignes, le sujet est récent et bouge vite: vérifiez l’état de patch de vos hôtes plutôt que de vous fier au seul « signing: True » d’un scan.
De notre côté, la liste ne change pas: appliquez les mises à jour, exigez la signature, exigez l’EPA, coupez les vecteurs de coercition. Le « signing enforced » n’est plus une case qui, cochée, clôt le dossier à elle seule, mais le laisser décoché revient toujours à laisser la porte grande ouverte.
Rémi Vernier
Responsable des opérations cybersécurité dans un grand groupe international. Identité, Active Directory, Entra ID, cloud hybride, et désormais SAP, IA et modèles en local.