DEV Community

Cover image for Durcir un Active Directory de A à Z : construire, attaquer, défendre, auditer
Hadi Mouter
Hadi Mouter

Posted on

Durcir un Active Directory de A à Z : construire, attaquer, défendre, auditer

Cet article retrace un cycle complet de durcissement Active Directory, monté de bout en bout sur un lab Azure. On construit l'infrastructure, on applique le tiering, on durcit par GPO, on audite avec PingCastle, puis on remédie. La différence avec un guide classique : pour chaque mesure défensive, je montre d'abord l'attaque qu'elle bloque. Si vous administrez un AD et que vous voulez comprendre pourquoi on durcit, pas seulement quoi cocher, c'est pour vous.

Pourquoi cet article

Active Directory est la cible numéro un en environnement Windows. Une fois le domaine compromis, c'est toute l'organisation qui tombe. Pourtant la plupart des guides de durcissement se contentent d'une liste : désactivez SMBv1, activez LSA Protection, forcez NTLMv2. On exécute, on coche, mais on ne comprend pas ce qu'on bloque.

Le souci, c'est qu'on durcit à l'aveugle. On ne sait pas distinguer la mesure critique de la mesure cosmétique, ni défendre un arbitrage quand la production impose une contrainte. Tant qu'on ignore quelle attaque une mesure neutralise, on ne sait ni la prioriser ni l'expliquer.

J'ai pris le problème dans l'autre sens. Pour chaque protection, je commence par l'attaque : ce que fait vraiment un adversaire, et comment la mesure le bloque. C'est de mon avis la seule façon de durcir intelligemment.

Le tout est démontré sur un lab réel, avec les preuves à chaque étape. Pas "la mesure est censée marcher", mais "voici l'output qui montre qu'elle marche".

Le terrain : un lab volontairement minimal

Le lab tient sur trois machines hébergées sur Azure, organisées selon les trois niveaux du modèle de tiering Microsoft.

Tier Machine Rôle IP privée
Tier 0 DC01 Contrôleur de domaine lab.local (AD DS + DNS) 172.16.0.4
Tier 1 SRV01 Serveur membre 172.16.0.5
Tier 2 WS01 Poste de travail (Windows 11) dynamique

Le groupe de ressources Azure avec les 3 machines du lab

Soyons honnêtes tout de suite : ce lab n'est pas une architecture de production. C'est un environnement d'apprentissage minimal, fait pour démontrer les mécanismes. Les écarts assumés avec une vraie prod :

  • Un seul contrôleur de domaine. En prod, jamais moins de deux, sinon le domaine s'arrête quand le DC tombe. Ici, un seul, pour limiter le coût.
  • Pas de bastion ni de poste d'administration dédié (PAW). L'accès admin passe par du RDP filtré sur IP, là où une prod imposerait un point d'entrée séparé.
  • Pas de vraie segmentation réseau entre les tiers.

Pourquoi le dire ? Parce que savoir nommer ces écarts fait partie du métier. Un audit signalera "un seul DC" comme un risque, et la bonne réponse n'est pas de paniquer mais de documenter un risque accepté en connaissance de cause. On y revient plus bas.

Le tiering : la fondation de tout le reste

Avant de durcir quoi que ce soit, il faut comprendre comment un attaquant remonte dans un AD. Sans ça, le durcissement n'est qu'un tas de réglages sans logique.

Le chemin d'escalade

Voici le scénario classique, étape par étape.

D'abord, un attaquant compromet un poste de travail par hameçonnage. C'est la machine la plus exposée, celle d'un employé lambda. À ce stade il a les identifiants de l'employé, rien de plus. Peu de dégâts.

Plus tard, un administrateur se connecte sur ce poste pour le dépanner. S'il le fait avec un compte à hauts privilèges, ses identifiants restent en mémoire sur la machine, dans le processus LSASS.

L'attaquant, toujours présent sur le poste, lit cette mémoire (un dump LSASS, typiquement avec mimikatz) et récupère les identifiants de l'admin. Si c'était un compte du domaine, c'est terminé : il contrôle l'AD entier.

Le point à retenir : l'attaquant n'a pas besoin que l'admin soit connecté en permanence. Il suffit qu'un compte à privilège se soit connecté une seule fois sur la machine compromise.

La parade : segmenter par niveau

Le tiering répond exactement à ce chemin. Il sépare comptes et machines en trois niveaux de sensibilité, avec une règle stricte : un compte d'un tier ne doit jamais pouvoir s'authentifier sur une machine d'un autre tier.

Concrètement, le compte qui administre le contrôleur de domaine (Tier 0) ne doit jamais ouvrir de session sur un poste de travail (Tier 2). Comme ça, même si ce poste est compromis, aucun identifiant Tier 0 ne s'y trouve jamais. Le chemin d'escalade est coupé.

Mise en œuvre : OU, groupes, GPO

La structure repose sur des unités d'organisation (OU) qui matérialisent les tiers.

lab.local
├── OU=Admins
│     ├── OU=Tier0   → compte adm-t0, groupe T0-Admins
│     ├── OU=Tier1   → compte adm-t1, groupe T1-Admins
│     └── OU=Tier2   → compte adm-t2, groupe T2-Admins
├── OU=Servers       → SRV01
├── OU=Workstations  → WS01
└── Domain Controllers (OU par défaut) → DC01
Enter fullscreen mode Exit fullscreen mode

L'arborescence des OU dans Active Directory Users and Computers

Première bonne pratique : on cible des groupes, pas des comptes individuels. Les règles s'appliquent à T1-Admins, pas à adm-t1. Demain un nouvel admin serveur rejoint le groupe, et toutes les règles s'appliquent à lui automatiquement.

New-ADGroup -Name "T0-Admins" -GroupScope Global -Path "OU=Tier0,OU=Admins,DC=lab,DC=local"
New-ADGroup -Name "T1-Admins" -GroupScope Global -Path "OU=Tier1,OU=Admins,DC=lab,DC=local"
New-ADGroup -Name "T2-Admins" -GroupScope Global -Path "OU=Tier2,OU=Admins,DC=lab,DC=local"

Add-ADGroupMember -Identity "T0-Admins" -Members "adm-t0"
Add-ADGroupMember -Identity "T1-Admins" -Members "adm-t1"
Add-ADGroupMember -Identity "T2-Admins" -Members "adm-t2"
Enter fullscreen mode Exit fullscreen mode

Les trois groupes de tier peuplés (Get-ADGroupMember)

Un piège qui en piège beaucoup : quand une machine rejoint le domaine, elle atterrit par défaut dans le conteneur CN=Computers, sur lequel on ne peut pas lier de GPO. La première chose à faire après un join, c'est donc de la déplacer dans la bonne OU.

Move-ADObject -Identity "CN=SRV01,CN=Computers,DC=lab,DC=local" `
              -TargetPath "OU=Servers,DC=lab,DC=local"
Enter fullscreen mode Exit fullscreen mode

Sans ce déplacement, vos GPO de tiering ne s'appliqueront jamais. Elles cibleront une OU vide.

Imposer le tiering techniquement

Le tiering devient réel grâce aux logon rights, des droits de connexion qu'on pilote par GPO. On crée une GPO par OU, qui interdit aux comptes du mauvais tier de se connecter.

GPO Liée à l'OU Comptes refusés (Deny log on locally + RDS)
Tier0-Deny-LowerTiers Domain Controllers T1-Admins, T2-Admins
Tier1-Deny-OtherTiers Servers T0-Admins, T2-Admins
Tier2-Deny-OtherTiers Workstations T0-Admins, T1-Admins

Le chemin dans l'éditeur de GPO :

Computer Configuration
└─ Policies > Windows Settings > Security Settings
   └─ Local Policies > User Rights Assignment
      ├─ Deny log on locally
      └─ Deny log on through Remote Desktop Services
Enter fullscreen mode Exit fullscreen mode

La GPO Tier0 refusant T1 et T2 sur le contrôleur de domaine

Règle de sécurité non négociable : ne mettez jamais dans le deny le compte que vous utilisez pour administrer, ni le tier légitime de la machine. Sinon vous vous verrouillez hors de votre propre infra. Gardez toujours une session admin ouverte et testez après chaque GPO. Jamais de modification en masse.

La preuve que ça marche

On tente une connexion RDP sur le contrôleur de domaine avec un compte Tier 2 (adm-t2). Résultat :

Error 0x2407 : connexion refusée par le tiering

L'erreur 0x2407 ("You might not have permission to sign in remotely") est la preuve visuelle. Détail important : le mot de passe a été accepté, l'authentification a réussi, mais la session est refusée par la GPO. Ce n'est pas un message "identifiants incorrects", qui voudrait dire mauvais mot de passe.

En clair : si un attaquant vole les identifiants adm-t2 sur un poste compromis, ils sont inutilisables pour atteindre le contrôleur de domaine. Le chemin d'escalade est coupé techniquement, pas par une consigne qu'on espère respectée.

Le durcissement : chaque défense face à son attaque

Le tiering protège qui peut se connecter où. Le durcissement, lui, désactive les protocoles et configurations faibles qui servent de vecteurs d'attaque. Voici le tableau central, chaque mesure reliée à l'offensive qu'elle bloque.

Mesure Réglage Attaque neutralisée
LSA Protection RunAsPPL = 1 Dump LSASS
WDigest off UseLogonCredential = 0 Mots de passe en clair en mémoire
SMBv1 off SMB1 = 0 EternalBlue, propagation latérale
SMB signing "Digitally sign communications (always)" NTLM relay
LLMNR off "Turn off multicast name resolution" Responder / poisoning
NTLM hardening NTLMv2 only, refuse LM & NTLM Pass-the-hash, cracking offline
No LM hash "Do not store LAN Manager hash" Cracking offline

Le combo anti-LSASS

Les deux premières lignes méritent qu'on s'y arrête, parce qu'elles forment le cœur de la défense contre le vol d'identifiants.

LSASS est le processus Windows qui garde les identifiants en mémoire. C'est lui que vise un dump : on lit sa mémoire pour en sortir hash et mots de passe. Deux mesures le verrouillent.

LSA Protection (RunAsPPL = 1) transforme LSASS en processus protégé. Le système refuse alors qu'un autre processus lise sa mémoire, même en administrateur. Le dump échoue.

WDigest off (UseLogonCredential = 0) empêche le stockage des mots de passe en clair en mémoire. Une précision qui compte : sur Windows Server 2016 et plus récent, ce réglage est déjà à 0 par défaut. On ne referme donc pas un trou ouvert, on épingle le réglage pour qu'un attaquant ne puisse pas le réactiver. Repasser UseLogonCredential à 1 est une technique de persistance connue, qui rendrait à nouveau les mots de passe lisibles en clair après un dump. C'est de la défense en profondeur et de l'anti-tampering, pas une correction de défaut.

L'un rend la mémoire illisible, l'autre garantit qu'on ne pourra pas y réintroduire de mot de passe en clair. Ensemble ils ferment la porte au scénario d'escalade vu plus haut.

Ces réglages se poussent par GPO via les préférences de registre.

L'entrée registre RunAsPPL dans la GPO LSA Protection

Côté méthode : on empile toutes les GPO de durcissement, puis on fait un seul redémarrage à la fin. On ne redémarre pas un contrôleur de domaine à chaque mesure, parce que pendant son reboot l'authentification de tout le domaine est coupée.

La preuve que LSA Protection est actif

Poser la clé ne suffit pas. LSA Protection ne s'active qu'au démarrage suivant, quand LSASS se lance en mode protégé. On vérifie donc que c'est vraiment effectif, pas seulement configuré.

Get-WinEvent -LogName System |
  Where-Object {$_.Message -like "*LSASS*protected*"} |
  Select -First 1 TimeCreated, Message
Enter fullscreen mode Exit fullscreen mode

Event système : LSASS started as a protected process, level 4

Le message "LSASS.exe was started as a protected process with level: 4" confirme. À partir de là, un dump LSASS sur cette machine se heurte au processus protégé et échoue.

Couper les protocoles faibles

Les autres mesures suivent la même logique.

SMBv1 est un protocole obsolète, vecteur d'EternalBlue (le mécanisme de propagation de WannaCry). Aucune raison de le garder.

SMB signing signe les paquets SMB, ce qui casse le NTLM relay : un paquet d'authentification falsifié est rejeté.

LLMNR est un protocole de résolution de noms de secours qu'un outil comme Responder exploite pour usurper des réponses et capturer des hash. On le coupe, en gardant en tête que LLMNR n'est qu'une partie du problème. NBT-NS et mDNS sont d'autres vecteurs de Responder, à traiter séparément.

Le durcissement NTLM force NTLMv2 et refuse LM/NTLMv1. Ces vieux protocoles produisent des empreintes cassables hors ligne en quelques minutes, et ouvrent la voie au pass-the-hash.

Le niveau d'authentification LAN Manager forcé en NTLMv2 only

Une prudence pour la prod : couper NTLM totalement peut casser des applications anciennes. L'approche raisonnable, c'est de durcir (NTLMv2 seulement) sans tout casser, puis de mener un projet séparé d'audit avant un éventuel blocage complet.

L'audit : mesurer avec PingCastle

Une fois le durcissement en place, comment savoir où on en est ? PingCastle est un outil d'audit AD gratuit, devenu un standard. Il scanne le domaine et sort un score de risque sur quatre axes, avec un rapport HTML détaillé.

.\PingCastle.exe --healthcheck --server lab.local
Enter fullscreen mode Exit fullscreen mode

Lire le score correctement

Voici le résultat initial sur le lab.

Le rapport PingCastle : score global 55/100

Le point le plus important pour interpréter PingCastle : le score global est le pire des quatre axes, pas leur moyenne.

Axe Score
Stale Objects 15
Privileged Accounts 40
Trusts 0
Anomalies 55
GLOBAL 55

Ici, le 55 vient entièrement de l'axe Anomalies. Pour faire baisser le global, c'est donc cet axe qu'il faut attaquer en premier. Optimiser un autre axe ne changerait rien au global tant qu'Anomalies reste à 55.

La liste des findings PingCastle déclenchés

Un point qui rassure

Avant même la remédiation, regardez ce que PingCastle ne signale pas : aucun finding SMBv1, aucun sur le dump LSASS, aucun NTLMv1. Pourquoi ? Parce que ces points ont été corrigés avant l'audit, pendant la phase de durcissement. L'audit confirme le travail déjà fait.

La remédiation : corriger n'est pas tout corriger

C'est là qu'on sépare l'amateur du pro. Un rapport PingCastle brut fait peur, tout semble rouge. Le réflexe du débutant, c'est de vouloir tout corriger. C'est une erreur.

Un rapport d'audit n'est pas une liste de cases à cocher en entier. C'est une base de priorisation. On trie les findings en trois catégories.

Catégorie 1 : les vraies failles, corrigées

Cinq findings exploitables, corrigés en priorité.

Finding Action Attaque visée
A-DC-Spooler Désactiver le service Print Spooler sur le DC PrintNightmare, coercition
A-RootDseAnonBinding Bloquer le LDAP anonyme Reconnaissance non authentifiée
A-AuditDC / A-AuditPowershell Audit avancé + journalisation PowerShell Aucune détection sans logs
A-MinPwdLen Longueur minimale de mot de passe = 14 Force brute, devinette
S-AesNotEnabled Forcer Kerberos AES (RC4 off) Kerberoasting

Le service Spooler sur un contrôleur de domaine est un vecteur connu (PrintNightmare, et certaines techniques de coercition d'authentification). Un DC n'imprime rien, on coupe.

Stop-Service Spooler -Force
Set-Service Spooler -StartupType Disabled
Enter fullscreen mode Exit fullscreen mode

Le service Spooler passé à Stopped / Disabled

L'audit avancé mérite une insistance, parce qu'il fait le lien avec la détection, le travail d'un SOC. Sans politique d'audit, le domaine est aveugle : aucune trace d'un Kerberoasting, d'une connexion suspecte ou d'une commande PowerShell malveillante. On l'active par GPO, ce qui couvre tous les contrôleurs de domaine, au lieu d'une commande locale qui ne couvrirait qu'une machine.

La GPO d'audit avec les sous-catégories Kerberos et Logon activées

On ajoute la journalisation PowerShell (Module Logging et Script Block Logging), pour tracer l'exécution de scripts offensifs.

Catégorie 2 : les risques acceptés, documentés

Certains findings ne sont pas des failles à corriger, mais des choix assumés.

  • A-NotEnoughDC : un seul contrôleur de domaine. C'est notre décision de lab, pas une faille.
  • A-LAPS-Not-Installed : LAPS est un projet à part entière, hors périmètre.
  • S-DC-SubnetMissing, P-RecycleBin : cosmétique pour un environnement isolé.

En audit réel, on consigne ces findings comme risque accepté, avec leur justification. Le rôle de l'auditeur n'est pas de tout corriger aveuglément, mais de savoir quoi corriger et quoi assumer selon le contexte.

Catégorie 3 : les délais d'application

Une subtilité que beaucoup ignorent : certaines remédiations sont posées mais ne deviennent effectives qu'après un événement. Le finding S-AesNotEnabled en est l'exemple parfait. La GPO force AES, mais les clés AES des comptes ne se génèrent qu'au prochain changement de mot de passe. Juste après la GPO, PingCastle continue donc de remonter le finding. Ce n'est pas un échec, c'est un délai normal.

Le verdict : avant / après

On relance PingCastle après remédiation et on compare.

Le rapport PingCastle après remédiation : score 40/100

Axe Avant Après
Stale Objects 15 15
Privileged Accounts 40 40
Anomalies 55 35
GLOBAL 55 40

Le score global passe de 55 à 40, soit 15 points de moins, portés par une baisse de 20 points sur l'axe Anomalies, exactement l'axe prioritaire repéré au départ.

Et c'est là que le principe "le score est le pire des axes" se vérifie en direct. En faisant tomber Anomalies de 55 à 35, on a fait disparaître l'axe qui plafonnait le score. Mais un nouveau plafond apparaît tout seul : Privileged Accounts, resté à 40, est maintenant l'axe qui détermine le global. C'est donc lui la cible de la prochaine itération : nettoyer les délégations, les membres de Schema Admins, protéger les OU. La boucle se referme concrètement. On traite l'axe prioritaire, le plafond se déplace, on recommence.

La leçon centrale : la remédiation ne fait pas tomber le score à zéro, et c'est normal. Trois cas coexistent. Corrigé (Spooler, audit, longueur de mot de passe). Effectif après délai (AES attend un renouvellement de secret). Risque accepté documenté (un seul DC). Un audit se mesure à la baisse du score sur les axes prioritaires, pas à un 0/100 illusoire.

Les leçons à retenir

Au-delà des commandes, voilà ce qui se transpose à n'importe quel environnement.

Les bonnes pratiques :

  1. Cibler des groupes, jamais des comptes individuels. Une règle s'applique à un rôle, pas à une personne.
  2. Ranger les machines dans la bonne OU. Une GPO ne s'applique qu'à l'OU où elle est liée, et toute machine jointe atterrit d'abord dans Computers.
  3. Imposer les règles techniquement, pas par consigne. Une restriction dans une GPO est appliquée. Une règle écrite dans un document est ignorée.
  4. Garder une session admin ouverte et tester après chaque GPO. Le verrouillage accidentel est un vrai risque.
  5. Empiler les GPO, un seul redémarrage à la fin. On ne redémarre pas un DC à chaque mesure.
  6. Prouver l'effet par un output. Event "LSASS protected", auditpol /get, erreur 0x2407. Ne jamais supposer.
  7. Trier un rapport d'audit. Risque accepté documenté contre faille exploitable corrigée. Ne pas viser le 0/100.

Les mauvaises pratiques à éviter :

  • Réutiliser le même mot de passe partout. Un compromis, et tout tombe.
  • Connecter un compte à hauts privilèges sur une machine exposée. Les identifiants restent en mémoire, prêts à être dumpés.
  • Exposer le RDP directement sur Internet. On filtre par IP source, ou on passe par un bastion ou un VPN d'administration.

Conclusion

Durcir un Active Directory n'est pas une case à cocher, c'est un cycle. On construit, on durcit en pensant comme l'attaquant, on audite pour mesurer, on remédie en priorisant, puis on recommence. Le score ne descendra jamais à zéro, et ce n'est pas le but. L'objectif, c'est de fermer méthodiquement les chemins d'attaque les plus exploitables et de documenter en conscience ce qu'on accepte.

L'angle attaque/défense n'est pas un gadget. Quand on sait précisément quelle technique une mesure neutralise, on sait aussi la prioriser, la justifier et l'expliquer. C'est la différence entre appliquer une checklist et sécuriser vraiment son environnement.


Lab monté de bout en bout sur Azure. Tous les outils sont gratuits : Active Directory, la console de gestion des stratégies de groupe, et PingCastle en édition gratuite (usage non commercial). Les commandes sont reproductibles telles quelles.

Top comments (0)