Le durcissement de Windows Server 2025 constitue un impératif stratégique pour toute organisation qui déploie des infrastructures Microsoft en environnement de production. Avec l'augmentation de 38 % des attaques ciblant les serveurs Windows entre 2024 et 2026 selon le rapport Mandiant M-Trends, et les 847 CVE critiques publiées par Microsoft sur la seule année 2025, la surface d'attaque par défaut d'un serveur Windows fraîchement installé est considérable. Ce guide rouge de durcissement Windows Server 2025 est conçu comme une référence opérationnelle exhaustive destinée aux administrateurs système, ingénieurs sécurité, architectes infrastructure et consultants en cybersécurité. Il couvre l'intégralité du cycle de vie de la sécurisation : de l'installation sécurisée au monitoring avancé, en passant par le hardening Active Directory, la configuration granulaire des GPO, la sécurisation réseau, le patch management et l'audit de conformité. Chaque recommandation s'appuie sur les référentiels CIS Benchmark v3.0, les Microsoft Security Baselines et les guides ANSSI de durcissement Windows. Les commandes PowerShell et configurations de registre sont directement applicables en production. Ce document de plus de 20 000 mots représente l'état de l'art francophone du hardening Windows Server 2025, rédigé par Ayi NEDJIMI, consultant expert en cybersécurité offensive et défensive.
Pourquoi durcir Windows Server 2025 est devenu indispensable
La surface d'attaque par défaut d'un Windows Server
Un serveur Windows Server 2025 fraîchement installé avec l'expérience Desktop présente une surface d'attaque considérable. Par défaut, plus de 180 services Windows sont activés, dont beaucoup ne sont pas nécessaires au rôle assigné au serveur. Le pare-feu Windows autorise des flux entrants sur des protocoles historiquement vulnérables comme SMBv1, NetBIOS et LLMNR. Le compte Administrator local possède un mot de passe qui ne change jamais automatiquement, les politiques d'audit ne capturent qu'une fraction des événements de sécurité pertinents, et les protocoles d'authentification acceptent encore des algorithmes obsolètes comme NTLMv1 et RC4 pour Kerberos.
Selon le CIS Benchmark for Windows Server 2025 v3.0, un serveur non durci échoue à 73 % des contrôles de sécurité de niveau 1. Le rapport CIS Controls v8.1 identifie que 94 % des organisations qui subissent une compromission Active Directory ont au moins un contrôleur de domaine dont le durcissement est insuffisant. La base nationale de vulnérabilités (NVD) recense plus de 2 300 CVE affectant Windows Server entre 2020 et 2025, dont 412 classées critiques (CVSS 9.0+).
Statistiques de compromission et vecteurs d'attaque
Les données de terrain collectées par les équipes de réponse à incidents confirment l'urgence du durcissement. Le rapport Sophos Active Adversary 2025 révèle que le temps médian entre la compromission initiale et le déploiement d'un ransomware est passé de 5 jours en 2023 à 24 heures en 2025. Les vecteurs d'attaque les plus exploités sur Windows Server sont, par ordre de fréquence : l'exploitation de services exposés (RDP en tête avec 32 % des intrusions initiales), le mouvement latéral via PsExec/WMI (67 % des cas), l'élévation de privilèges par abus de SeImpersonatePrivilege (41 % des serveurs IIS compromis), et l'extraction de credentials via LSASS dumping (89 % des attaques post-compromission).
Le coût moyen d'une compromission de serveur Windows est estimé à 4,2 millions d'euros selon le rapport IBM Cost of a Data Breach 2025, incluant les coûts directs de remédiation, la perte d'exploitation et l'atteinte réputationnelle. Face à ces chiffres, le durcissement n'est plus une option mais une obligation réglementaire et opérationnelle.
Les référentiels de durcissement : CIS, Microsoft et ANSSI
Trois référentiels majeurs encadrent le durcissement de Windows Server 2025. Le CIS Benchmark propose deux niveaux de durcissement (L1 et L2) avec respectivement 287 et 412 contrôles. Les Microsoft Security Baselines, distribuées via le Security Compliance Toolkit (SCT), fournissent des GPO pré-configurées alignées sur les recommandations internes de Microsoft. L'ANSSI publie des guides de durcissement spécifiques au contexte français, intégrant les exigences de la LPM (Loi de Programmation Militaire) et du référentiel PSSIE. Ce guide synthétise et approfondit les trois référentiels pour fournir une couverture maximale.
Points essentiels :
- Un Windows Server 2025 non durci échoue à 73 % des contrôles CIS de niveau 1
- Le temps médian entre intrusion et ransomware est passé à 24 heures en 2025
- RDP représente 32 % des vecteurs d'intrusion initiale sur Windows Server
- Trois référentiels font autorité : CIS Benchmark, Microsoft Security Baselines, ANSSI
- Le coût moyen d'une compromission de serveur Windows atteint 4,2 M€
Installation sécurisée de Windows Server 2025
Server Core vs Desktop Experience : le choix stratégique
La première décision de sécurité intervient avant même le premier clic d'installation. Windows Server 2025 propose deux modes d'installation : Server Core et Desktop Experience. Du point de vue du durcissement, Server Core est systématiquement recommandé par les trois référentiels (CIS, Microsoft, ANSSI). La raison est quantifiable : Server Core réduit la surface d'attaque de 60 % par rapport à Desktop Experience. Il supprime l'explorateur Windows, Internet Explorer/Edge, les composants graphiques et des dizaines de DLL potentiellement exploitables. Le binaire est 4,7 Go plus léger, ce qui signifie autant de code en moins susceptible de contenir des vulnérabilités.
Server Core nécessite une administration exclusivement en ligne de commande (PowerShell, sconfig) ou via des outils distants (Windows Admin Center, RSAT, Server Manager distant). Cette contrainte est en réalité un avantage sécuritaire : elle force l'adoption de pratiques d'administration moderne et élimine le risque qu'un administrateur navigue sur Internet depuis un serveur de production.
# Vérifier le mode d'installation actuel
Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion" | Select-Object InstallationType
# Convertir Desktop Experience vers Server Core (Windows Server 2025)
Uninstall-WindowsFeature Server-Gui-Mgmt-Infra, Server-Gui-Shell -Restart
# Vérifier les composants installés
Get-WindowsFeature | Where-Object {$_.Installed -eq $true} | Sort-Object Name | Format-Table Name, DisplayName
Partitionnement sécurisé du disque
Le partitionnement doit séparer les données du système d'exploitation, des applications et des logs. Cette séparation limite l'impact d'une attaque par déni de service (remplissage disque) et facilite la sauvegarde granulaire. La configuration recommandée pour un contrôleur de domaine est la suivante :
# Partitionnement recommandé (exemple diskpart script)
# C: Système (80 Go minimum) — OS + Windows
# D: Applications (100 Go+) — NTDS.dit, SYSVOL si DC
# E: Logs (50 Go+) — Event Logs, logs applicatifs
# F: Temp/Pagefile (20 Go+) — fichier d'échange
# Déplacer le pagefile sur une partition dédiée
$sys = Get-WmiObject Win32_ComputerSystem
$sys.AutomaticManagedPagefile = $false
$sys.Put()
# Supprimer le pagefile du C:
$pagefileC = Get-WmiObject Win32_PageFileSetting | Where-Object {$_.Name -like "C:*"}
if ($pagefileC) { $pagefileC.Delete() }
# Créer le pagefile sur F:
Set-WmiInstance -Class Win32_PageFileSetting -Arguments @{Name="F:\pagefile.sys"; InitialSize=4096; MaximumSize=8192}
Suppression des rôles et fonctionnalités inutiles
Le principe du moindre privilège fonctionnel s'applique dès l'installation. Chaque rôle ou fonctionnalité installé augmente la surface d'attaque. Un serveur dédié au rôle de contrôleur de domaine n'a aucun besoin du serveur web IIS, du service d'impression ou du serveur de fichiers. La suppression doit être méthodique et documentée.
# Lister toutes les fonctionnalités installées
Get-WindowsFeature | Where-Object {$_.Installed} | Format-Table Name, DisplayName, FeatureType
# Supprimer les fonctionnalités inutiles sur un DC
$inutiles = @(
"Print-Services",
"Print-Server",
"Internet-Print-Client",
"Windows-Media-Player",
"XPS-Viewer",
"FS-SMB1",
"Telnet-Client",
"TFTP-Client",
"Simple-TCPIP",
"SNMP-Service",
"WoW64-Support"
)
foreach ($feature in $inutiles) {
$f = Get-WindowsFeature -Name $feature
if ($f.Installed) {
Write-Host "Suppression de $($f.DisplayName)..." -ForegroundColor Yellow
Uninstall-WindowsFeature -Name $feature -Remove
}
}
# Désactiver SMBv1 complètement
Set-SmbServerConfiguration -EnableSMB1Protocol $false -Force
Disable-WindowsOptionalFeature -Online -FeatureName SMB1Protocol -NoRestart
Configuration de Windows Update et WSUS
La configuration du mécanisme de mise à jour doit être réalisée dès l'installation. En environnement d'entreprise, les serveurs ne doivent jamais télécharger les mises à jour directement depuis Microsoft Update mais uniquement via un serveur WSUS (Windows Server Update Services) ou SCCM/Intune. Cette centralisation permet le test préalable des correctifs et garantit la traçabilité.
# Configurer WSUS via le registre
$WUPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate"
$AUPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU"
New-Item -Path $WUPath -Force | Out-Null
New-Item -Path $AUPath -Force | Out-Null
# Pointer vers le serveur WSUS interne
Set-ItemProperty -Path $WUPath -Name "WUServer" -Value "https://wsus.domaine.local:8531"
Set-ItemProperty -Path $WUPath -Name "WUStatusServer" -Value "https://wsus.domaine.local:8531"
# Activer la détection automatique mais pas l'installation automatique
Set-ItemProperty -Path $AUPath -Name "UseWUServer" -Value 1
Set-ItemProperty -Path $AUPath -Name "NoAutoUpdate" -Value 0
Set-ItemProperty -Path $AUPath -Name "AUOptions" -Value 3 # 3 = Télécharger mais ne pas installer
Set-ItemProperty -Path $AUPath -Name "ScheduledInstallDay" -Value 0
Set-ItemProperty -Path $AUPath -Name "ScheduledInstallTime" -Value 3 # 3h du matin
# Forcer la détection immédiate
wuauclt /detectnow
(New-Object -ComObject Microsoft.Update.AutoUpdate).DetectNow()
Installation sécurisée :
- Toujours privilégier Server Core : 60 % de surface d'attaque en moins
- Séparer les partitions : système, applications, logs, pagefile
- Supprimer SMBv1 et toute fonctionnalité non requise par le rôle du serveur
- Configurer WSUS dès l'installation — jamais de mise à jour directe depuis Internet
Sécurisation du BIOS/UEFI et du boot
Le durcissement d'un Windows Server 2025 commence en réalité avant le système d'exploitation, au niveau du firmware UEFI. Un attaquant disposant d'un accès physique au serveur (ou d'un accès distant à l'interface IPMI/iDRAC/iLO) peut modifier les paramètres UEFI pour désactiver Secure Boot, booter sur un support externe et extraire les données du disque, y compris NTDS.dit sur un contrôleur de domaine. Les mesures de durcissement UEFI doivent être appliquées systématiquement lors du déploiement initial.
# Vérifier que Secure Boot est activé
Confirm-SecureBootUEFI
# Retourne True si Secure Boot est actif
# Vérifier le mode de boot (UEFI vs Legacy BIOS)
$firmware = Get-ItemProperty "HKLM:\SYSTEM\CurrentControlSet\Control\SecureBoot\State" -ErrorAction SilentlyContinue
if ($firmware) {
Write-Host "Mode UEFI avec Secure Boot : $($firmware.UEFISecureBootEnabled)" -ForegroundColor Green
} else {
Write-Host "ALERTE : Secure Boot non détecté — vérifier la configuration UEFI" -ForegroundColor Red
}
# Vérifier le statut TPM (requis pour BitLocker, Credential Guard, Measured Boot)
$tpm = Get-Tpm
Write-Host "TPM Present: $($tpm.TpmPresent)"
Write-Host "TPM Ready: $($tpm.TpmReady)"
Write-Host "TPM Version: $((Get-CimInstance -Namespace "root\cimv2\security\microsofttpm" -ClassName Win32_Tpm).SpecVersion)"
# Vérifier les fonctionnalités de sécurité matérielle
Get-CimInstance -ClassName Win32_DeviceGuard -Namespace root\Microsoft\Windows\DeviceGuard |
Select-Object -Property AvailableSecurityProperties, RequiredSecurityProperties,
VirtualizationBasedSecurityStatus, SecurityServicesRunning |
Format-List
Au niveau du BIOS/UEFI, les paramètres suivants doivent être configurés manuellement (ou via les outils de gestion du constructeur comme Dell RACADM, HP iLO CLI ou Lenovo OneCLI) : activer Secure Boot en mode personnalisé avec les clés Microsoft et les clés propres à l'organisation, définir un mot de passe UEFI d'au moins 16 caractères stocké dans un coffre-fort numérique, désactiver le boot sur périphérique USB et sur le réseau (PXE) sauf nécessité de déploiement, activer le TPM 2.0 et le configurer en mode discret, activer Intel TXT (Trusted Execution Technology) ou AMD SEV (Secure Encrypted Virtualization) si disponible, et configurer le boot order pour n'autoriser que le disque système interne.
Configuration initiale post-installation
Immédiatement après l'installation de Windows Server 2025, un ensemble de configurations initiales doit être appliqué avant toute mise en réseau du serveur. Cette phase de golden image hardening est critique car elle définit la baseline de sécurité avant que le serveur ne soit exposé à un quelconque trafic réseau. L'idéal est de réaliser ces opérations sur un réseau isolé (VLAN de staging) ou en mode déconnecté.
# Script de configuration initiale post-installation
# À exécuter AVANT la jonction au domaine
# 1. Configurer le nom du serveur selon la convention de nommage
Rename-Computer -NewName "SRV-APP01-P" -Force # P=Production, D=Dev, T=Test
# 2. Configurer l'adresse IP statique (pas de DHCP pour les serveurs)
New-NetIPAddress -InterfaceAlias "Ethernet" -IPAddress "10.0.10.50" -PrefixLength 24 -DefaultGateway "10.0.10.1"
Set-DnsClientServerAddress -InterfaceAlias "Ethernet" -ServerAddresses "10.0.1.10","10.0.1.11"
# 3. Configurer le fuseau horaire (synchronisation NTP critique pour Kerberos)
Set-TimeZone -Id "Romance Standard Time"
w32tm /config /manualpeerlist:"ntp.domaine.local" /syncfromflags:MANUAL /reliable:YES /update
Restart-Service w32time
w32tm /resync /force
# 4. Désactiver IPv6 si non utilisé (réduit la surface d'attaque réseau)
# ATTENTION : Microsoft déconseille de désactiver IPv6 complètement
# Préférer la désactivation sur les interfaces non utilisées
Get-NetAdapterBinding -ComponentID ms_tcpip6 |
Where-Object {$_.InterfaceAlias -ne "Loopback"} |
Disable-NetAdapterBinding -ComponentID ms_tcpip6
# 5. Configurer la politique d'exécution PowerShell
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope LocalMachine -Force
# 6. Activer Windows Defender (si pas de solution EDR tierce)
Set-MpPreference -DisableRealtimeMonitoring $false
Set-MpPreference -MAPSReporting Advanced
Set-MpPreference -SubmitSamplesConsent SendAllSamples
Update-MpSignature
# 7. Configurer Windows Defender Exploit Protection
Set-ProcessMitigation -System -Enable DEP,BottomUp,SEHOP
Set-ProcessMitigation -Name "lsass.exe" -Enable DisableExtensionPoints,AuditDynamicCode
# 8. Désactiver les protocoles et services inutiles immédiatement
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Lsa" -Name "NoLMHash" -Value 1
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Lsa" -Name "LmCompatibilityLevel" -Value 5
La configuration du pare-feu Windows Defender doit être réalisée à ce stade, avant toute connectivité réseau. Le profil par défaut doit bloquer toutes les connexions entrantes, n'autorisant que les flux strictement nécessaires à l'administration initiale (RDP depuis une IP spécifique, ou WinRM en HTTPS). Cette approche deny-by-default garantit que le serveur n'est jamais exposé avec un pare-feu ouvert, même temporairement.
Hardening de Windows Defender et de la protection antimalware
Windows Server 2025 intègre Microsoft Defender Antivirus de manière native, avec des capacités significativement améliorées par rapport aux versions précédentes. Dans les environnements où une solution EDR (Endpoint Detection and Response) tierce est déployée (CrowdStrike Falcon, SentinelOne, Microsoft Defender for Endpoint), Windows Defender peut être configuré en mode passif. Cependant, dans tous les cas, les fonctionnalités de protection contre les exploits et la réduction de la surface d'attaque doivent être activées.
# Configurer Windows Defender — paramètres de durcissement avancés
# Activer la protection en temps réel
Set-MpPreference -DisableRealtimeMonitoring $false
# Activer la protection délivrée par le cloud (Cloud-Delivered Protection)
Set-MpPreference -MAPSReporting Advanced
Set-MpPreference -CloudBlockLevel High
Set-MpPreference -CloudExtendedTimeout 50
# Activer les Attack Surface Reduction (ASR) rules
# Chaque règle est identifiée par un GUID
$asrRules = @{
# Bloquer les processus non approuvés et non signés exécutés depuis USB
"b2b3f03d-6a65-4f7b-a9c7-1c7ef74a9ba4" = "Enabled"
# Bloquer le contenu exécutable des clients de messagerie et webmail
"be9ba2d9-53ea-4cdc-84e5-9b1eeee46550" = "Enabled"
# Bloquer toutes les applications Office de la création de processus enfants
"d4f940ab-401b-4efc-aadc-ad5f3c50688a" = "Enabled"
# Bloquer les appels d'API Win32 depuis les macros Office
"92e97fa1-2edf-4476-bdd6-9dd0b4dddc7b" = "Enabled"
# Bloquer le vol de credentials depuis LSASS (complément à Credential Guard)
"9e6c4e1f-7d60-472f-ba1a-a39ef669e4b2" = "Enabled"
# Bloquer les créations de processus provenant de commandes PSExec et WMI
"d1e49aac-8f56-4280-b9ba-993a6d77406c" = "Enabled"
# Bloquer JavaScript/VBScript pour lancer du contenu exécutable téléchargé
"d3e037e1-3eb8-44c8-a917-57927947596d" = "Enabled"
# Bloquer l'exécution de scripts potentiellement obfusqués
"5beb7efe-fd9a-4556-801d-275e5ffc04cc" = "Enabled"
# Bloquer les processus non approuvés et non signés injectant du code
"3b576869-a4ec-4529-8536-b80a7769e899" = "Enabled"
}
foreach ($rule in $asrRules.GetEnumerator()) {
Add-MpPreference -AttackSurfaceReductionRules_Ids $rule.Key -AttackSurfaceReductionRules_Actions $rule.Value
}
# Activer la protection réseau (bloquer les connexions vers des domaines malveillants)
Set-MpPreference -EnableNetworkProtection Enabled
# Configurer les exclusions (uniquement si nécessaire pour les performances)
# ATTENTION : chaque exclusion est un angle mort pour la détection
# Exclure uniquement les chemins strictement nécessaires (ex: SQL data files)
# Add-MpPreference -ExclusionPath "D:\SQLData"
# Vérifier la configuration
Get-MpPreference | Select-Object DisableRealtimeMonitoring, CloudBlockLevel,
MAPSReporting, EnableNetworkProtection, AttackSurfaceReductionRules_Ids
# Vérifier le statut de protection
Get-MpComputerStatus | Select-Object AntivirusEnabled, RealTimeProtectionEnabled,
AntivirusSignatureLastUpdated, BehaviorMonitorEnabled
Les règles ASR (Attack Surface Reduction) sont particulièrement importantes car elles bloquent des techniques d'attaque courantes au niveau du système d'exploitation, indépendamment de la détection par signature. La règle de protection LSASS (GUID 9e6c4e1f-7d60-472f-ba1a-a39ef669e4b2) est un complément essentiel à Credential Guard et RunAsPPL, ajoutant une couche de défense supplémentaire contre les outils de type Mimikatz.
Gestion des comptes et des identités
Sécurisation du compte Administrator local
Le compte Administrator local (RID 500) est la cible prioritaire de toute attaque post-exploitation. Par défaut, ce compte ne se verrouille jamais après des tentatives d'authentification échouées, son SID est prévisible et son mot de passe est souvent identique sur tous les serveurs d'un parc. Le durcissement de ce compte est la première étape de la gestion des identités.
# Renommer le compte Administrator
Rename-LocalUser -Name "Administrator" -NewName "svc_admin_$(Get-Random -Minimum 1000 -Maximum 9999)"
# Désactiver le compte Administrator si un autre compte admin existe
# ATTENTION : ne jamais désactiver sur un DC (compte AD Administrator)
Disable-LocalUser -Name "Administrator"
# Définir un mot de passe complexe de 25+ caractères
$password = ConvertTo-SecureString -String (([char[]]([char]33..[char]126) | Get-Random -Count 30) -join '') -AsPlainText -Force
Set-LocalUser -Name "Administrator" -Password $password
# Configurer une description trompeuse (deception)
Set-LocalUser -Name "Administrator" -Description "Service account - do not modify"
LAPS : gestion automatisée des mots de passe locaux
Windows LAPS (Local Administrator Password Solution) est natif dans Windows Server 2025. Il résout le problème fondamental des mots de passe administrateur local identiques sur tout le parc. LAPS génère automatiquement un mot de passe unique et aléatoire pour le compte administrateur local de chaque serveur, le stocke chiffré dans Active Directory et assure sa rotation régulière. Pour approfondir le déploiement de LAPS, consultez notre guide complet LAPS.
# Vérifier que LAPS est disponible (natif Windows Server 2025)
Get-Command Get-LapsAADPassword, Get-LapsDiagnostics -ErrorAction SilentlyContinue
# Activer LAPS via GPO (PowerShell)
# Prérequis : schéma AD étendu pour LAPS
Update-LapsADSchema
# Autoriser les machines à écrire leur mot de passe dans AD
Set-LapsADComputerSelfPermission -Identity "OU=Servers,DC=domaine,DC=local"
# Autoriser un groupe à lire les mots de passe LAPS
Set-LapsADReadPasswordPermission -Identity "OU=Servers,DC=domaine,DC=local" -AllowedPrincipals "DOMAINE\GRP_LAPS_Readers"
# Configurer la politique LAPS via GPO
# Computer Configuration > Administrative Templates > System > LAPS
# - Password Settings : 20 chars, complexité élevée, rotation 30 jours
# - Configure password backup directory : Active Directory
# - Enable password encryption : Oui
# Vérifier le mot de passe LAPS d'un serveur
Get-LapsADPassword -Identity "SRV-DC01" -AsPlainText
Fine-Grained Password Policies (FGPP)
Les stratégies de mot de passe à granularité fine permettent d'appliquer des politiques de mot de passe différentes selon les groupes d'utilisateurs, contrairement à la politique de domaine par défaut qui s'applique uniformément. Pour les comptes privilégiés administrant des Windows Server, les exigences doivent être significativement plus strictes.
# Créer une FGPP pour les comptes administrateurs
New-ADFineGrainedPasswordPolicy -Name "PSO_Admins_Tier0" `
-Precedence 10 `
-MinPasswordLength 20 `
-MaxPasswordAge "30.00:00:00" `
-MinPasswordAge "1.00:00:00" `
-PasswordHistoryCount 24 `
-ComplexityEnabled $true `
-ReversibleEncryptionEnabled $false `
-LockoutThreshold 5 `
-LockoutDuration "00:30:00" `
-LockoutObservationWindow "00:30:00"
# Appliquer la FGPP au groupe des administrateurs Tier 0
Add-ADFineGrainedPasswordPolicySubject -Identity "PSO_Admins_Tier0" -Subjects "GRP_Admins_Tier0"
# Créer une FGPP pour les comptes de service
New-ADFineGrainedPasswordPolicy -Name "PSO_ServiceAccounts" `
-Precedence 20 `
-MinPasswordLength 30 `
-MaxPasswordAge "90.00:00:00" `
-PasswordHistoryCount 48 `
-ComplexityEnabled $true `
-ReversibleEncryptionEnabled $false `
-LockoutThreshold 0 # Pas de verrouillage pour les comptes de service
# Vérifier les FGPP appliquées
Get-ADFineGrainedPasswordPolicy -Filter * | Format-Table Name, Precedence, MinPasswordLength, MaxPasswordAge
Group Managed Service Accounts (gMSA)
Les gMSA (Group Managed Service Accounts) représentent la solution idéale pour les comptes de service Windows Server 2025. Contrairement aux comptes de service classiques dont le mot de passe est souvent connu de multiples administrateurs et rarement changé, les gMSA ont un mot de passe de 240 caractères géré automatiquement par Active Directory et changé tous les 30 jours. Aucun humain ne connaît ni ne manipule ce mot de passe.
# Prérequis : créer la clé racine KDS (une seule fois par forêt)
# En production, retirer le paramètre -EffectiveImmediately et attendre 10h
Add-KdsRootKey -EffectiveImmediately
# Créer un gMSA pour le service SQL Server
New-ADServiceAccount -Name "gMSA_SQLServer" `
-DNSHostName "gMSA_SQLServer.domaine.local" `
-PrincipalsAllowedToRetrieveManagedPassword "GRP_SQL_Servers" `
-KerberosEncryptionType AES128,AES256 `
-Description "gMSA pour service SQL Server"
# Installer le gMSA sur le serveur cible
Install-ADServiceAccount -Identity "gMSA_SQLServer"
# Tester le gMSA
Test-ADServiceAccount -Identity "gMSA_SQLServer"
# Configurer le service pour utiliser le gMSA
# Le mot de passe doit rester VIDE lors de la configuration
sc.exe config "MSSQLSERVER" obj= "DOMAINE\gMSA_SQLServer$" password= ""
Le groupe Protected Users
Le groupe Protected Users est un groupe de sécurité introduit dans Windows Server 2012 R2 et renforcé dans Windows Server 2025. Les membres de ce groupe bénéficient de protections supplémentaires contre le vol de credentials : pas de mise en cache des credentials en clair, pas d'authentification NTLM (Kerberos uniquement), pas de délégation Kerberos, durée de TGT réduite à 4 heures, et pas de chiffrement DES ou RC4. Ces protections sont appliquées au niveau du contrôleur de domaine et ne nécessitent aucune configuration sur le poste client, ce qui rend le déploiement simple et immédiat. Il est important de comprendre que les protections du groupe Protected Users sont non configurables : il n'est pas possible de modifier la durée du TGT à autre chose que 4 heures ou d'autoriser NTLM pour un membre spécifique. C'est une approche tout ou rien qui convient parfaitement aux comptes administrateurs mais qui peut poser problème pour les comptes ayant besoin de délégation Kerberos ou d'authentification NTLM dans certains scénarios legacy.
L'impact opérationnel du groupe Protected Users doit être évalué avant le déploiement. La durée de TGT de 4 heures signifie que les administrateurs devront se ré-authentifier plus fréquemment lors de sessions longues. L'interdiction de la mise en cache des credentials signifie qu'un administrateur ne pourra pas se connecter à un serveur si le DC est inaccessible (réseau hors service, DC en maintenance). L'impossibilité d'utiliser NTLM bloque l'accès aux ressources identifiées par adresse IP plutôt que par nom. Malgré ces contraintes, l'ajout de tous les comptes Tier 0 et Tier 1 dans Protected Users est considéré comme une mesure de sécurité fondamentale par les trois référentiels.
# Ajouter les comptes administrateurs au groupe Protected Users
$admins = @("admin.tier0", "admin.tier1", "admin.backup")
foreach ($admin in $admins) {
Add-ADGroupMember -Identity "Protected Users" -Members $admin
Write-Host "Ajouté $admin au groupe Protected Users" -ForegroundColor Green
}
# Vérifier les membres du groupe Protected Users
Get-ADGroupMember -Identity "Protected Users" | Format-Table Name, SamAccountName, ObjectClass
# ATTENTION : ne PAS ajouter les comptes de service (ils ont besoin de délégation)
# ATTENTION : ne PAS ajouter le compte krbtgt ou les comptes machine
Sécurisation des comptes de service
Les comptes de service sont des cibles de choix pour les attaquants car ils possèdent souvent des privilèges élevés et des mots de passe qui ne changent jamais. L'attaque Kerberoasting exploite précisément les comptes de service avec SPN pour extraire et craquer leurs mots de passe hors ligne.
# Auditer tous les comptes de service avec SPN
Get-ADUser -Filter {ServicePrincipalName -like "*"} -Properties ServicePrincipalName, PasswordLastSet, Enabled |
Select-Object Name, SamAccountName,
@{N='SPN';E={$_.ServicePrincipalName -join "; "}},
PasswordLastSet, Enabled |
Format-Table -AutoSize
# Identifier les comptes de service avec mot de passe ancien (>90 jours)
$threshold = (Get-Date).AddDays(-90)
Get-ADUser -Filter {ServicePrincipalName -like "*" -and PasswordLastSet -lt $threshold} -Properties PasswordLastSet, ServicePrincipalName |
Select-Object Name, PasswordLastSet |
Sort-Object PasswordLastSet
# Forcer le chiffrement AES uniquement pour les comptes de service
Get-ADUser -Filter {ServicePrincipalName -like "*"} |
Set-ADUser -KerberosEncryptionType AES128,AES256
# Configurer la délégation contrainte pour les comptes de service
Set-ADUser -Identity "svc_webapp" -TrustedForDelegation $false
Set-ADUser -Identity "svc_webapp" -Add @{'msDS-AllowedToDelegateTo'=@('HTTP/webserver.domaine.local')}
Gestion des identités — les fondamentaux :
- Déployer LAPS sur 100 % du parc serveur — mots de passe uniques et en rotation
- Migrer tous les comptes de service vers gMSA — mot de passe de 240 caractères géré par AD
- Placer les comptes administrateurs dans le groupe Protected Users
- Appliquer des FGPP avec 20+ caractères pour les comptes Tier 0
- Forcer AES256 sur tous les comptes de service pour contrer Kerberoasting
Hardening Active Directory sur les contrôleurs de domaine
AdminSDHolder et protection des objets privilégiés
Le mécanisme AdminSDHolder protège les membres des groupes privilégiés AD (Domain Admins, Enterprise Admins, Schema Admins, Administrators, etc.) en réinitialisant leurs ACL toutes les 60 minutes via le processus SDProp. Un attaquant qui modifie les permissions d'un compte privilégié verra ses changements annulés dans l'heure. Cependant, AdminSDHolder lui-même peut être abusé si un attaquant modifie l'objet AdminSDHolder directement. Pour une analyse approfondie des attaques ACL, consultez notre article sur l'ACL Abuse Active Directory.
# Vérifier les ACL de l'objet AdminSDHolder
$adminSDHolder = Get-ADObject -Filter {Name -eq "AdminSDHolder"} -SearchBase "CN=System,$((Get-ADDomain).DistinguishedName)"
(Get-Acl "AD:\$($adminSDHolder.DistinguishedName)").Access |
Where-Object {$_.IdentityReference -notlike "NT AUTHORITY\*" -and $_.IdentityReference -notlike "BUILTIN\*"} |
Format-Table IdentityReference, ActiveDirectoryRights, AccessControlType
# Configurer la fréquence SDProp (réduire de 60 à 30 minutes)
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\NTDS\Parameters" -Name "AdminSDProtectFrequency" -Value 1800 -Type DWord
# Lister les objets protégés par AdminSDHolder (adminCount=1)
Get-ADObject -Filter {adminCount -eq 1} -Properties adminCount, objectClass, whenChanged |
Sort-Object objectClass |
Format-Table Name, objectClass, whenChanged
Sécurisation du DSRM (Directory Services Restore Mode)
Le mot de passe DSRM est défini lors de la promotion du serveur en contrôleur de domaine. Ce mot de passe permet de se connecter au DC en mode restauration, contournant complètement Active Directory. Si un attaquant obtient ce mot de passe et un accès physique ou distant au DC, il peut prendre le contrôle total du serveur sans aucune authentification AD. Le mot de passe DSRM doit être changé régulièrement et stocké dans un coffre-fort numérique.
# Changer le mot de passe DSRM
ntdsutil "set dsrm password" "reset password on server null" quit quit
# Alternative PowerShell (Windows Server 2025)
$newPassword = Read-Host -AsSecureString "Entrez le nouveau mot de passe DSRM"
$cred = New-Object System.Management.Automation.PSCredential("dsrm", $newPassword)
Set-ADAccountPassword -Identity (Get-ADComputer $env:COMPUTERNAME).DistinguishedName -Reset -NewPassword $newPassword
# Configurer le comportement DSRM — INTERDIRE la connexion réseau avec DSRM
# Valeur 0 = utilisable uniquement en mode restauration (recommandé)
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Lsa" -Name "DsrmAdminLogonBehavior" -Value 0 -Type DWord
# Auditer les tentatives de connexion DSRM
# Event ID 4794 = tentative de changement du mot de passe DSRM
Vidage des groupes Schema Admins et Enterprise Admins
Les groupes Schema Admins et Enterprise Admins ne doivent contenir aucun membre permanent. Le groupe Schema Admins n'est nécessaire que pour les modifications de schéma AD (extrêmement rares en production), et Enterprise Admins n'est requis que pour les opérations inter-domaines ou de niveau forêt. Ces groupes doivent être vidés et un processus JIT (Just-In-Time) doit être mis en place pour les situations exceptionnelles.
# Auditer les membres des groupes hautement privilégiés
$criticalGroups = @("Schema Admins", "Enterprise Admins", "Domain Admins", "Administrators")
foreach ($group in $criticalGroups) {
Write-Host "`n=== $group ===" -ForegroundColor Cyan
$members = Get-ADGroupMember -Identity $group -Recursive
if ($members) {
$members | Format-Table Name, SamAccountName, ObjectClass
} else {
Write-Host " (aucun membre)" -ForegroundColor Green
}
}
# Vider Schema Admins et Enterprise Admins
Get-ADGroupMember -Identity "Schema Admins" | ForEach-Object {
Remove-ADGroupMember -Identity "Schema Admins" -Members $_ -Confirm:$false
Write-Host "Retiré $($_.Name) de Schema Admins" -ForegroundColor Yellow
}
Get-ADGroupMember -Identity "Enterprise Admins" | ForEach-Object {
Remove-ADGroupMember -Identity "Enterprise Admins" -Members $_ -Confirm:$false
Write-Host "Retiré $($_.Name) de Enterprise Admins" -ForegroundColor Yellow
}
LDAP Signing et Channel Binding
Le LDAP signing (signature LDAP) et le LDAP channel binding protègent les communications LDAP contre les attaques de type man-in-the-middle et relay NTLM. Microsoft a progressivement renforcé ces exigences, et Windows Server 2025 permet désormais d'imposer ces protections de manière stricte. Sans LDAP signing, un attaquant positionné sur le réseau peut intercepter et modifier les requêtes LDAP, y compris les modifications de mot de passe et les ajouts de membres à des groupes privilégiés.
# Imposer LDAP signing sur le contrôleur de domaine
# Valeur 2 = Exiger la signature (Require signing)
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\NTDS\Parameters" -Name "LDAPServerIntegrity" -Value 2 -Type DWord
# Imposer LDAP signing côté client
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\LDAP" -Name "LDAPClientIntegrity" -Value 2 -Type DWord
# Activer LDAP Channel Binding
# Valeur 2 = Always (When supported en mode 1)
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\NTDS\Parameters" -Name "LdapEnforceChannelBinding" -Value 2 -Type DWord
# Configurer LDAPS (LDAP over TLS/SSL) — port 636
# Nécessite un certificat valide sur le DC
# Vérifier la disponibilité de LDAPS
$ldapsConnection = New-Object System.DirectoryServices.Protocols.LdapConnection("dc01.domaine.local:636")
$ldapsConnection.SessionOptions.SecureSocketLayer = $true
$ldapsConnection.SessionOptions.ProtocolVersion = 3
try {
$ldapsConnection.Bind()
Write-Host "LDAPS fonctionnel sur le port 636" -ForegroundColor Green
} catch {
Write-Host "ERREUR LDAPS : $_" -ForegroundColor Red
}
Kerberos : imposer AES256 et désactiver RC4
Le chiffrement RC4-HMAC utilisé par défaut dans Kerberos est cryptographiquement faible et directement exploitable par des attaques de type Kerberoasting et AS-REP Roasting. Windows Server 2025 supporte nativement AES256-CTS-HMAC-SHA1-96, qui doit être imposé comme algorithme exclusif pour les échanges Kerberos.
# Configurer Kerberos pour AES uniquement via le registre
$krbPath = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\Kerberos\Parameters"
New-Item -Path $krbPath -Force | Out-Null
# SupportedEncryptionTypes : 0x18 = AES128 + AES256 (sans RC4/DES)
Set-ItemProperty -Path $krbPath -Name "SupportedEncryptionTypes" -Value 0x18 -Type DWord
# Configurer tous les comptes utilisateurs pour AES
Get-ADUser -Filter * -Properties msDS-SupportedEncryptionTypes |
Where-Object {$_.'msDS-SupportedEncryptionTypes' -ne 24} |
Set-ADUser -KerberosEncryptionType AES128,AES256
# Configurer tous les comptes machines pour AES
Get-ADComputer -Filter * -Properties msDS-SupportedEncryptionTypes |
Set-ADComputer -KerberosEncryptionType AES128,AES256
# Vérifier qu'aucun compte n'utilise encore RC4
Get-ADUser -Filter {msDS-SupportedEncryptionTypes -band 4} -Properties msDS-SupportedEncryptionTypes |
Select-Object Name, SamAccountName, @{N='EncTypes';E={$_.'msDS-SupportedEncryptionTypes'}} |
Format-Table -AutoSize
Protection du compte krbtgt
Le compte krbtgt est le Saint Graal d'Active Directory. Sa compromission permet de forger des Golden Tickets, offrant un accès illimité et persistant à l'intégralité du domaine. Le hash du mot de passe krbtgt doit être changé régulièrement (tous les 90 à 180 jours) de manière contrôlée (double changement avec intervalle de réplication).
# Vérifier la date du dernier changement de mot de passe krbtgt
Get-ADUser -Identity krbtgt -Properties PasswordLastSet, msDS-KeyVersionNumber |
Select-Object Name, PasswordLastSet, @{N='KeyVersion';E={$_.'msDS-KeyVersionNumber'}}
# Script de rotation du mot de passe krbtgt (à exécuter en heures creuses)
# ÉTAPE 1 : Premier changement
Set-ADAccountPassword -Identity krbtgt -Reset -NewPassword (
ConvertTo-SecureString -String ([System.Web.Security.Membership]::GeneratePassword(32,8)) -AsPlainText -Force
)
Write-Host "Premier changement krbtgt effectué. Attente de la réplication..." -ForegroundColor Yellow
# Vérifier la réplication
repadmin /syncall /AdeP
# ÉTAPE 2 : Attendre que TOUS les DC aient répliqué (24-48h)
# ÉTAPE 3 : Second changement (invalide les tickets basés sur l'ancien hash)
# Ne faire le second changement qu'après réplication COMPLÈTE confirmée
Hardening Active Directory — les impératifs :
- Vider les groupes Schema Admins et Enterprise Admins en permanence
- Imposer LDAP signing (valeur 2) et channel binding sur tous les DC
- Désactiver RC4 et imposer AES256 pour Kerberos sur tous les comptes
- Changer le mot de passe krbtgt tous les 90-180 jours (procédure en deux étapes)
- Configurer DsrmAdminLogonBehavior = 0 pour bloquer l'accès réseau DSRM
GPO de sécurité : 30+ paramètres critiques
Politiques d'audit avancées : 9 catégories essentielles
Les politiques d'audit avancées (Advanced Audit Policy Configuration) remplacent les politiques d'audit classiques et offrent un contrôle granulaire sur les événements journalisés. Les 9 catégories suivantes doivent être configurées pour assurer une visibilité complète sur les activités de sécurité. Cette configuration est alignée sur les recommandations CIS Benchmark Level 2 et les Microsoft Security Baselines. Pour les détails de mise en oeuvre GPO, consultez notre guide GPO de sécurisation AD.
# ============================================================
# CONFIGURATION DES 9 CATÉGORIES D'AUDIT AVANCÉ
# GPO: Computer Configuration > Windows Settings > Security Settings
# > Advanced Audit Policy Configuration
# ============================================================
# 1. Account Logon (Connexion de compte)
auditpol /set /subcategory:"Credential Validation" /success:enable /failure:enable
auditpol /set /subcategory:"Kerberos Authentication Service" /success:enable /failure:enable
auditpol /set /subcategory:"Kerberos Service Ticket Operations" /success:enable /failure:enable
auditpol /set /subcategory:"Other Account Logon Events" /success:enable /failure:enable
# 2. Account Management (Gestion des comptes)
auditpol /set /subcategory:"Application Group Management" /success:enable /failure:enable
auditpol /set /subcategory:"Computer Account Management" /success:enable /failure:enable
auditpol /set /subcategory:"Distribution Group Management" /success:enable /failure:enable
auditpol /set /subcategory:"Other Account Management Events" /success:enable /failure:enable
auditpol /set /subcategory:"Security Group Management" /success:enable /failure:enable
auditpol /set /subcategory:"User Account Management" /success:enable /failure:enable
# 3. Detailed Tracking (Suivi détaillé)
auditpol /set /subcategory:"DPAPI Activity" /success:enable /failure:enable
auditpol /set /subcategory:"PNP Activity" /success:enable
auditpol /set /subcategory:"Process Creation" /success:enable /failure:enable
auditpol /set /subcategory:"Process Termination" /success:enable
# 4. DS Access (Accès aux services d'annuaire)
auditpol /set /subcategory:"Directory Service Access" /success:enable /failure:enable
auditpol /set /subcategory:"Directory Service Changes" /success:enable /failure:enable
auditpol /set /subcategory:"Directory Service Replication" /success:enable /failure:enable
# 5. Logon/Logoff (Ouverture/fermeture de session)
auditpol /set /subcategory:"Account Lockout" /success:enable /failure:enable
auditpol /set /subcategory:"Group Membership" /success:enable
auditpol /set /subcategory:"Logoff" /success:enable
auditpol /set /subcategory:"Logon" /success:enable /failure:enable
auditpol /set /subcategory:"Network Policy Server" /success:enable /failure:enable
auditpol /set /subcategory:"Other Logon/Logoff Events" /success:enable /failure:enable
auditpol /set /subcategory:"Special Logon" /success:enable
# 6. Object Access (Accès aux objets)
auditpol /set /subcategory:"Certification Services" /success:enable /failure:enable
auditpol /set /subcategory:"Detailed File Share" /success:enable /failure:enable
auditpol /set /subcategory:"File Share" /success:enable /failure:enable
auditpol /set /subcategory:"File System" /success:enable /failure:enable
auditpol /set /subcategory:"Removable Storage" /success:enable /failure:enable
auditpol /set /subcategory:"SAM" /success:enable /failure:enable
# 7. Policy Change (Changement de stratégie)
auditpol /set /subcategory:"Audit Policy Change" /success:enable /failure:enable
auditpol /set /subcategory:"Authentication Policy Change" /success:enable
auditpol /set /subcategory:"Authorization Policy Change" /success:enable
auditpol /set /subcategory:"MPSSVC Rule-Level Policy Change" /success:enable /failure:enable
# 8. Privilege Use (Utilisation des privilèges)
auditpol /set /subcategory:"Sensitive Privilege Use" /success:enable /failure:enable
auditpol /set /subcategory:"Non Sensitive Privilege Use" /success:enable /failure:enable
# 9. System
auditpol /set /subcategory:"IPsec Driver" /success:enable /failure:enable
auditpol /set /subcategory:"Other System Events" /success:enable /failure:enable
auditpol /set /subcategory:"Security State Change" /success:enable /failure:enable
auditpol /set /subcategory:"Security System Extension" /success:enable /failure:enable
auditpol /set /subcategory:"System Integrity" /success:enable /failure:enable
# Activer l'inclusion de la ligne de commande dans les événements de création de processus
Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\Audit" -Name "ProcessCreationIncludeCmdLine_Enabled" -Value 1 -Type DWord
User Rights Assignment : 15 paramètres critiques
L'attribution des droits utilisateur détermine quels comptes peuvent effectuer des opérations sensibles au niveau du système. Une mauvaise configuration de ces droits est un vecteur d'élévation de privilèges majeur. Les paramètres suivants doivent être configurés via GPO sous Computer Configuration > Windows Settings > Security Settings > Local Policies > User Rights Assignment.
# Exporter la configuration actuelle des User Rights
secedit /export /cfg C:\Temp\secpol.cfg
Get-Content C:\Temp\secpol.cfg | Select-String "Se"
# Paramètres critiques (via GPO ou secedit) :
# ============================================================
# 1. SeNetworkLogonRight (Accès réseau) = Administrators, Authenticated Users
# 2. SeDenyNetworkLogonRight = Guests, Local account (sur les DC)
# 3. SeInteractiveLogonRight = Administrators uniquement
# 4. SeRemoteInteractiveLogonRight = Remote Desktop Users, Administrators
# 5. SeDenyRemoteInteractiveLogonRight = Guests, Local account
# 6. SeBackupPrivilege = Administrators uniquement
# 7. SeRestorePrivilege = Administrators uniquement
# 8. SeDebugPrivilege = PERSONNE (vide) — critique pour empêcher LSASS dump
# 9. SeTakeOwnershipPrivilege = Administrators uniquement
# 10. SeLoadDriverPrivilege = Administrators uniquement
# 11. SeImpersonatePrivilege = Administrators, LOCAL SERVICE, NETWORK SERVICE, SERVICE
# 12. SeAssignPrimaryTokenPrivilege = LOCAL SERVICE, NETWORK SERVICE
# 13. SeTcbPrivilege (Act as part of OS) = PERSONNE (vide)
# 14. SeCreateTokenPrivilege = PERSONNE (vide)
# 15. SeTrustedCredManAccessPrivilege = PERSONNE (vide)
# ============================================================
# Vérifier SeDebugPrivilege (DOIT être vide)
$whoHasDebug = (Get-ItemProperty "HKLM:\SECURITY\Policy\Accounts" -ErrorAction SilentlyContinue)
# Méthode plus fiable via secpol
secedit /export /cfg C:\Temp\secpol.cfg
Select-String "SeDebugPrivilege" C:\Temp\secpol.cfg
Security Options : 20 paramètres de durcissement
Les Security Options sont configurées sous Computer Configuration > Windows Settings > Security Settings > Local Policies > Security Options. Elles contrôlent des comportements fondamentaux de sécurité du système.
# ============================================================
# SECURITY OPTIONS — Configuration de durcissement complète
# ============================================================
# 1. Accounts: Administrator account status = Disabled (sauf DC)
# GPO: Accounts: Administrator account status → Disabled
# 2. Accounts: Guest account status = Disabled
Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" -Name "ForceGuest" -Value 0
# 3. Accounts: Rename administrator account
# GPO: Accounts: Rename administrator account → nom personnalisé
# 4. Interactive logon: Do not display last user name = Enabled
Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" -Name "DontDisplayLastUserName" -Value 1
# 5. Interactive logon: Machine inactivity limit = 900 secondes (15 min)
Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" -Name "InactivityTimeoutSecs" -Value 900
# 6. Interactive logon: Require CTRL+ALT+DEL = Enabled
Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" -Name "DisableCAD" -Value 0
# 7. Microsoft network client: Digitally sign communications (always) = Enabled
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\LanmanWorkstation\Parameters" -Name "RequireSecuritySignature" -Value 1
# 8. Microsoft network server: Digitally sign communications (always) = Enabled
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters" -Name "RequireSecuritySignature" -Value 1
# 9. Network access: Do not allow anonymous enumeration of SAM accounts = Enabled
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Lsa" -Name "RestrictAnonymousSAM" -Value 1
# 10. Network access: Do not allow anonymous enumeration of SAM accounts and shares = Enabled
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Lsa" -Name "RestrictAnonymous" -Value 1
# 11. Network access: Restrict anonymous access to Named Pipes and Shares = Enabled
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters" -Name "RestrictNullSessAccess" -Value 1
# 12. Network security: LAN Manager authentication level = Send NTLMv2 response only. Refuse LM & NTLM
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Lsa" -Name "LmCompatibilityLevel" -Value 5
# 13. Network security: LDAP client signing requirements = Require signing
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\LDAP" -Name "LDAPClientIntegrity" -Value 2
# 14. Network security: Minimum session security for NTLM SSP = Require NTLMv2 + 128-bit
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Lsa\MSV1_0" -Name "NTLMMinClientSec" -Value 537395200
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Lsa\MSV1_0" -Name "NTLMMinServerSec" -Value 537395200
# 15. User Account Control: Admin Approval Mode = Enabled
Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" -Name "EnableLUA" -Value 1
# 16. UAC: Behavior of the elevation prompt for administrators = Prompt for consent on secure desktop
Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" -Name "ConsentPromptBehaviorAdmin" -Value 2
# 17. UAC: Only elevate executables that are signed and validated = Enabled
Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" -Name "ValidateAdminCodeSignatures" -Value 1
# 18. Shutdown: Clear virtual memory pagefile = Enabled
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management" -Name "ClearPageFileAtShutdown" -Value 1
# 19. System objects: Strengthen default permissions = Enabled
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager" -Name "ProtectionMode" -Value 1
# 20. Network security: Do not store LAN Manager hash value = Enabled
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Lsa" -Name "NoLMHash" -Value 1
Windows Defender Firewall via GPO
Le pare-feu Windows Defender doit être activé et configuré sur les trois profils (Domain, Private, Public) via GPO. La stratégie de base est le deny all inbound avec des exceptions explicites pour les services autorisés. Les connexions sortantes doivent également être restreintes sur les serveurs critiques.
# Activer le pare-feu sur les trois profils avec blocage par défaut
Set-NetFirewallProfile -Profile Domain,Private,Public -Enabled True
Set-NetFirewallProfile -Profile Domain,Private,Public -DefaultInboundAction Block
Set-NetFirewallProfile -Profile Domain,Private,Public -DefaultOutboundAction Allow
Set-NetFirewallProfile -Profile Domain,Private,Public -NotifyOnListen True
Set-NetFirewallProfile -Profile Domain,Private,Public -LogAllowed True
Set-NetFirewallProfile -Profile Domain,Private,Public -LogBlocked True
Set-NetFirewallProfile -Profile Domain,Private,Public -LogFileName "%SystemRoot%\System32\LogFiles\Firewall\pfirewall.log"
Set-NetFirewallProfile -Profile Domain,Private,Public -LogMaxSizeKilobytes 32768
# Configurer les logs du pare-feu
Set-NetFirewallProfile -Profile Domain -LogAllowed True -LogBlocked True -LogIgnored False
# Règles de base pour un DC
# Autoriser DNS
New-NetFirewallRule -DisplayName "DC - DNS TCP" -Direction Inbound -Protocol TCP -LocalPort 53 -Action Allow -Profile Domain
New-NetFirewallRule -DisplayName "DC - DNS UDP" -Direction Inbound -Protocol UDP -LocalPort 53 -Action Allow -Profile Domain
# Autoriser Kerberos
New-NetFirewallRule -DisplayName "DC - Kerberos TCP" -Direction Inbound -Protocol TCP -LocalPort 88 -Action Allow -Profile Domain
New-NetFirewallRule -DisplayName "DC - Kerberos UDP" -Direction Inbound -Protocol UDP -LocalPort 88 -Action Allow -Profile Domain
# Autoriser LDAP/LDAPS
New-NetFirewallRule -DisplayName "DC - LDAP" -Direction Inbound -Protocol TCP -LocalPort 389 -Action Allow -Profile Domain
New-NetFirewallRule -DisplayName "DC - LDAPS" -Direction Inbound -Protocol TCP -LocalPort 636 -Action Allow -Profile Domain
# Autoriser RPC/NTDS Replication
New-NetFirewallRule -DisplayName "DC - RPC Endpoint Mapper" -Direction Inbound -Protocol TCP -LocalPort 135 -Action Allow -Profile Domain
# Bloquer explicitement les protocoles dangereux
New-NetFirewallRule -DisplayName "BLOCK - NetBIOS" -Direction Inbound -Protocol TCP -LocalPort 137-139 -Action Block -Profile Any
New-NetFirewallRule -DisplayName "BLOCK - NetBIOS UDP" -Direction Inbound -Protocol UDP -LocalPort 137-139 -Action Block -Profile Any
AppLocker et WDAC (Windows Defender Application Control)
AppLocker et WDAC (Windows Defender Application Control) sont les deux mécanismes de contrôle d'application de Windows Server 2025. WDAC est le successeur recommandé par Microsoft, offrant une protection au niveau du noyau (kernel-mode) et une résistance supérieure au contournement. Cependant, AppLocker reste pertinent pour les scénarios de contrôle utilisateur et est plus simple à déployer.
# ============================================================
# APPLOCKER — Politique de base restrictive
# ============================================================
# Démarrer le service Application Identity (requis pour AppLocker)
Set-Service -Name AppIDSvc -StartupType Automatic
Start-Service AppIDSvc
# Créer une politique AppLocker de base
# Règle par défaut : autoriser uniquement les exécutables signés Microsoft
# dans les répertoires système
# Exporter la politique actuelle
Get-AppLockerPolicy -Effective -Xml > C:\Temp\AppLocker_Current.xml
# Créer les règles par défaut
$policy = [Microsoft.Security.ApplicationId.PolicyManagement.PolicyModel.AppLockerPolicy]::new()
# Règle : autoriser les exécutables dans C:\Windows\*
# Règle : autoriser les exécutables dans C:\Program Files\*
# Règle : bloquer tout le reste
# Alternative simplifiée via PowerShell
Set-AppLockerPolicy -PolicyObject (
New-AppLockerPolicy -RuleType Publisher,Path -User Everyone `
-RuleNamePrefix "Default" -AllowWindows -Optimize
) -Merge
# ============================================================
# WDAC — Windows Defender Application Control (niveau supérieur)
# ============================================================
# Créer une politique WDAC basée sur le mode audit
# Étape 1 : Scanner le système de référence pour créer une baseline
New-CIPolicy -Level Publisher -FilePath "C:\Temp\WDAC_Baseline.xml" -Fallback Hash -UserPEs
# Étape 2 : Activer le mode audit d'abord (CRITIQUE avant mise en production)
Set-RuleOption -FilePath "C:\Temp\WDAC_Baseline.xml" -Option 3 # Audit Mode
# Étape 3 : Compiler la politique
ConvertFrom-CIPolicy -XmlFilePath "C:\Temp\WDAC_Baseline.xml" -BinaryFilePath "C:\Temp\WDAC_Baseline.p7b"
# Étape 4 : Déployer via GPO
# Computer Configuration > Administrative Templates > System > Device Guard
# > Deploy Windows Defender Application Control → Activer + chemin vers .p7b
Credential Guard
Credential Guard utilise la virtualisation matérielle (VBS — Virtualization Based Security) pour isoler les secrets d'authentification (hashes NTLM, tickets Kerberos TGT) dans un environnement protégé inaccessible même au noyau Windows. C'est la protection la plus efficace contre les attaques Pass-the-Hash, Pass-the-Ticket et le dumping LSASS. Windows Server 2025 améliore Credential Guard avec le support natif sans configuration Hyper-V explicite.
# Vérifier les prérequis matériels pour Credential Guard
# TPM 2.0, UEFI Secure Boot, virtualisation matérielle (VT-x/AMD-V)
Get-CimInstance -ClassName Win32_DeviceGuard -Namespace root\Microsoft\Windows\DeviceGuard |
Select-Object AvailableSecurityProperties, RequiredSecurityProperties,
SecurityServicesConfigured, SecurityServicesRunning, VirtualizationBasedSecurityStatus
# Activer Credential Guard via le registre
# Activer VBS (Virtualization Based Security)
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\DeviceGuard" -Name "EnableVirtualizationBasedSecurity" -Value 1 -Type DWord
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\DeviceGuard" -Name "RequirePlatformSecurityFeatures" -Value 3 -Type DWord
# 1 = Secure Boot, 3 = Secure Boot + DMA Protection
# Activer Credential Guard
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Lsa" -Name "LsaCfgFlags" -Value 1 -Type DWord
# 1 = Activé avec verrouillage UEFI (recommandé)
# 2 = Activé sans verrouillage (peut être désactivé)
# Vérifier après redémarrage
Get-CimInstance -ClassName Win32_DeviceGuard -Namespace root\Microsoft\Windows\DeviceGuard |
Select-Object SecurityServicesRunning
# La valeur 1 dans SecurityServicesRunning indique que Credential Guard est actif
BitLocker pour les serveurs
BitLocker protège les données au repos contre le vol physique du disque dur ou du serveur. Sur un contrôleur de domaine, BitLocker protège le fichier NTDS.dit (la base de données Active Directory) qui contient tous les hashes de mots de passe du domaine. Sans BitLocker, un attaquant qui accède physiquement au serveur peut copier NTDS.dit et extraire tous les secrets hors ligne.
# Installer la fonctionnalité BitLocker
Install-WindowsFeature BitLocker -IncludeManagementTools -Restart
# Vérifier le statut TPM
Get-Tpm | Select-Object TpmPresent, TpmReady, TpmEnabled, TpmActivated
# Chiffrer le volume système avec TPM + PIN
$pin = Read-Host -AsSecureString "Entrez le PIN BitLocker"
Enable-BitLocker -MountPoint "C:" -EncryptionMethod XtsAes256 -TpmAndPinProtector -Pin $pin
# Chiffrer le volume données (NTDS.dit sur D:)
Enable-BitLocker -MountPoint "D:" -EncryptionMethod XtsAes256 -RecoveryPasswordProtector
# Sauvegarder la clé de récupération dans AD
Backup-BitLockerKeyProtector -MountPoint "C:" -KeyProtectorId (
(Get-BitLockerVolume -MountPoint "C:").KeyProtector |
Where-Object {$_.KeyProtectorType -eq "RecoveryPassword"} |
Select-Object -ExpandProperty KeyProtectorId
)
# Vérifier le statut de chiffrement
Get-BitLockerVolume | Select-Object MountPoint, VolumeStatus, EncryptionMethod, ProtectionStatus, EncryptionPercentage
GPO de sécurité — les 6 piliers :
- Configurer les 9 catégories d'audit avancé avec succès ET échec
- Retirer SeDebugPrivilege à TOUT le monde — empêche le dump LSASS
- LmCompatibilityLevel = 5 — refuser LM et NTLMv1, n'accepter que NTLMv2
- Déployer Credential Guard sur tous les serveurs compatibles VBS
- Activer BitLocker XTS-AES-256 sur tous les volumes, y compris NTDS.dit
- WDAC en mode audit avant production — ne jamais déployer directement en enforcement
Sécurisation réseau avancée
Windows Firewall avec sécurité avancée : règles granulaires
Au-delà de la configuration de base du pare-feu, la sécurité réseau d'un Windows Server 2025 nécessite des règles granulaires adaptées au rôle du serveur. La méthodologie consiste à bloquer tout par défaut, puis à ouvrir uniquement les flux strictement nécessaires, documentés et révisés régulièrement. Chaque règle doit être nommée de manière explicite, limitée à un profil réseau spécifique, et restreinte à des adresses IP sources précises lorsque possible.
# Supprimer toutes les règles de pare-feu non essentielles
# ATTENTION : à exécuter UNIQUEMENT après avoir créé les règles nécessaires
Get-NetFirewallRule | Where-Object {
$_.Enabled -eq "True" -and
$_.Direction -eq "Inbound" -and
$_.DisplayName -notlike "Core Networking*" -and
$_.DisplayGroup -notlike "Core Networking*"
} | Format-Table DisplayName, Direction, Action, Enabled
# Règles pour un serveur membre (non-DC)
# Autoriser WinRM uniquement depuis le réseau d'administration
New-NetFirewallRule -DisplayName "ALLOW - WinRM from Admin VLAN" `
-Direction Inbound -Protocol TCP -LocalPort 5985,5986 `
-RemoteAddress "10.0.100.0/24" -Action Allow -Profile Domain
# Autoriser RDP uniquement depuis les jump servers
New-NetFirewallRule -DisplayName "ALLOW - RDP from Jump Servers" `
-Direction Inbound -Protocol TCP -LocalPort 3389 `
-RemoteAddress "10.0.100.10,10.0.100.11" -Action Allow -Profile Domain
# Autoriser ICMP (ping) uniquement depuis le réseau de monitoring
New-NetFirewallRule -DisplayName "ALLOW - ICMP from Monitoring" `
-Direction Inbound -Protocol ICMPv4 -IcmpType 8 `
-RemoteAddress "10.0.200.0/24" -Action Allow -Profile Domain
# Bloquer les connexions sortantes non autorisées sur les serveurs critiques
Set-NetFirewallProfile -Profile Domain -DefaultOutboundAction Block
# Autoriser DNS sortant
New-NetFirewallRule -DisplayName "ALLOW OUT - DNS" `
-Direction Outbound -Protocol UDP -RemotePort 53 `
-RemoteAddress "10.0.1.1,10.0.1.2" -Action Allow -Profile Domain
# Autoriser HTTPS sortant vers WSUS uniquement
New-NetFirewallRule -DisplayName "ALLOW OUT - WSUS" `
-Direction Outbound -Protocol TCP -RemotePort 8531 `
-RemoteAddress "10.0.50.10" -Action Allow -Profile Domain
# Exporter la configuration complète du pare-feu
netsh advfirewall export "C:\Backup\firewall-config-$(Get-Date -Format 'yyyyMMdd').wfw"
IPsec : chiffrement des communications inter-serveurs
IPsec (Internet Protocol Security) permet de chiffrer et authentifier les communications réseau entre les serveurs du domaine. Sur Windows Server 2025, IPsec peut être déployé via GPO pour imposer le chiffrement de toutes les communications entre contrôleurs de domaine, ou entre les serveurs Tier 0 et les postes d'administration.
# Créer une règle IPsec pour sécuriser les communications DC-to-DC
# Via PowerShell (équivalent GPO)
# Créer une proposition d'authentification (Kerberos)
$authProposal = New-NetIPsecAuthProposal -Machine -Kerberos
# Créer la phase 1 (Main Mode)
$mmAuth = New-NetIPsecMainModeCryptoSet -DisplayName "DC-MM-AES256-SHA256" `
-Proposal (New-NetIPsecMainModeCryptoProposal -Encryption AES256 -Hash SHA256 -KeyExchange DH14)
# Créer la phase 2 (Quick Mode)
$qmCrypto = New-NetIPsecQuickModeCryptoSet -DisplayName "DC-QM-ESP-AES256" `
-Proposal (New-NetIPsecQuickModeCryptoProposal -Encapsulation ESP -Encryption AES256 -ESPHash SHA256)
# Créer la règle de connexion IPsec
New-NetIPsecRule -DisplayName "DC to DC - IPsec Required" `
-InboundSecurity Require -OutboundSecurity Require `
-Phase1AuthSet $mmAuth.Name -Phase2CryptoSet $qmCrypto.Name `
-Protocol Any `
-LocalAddress "10.0.1.10" -RemoteAddress "10.0.1.11,10.0.1.12" `
-Profile Domain
# Vérifier les associations de sécurité IPsec
Get-NetIPsecMainModeSA
Get-NetIPsecQuickModeSA
SMB Signing et SMB Encryption
Le protocole SMB (Server Message Block) est omniprésent dans les environnements Windows. Sans signature SMB, un attaquant peut réaliser des attaques de relay NTLM en interceptant et relayant les authentifications SMB. Windows Server 2025 supporte SMB 3.1.1 avec chiffrement AES-256-GCM, offrant une protection complète des données en transit.
# Imposer la signature SMB (serveur ET client)
Set-SmbServerConfiguration -RequireSecuritySignature $true -Force
Set-SmbClientConfiguration -RequireSecuritySignature $true -Force
# Désactiver SMBv1 (rappel — déjà fait à l'installation)
Set-SmbServerConfiguration -EnableSMB1Protocol $false -Force
# Imposer le chiffrement SMB 3.x
Set-SmbServerConfiguration -EncryptData $true -Force
Set-SmbServerConfiguration -RejectUnencryptedAccess $true -Force
# Configurer la version minimale de SMB
Set-SmbServerConfiguration -MinimumSMBDialect "SMB311" -Force
# Vérifier la configuration SMB complète
Get-SmbServerConfiguration | Select-Object EnableSMB1Protocol, EnableSMB2Protocol,
RequireSecuritySignature, EncryptData, RejectUnencryptedAccess
# Auditer les connexions SMB actives et leurs protocoles
Get-SmbConnection | Select-Object ServerName, ShareName, Dialect, Signed, Encrypted |
Format-Table -AutoSize
# Désactiver les partages administratifs par défaut (optionnel, attention aux impacts)
# Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters" -Name "AutoShareServer" -Value 0
Désactivation de TLS 1.0/1.1, forcer TLS 1.2/1.3
Les protocoles TLS 1.0 et TLS 1.1 sont considérés comme obsolètes et vulnérables (BEAST, POODLE, Lucky 13). Windows Server 2025 supporte nativement TLS 1.3, qui offre un handshake plus rapide et une sécurité renforcée. Tous les protocoles antérieurs à TLS 1.2 doivent être désactivés.
# ============================================================
# DÉSACTIVATION DES PROTOCOLES OBSOLÈTES
# ============================================================
# Désactiver SSL 2.0
New-Item "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 2.0\Server" -Force | Out-Null
New-Item "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 2.0\Client" -Force | Out-Null
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 2.0\Server" -Name "Enabled" -Value 0 -Type DWord
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 2.0\Client" -Name "Enabled" -Value 0 -Type DWord
# Désactiver SSL 3.0
New-Item "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 3.0\Server" -Force | Out-Null
New-Item "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 3.0\Client" -Force | Out-Null
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 3.0\Server" -Name "Enabled" -Value 0 -Type DWord
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 3.0\Client" -Name "Enabled" -Value 0 -Type DWord
# Désactiver TLS 1.0
New-Item "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.0\Server" -Force | Out-Null
New-Item "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.0\Client" -Force | Out-Null
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.0\Server" -Name "Enabled" -Value 0 -Type DWord
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.0\Client" -Name "Enabled" -Value 0 -Type DWord
# Désactiver TLS 1.1
New-Item "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.1\Server" -Force | Out-Null
New-Item "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.1\Client" -Force | Out-Null
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.1\Server" -Name "Enabled" -Value 0 -Type DWord
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.1\Client" -Name "Enabled" -Value 0 -Type DWord
# Activer explicitement TLS 1.2
New-Item "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Server" -Force | Out-Null
New-Item "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Client" -Force | Out-Null
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Server" -Name "Enabled" -Value 1 -Type DWord
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Client" -Name "Enabled" -Value 1 -Type DWord
# Activer TLS 1.3 (natif Windows Server 2025)
New-Item "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.3\Server" -Force | Out-Null
New-Item "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.3\Client" -Force | Out-Null
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.3\Server" -Name "Enabled" -Value 1 -Type DWord
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.3\Client" -Name "Enabled" -Value 1 -Type DWord
# Configurer les suites de chiffrement (cipher suites) — n'autoriser que les suites fortes
$cipherSuites = @(
"TLS_AES_256_GCM_SHA384", # TLS 1.3
"TLS_AES_128_GCM_SHA256", # TLS 1.3
"TLS_CHACHA20_POLY1305_SHA256", # TLS 1.3
"TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", # TLS 1.2
"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", # TLS 1.2
"TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", # TLS 1.2
"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256" # TLS 1.2
)
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Cryptography\Configuration\SSL\00010002" `
-Name "Functions" -Value ($cipherSuites -join ",")
Désactiver NetBIOS, LLMNR et WPAD
Les protocoles NetBIOS, LLMNR (Link-Local Multicast Name Resolution) et WPAD (Web Proxy Auto-Discovery) sont des vecteurs d'attaque classiques exploités par des outils comme Responder et Inveigh. Ces protocoles permettent à un attaquant positionné sur le réseau local de capturer des hashes NTLMv2 en répondant aux requêtes de résolution de noms non résolues par DNS. Leur désactivation est une mesure de durcissement fondamentale.
# ============================================================
# DÉSACTIVATION NETBIOS
# ============================================================
# Désactiver NetBIOS sur toutes les interfaces réseau
$adapters = Get-WmiObject Win32_NetworkAdapterConfiguration | Where-Object {$_.IPEnabled -eq $true}
foreach ($adapter in $adapters) {
# 2 = Désactiver NetBIOS over TCP/IP
$adapter.SetTcpipNetbios(2) | Out-Null
Write-Host "NetBIOS désactivé sur $($adapter.Description)" -ForegroundColor Green
}
# Vérification
Get-WmiObject Win32_NetworkAdapterConfiguration | Where-Object {$_.IPEnabled} |
Select-Object Description, TcpipNetbiosOptions
# 2 = Disabled, 1 = Enabled, 0 = Default (DHCP)
# ============================================================
# DÉSACTIVATION LLMNR
# ============================================================
# Via le registre (équivalent GPO)
$llmnrPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\DNSClient"
New-Item -Path $llmnrPath -Force | Out-Null
Set-ItemProperty -Path $llmnrPath -Name "EnableMulticast" -Value 0 -Type DWord
# ============================================================
# DÉSACTIVATION WPAD
# ============================================================
# Désactiver la détection automatique de proxy
Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings\WinHttp" -Name "DisableWpad" -Value 1 -Type DWord
# Désactiver le service WinHTTP Web Proxy Auto-Discovery
Set-Service -Name WinHttpAutoProxySvc -StartupType Disabled
Stop-Service WinHttpAutoProxySvc -Force -ErrorAction SilentlyContinue
# Ajouter une entrée DNS pour neutraliser WPAD (sur le serveur DNS)
# Créer un enregistrement A "wpad" pointant vers une IP inexistante
# Add-DnsServerResourceRecordA -Name "wpad" -ZoneName "domaine.local" -IPv4Address "0.0.0.0"
# ============================================================
# DÉSACTIVATION mDNS
# ============================================================
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\Dnscache\Parameters" -Name "EnableMDNS" -Value 0 -Type DWord
Sécurisation réseau — les non-négociables :
- Désactiver NetBIOS (valeur 2), LLMNR (EnableMulticast=0) et WPAD sur 100 % des serveurs
- Imposer SMB signing ET encryption avec SMB 3.1.1 minimum
- Désactiver SSL 2.0/3.0 et TLS 1.0/1.1 — seuls TLS 1.2 et 1.3 doivent être actifs
- Configurer IPsec entre les DC et les serveurs Tier 0
- Bloquer les connexions sortantes par défaut sur les serveurs critiques
Sécurisation des services et rôles Windows Server
Durcissement de IIS (Internet Information Services)
IIS est l'un des services les plus exposés sur un Windows Server. Sa surface d'attaque est considérable : exécution de code côté serveur, accès au système de fichiers, élévation de privilèges via SeImpersonatePrivilege. Le durcissement d'IIS sur Windows Server 2025 commence par la suppression de tous les modules et fonctionnalités non nécessaires.
# Supprimer les modules IIS inutiles
$modulesASupprimer = @(
"WebDAVModule",
"TraceModule",
"CustomErrorModule"
)
Import-Module WebAdministration
foreach ($module in $modulesASupprimer) {
Remove-WebGlobalModule -Name $module -ErrorAction SilentlyContinue
}
# Désactiver le listing de répertoire
Set-WebConfigurationProperty -Filter "/system.webServer/directoryBrowse" -Name "enabled" -Value $false -PSPath "IIS:\"
# Supprimer les en-têtes de version (information disclosure)
# Supprimer le header X-Powered-By
Remove-WebConfigurationProperty -Filter "/system.webServer/httpProtocol/customHeaders" -Name "." -AtElement @{name="X-Powered-By"} -PSPath "IIS:\"
# Supprimer le header Server
Set-WebConfigurationProperty -Filter "/system.webServer/security/requestFiltering" -Name "removeServerHeader" -Value $true -PSPath "IIS:\"
# Configurer les en-têtes de sécurité
Add-WebConfigurationProperty -Filter "/system.webServer/httpProtocol/customHeaders" -Name "." -Value @{name="X-Content-Type-Options"; value="nosniff"} -PSPath "IIS:\"
Add-WebConfigurationProperty -Filter "/system.webServer/httpProtocol/customHeaders" -Name "." -Value @{name="X-Frame-Options"; value="DENY"} -PSPath "IIS:\"
Add-WebConfigurationProperty -Filter "/system.webServer/httpProtocol/customHeaders" -Name "." -Value @{name="Strict-Transport-Security"; value="max-age=31536000; includeSubDomains"} -PSPath "IIS:\"
Add-WebConfigurationProperty -Filter "/system.webServer/httpProtocol/customHeaders" -Name "." -Value @{name="Content-Security-Policy"; value="default-src 'self'"} -PSPath "IIS:\"
# Configurer le Request Filtering (bloquer les extensions dangereuses)
$extensionsDangereuses = @(".asa", ".asax", ".ascx", ".ashx", ".asmx", ".axd", ".bat", ".cmd", ".com", ".config", ".cs", ".csproj", ".dll", ".exe", ".ini", ".log", ".mdb", ".ps1", ".vb", ".vbs")
foreach ($ext in $extensionsDangereuses) {
Add-WebConfigurationProperty -Filter "/system.webServer/security/requestFiltering/fileExtensions" -Name "." -Value @{fileExtension=$ext; allowed="False"} -PSPath "IIS:\" -ErrorAction SilentlyContinue
}
# Limiter la taille des requêtes (anti-DoS)
Set-WebConfigurationProperty -Filter "/system.webServer/security/requestFiltering/requestLimits" -Name "maxAllowedContentLength" -Value 30000000 -PSPath "IIS:\" # 30 Mo max
Set-WebConfigurationProperty -Filter "/system.webServer/security/requestFiltering/requestLimits" -Name "maxUrl" -Value 4096 -PSPath "IIS:\"
Set-WebConfigurationProperty -Filter "/system.webServer/security/requestFiltering/requestLimits" -Name "maxQueryString" -Value 2048 -PSPath "IIS:\"
# Exécuter le pool d'applications avec un compte dédié (pas LocalSystem !)
Set-ItemProperty -Path "IIS:\AppPools\DefaultAppPool" -Name processModel.identityType -Value "SpecificUser"
Durcissement de SQL Server
SQL Server est fréquemment installé sur Windows Server et représente une cible de haute valeur. Les bases de données contiennent souvent des données sensibles (informations personnelles, données financières, credentials applicatifs). Le durcissement couvre l'authentification, le chiffrement, les permissions et l'audit.
# Désactiver l'authentification SQL (mode mixte) — imposer Windows Authentication
# Via SQL Management Objects
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.Smo") | Out-Null
$server = New-Object Microsoft.SqlServer.Management.Smo.Server("localhost")
$server.Settings.LoginMode = [Microsoft.SqlServer.Management.Smo.ServerLoginMode]::Integrated
$server.Alter()
# Désactiver le compte SA si l'authentification mixte est requise
Invoke-Sqlcmd -Query "ALTER LOGIN sa DISABLE; ALTER LOGIN sa WITH NAME = [sa_disabled_$(Get-Random)];"
# Désactiver xp_cmdshell (exécution de commandes OS depuis SQL)
Invoke-Sqlcmd -Query "
EXEC sp_configure 'show advanced options', 1; RECONFIGURE;
EXEC sp_configure 'xp_cmdshell', 0; RECONFIGURE;
EXEC sp_configure 'Ole Automation Procedures', 0; RECONFIGURE;
EXEC sp_configure 'Ad Hoc Distributed Queries', 0; RECONFIGURE;
EXEC sp_configure 'clr enabled', 0; RECONFIGURE;
EXEC sp_configure 'cross db ownership chaining', 0; RECONFIGURE;
"
# Activer l'audit SQL Server
Invoke-Sqlcmd -Query "
CREATE SERVER AUDIT [SecurityAudit]
TO FILE (FILEPATH = 'D:\SQLAudit\', MAXSIZE = 1024 MB, MAX_ROLLOVER_FILES = 10)
WITH (ON_FAILURE = SHUTDOWN);
ALTER SERVER AUDIT [SecurityAudit] WITH (STATE = ON);
CREATE SERVER AUDIT SPECIFICATION [LoginAudit]
FOR SERVER AUDIT [SecurityAudit]
ADD (FAILED_LOGIN_GROUP),
ADD (SUCCESSFUL_LOGIN_GROUP),
ADD (SERVER_ROLE_MEMBER_CHANGE_GROUP),
ADD (DATABASE_ROLE_MEMBER_CHANGE_GROUP)
WITH (STATE = ON);
"
# Activer TDE (Transparent Data Encryption)
Invoke-Sqlcmd -Query "
USE master;
CREATE MASTER KEY ENCRYPTION BY PASSWORD = 'C0mpl3x_P@ssword_TDE_2025!';
CREATE CERTIFICATE TDE_Cert WITH SUBJECT = 'TDE Certificate';
-- Sur chaque base de données sensible :
USE [MaBaseSensible];
CREATE DATABASE ENCRYPTION KEY WITH ALGORITHM = AES_256
ENCRYPTION BY SERVER CERTIFICATE TDE_Cert;
ALTER DATABASE [MaBaseSensible] SET ENCRYPTION ON;
"
Sécurisation de RDP et NLA
Le protocole RDP (Remote Desktop Protocol) est le vecteur d'intrusion initiale numéro un sur Windows Server. 32 % des compromissions de serveurs Windows commencent par une connexion RDP compromise (credentials volés, brute force, exploitation de vulnérabilité). Le durcissement de RDP est une priorité absolue.
# Imposer NLA (Network Level Authentication)
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp" -Name "UserAuthentication" -Value 1
# Imposer TLS 1.2+ pour RDP (Security Layer = 2 = TLS)
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp" -Name "SecurityLayer" -Value 2
# Définir le niveau de chiffrement minimal (3 = High, 4 = FIPS)
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp" -Name "MinEncryptionLevel" -Value 3
# Changer le port RDP par défaut (sécurité par l'obscurité — mesure complémentaire)
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp" -Name "PortNumber" -Value 13389
# Limiter les sessions RDP
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" -Name "MaxInstanceCount" -Value 2
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" -Name "MaxIdleTime" -Value 900000 # 15 min
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" -Name "MaxDisconnectionTime" -Value 300000 # 5 min
# Désactiver le presse-papiers et la redirection de lecteurs (anti-exfiltration)
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" -Name "fDisableClip" -Value 1
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" -Name "fDisableCdm" -Value 1
# Activer Restricted Admin Mode (empêche la mise en cache des credentials)
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Lsa" -Name "DisableRestrictedAdmin" -Value 0
# Connexion en Restricted Admin : mstsc /restrictedadmin
# Activer Remote Credential Guard (meilleure protection)
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Lsa" -Name "DisableRestrictedAdminOutboundCreds" -Value 1
# Connexion avec Remote Credential Guard : mstsc /remoteGuard
Sécurisation DNS, DHCP et services annexes
Le serveur DNS intégré à Active Directory est une cible de choix : un attaquant qui compromet le DNS peut rediriger les requêtes de résolution et réaliser des attaques de type man-in-the-middle à grande échelle. Le service DHCP peut être abusé pour distribuer des configurations réseau malveillantes. Le service Print Spooler a été à l'origine de vulnérabilités critiques (PrintNightmare, CVE-2021-34527) et doit être désactivé sur tous les serveurs qui ne sont pas des serveurs d'impression.
# ============================================================
# DNS — Sécurisation
# ============================================================
# Activer DNSSEC sur les zones DNS
$zones = Get-DnsServerZone | Where-Object {$_.ZoneType -eq "Primary" -and !$_.IsAutoCreated}
foreach ($zone in $zones) {
# Signer la zone avec DNSSEC
Invoke-DnsServerSigningKeyRollover -ZoneName $zone.ZoneName -Force -ErrorAction SilentlyContinue
}
# Désactiver la récursion si le serveur n'est pas un résolveur
Set-DnsServerRecursion -Enable $false
# Limiter les transferts de zone
Set-DnsServerPrimaryZone -Name "domaine.local" -SecureSecondaries TransferToSecureServers
# Activer les logs DNS analytiques
Set-DnsServerDiagnostics -All $true
Set-DnsServerDiagnostics -EnableLogFileRollover $true -LogFilePath "E:\Logs\DNS" -MaxMBFileSize 512
# ============================================================
# PRINT SPOOLER — Désactivation (sauf serveur d'impression)
# ============================================================
Stop-Service -Name Spooler -Force
Set-Service -Name Spooler -StartupType Disabled
Write-Host "Print Spooler désactivé — protection contre PrintNightmare" -ForegroundColor Green
# ============================================================
# WinRM — Sécurisation
# ============================================================
# Imposer HTTPS pour WinRM (port 5986)
# Prérequis : certificat serveur valide
$cert = Get-ChildItem Cert:\LocalMachine\My | Where-Object {$_.Subject -like "*$env:COMPUTERNAME*"}
if ($cert) {
New-Item -Path WSMan:\localhost\Listener -Transport HTTPS -Address * -CertificateThumbPrint $cert.Thumbprint -Force
# Désactiver le listener HTTP (port 5985)
Remove-Item -Path WSMan:\localhost\Listener\Listener_*_HTTP -Recurse -Force
}
# Limiter WinRM aux adresses IP autorisées
Set-Item WSMan:\localhost\Service\IPv4Filter -Value "10.0.100.0/24"
# Activer l'audit WinRM
Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WSMAN\Service" -Name "audit" -Value 1
# ============================================================
# SERVICES INUTILES — Désactivation
# ============================================================
$servicesADesactiver = @(
"Browser", # Computer Browser
"IISADMIN", # IIS Admin (si pas de serveur web)
"RemoteRegistry", # Registre distant
"lmhosts", # TCP/IP NetBIOS Helper
"Fax", # Service de fax
"TapiSrv", # Telephony
"SNMPTRAP", # SNMP Trap
"SharedAccess", # Internet Connection Sharing
"RasAuto", # Remote Access Auto Connection
"RasMan", # Remote Access Connection Manager
"SessionEnv", # Remote Desktop Configuration
"TermService", # Remote Desktop Services (si pas besoin)
"UmRdpService", # Remote Desktop UserMode Port Redirector
"W3SVC", # World Wide Web Publishing (si pas IIS)
"XblAuthManager", # Xbox Live Auth Manager
"XblGameSave" # Xbox Live Game Save
)
foreach ($svc in $servicesADesactiver) {
$service = Get-Service -Name $svc -ErrorAction SilentlyContinue
if ($service) {
Stop-Service -Name $svc -Force -ErrorAction SilentlyContinue
Set-Service -Name $svc -StartupType Disabled
Write-Host "Service $svc désactivé" -ForegroundColor Yellow
}
}
Durcissement du rôle Hyper-V
Windows Server 2025 avec le rôle Hyper-V présente des considérations de sécurité spécifiques. L'hyperviseur est une cible de haute valeur : sa compromission donne accès à toutes les machines virtuelles hébergées. Le durcissement Hyper-V couvre l'isolation réseau des VM, la protection de la partition de management, le chiffrement des VM sensibles et la configuration des switches virtuels.
# ============================================================
# HYPER-V — Durcissement
# ============================================================
# Activer l'intégration Enhanced Session Mode (pour les VM de management uniquement)
Set-VMHost -EnableEnhancedSessionMode $false # Désactiver par défaut
# Configurer le Virtual Switch avec isolation
New-VMSwitch -Name "Production-SW" -SwitchType Internal -Notes "Switch isolé production"
# Activer la protection contre le MAC Address Spoofing sur toutes les VM
Get-VM | Get-VMNetworkAdapter | Set-VMNetworkAdapter -MacAddressSpoofing Off
# Activer le DHCP Guard (empêche une VM de se faire passer pour un serveur DHCP)
Get-VM | Get-VMNetworkAdapter | Set-VMNetworkAdapter -DhcpGuard On
# Activer le Router Guard (empêche une VM de router du trafic)
Get-VM | Get-VMNetworkAdapter | Set-VMNetworkAdapter -RouterGuard On
# Activer le chiffrement des VM sensibles (Shielded VMs)
# Prérequis : Host Guardian Service (HGS) déployé
# $keyProtector = New-HgsKeyProtector -Owner $owner -AllowUntrustedRoot
# Set-VMKeyProtector -VMName "VM-Sensible" -KeyProtector $keyProtector.RawData
# Enable-VMTPM -VMName "VM-Sensible"
# Configurer les limites de ressources pour prévenir le DoS inter-VM
Get-VM | ForEach-Object {
Set-VMProcessor -VMName $_.Name -Maximum 80 # Limiter à 80% CPU max
Set-VMMemory -VMName $_.Name -MaximumBytes 16GB # Plafonner la mémoire
}
# Désactiver les Integration Services non nécessaires
$unnecessaryServices = @("Guest Service Interface", "Time Synchronization")
Get-VM | ForEach-Object {
foreach ($svc in $unnecessaryServices) {
Disable-VMIntegrationService -VMName $_.Name -Name $svc -ErrorAction SilentlyContinue
}
}
# Sauvegarder la configuration Hyper-V
Export-VMHyperVConfiguration -Path "E:\Backup\HyperV-Config"
La partition de management Hyper-V (le serveur hôte lui-même) ne doit jamais être utilisée pour d'autres rôles. Elle ne doit pas exécuter d'applications utilisateur, ne doit pas être utilisée pour la navigation web, et son accès RDP doit être limité aux comptes d'administration Hyper-V dédiés. L'idéal est d'administrer Hyper-V exclusivement via Windows Admin Center ou System Center Virtual Machine Manager (SCVMM), en désactivant la connexion interactive directe sur l'hôte.
Sécurisation des certificats et de la PKI
Les certificats numériques jouent un rôle central dans la sécurité de Windows Server 2025 : authentification LDAPS, chiffrement TLS pour IIS et WinRM, signature de code pour WDAC, chiffrement BitLocker, et authentification machine. La gestion des certificats doit être rigoureuse : inventaire complet, monitoring des expirations, protection des clés privées et audit des émissions. Si l'organisation dispose d'une PKI interne (Active Directory Certificate Services — ADCS), sa sécurisation est critique car une CA compromise permet de forger des certificats d'authentification pour n'importe quel compte du domaine.
# Inventaire complet des certificats sur le serveur
Get-ChildItem Cert:\LocalMachine -Recurse | Where-Object {$_ -is [System.Security.Cryptography.X509Certificates.X509Certificate2]} |
Select-Object Subject, Issuer, NotBefore, NotAfter, Thumbprint, HasPrivateKey,
@{N='DaysToExpiry';E={($_.NotAfter - (Get-Date)).Days}},
@{N='Store';E={$_.PSParentPath -replace '.*::'}} |
Sort-Object NotAfter |
Format-Table -AutoSize
# Identifier les certificats qui expirent dans les 60 prochains jours
$threshold = (Get-Date).AddDays(60)
$expiringCerts = Get-ChildItem Cert:\LocalMachine\My | Where-Object {$_.NotAfter -lt $threshold -and $_.NotAfter -gt (Get-Date)}
if ($expiringCerts) {
Write-Host "ALERTE : $($expiringCerts.Count) certificat(s) expire(nt) dans les 60 jours" -ForegroundColor Red
$expiringCerts | Select-Object Subject, NotAfter | Format-Table
}
# Vérifier la protection des clés privées
Get-ChildItem Cert:\LocalMachine\My | Where-Object {$_.HasPrivateKey} | ForEach-Object {
$keyInfo = $_.PrivateKey
Write-Host "Certificat: $($_.Subject)"
Write-Host " Exportable: $($_.PrivateKey.CspKeyContainerInfo.Exportable)" -ForegroundColor $(if($_.PrivateKey.CspKeyContainerInfo.Exportable){"Red"}else{"Green"})
}
# Sécuriser ADCS — désactiver les templates vulnérables (ESC1-ESC8)
# Vérifier les templates avec enrollment pour les utilisateurs non privilégiés
$templates = Get-ADObject -Filter {objectClass -eq "pKICertificateTemplate"} -SearchBase "CN=Certificate Templates,CN=Public Key Services,CN=Services,CN=Configuration,$((Get-ADDomain).DistinguishedName)" -Properties *
foreach ($tpl in $templates) {
Write-Host "Template: $($tpl.Name)" -ForegroundColor Cyan
Write-Host " msPKI-Certificate-Name-Flag: $($tpl.'msPKI-Certificate-Name-Flag')"
# Flag 1 = ENROLLEE_SUPPLIES_SUBJECT — potentiellement dangereux (ESC1)
if ($tpl.'msPKI-Certificate-Name-Flag' -band 1) {
Write-Host " ALERTE: ENROLLEE_SUPPLIES_SUBJECT activé — risque ESC1 !" -ForegroundColor Red
}
}
Les attaques ADCS (ESC1 à ESC8) sont devenues l'un des vecteurs de compromission Active Directory les plus exploités en 2025. L'outil Certify (côté attaquant) et PSPKIAudit (côté défenseur) permettent d'identifier les templates vulnérables. La sécurisation passe par la revue de chaque template de certificat, la restriction des permissions d'enrollment, la désactivation du flag ENROLLEE_SUPPLIES_SUBJECT sur les templates d'authentification, et l'audit continu des certificats émis.
Restriction de PowerShell et prévention de l'abus de langages de script
PowerShell est à la fois le principal outil d'administration de Windows Server et l'un des outils les plus exploités par les attaquants (living-off-the-land). La stratégie de durcissement PowerShell doit trouver l'équilibre entre fonctionnalité d'administration et restriction des abus. Windows Server 2025 offre le Constrained Language Mode (CLM) qui limite les capacités PowerShell aux cmdlets approuvées et bloque l'accès direct au .NET Framework, aux objets COM et aux API Windows.
# Vérifier le mode de langage PowerShell actuel
$ExecutionContext.SessionState.LanguageMode
# FullLanguage = aucune restriction (par défaut)
# ConstrainedLanguage = mode restreint (recommandé pour les utilisateurs non-admin)
# Activer Constrained Language Mode via la variable d'environnement
# (doit être combiné avec WDAC pour être efficace — sinon contournable)
[Environment]::SetEnvironmentVariable('__PSLockdownPolicy', '4', 'Machine')
# Désactiver PowerShell v2 (contournement classique des restrictions PS v5+)
Disable-WindowsOptionalFeature -Online -FeatureName MicrosoftWindowsPowerShellV2Root -NoRestart
Disable-WindowsOptionalFeature -Online -FeatureName MicrosoftWindowsPowerShellV2 -NoRestart
# Vérifier que PowerShell v2 est bien désactivé
Get-WindowsOptionalFeature -Online -FeatureName MicrosoftWindowsPowerShellV2Root |
Select-Object FeatureName, State
# Configurer l'exécution de scripts signés uniquement
Set-ExecutionPolicy -ExecutionPolicy AllSigned -Scope LocalMachine -Force
# Désactiver Windows Script Host (VBScript, JScript — vecteurs d'attaque classiques)
Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows Script Host\Settings" -Name "Enabled" -Value 0 -Type DWord
# Bloquer les interpréteurs de script dangereux via Software Restriction ou AppLocker
# cscript.exe, wscript.exe, mshta.exe, wmic.exe, regsvr32.exe, rundll32.exe
$dangerousBindings = @("cscript.exe", "wscript.exe", "mshta.exe")
foreach ($exe in $dangerousBindings) {
$exePath = Join-Path $env:SystemRoot "System32\$exe"
if (Test-Path $exePath) {
# Retirer les permissions d'exécution pour tous sauf SYSTEM et Administrators
$acl = Get-Acl $exePath
$acl.SetAccessRuleProtection($true, $false)
$rule = New-Object System.Security.AccessControl.FileSystemAccessRule("BUILTIN\Administrators", "FullControl", "Allow")
$acl.AddAccessRule($rule)
$rule = New-Object System.Security.AccessControl.FileSystemAccessRule("NT AUTHORITY\SYSTEM", "FullControl", "Allow")
$acl.AddAccessRule($rule)
Set-Acl $exePath $acl
Write-Host "Permissions restreintes sur $exe" -ForegroundColor Yellow
}
}
Il est fondamental de comprendre que le Constrained Language Mode seul n'est pas suffisant. Sans WDAC, un attaquant peut contourner CLM en créant un script signé ou en utilisant un exécutable compilé. La combinaison WDAC + CLM est la seule configuration qui résiste aux contournements connus. De plus, la désactivation de PowerShell v2 est critique car cette version ancienne ne supporte ni le Script Block Logging ni le CLM, et un attaquant peut forcer son utilisation via powershell.exe -Version 2 si elle est installée.
Sécurisation des services — au-delà des basiques :
- Désactiver PowerShell v2 sur tous les serveurs — contournement classique du logging et du CLM
- Activer les règles ASR de Windows Defender, notamment la protection LSASS
- Isoler la partition de management Hyper-V — jamais d'autres rôles sur l'hôte
- Auditer les templates ADCS pour les vulnérabilités ESC1 à ESC8
- Combiner WDAC + Constrained Language Mode pour une restriction PowerShell efficace
Logging et monitoring avancé
Configuration des Event Logs
La taille par défaut des journaux d'événements Windows est ridiculement insuffisante pour un serveur de production. Le journal Security est limité à 20 Mo par défaut, ce qui est écrasé en quelques heures sur un serveur actif. Un attaquant sophistiqué peut intentionnellement générer du bruit pour faire tourner les logs et effacer ses traces. La première action est d'augmenter considérablement la taille de tous les journaux critiques.
# Augmenter la taille des journaux d'événements
$logConfig = @{
"Security" = 4GB # 4 Go — journal le plus critique
"System" = 1GB
"Application" = 1GB
"Microsoft-Windows-Sysmon/Operational" = 2GB
"Microsoft-Windows-PowerShell/Operational" = 1GB
"Microsoft-Windows-WMI-Activity/Operational" = 512MB
"Microsoft-Windows-TaskScheduler/Operational" = 512MB
"Microsoft-Windows-TerminalServices-LocalSessionManager/Operational" = 512MB
"Directory Service" = 1GB # DC uniquement
}
foreach ($log in $logConfig.GetEnumerator()) {
try {
$eventLog = Get-WinEvent -ListLog $log.Key -ErrorAction Stop
$eventLog.MaximumSizeInBytes = $log.Value
$eventLog.IsEnabled = $true
$eventLog.LogMode = "Circular" # Ou "AutoBackup" pour archivage
$eventLog.SaveChanges()
Write-Host "Journal $($log.Key) configuré à $($log.Value / 1MB) Mo" -ForegroundColor Green
} catch {
Write-Host "Impossible de configurer $($log.Key): $_" -ForegroundColor Red
}
}
# Activer les logs PowerShell détaillés (Script Block Logging + Transcription)
$psLogPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell"
# Script Block Logging — enregistre TOUT le code PowerShell exécuté
New-Item -Path "$psLogPath\ScriptBlockLogging" -Force | Out-Null
Set-ItemProperty -Path "$psLogPath\ScriptBlockLogging" -Name "EnableScriptBlockLogging" -Value 1
Set-ItemProperty -Path "$psLogPath\ScriptBlockLogging" -Name "EnableScriptBlockInvocationLogging" -Value 1
# Module Logging
New-Item -Path "$psLogPath\ModuleLogging" -Force | Out-Null
Set-ItemProperty -Path "$psLogPath\ModuleLogging" -Name "EnableModuleLogging" -Value 1
New-Item -Path "$psLogPath\ModuleLogging\ModuleNames" -Force | Out-Null
Set-ItemProperty -Path "$psLogPath\ModuleLogging\ModuleNames" -Name "*" -Value "*"
# Transcription PowerShell — sauvegarde en fichier texte
New-Item -Path "$psLogPath\Transcription" -Force | Out-Null
Set-ItemProperty -Path "$psLogPath\Transcription" -Name "EnableTranscripting" -Value 1
Set-ItemProperty -Path "$psLogPath\Transcription" -Name "OutputDirectory" -Value "E:\Logs\PowerShell\Transcripts"
Set-ItemProperty -Path "$psLogPath\Transcription" -Name "EnableInvocationHeader" -Value 1
Sysmon : la visibilité que Windows ne fournit pas nativement
Sysmon (System Monitor) est l'outil de monitoring indispensable pour tout serveur Windows en environnement de production. Développé par l'équipe Sysinternals (propriété de Microsoft), Sysmon est gratuit, léger (moins de 2 % de surcharge CPU en fonctionnement normal) et extrêmement puissant. Son principal avantage réside dans sa capacité à fournir un contexte riche pour chaque événement : lorsqu'un processus est créé, Sysmon enregistre non seulement le nom et le chemin de l'exécutable, mais aussi la ligne de commande complète, le hash du fichier (MD5, SHA256, IMPHASH), le processus parent avec sa ligne de commande, l'utilisateur qui a lancé le processus, la session logon associée, et les flags d'intégrité. Cette richesse d'information transforme la capacité de détection et de forensique. Sans Sysmon, un analyste SOC qui voit un Event ID 4688 (process creation) dans le journal Security n'a que le nom du processus et le compte — avec Sysmon, il a l'intégralité de la chaîne d'exécution permettant de reconstruire l'attaque étape par étape.
La configuration de Sysmon détermine sa valeur. Une configuration par défaut sans fichier XML personnalisé enregistre trop d'événements inutiles et rate des événements critiques. La communauté de sécurité maintient plusieurs configurations de référence. La plus utilisée est celle de SwiftOnSecurity (github.com/SwiftOnSecurity/sysmon-config), qui filtre intelligemment le bruit tout en capturant les événements pertinents pour la détection d'intrusion. Pour les environnements avancés, la configuration Olaf Hartong (sysmon-modular) offre une approche modulaire permettant d'activer ou désactiver des catégories de détection spécifiques. Quelle que soit la configuration choisie, elle doit être personnalisée pour l'environnement spécifique : ajouter les chemins des applications métier dans les exclusions, et ajouter des règles de détection pour les outils d'attaque spécifiques à votre secteur.
Sysmon fournit une visibilité granulaire sur les événements que les journaux Windows natifs ne capturent pas : création de processus avec arborescence complète, connexions réseau par processus, chargement de DLL, modification du registre, accès aux fichiers sensibles, création de threads distants (injection de code), et bien plus. La configuration de Sysmon est définie par un fichier XML qui détermine quels événements sont capturés et lesquels sont filtrés.
# Télécharger et installer Sysmon
# https://learn.microsoft.com/en-us/sysinternals/downloads/sysmon
# Utiliser la configuration SwiftOnSecurity comme base
# https://github.com/SwiftOnSecurity/sysmon-config
# Installation avec une configuration optimisée
.\Sysmon64.exe -accepteula -i sysmonconfig-export.xml
# Configuration Sysmon recommandée pour Windows Server 2025 (extrait)
# Les Event IDs critiques à monitorer :
# - ID 1 : Process Creation (avec hash et ligne de commande complète)
# - ID 3 : Network Connection (connexions sortantes suspectes)
# - ID 7 : Image Loaded (chargement de DLL — détection DLL injection)
# - ID 8 : CreateRemoteThread (injection de code inter-processus)
# - ID 10 : ProcessAccess (détection LSASS dump — Mimikatz)
# - ID 11 : FileCreate (création de fichiers dans répertoires sensibles)
# - ID 12/13/14 : Registry Events (persistence via registre)
# - ID 22 : DNS Query (résolution DNS suspecte — C2 detection)
# - ID 23 : FileDelete (détection ransomware — suppression massive)
# - ID 25 : ProcessTampering (process hollowing, herpaderping)
# Vérifier que Sysmon est installé et opérationnel
Get-Service Sysmon64 | Select-Object Status, StartType
Get-WinEvent -LogName "Microsoft-Windows-Sysmon/Operational" -MaxEvents 5 | Format-Table TimeCreated, Id, Message -Wrap
# Mettre à jour la configuration Sysmon sans réinstaller
.\Sysmon64.exe -c sysmonconfig-updated.xml
Événements critiques à surveiller
Parmi les milliers d'Event IDs Windows, certains sont des indicateurs directs de compromission (IoC) ou de tentatives d'attaque. La liste suivante représente les événements à haute priorité qui doivent déclencher une alerte immédiate dans le SIEM. Pour l'intégration avec un SIEM, consultez notre article sur la détection de menaces par IA et SIEM augmenté.
# ============================================================
# ÉVÉNEMENTS CRITIQUES — Requêtes de détection
# ============================================================
# 4624/4625 — Connexions réussies/échouées
# Détecter le brute force (>10 échecs en 5 min pour un même compte)
Get-WinEvent -FilterHashtable @{LogName='Security'; Id=4625; StartTime=(Get-Date).AddMinutes(-5)} |
Group-Object {$_.Properties[5].Value} |
Where-Object {$_.Count -gt 10} |
Format-Table Name, Count
# 4672 — Attribution de privilèges spéciaux (élévation)
Get-WinEvent -FilterHashtable @{LogName='Security'; Id=4672; StartTime=(Get-Date).AddHours(-1)} |
Select-Object TimeCreated, @{N='User';E={$_.Properties[1].Value}} |
Format-Table -AutoSize
# 4720 — Création de compte utilisateur (backdoor potentielle)
Get-WinEvent -FilterHashtable @{LogName='Security'; Id=4720; StartTime=(Get-Date).AddDays(-7)} |
Select-Object TimeCreated, @{N='Creator';E={$_.Properties[4].Value}}, @{N='NewAccount';E={$_.Properties[0].Value}}
# 4728/4732/4756 — Ajout à un groupe de sécurité (Domain Admins, etc.)
Get-WinEvent -FilterHashtable @{LogName='Security'; Id=4728,4732,4756; StartTime=(Get-Date).AddDays(-7)} |
Select-Object TimeCreated, @{N='Group';E={$_.Properties[2].Value}}, @{N='Member';E={$_.Properties[0].Value}}
# 4688 — Création de processus suspect (outils d'attaque)
$suspiciousProcesses = @("mimikatz", "rubeus", "certify", "sharphound", "bloodhound", "psexec", "procdump", "lazagne", "secretsdump", "impacket", "cobalt", "beacon")
Get-WinEvent -FilterHashtable @{LogName='Security'; Id=4688; StartTime=(Get-Date).AddHours(-24)} |
Where-Object {
$cmd = $_.Properties[8].Value
$suspiciousProcesses | Where-Object {$cmd -like "*$_*"}
} | Format-Table TimeCreated, @{N='CommandLine';E={$_.Properties[8].Value}}
# 1102 — Effacement du journal de sécurité (anti-forensics)
Get-WinEvent -FilterHashtable @{LogName='Security'; Id=1102} |
Select-Object TimeCreated, @{N='ClearedBy';E={$_.Properties[1].Value}}
# 4697 — Installation d'un service (persistence)
Get-WinEvent -FilterHashtable @{LogName='Security'; Id=4697; StartTime=(Get-Date).AddDays(-7)} |
Select-Object TimeCreated, @{N='ServiceName';E={$_.Properties[4].Value}}, @{N='ServicePath';E={$_.Properties[5].Value}}
# 4768/4769 — Kerberos TGT/TGS (détection Kerberoasting, Golden Ticket)
# Tickets avec chiffrement RC4 (0x17) = suspect
Get-WinEvent -FilterHashtable @{LogName='Security'; Id=4769; StartTime=(Get-Date).AddHours(-1)} |
Where-Object {$_.Properties[5].Value -eq "0x17"} |
Select-Object TimeCreated, @{N='ServiceName';E={$_.Properties[0].Value}}, @{N='ClientAddress';E={$_.Properties[6].Value}}
Windows Event Forwarding (WEF)
Le WEF (Windows Event Forwarding) permet de centraliser les événements de sécurité de tous les serveurs vers un collecteur unique, sans installer d'agent tiers. Cette architecture est recommandée par Microsoft et l'ANSSI comme première étape avant l'intégration SIEM. Le collecteur WEF peut ensuite transmettre les événements au SIEM pour corrélation et analyse avancée.
# ============================================================
# CONFIGURATION DU COLLECTEUR WEF
# ============================================================
# Sur le serveur collecteur : activer le service Windows Event Collector
wecutil qc /q
# Créer un abonnement pour les événements de sécurité critiques
$subscriptionXml = @"
SecurityEvents-Critical
SourceInitiated
Événements de sécurité critiques de tous les serveurs
true
http://schemas.microsoft.com/wbem/wsman/1/windows/EventLog
Custom
60000
]]>
false
HTTP
O:NSG:NSD:(A;;GA;;;DC)(A;;GA;;;NS)
"@
$subscriptionXml | Out-File "C:\Temp\WEF-Critical.xml" -Encoding UTF8
wecutil cs "C:\Temp\WEF-Critical.xml"
# Sur les serveurs sources : configurer le forwarding via GPO
# Computer Configuration > Administrative Templates > Windows Components
# > Event Forwarding > Configure target Subscription Manager
# Valeur : Server=http://wef-collector.domaine.local:5985/wsman/SubscriptionManager/WEC
# Vérifier le statut des abonnements
wecutil es # Liste les abonnements
wecutil gs "SecurityEvents-Critical" # Détails d'un abonnement
wecutil gr "SecurityEvents-Critical" # Runtime status
Logging et monitoring — les fondamentaux :
- Augmenter le journal Security à 4 Go minimum — 20 Mo par défaut est une aberration
- Déployer Sysmon sur 100 % des serveurs avec la config SwiftOnSecurity comme base
- Activer Script Block Logging et Transcription PowerShell
- Surveiller en priorité : Event ID 1102 (effacement logs), 4720 (création compte), 4728 (ajout groupe admin), 4769 avec RC4 (Kerberoasting)
- Centraliser avec WEF avant d'intégrer au SIEM
Intégration SIEM et corrélation d'événements
La centralisation des logs via WEF n'est que la première étape. L'intégration avec un SIEM (Security Information and Event Management) comme Microsoft Sentinel, Splunk, Elastic Security ou Wazuh permet la corrélation d'événements provenant de sources multiples (Windows Events, Sysmon, pare-feu, antivirus, proxy web, VPN) pour détecter des attaques complexes qui ne seraient pas visibles dans une source unique. Par exemple, une attaque de type Kerberoasting génère un Event ID 4769 avec chiffrement RC4 sur le DC (source AD), suivi d'un trafic réseau sortant anormal (source pare-feu), puis d'une tentative de connexion avec un compte de service depuis une IP inhabituelle (source VPN ou proxy). Seule la corrélation de ces trois événements dans un SIEM permet de détecter l'attaque dans sa globalité.
Les règles de corrélation essentielles pour Windows Server 2025 doivent couvrir les scénarios suivants : brute force (plus de 10 échecs de connexion en 5 minutes depuis une même source), lateral movement (connexion réseau réussie suivie d'une création de service ou de tâche planifiée sur un serveur distant), privilege escalation (attribution de SeDebugPrivilege ou ajout à un groupe privilégié par un compte non autorisé), data exfiltration (volume de données transféré anormalement élevé vers une IP externe), et ransomware (création de fichiers avec extensions suspectes, suppression des shadow copies, modification de boot configuration).
# Exemple de règles de détection pour Wazuh/Elastic (format pseudo-code)
# Ces règles doivent être adaptées au SIEM utilisé
# Règle 1 : Détection de Password Spraying
# Condition : > 5 comptes différents échouent avec le même mot de passe en 10 min
# Sources : Event ID 4625 (Windows Security Log)
# Sévérité : Critique
# Règle 2 : Détection de DCSync (extraction de la base AD)
# Condition : Event ID 4662 avec droits "DS-Replication-Get-Changes-All"
# par un compte NON contrôleur de domaine
# Sources : Event ID 4662 (Directory Service)
# Sévérité : Critique
# Règle 3 : Détection de Golden Ticket
# Condition : Event ID 4768 (TGT request) avec un compte inexistant ou
# un TGT avec durée de vie anormalement longue
# Sources : Event ID 4768, 4769 (Kerberos)
# Sévérité : Critique
# PowerShell — Vérifier les événements suspects de réplication AD
Get-WinEvent -FilterHashtable @{LogName='Security'; Id=4662; StartTime=(Get-Date).AddHours(-24)} |
Where-Object {
$_.Message -match "DS-Replication-Get-Changes" -and
$_.Message -notmatch "DC\$" # Exclure les comptes machine des DC
} | Select-Object TimeCreated, @{N='Account';E={$_.Properties[1].Value}},
@{N='AccessMask';E={$_.Properties[8].Value}} | Format-Table
# Configurer l'envoi des logs vers un SIEM Syslog (Splunk, Elastic, etc.)
# Via NXLog Community Edition (agent de forwarding de logs)
# Configuration NXLog pour envoyer les événements critiques en temps réel
# Protocole recommandé : TLS/TCP vers le collecteur SIEM
Détection des techniques Living Off The Land (LOLBins)
Les attaquants modernes utilisent de moins en moins de malware personnalisé et de plus en plus les outils légitimes du système d'exploitation — une technique appelée Living Off The Land (LOTL). Sur Windows Server 2025, les binaires les plus abusés sont : PowerShell.exe (exécution de code), certutil.exe (téléchargement de fichiers, encodage/décodage), mshta.exe (exécution de HTA malveillant), rundll32.exe (chargement de DLL arbitraire), regsvr32.exe (exécution de scriptlets via squiblydoo), msbuild.exe (exécution de code C# inline), bitsadmin.exe (téléchargement de fichiers) et wmic.exe (exécution de commandes distantes). La détection de l'abus de ces binaires nécessite une combinaison de Sysmon (Event ID 1 — Process Creation) avec des règles de détection basées sur les paramètres de ligne de commande inhabituels.
# Détection LOLBins — requêtes de chasse aux menaces (Threat Hunting)
# Détecter l'utilisation suspecte de certutil (téléchargement ou décodage)
Get-WinEvent -FilterHashtable @{LogName='Microsoft-Windows-Sysmon/Operational'; Id=1} |
Where-Object {$_.Message -match "certutil.*(-urlcache|-decode|-encode|-verifyctl)"} |
Select-Object TimeCreated, @{N='CommandLine';E={($_.Message -split "`n" | Select-String "CommandLine:").ToString().Trim()}}
# Détecter l'utilisation de mshta.exe (exécution de contenu distant)
Get-WinEvent -FilterHashtable @{LogName='Microsoft-Windows-Sysmon/Operational'; Id=1} |
Where-Object {$_.Message -match "mshta.*http"} |
Select-Object TimeCreated, @{N='CommandLine';E={($_.Message -split "`n" | Select-String "CommandLine:").ToString().Trim()}}
# Détecter l'utilisation de bitsadmin pour télécharger des fichiers
Get-WinEvent -FilterHashtable @{LogName='Microsoft-Windows-Sysmon/Operational'; Id=1} |
Where-Object {$_.Message -match "bitsadmin.*/transfer"} |
Select-Object TimeCreated, @{N='CommandLine';E={($_.Message -split "`n" | Select-String "CommandLine:").ToString().Trim()}}
# Détecter les connexions réseau sortantes de processus suspects
# Sysmon Event ID 3 — Network Connection
Get-WinEvent -FilterHashtable @{LogName='Microsoft-Windows-Sysmon/Operational'; Id=3} |
Where-Object {
$_.Message -match "(powershell|cmd|certutil|mshta|rundll32|wscript|cscript)\.exe" -and
$_.Message -match "DestinationPort: (80|443|8080|4444|5555)"
} | Select-Object TimeCreated, @{N='Process';E={($_.Message -split "`n" | Select-String "Image:").ToString().Trim()}},
@{N='DestIP';E={($_.Message -split "`n" | Select-String "DestinationIp:").ToString().Trim()}}
# Créer un rapport de LOLBins suspects sur les dernières 24h
$suspiciousLolbins = @("certutil", "mshta", "rundll32", "regsvr32", "msbuild", "bitsadmin", "wmic")
$report = @()
foreach ($lolbin in $suspiciousLolbins) {
$events = Get-WinEvent -FilterHashtable @{LogName='Microsoft-Windows-Sysmon/Operational'; Id=1; StartTime=(Get-Date).AddHours(-24)} -ErrorAction SilentlyContinue |
Where-Object {$_.Message -match "$lolbin\.exe"}
if ($events) {
$report += [PSCustomObject]@{LOLBin=$lolbin; Count=$events.Count; LastSeen=$events[0].TimeCreated}
}
}
$report | Format-Table LOLBin, Count, LastSeen -AutoSize
Patch management et gestion des vulnérabilités
Stratégie de patch management pour Windows Server 2025
Le Patch Tuesday de Microsoft (deuxième mardi de chaque mois) est le moment clé du cycle de patch management. Cependant, les correctifs out-of-band (hors cycle) pour les vulnérabilités critiques exploitées activement sont de plus en plus fréquents. En 2025, Microsoft a publié 23 correctifs out-of-band, dont 8 pour des zero-days activement exploités. La stratégie de patch management doit intégrer ces deux rythmes.
L'architecture recommandée repose sur un serveur WSUS (Windows Server Update Services) pour les environnements on-premise, complété par SCCM/MECM (Microsoft Endpoint Configuration Manager) pour les parcs importants, ou Microsoft Intune pour les environnements hybrides. Le déploiement suit un processus en 4 phases : test en laboratoire (J+1), déploiement pilote (J+3), déploiement progressif production (J+7 à J+14), et vérification de conformité (J+30).
# ============================================================
# WSUS — Configuration et gestion
# ============================================================
# Installer le rôle WSUS
Install-WindowsFeature -Name UpdateServices, UpdateServices-DB, UpdateServices-RSAT -IncludeManagementTools
# Configuration initiale de WSUS
& "C:\Program Files\Update Services\Tools\wsusutil.exe" postinstall CONTENT_DIR=D:\WSUS SQL_INSTANCE_NAME="localhost"
# Configurer les produits et classifications à synchroniser
[void][reflection.assembly]::LoadWithPartialName("Microsoft.UpdateServices.Administration")
$wsus = [Microsoft.UpdateServices.Administration.AdminProxy]::getUpdateServer()
# Configurer les classifications (Critique + Sécurité uniquement par défaut)
$classifications = $wsus.GetUpdateClassifications()
$classifications | ForEach-Object {$_.Enabled = $false}
$classifications | Where-Object {$_.Title -in @("Critical Updates", "Security Updates", "Definition Updates")} |
ForEach-Object {$_.Enabled = $true}
# Créer des groupes d'ordinateurs pour le déploiement progressif
$wsus.CreateComputerTargetGroup("Phase1-Pilote")
$wsus.CreateComputerTargetGroup("Phase2-Production-NonCritique")
$wsus.CreateComputerTargetGroup("Phase3-Production-Critique")
$wsus.CreateComputerTargetGroup("Phase4-DC")
# ============================================================
# VÉRIFICATION DE CONFORMITÉ
# ============================================================
# Vérifier les mises à jour manquantes sur le serveur local
$updateSession = New-Object -ComObject Microsoft.Update.Session
$updateSearcher = $updateSession.CreateUpdateSearcher()
$searchResult = $updateSearcher.Search("IsInstalled=0 AND Type='Software'")
Write-Host "`n=== Mises à jour manquantes ===" -ForegroundColor Red
$searchResult.Updates | ForEach-Object {
Write-Host " - $($_.Title)" -ForegroundColor Yellow
Write-Host " Sévérité: $($_.MsrcSeverity)" -ForegroundColor Cyan
}
# Rapport PowerShell sur le statut des patches
Get-HotFix | Sort-Object InstalledOn -Descending | Select-Object -First 20 |
Format-Table HotFixID, Description, InstalledOn, InstalledBy
Gestion des correctifs out-of-band et des zero-days
Les correctifs out-of-band (OOB) sont publiés par Microsoft en dehors du cycle mensuel du Patch Tuesday pour corriger des vulnérabilités critiques activement exploitées. En 2025, le temps moyen entre la publication d'un exploit public et la première exploitation en masse est tombé à 3,7 jours selon le rapport Mandiant. Ce délai extrêmement court signifie que le processus habituel de test en laboratoire puis déploiement progressif n'est pas applicable pour les correctifs OOB. Une procédure d'urgence doit être définie et testée à l'avance.
La procédure de patching d'urgence recommandée suit ce workflow : dès la publication d'un correctif OOB avec exploitation active confirmée (CISA KEV, Microsoft Security Response Center), l'équipe sécurité évalue l'exposition de l'infrastructure en moins de 2 heures. Si les serveurs sont exposés, le correctif est déployé en moins de 24 heures sur les serveurs critiques (DC, serveurs de messagerie, serveurs web exposés), en acceptant le risque de régression. Le déploiement sur le reste du parc suit dans les 72 heures. Un rollback plan doit être prêt avant chaque déploiement d'urgence.
# Script de déploiement d'urgence d'un correctif OOB
param(
[string]$KBNumber = "KB5040442", # Numéro du correctif à déployer
[string[]]$TargetServers = @("DC01", "DC02", "EXC01", "WEB01")
)
foreach ($server in $TargetServers) {
Write-Host "`n=== Déploiement $KBNumber sur $server ===" -ForegroundColor Cyan
# Vérifier si le correctif est déjà installé
$installed = Invoke-Command -ComputerName $server -ScriptBlock {
Get-HotFix -Id $using:KBNumber -ErrorAction SilentlyContinue
}
if ($installed) {
Write-Host " DÉJÀ INSTALLÉ : $KBNumber sur $server" -ForegroundColor Green
continue
}
# Créer un point de restauration avant le patching
Invoke-Command -ComputerName $server -ScriptBlock {
wbadmin start systemstatebackup -backupTarget:E: -quiet
}
# Forcer la détection et l'installation via WSUS
Invoke-Command -ComputerName $server -ScriptBlock {
$session = New-Object -ComObject Microsoft.Update.Session
$searcher = $session.CreateUpdateSearcher()
$searchResult = $searcher.Search("IsInstalled=0 AND Type='Software'")
$targetUpdate = $searchResult.Updates | Where-Object {$_.Title -like "*$using:KBNumber*"}
if ($targetUpdate) {
$downloader = $session.CreateUpdateDownloader()
$downloader.Updates = $targetUpdate
$downloader.Download()
$installer = $session.CreateUpdateInstaller()
$installer.Updates = $targetUpdate
$result = $installer.Install()
Write-Host " Résultat installation : $($result.ResultCode)" -ForegroundColor $(
if ($result.ResultCode -eq 2) {"Green"} else {"Red"}
)
}
}
}
# Vérification post-déploiement
Write-Host "`n=== VÉRIFICATION ===" -ForegroundColor Cyan
foreach ($server in $TargetServers) {
$check = Invoke-Command -ComputerName $server -ScriptBlock {
Get-HotFix -Id $using:KBNumber -ErrorAction SilentlyContinue
}
$status = if ($check) {"OK"} else {"MANQUANT"}
Write-Host " $server : $status" -ForegroundColor $(if ($check) {"Green"} else {"Red"})
}
Vulnerability scanning et priorisation
Le patch management ne se limite pas à l'application des correctifs Microsoft. Les applications tierces installées sur les serveurs (Java, .NET Framework, OpenSSL, agents de monitoring) représentent une surface d'attaque souvent négligée. Un programme de vulnerability scanning régulier est indispensable pour identifier les failles non couvertes par WSUS.
# Script d'audit rapide des vulnérabilités connues
# Vérifier les versions des composants critiques
# Vérifier la version .NET Framework
Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full" | Select-Object Release, Version
# Vérifier la version de PowerShell
$PSVersionTable.PSVersion
# Vérifier la version TLS configurée
[Net.ServicePointManager]::SecurityProtocol
# Vérifier les certificats expirés ou bientôt expirés
Get-ChildItem Cert:\LocalMachine\My | Where-Object {$_.NotAfter -lt (Get-Date).AddDays(30)} |
Select-Object Subject, NotAfter, Thumbprint |
Format-Table -AutoSize
# Vérifier les logiciels installés et leurs versions
Get-ItemProperty HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\* |
Where-Object {$_.DisplayName} |
Select-Object DisplayName, DisplayVersion, Publisher, InstallDate |
Sort-Object DisplayName |
Format-Table -AutoSize
# Vérifier si le serveur est vulnérable à des CVE connues
# Exemple : vérifier PrintNightmare (CVE-2021-34527)
$spoolerService = Get-Service -Name Spooler
if ($spoolerService.Status -eq "Running") {
Write-Host "ALERTE : Print Spooler est activé — risque PrintNightmare !" -ForegroundColor Red
} else {
Write-Host "OK : Print Spooler est désactivé" -ForegroundColor Green
}
# Vérifier les patches spécifiques
$criticalKBs = @("KB5034439", "KB5035857", "KB5036893") # Exemples de KB critiques
foreach ($kb in $criticalKBs) {
$installed = Get-HotFix -Id $kb -ErrorAction SilentlyContinue
if ($installed) {
Write-Host "OK : $kb installé le $($installed.InstalledOn)" -ForegroundColor Green
} else {
Write-Host "MANQUANT : $kb non installé !" -ForegroundColor Red
}
}
Backup et recovery
Stratégie de sauvegarde 3-2-1
La règle 3-2-1 est le standard industriel de sauvegarde : 3 copies des données, sur 2 types de support différents, dont 1 copie hors site (ou hors ligne). Pour un Windows Server 2025, cette stratégie doit être complétée par une copie immuable (non modifiable même par un administrateur) pour résister aux attaques ransomware qui ciblent systématiquement les sauvegardes. Les détails sur la réponse aux incidents ransomware sont couverts dans notre guide Ransomware : Kill Chain et Contre-mesures.
# ============================================================
# WINDOWS SERVER BACKUP — Configuration
# ============================================================
# Installer la fonctionnalité Windows Server Backup
Install-WindowsFeature Windows-Server-Backup -IncludeManagementTools
# Créer une politique de sauvegarde quotidienne
$policy = New-WBPolicy
# Ajouter les volumes à sauvegarder
$volume = Get-WBVolume -AllVolumes | Where-Object {$_.MountPoint -eq "C:"}
Add-WBVolume -Policy $policy -Volume $volume
# Ajouter la cible de sauvegarde (volume dédié ou partage réseau)
$backupTarget = New-WBBackupTarget -NetworkPath "\\backup-server\WS-Backups$" -Credential (Get-Credential)
Add-WBBackupTarget -Policy $policy -Target $backupTarget
# Configurer le planning (quotidien à 2h)
Set-WBSchedule -Policy $policy -Schedule 02:00
# Inclure le System State (critique pour les DC)
Add-WBSystemState -Policy $policy
# Inclure les BMR (Bare Metal Recovery) components
Add-WBBareMetalRecovery -Policy $policy
# Appliquer la politique
Set-WBPolicy -Policy $policy -Force
# Vérifier le statut de la dernière sauvegarde
Get-WBJob -Previous 5 | Select-Object StartTime, EndTime, JobState, HResult | Format-Table
Sauvegarde Active Directory : ntdsutil et snapshots
La sauvegarde d'un contrôleur de domaine nécessite des considérations spécifiques. Le fichier NTDS.dit contient l'intégralité de la base de données Active Directory et ne peut pas être sauvegardé par une simple copie de fichier (il est verrouillé en permanence). La sauvegarde du System State via Windows Server Backup est la méthode officielle. En complément, ntdsutil permet de créer des snapshots de la base AD pour l'analyse forensique ou la restauration granulaire.
# ============================================================
# SAUVEGARDE ACTIVE DIRECTORY
# ============================================================
# Méthode 1 : Windows Server Backup avec System State
wbadmin start systemstatebackup -backupTarget:E: -quiet
# Méthode 2 : Snapshot AD via ntdsutil (pour analyse/restauration granulaire)
ntdsutil "activate instance ntds" "snapshot" "create" quit quit
# Lister les snapshots existants
ntdsutil "activate instance ntds" "snapshot" "list all" quit quit
# Monter un snapshot pour analyse
ntdsutil "activate instance ntds" "snapshot" "mount {GUID-du-snapshot}" quit quit
# Le snapshot est accessible via dsamain :
dsamain -dbpath "C:\$SNAP_datetime_VOLUMEC$\Windows\NTDS\ntds.dit" -ldapPort 50000
# ============================================================
# TEST DE RESTAURATION (à faire RÉGULIÈREMENT)
# ============================================================
# Vérifier l'intégrité de la base AD
$dbPath = (Get-ItemProperty "HKLM:\SYSTEM\CurrentControlSet\Services\NTDS\Parameters")."DSA Database File"
esentutl /g $dbPath /!10240 /8 /o
# Script de vérification automatique de la sauvegarde
$lastBackup = Get-WBJob -Previous 1
if ($lastBackup.JobState -eq "Completed" -and $lastBackup.HResult -eq 0) {
$age = (Get-Date) - $lastBackup.EndTime
if ($age.TotalHours -gt 25) {
Write-Host "ALERTE : Dernière sauvegarde réussie il y a $([math]::Round($age.TotalHours)) heures" -ForegroundColor Red
} else {
Write-Host "OK : Sauvegarde récente ($([math]::Round($age.TotalHours))h)" -ForegroundColor Green
}
} else {
Write-Host "CRITIQUE : Dernière sauvegarde en échec ! HResult: $($lastBackup.HResult)" -ForegroundColor Red
}
# Sauvegarde DFSR/SYSVOL (complémentaire)
# SYSVOL est répliqué via DFS-R — la sauvegarde System State le couvre
# Vérification de la santé DFS-R :
dfsrdiag PollAD /member:$env:COMPUTERNAME
Get-DfsrBacklog -GroupName "Domain System Volume" -SourceComputerName $env:COMPUTERNAME -DestinationComputerName "DC02"
Plan de Disaster Recovery pour Windows Server 2025
Un plan de Disaster Recovery (DR) pour Windows Server 2025 doit documenter précisément les procédures de restauration pour chaque scénario de sinistre : panne matérielle simple (disque, alimentation), corruption logicielle (mise à jour défectueuse, ransomware), compromission Active Directory (Golden Ticket, destruction malveillante d'objets AD), et sinistre physique total (incendie, inondation du datacenter). Chaque scénario requiert une procédure différente et un RTO (Recovery Time Objective) et RPO (Recovery Point Objective) définis.
Pour un contrôleur de domaine, le scénario le plus critique est la compromission complète de la forêt Active Directory. Dans ce cas, la procédure de forest recovery documentée par Microsoft doit être suivie : isoler tous les DC du réseau, identifier un DC sain avec une sauvegarde de System State valide, restaurer le premier DC à partir de la sauvegarde, effectuer un nettoyage des métadonnées AD pour retirer les DC compromis, changer tous les mots de passe (krbtgt deux fois, trust passwords, Administrator), puis reconstruire les DC supplémentaires par promotion. Cette procédure prend typiquement entre 24 et 72 heures et doit être testée au moins une fois par an dans un environnement isolé.
# ============================================================
# DISASTER RECOVERY — Procédures critiques
# ============================================================
# Procédure de restauration authoritative d'un objet AD supprimé
# (Utilisation de la Corbeille AD — Active Directory Recycle Bin)
# Vérifier que la corbeille AD est activée
Get-ADOptionalFeature -Filter {Name -eq "Recycle Bin Feature"} |
Select-Object Name, EnabledScopes
# Activer la corbeille AD (si non activée — opération irréversible)
# Enable-ADOptionalFeature -Identity "Recycle Bin Feature" -Scope ForestOrConfigurationSet -Target "domaine.local" -Confirm:$false
# Restaurer un objet supprimé via la corbeille AD
Get-ADObject -Filter {DisplayName -eq "Objet Supprimé"} -IncludeDeletedObjects |
Restore-ADObject
# Restauration authoritative (quand la corbeille n'est pas disponible)
# 1. Démarrer le DC en mode DSRM (F8 au boot)
# 2. Se connecter avec le mot de passe DSRM
# 3. Exécuter ntdsutil :
# ntdsutil "authoritative restore" "restore subtree OU=Finance,DC=domaine,DC=local" quit quit
# 4. Redémarrer normalement — les données restaurées seront répliquées vers tous les DC
# Vérification de l'intégrité de la base AD après restauration
dcdiag /v /c /d /e /s:DC01
repadmin /replsummary
repadmin /showrepl DC01
# Test de disaster recovery automatisé
# Script à planifier mensuellement pour valider la capacité de restauration
$drTestResults = @()
# Test 1 : Vérifier que la sauvegarde System State est valide
$lastBackup = Get-WBJob -Previous 1
$drTestResults += [PSCustomObject]@{
Test = "Sauvegarde System State"
Status = if ($lastBackup.JobState -eq "Completed") {"PASS"} else {"FAIL"}
Detail = "Dernière: $($lastBackup.EndTime)"
}
# Test 2 : Vérifier que tous les DC répliquent correctement
$replErrors = repadmin /showrepl /errorsonly 2>&1
$drTestResults += [PSCustomObject]@{
Test = "Réplication AD"
Status = if ($replErrors -match "0 failures") {"PASS"} else {"FAIL"}
Detail = "$replErrors"
}
# Test 3 : Vérifier que la corbeille AD est active
$recycleBin = Get-ADOptionalFeature -Filter {Name -eq "Recycle Bin Feature"}
$drTestResults += [PSCustomObject]@{
Test = "Corbeille AD"
Status = if ($recycleBin.EnabledScopes) {"PASS"} else {"FAIL"}
Detail = "Scopes: $($recycleBin.EnabledScopes -join ', ')"
}
# Test 4 : Vérifier les clés BitLocker dans AD
$blKeys = Get-ADObject -Filter {objectClass -eq "msFVE-RecoveryInformation"} -SearchBase (Get-ADDomain).DistinguishedName
$drTestResults += [PSCustomObject]@{
Test = "Clés BitLocker dans AD"
Status = if ($blKeys.Count -gt 0) {"PASS"} else {"WARN"}
Detail = "$($blKeys.Count) clé(s) sauvegardée(s)"
}
$drTestResults | Format-Table Test, Status, Detail -AutoSize
Le test de Disaster Recovery est souvent la lacune la plus critique des programmes de sécurité. Selon une étude Gartner 2025, 76 % des organisations qui disposent d'un plan de DR n'ont jamais réalisé de test complet de restauration. Or, les sauvegardes corrompues, les procédures obsolètes et les erreurs de configuration ne sont découvertes que lors d'un test — ou lors d'un sinistre réel, quand il est trop tard. L'engagement de la direction pour allouer un créneau de maintenance trimestriel au test de restauration est un investissement qui peut sauver l'entreprise.
Backup et recovery :
- Appliquer la règle 3-2-1 avec une copie immuable — les ransomwares ciblent les sauvegardes
- Inclure System State et BMR dans chaque sauvegarde de serveur
- Tester la restauration au moins une fois par trimestre — une sauvegarde non testée ne vaut rien
- Vérifier automatiquement l'âge et le statut de la dernière sauvegarde chaque jour
- La tombstone lifetime AD est de 180 jours — les sauvegardes plus anciennes sont inutilisables
Outils d'audit et de conformité
Microsoft Security Compliance Toolkit (SCT)
Le Security Compliance Toolkit (SCT) de Microsoft fournit des baselines de sécurité officielles sous forme de GPO préconfigurées, accompagnées de l'outil LGPO.exe pour les appliquer localement et de PolicyAnalyzer pour comparer les configurations actuelles avec les baselines. Le SCT pour Windows Server 2025 inclut des baselines pour les serveurs membres, les contrôleurs de domaine et les Credential Guard settings.
# Télécharger le SCT depuis le Microsoft Download Center
# https://www.microsoft.com/en-us/download/details.aspx?id=55319
# Appliquer la baseline localement avec LGPO
.\LGPO.exe /g ".\Windows Server 2025 - Member Server\GPOs\{GUID}"
# Comparer la configuration actuelle avec la baseline
# Utiliser PolicyAnalyzer (GUI) ou export secedit
secedit /export /cfg C:\Temp\CurrentConfig.inf
# Comparer manuellement avec la baseline .inf fournie dans le SCT
# Export GPO pour comparaison
$gpo = Get-GPO -Name "Hardening-WindowsServer2025"
$gpo | Get-GPOReport -ReportType Xml -Path "C:\Temp\GPO-Report.xml"
CIS-CAT : audit automatisé CIS Benchmark
CIS-CAT Pro est l'outil officiel du Center for Internet Security pour auditer automatiquement la conformité d'un serveur par rapport aux CIS Benchmarks. Il génère un rapport détaillé avec le pourcentage de conformité, chaque contrôle évalué (pass/fail/not applicable) et les remédiations recommandées. La version Lite est gratuite, la version Pro nécessite une adhésion CIS SecureSuite.
# Exécuter CIS-CAT Pro en ligne de commande
# Prérequis : Java 11+
java -jar Assessor-CLI.jar -b "CIS_Microsoft_Windows_Server_2025_Benchmark_v3.0.0-xccdf.xml" `
-p "Level 2 - Domain Controller" `
-rd "C:\Audit\CIS-Results" `
-nts -html
# Analyser les résultats
$results = [xml](Get-Content "C:\Audit\CIS-Results\report.xml")
$totalChecks = ($results.Benchmark.TestResult.rule-result).Count
$passed = ($results.Benchmark.TestResult.'rule-result' | Where-Object {$_.result -eq "pass"}).Count
$failed = ($results.Benchmark.TestResult.'rule-result' | Where-Object {$_.result -eq "fail"}).Count
Write-Host "Score CIS Benchmark : $([math]::Round($passed/$totalChecks*100))% ($passed/$totalChecks)" -ForegroundColor $(if ($passed/$totalChecks -gt 0.9) {"Green"} else {"Red"})
PingCastle : audit Active Directory
PingCastle est l'outil de référence pour l'audit de sécurité Active Directory, utilisé par la majorité des équipes de sécurité et des auditeurs en France et en Europe. Développé par Vincent Le Toux, expert reconnu en sécurité AD, PingCastle analyse en profondeur la configuration Active Directory et attribue un score de risque global de 0 (excellent) à 100 (critique) réparti en quatre catégories : Stale Objects (comptes et machines obsolètes qui augmentent la surface d'attaque), Privileged Accounts (comptes avec des droits excessifs ou mal protégés), Trusts (relations d'approbation potentiellement dangereuses avec d'autres domaines ou forêts) et Anomalies (configurations qui dévient des bonnes pratiques). L'objectif est d'atteindre un score inférieur à 30 dans chaque catégorie, ce qui correspond à un niveau de risque acceptable. Un score supérieur à 60 dans n'importe quelle catégorie nécessite une remédiation urgente.
PingCastle génère un rapport HTML extrêmement détaillé qui constitue une véritable feuille de route de remédiation. Chaque finding est classé par niveau de risque, accompagné d'une explication technique de la vulnérabilité, des vecteurs d'exploitation possibles et des étapes de remédiation. Le rapport identifie également les chemins d'attaque (attack paths) les plus courts entre un compte standard et les privilèges Domain Admin, ce qui permet de prioriser les remédiations en fonction de leur impact réel sur la réduction du risque. En complément de PingCastle, l'outil BloodHound (version défensive : PlumHound) permet de visualiser graphiquement ces chemins d'attaque et d'identifier les points de passage obligés (choke points) où une seule remédiation peut couper de nombreux chemins d'attaque. PingCastle identifie les faiblesses structurelles (trusts dangereux, comptes périmés, configurations obsolètes) et fournit des recommandations priorisées. Pour l'analyse forensique Windows complémentaire, consultez notre guide Windows Forensics.
# Exécuter PingCastle en mode healthcheck
.\PingCastle.exe --healthcheck --server domaine.local
# Exécuter en mode scanner (détection de vulnérabilités spécifiques)
.\PingCastle.exe --scanner --scanneridle # Comptes inactifs
.\PingCastle.exe --scanner --scannernoexpire # Comptes sans expiration de mot de passe
.\PingCastle.exe --scanner --scannersmb # Partages SMB accessibles
.\PingCastle.exe --scanner --scannerspooler # Print Spooler actif (PrintNightmare)
.\PingCastle.exe --scanner --scannernullsession # Sessions NULL autorisées
# Analyser le rapport HTML généré
# Score de 0 à 100 par catégorie :
# - Stale Objects (objets obsolètes)
# - Privileged Accounts (comptes privilégiés)
# - Trusts (relations d'approbation)
# - Anomalies (configurations anormales)
# Objectif : score < 30 dans chaque catégorie
PowerShell DSC (Desired State Configuration)
PowerShell DSC permet de définir l'état souhaité d'un serveur sous forme de code (Infrastructure as Code) et de s'assurer en continu que le serveur reste conforme à cette configuration. C'est l'outil idéal pour maintenir le durcissement dans le temps et détecter les dérives de configuration (configuration drift).
# ============================================================
# CONFIGURATION DSC DE DURCISSEMENT
# ============================================================
Configuration WindowsServerHardening {
param (
[string[]]$ComputerName = 'localhost'
)
Import-DscResource -ModuleName PSDesiredStateConfiguration
Import-DscResource -ModuleName SecurityPolicyDsc
Import-DscResource -ModuleName AuditPolicyDsc
Node $ComputerName {
# Désactiver SMBv1
WindowsOptionalFeature DisableSMBv1 {
Name = 'SMB1Protocol'
Ensure = 'Disable'
}
# Désactiver Print Spooler
Service DisableSpooler {
Name = 'Spooler'
State = 'Stopped'
StartupType = 'Disabled'
}
# Désactiver Remote Registry
Service DisableRemoteRegistry {
Name = 'RemoteRegistry'
State = 'Stopped'
StartupType = 'Disabled'
}
# Configurer le registre — LmCompatibilityLevel
Registry LmCompatibility {
Key = 'HKLM:\SYSTEM\CurrentControlSet\Control\Lsa'
ValueName = 'LmCompatibilityLevel'
ValueData = '5'
ValueType = 'Dword'
Ensure = 'Present'
}
# Configurer le registre — Désactiver LLMNR
Registry DisableLLMNR {
Key = 'HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\DNSClient'
ValueName = 'EnableMulticast'
ValueData = '0'
ValueType = 'Dword'
Ensure = 'Present'
}
# Configurer le registre — NLA pour RDP
Registry RequireNLA {
Key = 'HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp'
ValueName = 'UserAuthentication'
ValueData = '1'
ValueType = 'Dword'
Ensure = 'Present'
}
# Configurer le registre — Credential Guard
Registry CredentialGuard {
Key = 'HKLM:\SYSTEM\CurrentControlSet\Control\Lsa'
ValueName = 'LsaCfgFlags'
ValueData = '1'
ValueType = 'Dword'
Ensure = 'Present'
}
# Configurer le registre — Désactiver WDigest (anti-cleartext credentials)
Registry DisableWDigest {
Key = 'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\WDigest'
ValueName = 'UseLogonCredential'
ValueData = '0'
ValueType = 'Dword'
Ensure = 'Present'
}
# Configurer le registre — SMB Signing
Registry SMBServerSigning {
Key = 'HKLM:\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters'
ValueName = 'RequireSecuritySignature'
ValueData = '1'
ValueType = 'Dword'
Ensure = 'Present'
}
}
}
# Compiler la configuration
WindowsServerHardening -OutputPath "C:\DSC\Hardening"
# Appliquer la configuration
Start-DscConfiguration -Path "C:\DSC\Hardening" -Wait -Verbose -Force
# Vérifier la conformité
Test-DscConfiguration -Detailed | Format-Table ResourceId, InDesiredState, @{N='Status';E={if($_.InDesiredState){'CONFORME'}else{'NON CONFORME'}}} -AutoSize
Nessus et scanners de vulnérabilités
Tenable Nessus est le scanner de vulnérabilités le plus utilisé en entreprise. Pour le durcissement Windows Server, Nessus propose des plugins d'audit de conformité CIS et Microsoft Baseline, ainsi que des checks de vulnérabilités actives. L'exécution régulière de scans authentifiés permet d'identifier les failles avant qu'un attaquant ne les exploite.
# Préparer un serveur Windows pour un scan Nessus authentifié
# Prérequis : compte de scan avec droits administrateur local
# Activer WMI pour le scan distant
Set-Service -Name Winmgmt -StartupType Automatic
Start-Service Winmgmt
# Configurer les exceptions pare-feu pour Nessus
New-NetFirewallRule -DisplayName "Nessus Scanner - WMI" -Direction Inbound -Protocol TCP -LocalPort 135 -RemoteAddress "10.0.200.50" -Action Allow
New-NetFirewallRule -DisplayName "Nessus Scanner - SMB" -Direction Inbound -Protocol TCP -LocalPort 445 -RemoteAddress "10.0.200.50" -Action Allow
# Activer la Remote Registry temporairement pour le scan
Set-Service -Name RemoteRegistry -StartupType Manual
Start-Service RemoteRegistry
# IMPORTANT : désactiver après le scan
# Stop-Service RemoteRegistry; Set-Service -Name RemoteRegistry -StartupType Disabled
# Configurer le registre pour les scans WMI distants
Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" -Name "LocalAccountTokenFilterPolicy" -Value 1
# IMPORTANT : remettre à 0 après le scan pour la sécurité
Checklist de durcissement Windows Server 2025 : 65 contrôles
La checklist suivante synthétise l'ensemble des recommandations de ce guide en 65 contrôles opérationnels, classés par catégorie et niveau de criticité. Chaque contrôle est accompagné de la commande PowerShell de vérification correspondante. Cette checklist peut être utilisée comme base pour un audit de conformité ou intégrée dans un processus de déploiement automatisé.
| N° | Catégorie | Contrôle | Criticité | Commande de vérification |
|---|---|---|---|---|
| 1 | Installation | Server Core installé | Haute | Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion" | Select InstallationType |
| 2 | Installation | SMBv1 désactivé | Critique | Get-SmbServerConfiguration | Select EnableSMB1Protocol |
| 3 | Installation | Fonctionnalités inutiles supprimées | Haute | Get-WindowsFeature | Where Installed | Select Name |
| 4 | Installation | WSUS configuré | Haute | Get-ItemProperty "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate" | Select WUServer |
| 5 | Installation | Partitions séparées (système/données/logs) | Moyenne | Get-Volume | Select DriveLetter, FileSystemLabel, Size |
| 6 | Comptes | Compte Administrator renommé | Haute | Get-LocalUser | Where SID -like "*-500" | Select Name |
| 7 | Comptes | LAPS déployé | Critique | Get-LapsADPassword -Identity $env:COMPUTERNAME -ErrorAction SilentlyContinue |
| 8 | Comptes | FGPP appliquée aux admins (20+ chars) | Critique | Get-ADFineGrainedPasswordPolicy -Filter * | Select Name, MinPasswordLength |
| 9 | Comptes | gMSA pour comptes de service | Haute | Get-ADServiceAccount -Filter * | Select Name, Enabled |
| 10 | Comptes | Admins dans Protected Users | Haute | Get-ADGroupMember "Protected Users" | Select Name |
| 11 | Comptes | AES256 forcé sur comptes de service | Haute | Get-ADUser -Filter {ServicePrincipalName -like "*"} -Prop msDS-SupportedEncryptionTypes |
| 12 | Comptes | Compte Guest désactivé | Haute | Get-LocalUser -Name Guest | Select Enabled |
| 13 | AD | Schema Admins vide | Critique | Get-ADGroupMember "Schema Admins" | Measure-Object | Select Count |
| 14 | AD | Enterprise Admins vide | Critique | Get-ADGroupMember "Enterprise Admins" | Measure-Object | Select Count |
| 15 | AD | LDAP signing imposé (valeur 2) | Critique | Get-ItemProperty "HKLM:\SYSTEM\CurrentControlSet\Services\NTDS\Parameters" -Name LDAPServerIntegrity |
| 16 | AD | LDAP channel binding activé | Haute | Get-ItemProperty "HKLM:\SYSTEM\CurrentControlSet\Services\NTDS\Parameters" -Name LdapEnforceChannelBinding |
| 17 | AD | RC4 désactivé pour Kerberos | Critique | Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\Kerberos\Parameters" -Name SupportedEncryptionTypes |
| 18 | AD | Mot de passe krbtgt changé récemment (<180j) | Critique | Get-ADUser krbtgt -Prop PasswordLastSet | Select PasswordLastSet |
| 19 | AD | DSRM logon behavior = 0 | Haute | Get-ItemProperty "HKLM:\SYSTEM\CurrentControlSet\Control\Lsa" -Name DsrmAdminLogonBehavior |
| 20 | AD | AdminSDHolder ACL vérifiées | Haute | Get-ADObject -Filter {Name -eq "AdminSDHolder"} -SearchBase "CN=System,DC=domaine,DC=local" |
| 21 | GPO | Audit avancé 9 catégories configuré | Critique | auditpol /get /category:* |
| 22 | GPO | Process creation include command line | Haute | Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\Audit" -Name ProcessCreationIncludeCmdLine_Enabled |
| 23 | GPO | SeDebugPrivilege retiré à tous | Critique | secedit /export /cfg C:\Temp\sec.cfg; Select-String "SeDebugPrivilege" C:\Temp\sec.cfg |
| 24 | GPO | LmCompatibilityLevel = 5 | Critique | Get-ItemProperty "HKLM:\SYSTEM\CurrentControlSet\Control\Lsa" -Name LmCompatibilityLevel |
| 25 | GPO | NoLMHash activé | Critique | Get-ItemProperty "HKLM:\SYSTEM\CurrentControlSet\Control\Lsa" -Name NoLMHash |
| 26 | GPO | UAC activé (EnableLUA = 1) | Haute | Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" -Name EnableLUA |
| 27 | GPO | Dernier utilisateur non affiché | Moyenne | Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" -Name DontDisplayLastUserName |
| 28 | GPO | Inactivité verrouillée à 15 min | Haute | Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" -Name InactivityTimeoutSecs |
| 29 | GPO | SMB signing imposé (serveur) | Critique | Get-SmbServerConfiguration | Select RequireSecuritySignature |
| 30 | GPO | SMB signing imposé (client) | Critique | Get-SmbClientConfiguration | Select RequireSecuritySignature |
| 31 | GPO | Credential Guard activé | Critique | Get-ItemProperty "HKLM:\SYSTEM\CurrentControlSet\Control\Lsa" -Name LsaCfgFlags |
| 32 | GPO | BitLocker actif sur tous les volumes | Haute | Get-BitLockerVolume | Select MountPoint, ProtectionStatus |
| 33 | GPO | WDAC ou AppLocker configuré | Haute | Get-AppLockerPolicy -Effective | Select -Expand RuleCollections |
| 34 | GPO | Anonymous enumeration bloquée | Haute | Get-ItemProperty "HKLM:\SYSTEM\CurrentControlSet\Control\Lsa" -Name RestrictAnonymous |
| 35 | GPO | Pagefile effacé à l'arrêt | Moyenne | Get-ItemProperty "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management" -Name ClearPageFileAtShutdown |
| 36 | Réseau | Pare-feu activé 3 profils | Critique | Get-NetFirewallProfile | Select Name, Enabled |
| 37 | Réseau | Inbound default = Block | Critique | Get-NetFirewallProfile | Select Name, DefaultInboundAction |
| 38 | Réseau | NetBIOS désactivé | Haute | Get-WmiObject Win32_NetworkAdapterConfiguration | Where IPEnabled | Select Description, TcpipNetbiosOptions |
| 39 | Réseau | LLMNR désactivé | Haute | Get-ItemProperty "HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\DNSClient" -Name EnableMulticast |
| 40 | Réseau | WPAD désactivé | Haute | Get-Service WinHttpAutoProxySvc | Select Status, StartType |
| 41 | Réseau | mDNS désactivé | Moyenne | Get-ItemProperty "HKLM:\SYSTEM\CurrentControlSet\Services\Dnscache\Parameters" -Name EnableMDNS |
| 42 | Réseau | TLS 1.0/1.1 désactivé | Critique | Get-ItemProperty "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.0\Server" -Name Enabled |
| 43 | Réseau | TLS 1.2/1.3 activé | Critique | Get-ItemProperty "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Server" -Name Enabled |
| 44 | Réseau | SMB chiffrement activé | Haute | Get-SmbServerConfiguration | Select EncryptData |
| 45 | Réseau | IPsec entre DC configuré | Moyenne | Get-NetIPsecRule | Select DisplayName, Enabled |
| 46 | Services | Print Spooler désactivé (non-print servers) | Critique | Get-Service Spooler | Select Status, StartType |
| 47 | Services | Remote Registry désactivé | Haute | Get-Service RemoteRegistry | Select Status, StartType |
| 48 | Services | RDP NLA activé | Critique | Get-ItemProperty "HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp" -Name UserAuthentication |
| 49 | Services | RDP Security Layer = TLS | Haute | Get-ItemProperty "HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp" -Name SecurityLayer |
| 50 | Services | RDP timeout inactivité configuré | Moyenne | Get-ItemProperty "HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" -Name MaxIdleTime |
| 51 | Services | WinRM en HTTPS uniquement | Haute | Get-ChildItem WSMan:\localhost\Listener | Select Keys |
| 52 | Services | IIS headers de version supprimés | Moyenne | Get-WebConfigurationProperty -Filter "/system.webServer/httpProtocol/customHeaders" -Name "." | Select Name, Value |
| 53 | Services | SQL xp_cmdshell désactivé | Critique | Invoke-Sqlcmd "EXEC sp_configure 'xp_cmdshell'" | Select ConfigValue |
| 54 | Services | WDigest désactivé (UseLogonCredential=0) | Critique | Get-ItemProperty "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\WDigest" -Name UseLogonCredential |
| 55 | Logging | Journal Security >= 4 Go | Haute | (Get-WinEvent -ListLog Security).MaximumSizeInBytes / 1GB |
| 56 | Logging | Sysmon installé et actif | Critique | Get-Service Sysmon64 | Select Status |
| 57 | Logging | Script Block Logging activé | Haute | Get-ItemProperty "HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging" -Name EnableScriptBlockLogging |
| 58 | Logging | PowerShell Transcription activée | Haute | Get-ItemProperty "HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell\Transcription" -Name EnableTranscripting |
| 59 | Logging | WEF configuré | Haute | wecutil es |
| 60 | Patch | Dernière mise à jour < 30 jours | Critique | Get-HotFix | Sort InstalledOn -Descending | Select -First 1 |
| 61 | Patch | Aucun KB critique manquant | Critique | (New-Object -Com Microsoft.Update.Session).CreateUpdateSearcher().Search("IsInstalled=0").Updates.Count |
| 62 | Backup | Sauvegarde System State < 24h | Critique | Get-WBJob -Previous 1 | Select EndTime, JobState |
| 63 | Backup | BitLocker key sauvegardée dans AD | Haute | Get-BitLockerVolume | Select MountPoint, KeyProtector |
| 64 | Backup | Test de restauration documenté | Haute | # Vérification manuelle du dernier PV de test de restauration |
| 65 | Audit | Score PingCastle < 30 par catégorie | Haute | # Vérification du dernier rapport PingCastle |
Comparaison CIS Benchmark vs Microsoft Baseline vs ANSSI
Philosophie et approche de chaque référentiel
Les trois référentiels majeurs de durcissement Windows Server partagent des objectifs communs mais diffèrent dans leur approche, leur granularité et leur contexte d'application. Comprendre ces différences est essentiel pour construire une politique de durcissement adaptée à votre contexte.
Le CIS Benchmark adopte une approche prescriptive et universelle. Chaque contrôle est documenté avec une justification technique, une procédure d'audit et une procédure de remédiation. Les deux niveaux (L1 et L2) permettent d'adapter le durcissement au profil de risque. Le CIS Benchmark est le référentiel le plus détaillé et le plus régulièrement mis à jour.
Les Microsoft Security Baselines sont des GPO pré-configurées accompagnées de documentation. Leur force réside dans le fait qu'elles sont développées par l'éditeur lui-même, garantissant la compatibilité et la prise en compte des spécificités Windows. Elles sont moins granulaires que le CIS mais plus immédiatement applicables.
Les recommandations ANSSI s'inscrivent dans un cadre réglementaire français (LPM, PSSIE, NIS2) et intègrent des considérations géopolitiques (protection contre l'espionnage étatique). L'ANSSI impose des exigences plus strictes sur certains points (chiffrement, cloisonnement réseau) et fournit un contexte opérationnel adapté aux OIV (Opérateurs d'Importance Vitale) et OSE (Opérateurs de Services Essentiels).
| Critère | CIS Benchmark v3.0 | Microsoft Security Baseline | ANSSI Recommandations |
|---|---|---|---|
| Nombre de contrôles | 412 (L2) | ~250 | ~180 |
| Format de livraison | PDF + OVAL/SCAP | GPO + LGPO.exe | PDF + fiches techniques |
| Niveaux de durcissement | L1 (standard) + L2 (avancé) | Unique (baseline) | 3 niveaux (renforcé, intermédiaire, standard) |
| Mise à jour | Trimestrielle | Avec chaque version Windows | Annuelle |
| Outil d'audit | CIS-CAT Pro/Lite | PolicyAnalyzer, SCT | Pas d'outil dédié |
| Licence | Gratuit (L1) / SecureSuite (L2) | Gratuit | Gratuit |
| Kerberos chiffrement | AES128+AES256 (L2) | AES256 recommandé | AES256 obligatoire |
| NTLM | Refuser LM+NTLMv1 (L1) | Refuser LM+NTLMv1 | Désactiver NTLM complètement |
| SMB signing | Requis (L1) | Requis | Requis + chiffrement |
| TLS minimum | TLS 1.2 (L1) | TLS 1.2 | TLS 1.2 (TLS 1.3 recommandé) |
| Print Spooler | Désactiver si non nécessaire (L1) | Désactiver sur DC | Désactiver sur tous les serveurs |
| Credential Guard | Recommandé (L2) | Recommandé | Obligatoire sur Tier 0 |
| LAPS | Recommandé (L1) | Recommandé | Obligatoire |
| Taille logs Security | 196 Mo min (L1) | Non spécifié | 1 Go minimum |
| Sysmon | Non couvert | Non couvert | Recommandé |
| Contexte réglementaire | International (PCI-DSS, HIPAA) | Écosystème Microsoft | Français (LPM, NIS2, RGPD) |
Analyse détaillée des divergences entre référentiels
Les divergences les plus significatives entre les trois référentiels méritent une attention particulière car elles reflètent des philosophies de sécurité différentes et des contextes d'application distincts. Comprendre ces différences permet de prendre des décisions éclairées lorsqu'un référentiel est plus strict qu'un autre sur un point donné.
Sur la question de NTLM, le CIS Benchmark et Microsoft recommandent de refuser LM et NTLMv1 (LmCompatibilityLevel = 5), ce qui laisse NTLMv2 activé. L'ANSSI va plus loin en recommandant la désactivation complète de NTLM (y compris NTLMv2) au profit exclusif de Kerberos. Cette position plus stricte est justifiée par le fait que NTLMv2 reste vulnérable aux attaques de relay. En pratique, la désactivation totale de NTLM nécessite un audit exhaustif préalable car de nombreuses applications legacy et certains scénarios d'authentification (accès par IP plutôt que par nom, connexion à des serveurs hors domaine) reposent encore sur NTLM. La fonctionnalité NTLM Auditing de Windows Server 2025 permet d'identifier tous les flux NTLM résiduels avant de procéder à la désactivation.
# Activer l'audit NTLM pour identifier les flux résiduels avant désactivation
# GPO: Computer Configuration > Windows Settings > Security Settings > Local Policies
# > Security Options > Network security: Restrict NTLM
# Auditer toutes les authentifications NTLM entrantes
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Lsa\MSV1_0" -Name "AuditReceivingNTLMTraffic" -Value 2 -Type DWord
# Auditer les authentifications NTLM dans le domaine (sur les DC)
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\Netlogon\Parameters" -Name "AuditNTLMInDomain" -Value 7 -Type DWord
# Après 2-4 semaines d'audit, analyser les résultats
# Event ID 8001 : NTLM authentication requests from applications
# Event ID 8002 : NTLM authentication in the domain
Get-WinEvent -FilterHashtable @{LogName='Microsoft-Windows-NTLM/Operational'; StartTime=(Get-Date).AddDays(-14)} |
Group-Object {$_.Properties[0].Value} |
Sort-Object Count -Descending |
Select-Object Name, Count |
Format-Table -AutoSize
Sur la question de la taille des journaux d'événements, les trois référentiels divergent considérablement. Le CIS Benchmark Level 1 fixe un minimum de 196 Mo pour le journal Security, ce qui est largement insuffisant pour un serveur actif (un DC peut générer 1 Go de logs Security par jour). Microsoft ne spécifie pas de taille minimum dans ses baselines, laissant l'administrateur responsable. L'ANSSI recommande un minimum de 1 Go pour le journal Security, ce qui est plus réaliste mais reste insuffisant pour une rétention de plusieurs jours. Notre recommandation est de 4 Go minimum pour le journal Security sur les serveurs critiques, complété par un archivage vers un système central (WEF + SIEM).
Concernant Sysmon, aucun des trois référentiels ne couvre explicitement son déploiement, bien que l'ANSSI le mentionne dans ses recommandations opérationnelles. C'est une lacune significative car Sysmon fournit une visibilité indispensable que les journaux Windows natifs ne couvrent pas : arborescence des processus, connexions réseau par processus, chargement de DLL, et détection des injections de code. Le déploiement de Sysmon est une mesure de durcissement hors référentiel mais indispensable pour toute organisation disposant d'un SOC ou d'un SIEM.
La question du Print Spooler illustre parfaitement l'évolution des référentiels face aux menaces émergentes. Avant PrintNightmare (CVE-2021-34527), aucun référentiel ne recommandait la désactivation systématique du Print Spooler. Aujourd'hui, le CIS recommande la désactivation si non nécessaire (formulation prudente), Microsoft recommande la désactivation sur les DC, et l'ANSSI recommande la désactivation sur tous les serveurs sans exception, le rôle d'impression devant être isolé sur des serveurs d'impression dédiés. Cette position de l'ANSSI est la plus pragmatique : le risque du Print Spooler (exécution de code à distance avec privilèges SYSTEM) dépasse largement le bénéfice de pouvoir imprimer depuis un serveur.
Recommandation : approche combinée
La stratégie optimale consiste à utiliser les Microsoft Security Baselines comme point de départ (application rapide via GPO), puis à renforcer avec les contrôles CIS Benchmark Level 2 pour une couverture technique maximale, et enfin à valider la conformité avec les exigences ANSSI pour le contexte réglementaire français. Cette approche en couches garantit à la fois la compatibilité opérationnelle et le niveau de sécurité le plus élevé.
# Script de vérification rapide de conformité multi-référentiel
$results = @()
# Vérification LmCompatibilityLevel (CIS L1 + MS Baseline + ANSSI)
$lmLevel = (Get-ItemProperty "HKLM:\SYSTEM\CurrentControlSet\Control\Lsa").LmCompatibilityLevel
$results += [PSCustomObject]@{
Controle = "LmCompatibilityLevel"
Valeur = $lmLevel
CIS = if ($lmLevel -ge 5) {"PASS"} else {"FAIL"}
Microsoft = if ($lmLevel -ge 5) {"PASS"} else {"FAIL"}
ANSSI = if ($lmLevel -ge 5) {"PASS"} else {"FAIL"}
}
# Vérification SMB Signing
$smbSign = (Get-SmbServerConfiguration).RequireSecuritySignature
$results += [PSCustomObject]@{
Controle = "SMB Server Signing"
Valeur = $smbSign
CIS = if ($smbSign) {"PASS"} else {"FAIL"}
Microsoft = if ($smbSign) {"PASS"} else {"FAIL"}
ANSSI = if ($smbSign) {"PASS"} else {"FAIL"}
}
# Vérification SMB Encryption (ANSSI exige, CIS/MS recommandent)
$smbEnc = (Get-SmbServerConfiguration).EncryptData
$results += [PSCustomObject]@{
Controle = "SMB Encryption"
Valeur = $smbEnc
CIS = if ($smbEnc) {"PASS"} else {"WARN"}
Microsoft = if ($smbEnc) {"PASS"} else {"WARN"}
ANSSI = if ($smbEnc) {"PASS"} else {"FAIL"}
}
# Vérification Credential Guard
$credGuard = (Get-ItemProperty "HKLM:\SYSTEM\CurrentControlSet\Control\Lsa" -ErrorAction SilentlyContinue).LsaCfgFlags
$results += [PSCustomObject]@{
Controle = "Credential Guard"
Valeur = $credGuard
CIS = if ($credGuard -ge 1) {"PASS"} else {"WARN"}
Microsoft = if ($credGuard -ge 1) {"PASS"} else {"WARN"}
ANSSI = if ($credGuard -ge 1) {"PASS"} else {"FAIL"}
}
$results | Format-Table -AutoSize
FAQ — 10 questions sur le durcissement Windows Server 2025
Quel est le temps nécessaire pour durcir un Windows Server 2025 ?
Le temps de durcissement dépend du rôle du serveur et du niveau de maturité de l'organisation. Pour un serveur membre standard, comptez 4 à 8 heures pour un durcissement CIS Level 1 complet, incluant la configuration, les tests et la documentation. Pour un contrôleur de domaine, prévoyez 8 à 16 heures en raison de la complexité des paramètres AD (Kerberos, LDAP, réplication). L'automatisation via PowerShell DSC ou GPO réduit ce temps à 30 minutes par serveur après la création initiale des templates. L'investissement initial dans l'automatisation est rentabilisé dès le deuxième serveur durci.
Le durcissement peut-il casser des applications en production ?
Oui, c'est le risque principal du durcissement. Les mesures les plus susceptibles de provoquer des dysfonctionnements sont : la désactivation de NTLMv1 (applications legacy qui ne supportent pas NTLMv2), la désactivation de TLS 1.0/1.1 (applications anciennes), le blocage de RC4 pour Kerberos (certaines applications Java anciennes), et les politiques AppLocker/WDAC trop restrictives. La méthodologie recommandée est systématiquement : audit d'abord, enforcement ensuite. Activez chaque mesure en mode audit ou monitoring pendant 2 à 4 semaines avant de l'imposer en production. Analysez les journaux d'événements pour identifier les incompatibilités avant qu'elles ne deviennent des incidents.
Faut-il durcir les serveurs dans le cloud (Azure/AWS) ?
Absolument. Le modèle de responsabilité partagée du cloud signifie que le fournisseur sécurise l'infrastructure physique et l'hyperviseur, mais le durcissement du système d'exploitation reste de votre responsabilité. Une VM Windows Server 2025 dans Azure ou AWS est aussi vulnérable qu'un serveur on-premise si elle n'est pas durcie. De plus, l'exposition Internet est souvent plus directe dans le cloud. Les images de marketplace ne sont généralement pas durcies. Microsoft propose des images pré-durcies dans Azure (CIS Hardened Images) mais elles nécessitent une licence spécifique.
Comment gérer le durcissement sur un parc de 500+ serveurs ?
À cette échelle, le durcissement manuel est impossible. La stratégie repose sur trois piliers : 1) GPO centralisées avec des OU (Organizational Units) structurées par rôle serveur (DC, serveurs web, serveurs SQL, serveurs de fichiers) et des GPO de durcissement spécifiques à chaque rôle. 2) PowerShell DSC ou Ansible pour la configuration as code, permettant le déploiement automatisé et la détection de dérive. 3) Scanning continu avec CIS-CAT, Nessus ou Qualys pour valider la conformité en continu et générer des tableaux de bord de couverture. Le taux de conformité cible est de 95 % minimum sur les contrôles critiques.
Quelle est la différence entre Credential Guard et LSASS protection ?
Credential Guard utilise la virtualisation (VBS) pour isoler les secrets dans un environnement sécurisé inaccessible au noyau Windows. C'est la protection la plus forte mais elle nécessite un matériel compatible (TPM 2.0, UEFI, virtualisation). LSA Protection (RunAsPPL) configure le processus LSASS en mode Protected Process Light, empêchant les processus non signés Microsoft d'y accéder. LSA Protection est plus légère, compatible avec plus de matériel, mais contournable par un attaquant avec des droits kernel. Les deux protections sont complémentaires et doivent être activées simultanément.
# Activer LSA Protection (RunAsPPL) — complémentaire à Credential Guard
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Lsa" -Name "RunAsPPL" -Value 1 -Type DWord
# Vérifier que LSA est en mode PPL après redémarrage
Get-CimInstance -ClassName Win32_Process -Filter "Name='lsass.exe'" | Select-Object ProcessId, Name
# Vérifier dans Event Log : System > Event ID 12 source "Wininit"
Comment auditer les modifications de GPO de durcissement ?
Les modifications de GPO sont tracées par l'Event ID 5136 (Directory Service Changes) sur les contrôleurs de domaine. Pour une granularité maximale, activez également l'audit SYSVOL via les propriétés de sécurité avancées du dossier SYSVOL. L'outil GPO Change Tracking intégré à AGPM (Advanced Group Policy Management) fournit un workflow d'approbation et un historique complet des versions. En l'absence d'AGPM, un script PowerShell planifié peut sauvegarder quotidiennement toutes les GPO et détecter les changements par comparaison de hash.
# Sauvegarder toutes les GPO pour détection de changement
$backupPath = "E:\Backup\GPO\$(Get-Date -Format 'yyyy-MM-dd')"
New-Item -Path $backupPath -ItemType Directory -Force | Out-Null
Get-GPO -All | ForEach-Object {
Backup-GPO -Guid $_.Id -Path $backupPath | Out-Null
Write-Host "Sauvegardé : $($_.DisplayName)" -ForegroundColor Green
}
# Comparer avec la sauvegarde précédente
$today = Get-ChildItem $backupPath -Recurse -File | Get-FileHash | Sort-Object Path
$yesterday = Get-ChildItem "E:\Backup\GPO\$((Get-Date).AddDays(-1).ToString('yyyy-MM-dd'))" -Recurse -File | Get-FileHash | Sort-Object Path
Compare-Object $today $yesterday -Property Hash, Path | Where-Object {$_.SideIndicator -eq "<="} |
ForEach-Object { Write-Host "GPO MODIFIÉE : $($_.Path)" -ForegroundColor Red }
Peut-on appliquer le CIS Benchmark Level 2 sur un contrôleur de domaine ?
Oui, mais avec des précautions. Le CIS Benchmark Level 2 inclut des contrôles qui peuvent affecter la fonctionnalité et la performance du DC. Par exemple, l'audit exhaustif de tous les accès aux objets AD (Object Access) génère un volume de logs considérable qui peut impacter les performances. La désactivation complète de NTLM peut bloquer la jonction au domaine de certains équipements. L'approche recommandée est d'appliquer CIS Level 1 intégralement sur les DC, puis d'ajouter les contrôles Level 2 un par un en testant chaque impact. Les contrôles Level 2 marqués "DC Only" dans le benchmark ont été spécifiquement testés pour les contrôleurs de domaine.
Quel est l'impact performance du durcissement sur Windows Server ?
L'impact performance est généralement inférieur à 5 % pour la majorité des mesures de durcissement. Les exceptions notables sont : Credential Guard (2-3 % de surcharge mémoire due à la virtualisation), BitLocker (1-5 % de surcharge I/O selon le matériel et le type de chiffrement), l'audit exhaustif (3-8 % sur les DC très sollicités), et WDAC en mode enforcement (1-3 % au lancement des applications). L'utilisation de SSD NVMe et de processeurs récents avec AES-NI (accélération matérielle du chiffrement) réduit ces impacts à un niveau négligeable. Le gain en sécurité justifie largement cette surcharge marginale.
Comment maintenir le durcissement dans le temps ?
Le durcissement initial n'est que le début. La dérive de configuration (configuration drift) est le principal ennemi du durcissement à long terme. Un administrateur qui ouvre temporairement un port de pare-feu pour un dépannage et oublie de le refermer, une mise à jour qui réactive un service désactivé, un nouveau logiciel qui nécessite d'assouplir une politique AppLocker — chaque événement érode le durcissement. La solution combine : 1) PowerShell DSC en mode continu pour détecter et corriger automatiquement les dérives, 2) Scans CIS-CAT hebdomadaires avec alertes sur les régressions, 3) Revue trimestrielle de la politique de durcissement avec toutes les parties prenantes, et 4) Documentation systématique de toute exception avec date de péremption.
Comment intégrer le durcissement dans un pipeline CI/CD pour l'infrastructure ?
L'approche Infrastructure as Code (IaC) est la clé pour intégrer le durcissement dans les pipelines CI/CD. Les templates de durcissement sont versionnés dans Git (configurations DSC, scripts PowerShell, GPO exportées). Chaque modification passe par une pull request avec revue de code par un ingénieur sécurité. Le pipeline CI exécute des tests de conformité automatisés (Pester pour PowerShell, InSpec pour les audits CIS) sur une VM de test. Le pipeline CD déploie les configurations approuvées via Ansible, SCCM ou Azure Automation DSC. Les résultats des scans de conformité post-déploiement alimentent un dashboard Grafana ou Power BI pour le suivi en temps réel.
# Exemple de test Pester pour valider le durcissement
Describe "Windows Server 2025 Hardening" {
Context "Protocoles réseau" {
It "SMBv1 doit être désactivé" {
(Get-SmbServerConfiguration).EnableSMB1Protocol | Should -Be $false
}
It "LLMNR doit être désactivé" {
(Get-ItemProperty "HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\DNSClient" -ErrorAction SilentlyContinue).EnableMulticast | Should -Be 0
}
It "NetBIOS doit être désactivé sur toutes les interfaces" {
Get-WmiObject Win32_NetworkAdapterConfiguration | Where-Object {$_.IPEnabled -and $_.TcpipNetbiosOptions -ne 2} | Should -BeNullOrEmpty
}
}
Context "Authentification" {
It "LmCompatibilityLevel doit être 5" {
(Get-ItemProperty "HKLM:\SYSTEM\CurrentControlSet\Control\Lsa").LmCompatibilityLevel | Should -Be 5
}
It "Credential Guard doit être activé" {
(Get-ItemProperty "HKLM:\SYSTEM\CurrentControlSet\Control\Lsa").LsaCfgFlags | Should -BeGreaterOrEqual 1
}
}
Context "Services" {
It "Print Spooler doit être désactivé" {
(Get-Service Spooler).StartType | Should -Be "Disabled"
}
It "Remote Registry doit être désactivé" {
(Get-Service RemoteRegistry).StartType | Should -Be "Disabled"
}
}
Context "Logging" {
It "Journal Security doit être >= 1 Go" {
(Get-WinEvent -ListLog Security).MaximumSizeInBytes | Should -BeGreaterOrEqual 1GB
}
It "Script Block Logging doit être activé" {
(Get-ItemProperty "HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging" -ErrorAction SilentlyContinue).EnableScriptBlockLogging | Should -Be 1
}
}
}
Conclusion : la sécurité comme processus continu
Le durcissement de Windows Server 2025 est un investissement stratégique qui transforme fondamentalement la posture de sécurité d'une organisation. Ce n'est pas un projet ponctuel mais un processus continu qui s'inscrit dans la stratégie globale de cybersécurité de l'organisation. Ce guide a couvert les 65 contrôles essentiels répartis en 12 domaines : installation sécurisée, gestion des identités, hardening Active Directory, GPO de sécurité, sécurisation réseau, durcissement des services, logging et monitoring, patch management, backup et recovery, et audit de conformité.
Les chiffres sont sans appel : un serveur Windows Server 2025 durci selon les recommandations de ce guide réduit sa surface d'attaque de plus de 80 % par rapport à une installation par défaut. La combinaison de Credential Guard (protection des credentials), WDAC (contrôle des applications), SMB encryption (protection des communications), BitLocker (protection des données au repos) et Sysmon (détection des menaces) constitue un ensemble défensif qui contraint significativement les capacités d'un attaquant, même disposant d'un accès initial au réseau.
Cependant, aucun durcissement n'est parfait. Les zero-days continueront d'émerger, les techniques d'attaque évolueront, et les erreurs de configuration se produiront. C'est pourquoi le durcissement doit être complété par une capacité de détection (SOC/SIEM), de réponse aux incidents et de recovery testée et documentée. L'approche defense in depth (défense en profondeur) garantit qu'aucune couche de sécurité défaillante ne compromet l'ensemble du système.
L'importance de la documentation ne doit pas être sous-estimée. Chaque mesure de durcissement appliquée doit être documentée avec sa justification, le référentiel source (CIS/Microsoft/ANSSI), la date d'application, le responsable, et les éventuelles exceptions accordées avec leur date de péremption. Cette documentation sert de référence pour les audits de conformité, les réponses à incidents (comprendre la configuration du serveur au moment de l'incident), et la formation des nouveaux administrateurs. L'utilisation de PowerShell DSC comme source de vérité (single source of truth) pour la configuration de durcissement facilite grandement cette documentation car la configuration est exprimée sous forme de code versionné dans Git.
La feuille de route recommandée pour une organisation débutant son programme de durcissement est la suivante : mois 1 — déployer les contrôles CIS Level 1 critiques (LAPS, SMB signing, désactivation protocoles obsolètes) ; mois 2-3 — compléter avec CIS Level 1 et déployer Sysmon + logging avancé ; mois 4-6 — implémenter CIS Level 2, Credential Guard, WDAC en mode audit ; mois 7-12 — passer WDAC en enforcement, déployer DSC pour la conformité continue, intégrer dans le pipeline CI/CD. À l'issue de cette année, votre parc Windows Server sera l'un des plus sécurisés de votre secteur.
Il est essentiel de rappeler que le durcissement technique ne remplace pas une gouvernance de sécurité solide. Les contrôles techniques les plus sophistiqués sont contournables si les processus organisationnels ne suivent pas : gestion des accès sans revue régulière, exceptions de sécurité accordées sans date de péremption, comptes orphelins non désactivés après le départ d'un collaborateur, mots de passe administrateur partagés entre équipes. La technologie doit être soutenue par des procédures documentées, des responsabilités clairement attribuées et un engagement de la direction pour allouer les ressources nécessaires au maintien du durcissement dans le temps. L'expérience montre que les organisations qui réussissent le mieux leur programme de durcissement sont celles qui le traitent comme un programme permanent intégré dans les opérations quotidiennes, et non comme un projet avec une date de fin.
Enfin, le durcissement Windows Server s'inscrit dans un écosystème de sécurité plus large. La sécurité d'un serveur durci est compromise si le réseau qui le connecte est plat et non segmenté, si les postes d'administration sont vulnérables, ou si les sauvegardes sont stockées sur un partage réseau accessible par un ransomware. Le modèle de tiering Active Directory, la segmentation réseau en micro-segments, le déploiement de PAW (Privileged Access Workstations) pour l'administration, et la mise en place d'un SOC avec capacité de détection et réponse 24/7 sont des éléments complémentaires indispensables. Ce guide fournit les fondations techniques du durcissement serveur ; les guides complémentaires sur le tiering model AD, la sécurisation des postes de travail et la réponse aux incidents complètent le dispositif pour une défense en profondeur véritablement efficace.
Les 10 commandements du durcissement Windows Server 2025 :
- 1. Server Core tu installeras — 60 % de surface d'attaque en moins
- 2. LAPS et gMSA tu déploieras — plus aucun mot de passe partagé ou statique
- 3. Credential Guard tu activeras — les credentials ne seront plus volés
- 4. SMBv1, NetBIOS, LLMNR, WPAD tu désactiveras — les outils d'attaque réseau deviendront inutiles
- 5. AES256 pour Kerberos tu imposeras — Kerberoasting ne fonctionnera plus
- 6. SeDebugPrivilege à personne tu n'attribueras — Mimikatz sera neutralisé
- 7. Sysmon et Script Block Logging tu activeras — chaque action sera tracée
- 8. Les sauvegardes 3-2-1 tu maintiendras — le ransomware ne sera plus fatal
- 9. Les patches sous 30 jours tu appliqueras — les zero-days seront comblés
- 10. La conformité en continu tu vérifieras — la dérive de configuration sera détectée