Hardening Windows Server — CIS Benchmark
Durcissement Windows Server selon CIS : comptes, audit, services, GPO, AppLocker
Comptes et authentification
# Renommer le compte Administrator intégréRename-LocalUser -Name "Administrator" -NewName "{{ADMIN_ALIAS}}"# Désactiver le compte GuestDisable-LocalUser -Name "Guest"# Politique de mots de passenet accounts /minpwlen:14 /maxpwage:90 /minpwage:1 /uniquepw:24 /lockoutthreshold:5 /lockoutduration:30 /lockoutwindow:30# Vérifier la politique actuellenet accounts
# Désactiver NTLM v1 via registreSet-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Lsa" `-Name "LmCompatibilityLevel" -Value 5# Valeur 5 = NTLMv2 only, refuse LM et NTLMv1# Équivalent GPO : Network security: LAN Manager authentication level = NTLMv2 only
# Credential Guard — activation (nécessite Virtualization Based Security)# Via GPO : Computer Configuration > Administrative Templates > System > Device Guard# Enable Virtualization Based Security = Enabled# Credential Guard Configuration = Enabled with UEFI lock# Vérification après redémarrageGet-CimInstance -ClassName Win32_DeviceGuard -Namespace root\Microsoft\Windows\DeviceGuard |Select-Object -Property SecurityServicesRunning# 1 = Credential Guard actif
Avant de forcer NTLMv2 only (LmCompatibilityLevel = 5), vérifier qu'aucun système legacy (Windows XP, anciens NAS, imprimantes réseau) ne dépend de NTLM v1 ou LM — ils perdront l'accès réseau immédiatement.
Audit et journalisation
# Activer toutes les catégories d'auditauditpol /set /category:* /success:enable /failure:enable# Catégories critiques en détailauditpol /set /subcategory:"Logon" /success:enable /failure:enableauditpol /set /subcategory:"Account Lockout" /success:enable /failure:enableauditpol /set /subcategory:"Process Creation" /success:enable /failure:enableauditpol /set /subcategory:"Scheduled Task" /success:enable /failure:enableauditpol /set /subcategory:"Security Group Management" /success:enable /failure:enableauditpol /set /subcategory:"User Account Management" /success:enable /failure:enableauditpol /set /subcategory:"Service" /success:enable /failure:enable# Vérifier la configurationauditpol /get /category:*
Event IDs critiques à surveiller :
| Event ID | Description | |---|---| | 4624 | Connexion réussie | | 4625 | Échec de connexion | | 4648 | Connexion avec credentials explicites (runas) | | 4688 | Création d'un processus (avec command line) | | 4698 | Création d'une tâche planifiée | | 4720 | Création d'un compte utilisateur | | 4726 | Suppression d'un compte utilisateur | | 7045 | Nouveau service installé | | 4104 | PowerShell ScriptBlock logging |
# Activer le logging de la ligne de commande dans 4688Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\Audit" `-Name "ProcessCreationIncludeCmdLine_Enabled" -Value 1 -Type DWord# PowerShell ScriptBlock Logging (Event ID 4104)$psLogPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging"New-Item -Path $psLogPath -Force | Out-NullSet-ItemProperty -Path $psLogPath -Name "EnableScriptBlockLogging" -Value 1# Dimensionner le Security log à 1 Go minimumwevtutil sl Security /ms:1073741824# Vérifier la taille configuréewevtutil gl Security | Select-String "maxSize"
Services à désactiver
# Désactiver SMBv1 (vecteur WannaCry, NotPetya)Set-SmbServerConfiguration -EnableSMB1Protocol $false -ForceSet-SmbClientConfiguration -EnableSMB1Protocol $false -Force# VérifierGet-SmbServerConfiguration | Select-Object EnableSMB1Protocol, EnableSMB2Protocol# Services inutiles à désactiver$services = @("Spooler", # Print Spooler (si pas d'impression sur ce serveur)"TlntSvr", # Telnet"RemoteRegistry", # Remote Registry"TFTPD", # TFTP"WinHttpAutoProxySvc")foreach ($svc in $services) {if (Get-Service -Name $svc -ErrorAction SilentlyContinue) {Stop-Service -Name $svc -ForceSet-Service -Name $svc -StartupType DisabledWrite-Host "$svc désactivé"}}# Désactiver LLMNR via registreSet-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\DNSClient" `-Name "EnableMulticast" -Value 0# Désactiver NetBIOS over TCP/IP (via WMI, à appliquer sur chaque interface)$adapters = Get-WmiObject -Class Win32_NetworkAdapterConfiguration -Filter "IPEnabled=True"foreach ($adapter in $adapters) {$adapter.SetTcpipNetbios(2) # 2 = Disable NetBIOS}
Pare-feu Windows
# Activer le pare-feu sur tous les profilsSet-NetFirewallProfile -Profile Domain,Public,Private -Enabled True# Bloquer LLMNR (UDP 5355)New-NetFirewallRule -DisplayName "Block LLMNR" -Direction Inbound `-Protocol UDP -LocalPort 5355 -Action Block# Bloquer NetBIOS (UDP 137-138, TCP 139)New-NetFirewallRule -DisplayName "Block NetBIOS UDP 137" -Direction Inbound `-Protocol UDP -LocalPort 137 -Action BlockNew-NetFirewallRule -DisplayName "Block NetBIOS UDP 138" -Direction Inbound `-Protocol UDP -LocalPort 138 -Action BlockNew-NetFirewallRule -DisplayName "Block NetBIOS TCP 139" -Direction Inbound `-Protocol TCP -LocalPort 139 -Action Block# Restreindre WinRM à un sous-réseau de gestionSet-NetFirewallRule -DisplayName "Windows Remote Management (HTTP-In)" `-RemoteAddress "{{MGMT_SUBNET}}"
# netsh — vérifier l'état du pare-feunetsh advfirewall show allprofiles state# Bloquer tout le trafic sortant non autorisé (optionnel, restrictif)netsh advfirewall set allprofiles firewallpolicy blockinbound,blockoutbound
AppLocker — Whitelisting
# Activer le service Application Identity (prérequis AppLocker)Set-Service -Name AppIDSvc -StartupType AutomaticStart-Service AppIDSvc# Créer les règles par défaut (allow Admins + Everyone sur %ProgramFiles%)Get-AppLockerPolicy -Effective | Test-AppLockerPolicy -Path "C:\Windows\System32\cmd.exe" -User Everyone# Générer les règles par défaut via GPO (recommandé)# Computer Configuration > Windows Settings > Security Settings > Application Control Policies > AppLocker# Create Default Rules pour : Executable Rules, Windows Installer Rules, Script Rules
<!-- Exemple de règle AppLocker XML — Publisher rule pour Microsoft Office --><RuleCollection Type="Exe" EnforcementMode="Enforced"><FilePublisherRule Id="{{GUID}}" Name="Allow signed Microsoft Office"Description="Allow executables signed by Microsoft Corporation"UserOrGroupSid="S-1-1-0" Action="Allow"><Conditions><FilePublisherCondition PublisherName="O=MICROSOFT CORPORATION, L=REDMOND, S=WASHINGTON, C=US"ProductName="*" BinaryName="*"><BinaryVersionRange LowSection="*" HighSection="*" /></FilePublisherCondition></Conditions></FilePublisherRule></RuleCollection>
GPO Hardening — Security Options
Chemin GPO : Computer Configuration\Windows Settings\Security Settings\Local Policies\Security Options
| Paramètre | Valeur recommandée |
|---|---|
| Interactive logon: Message for users attempting to log on | Texte d'avertissement légal |
| Interactive logon: Do not display last user name | Enabled |
| Network access: Do not allow anonymous enumeration of SAM accounts | Enabled |
| Network access: Restrict anonymous access to Named Pipes and Shares | Enabled |
| User Account Control: Only elevate executables that are signed and validated | Enabled |
| User Account Control: Run all administrators in Admin Approval Mode | Enabled |
| User Account Control: Behavior of the elevation prompt for administrators | Prompt for credentials on the secure desktop |
| Accounts: Rename administrator account | ADMIN_ALIAS (ex: sysadm) |
| Accounts: Rename guest account | GUEST_ALIAS (ex: invité-désactivé) |
| Microsoft network server: Digitally sign communications (always) | Enabled |
| Microsoft network client: Digitally sign communications (always) | Enabled |
Windows Defender & ASR
# S'assurer que la protection en temps réel est activeSet-MpPreference -DisableRealtimeMonitoring $falseSet-MpPreference -DisableBehaviorMonitoring $falseSet-MpPreference -DisableIOAVProtection $false# Activer les règles Attack Surface Reduction (ASR)# Mode : 1 = Block, 2 = Audit, 0 = Disabled$asrRules = @{"BE9BA2D9-53EA-4CDC-84E5-9B1EEEE46550" = 1 # Block executable content from email/webmail"D4F940AB-401B-4EFC-AADC-AD5F3C50688A" = 1 # Block Office apps from creating child processes"3B576869-A4EC-4529-8536-B80A7769E899" = 1 # Block Office apps from creating executable content"75668C1F-73B5-4CF0-BB93-3ECF5CB7CC84" = 1 # Block Office apps from injecting into processes"D3E037E1-3EB8-44C8-A917-57927947596D" = 1 # Block JS/VBS from launching downloaded exe"5BEB7EFE-FD9A-4556-801D-275E5FFC04CC" = 1 # Block execution of potentially obfuscated scripts"92E97FA1-2EDF-4476-BDD6-9DD0B4DDDC7B" = 1 # Block Win32 API calls from Office macros"01443614-CD74-433A-B99E-2ECDC07BFC25" = 1 # Block executable files unless they meet prevalence criteria}foreach ($rule in $asrRules.GetEnumerator()) {Add-MpPreference -AttackSurfaceReductionRules_Ids $rule.Key `-AttackSurfaceReductionRules_Actions $rule.Value}# Activer Tamper Protection (via Defender Security Center UI ou Intune)# Registre (lecture seule si Tamper Protection actif) :Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows Defender\Features" -Name "TamperProtection"# Valeur 5 = Tamper Protection activé# Vérifier l'état completGet-MpComputerStatus | Select-Object AMRunningMode, RealTimeProtectionEnabled, TamperProtectionSource
RDP — Sécurisation
# Forcer NLA (Network Level Authentication) obligatoireSet-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp" `-Name "UserAuthentication" -Value 1# Changer le port RDP par défaut (3389 → port personnalisé)Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp" `-Name "PortNumber" -Value {{RDP_PORT}}# Limiter les utilisateurs autorisés# Ajouter uniquement les comptes nécessaires au groupe "Remote Desktop Users"Add-LocalGroupMember -Group "Remote Desktop Users" -Member "{{DOMAIN}}\{{RDP_USER}}"# Désactiver RDP si non utiliséSet-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server" `-Name "fDenyTSConnections" -Value 1
PowerShell Constrained Language Mode
# Activer Constrained Language Mode via GPO AppLocker ou WDAC# (Automatique si AppLocker est configuré avec règles de whitelisting)# Vérifier le language mode actuel$ExecutionContext.SessionState.LanguageMode# FullLanguage = pas de restriction# ConstrainedLanguage = mode restreint actif# Forcer via variable d'environnement (test uniquement, non persistant)[Environment]::SetEnvironmentVariable("__PSLockdownPolicy", "4", "Machine")# Redémarrer PowerShell pour effet
LAPS — Local Administrator Password Solution
# Installer le module LAPS (Windows LAPS natif Windows Server 2022 / Win 11 22H2+)# Vérifier la disponibilitéGet-Module -ListAvailable -Name LAPS# Configurer via GPO :# Computer Configuration > Administrative Templates > System > LAPS# Enable local admin password management = Enabled# Password Settings : longueur 15+, complexité, rotation 30 jours# Lire le mot de passe LAPS d'un ordinateur (nécessite droits de lecture)Get-LapsADPassword -Identity "{{COMPUTER_NAME}}" -AsPlainText# Pour LAPS legacy (Microsoft LAPS v1) :# Import-Module AdmPwd.PS# Get-AdmPwdPassword -ComputerName "{{COMPUTER_NAME}}"
Checklist hardening Windows
Activer Process Creation audit (Event ID 4688) avec command line logging — c'est la source de détection la plus riche pour un SOC Windows. Sans cette option, les logs 4688 n'incluent pas la commande exécutée, rendant l'analyse forensique quasi impossible. Coupler avec PowerShell ScriptBlock Logging (4104) pour une couverture complète.