Durcissement de la stratégie de groupe et de SYSVOL
Verrouiller la délégation des GPO, purger de SYSVOL les secrets cpassword des Group Policy Preferences et instaurer un contrôle des changements contre les abus de GPO.
La stratégie de groupe est l'un des plans de contrôle les plus puissants d'Active Directory : une GPO liée à la mauvaise UO, ou un droit de modification délégué au mauvais groupe, peut déployer une tâche planifiée ou un script de démarrage sur chaque ordinateur de son périmètre. SYSVOL, le partage qui réplique le contenu des GPO sur chaque contrôleur de domaine, traîne sa propre longue liste de risques hérités, dont le plus célèbre est le champ cpassword laissé par les Group Policy Preferences. Ce guide couvre la revue des délégations, le nettoyage des cpassword, les autorisations de SYSVOL et le contrôle des changements, avec du PowerShell pour chaque étape.
Délégation des GPO : qui peut modifier et lier
Deux autorisations distinctes comptent et sont souvent confondues : les droits de modification sur l'objet GPO lui-même (qui peut changer ce que fait la stratégie) et les droits de liaison sur l'objet UO ou domaine (qui peut décider où elle s'applique). Un utilisateur disposant uniquement de droits de modification sur une GPO liée à aucun emplacement sensible présente un risque faible ; un utilisateur disposant de droits de liaison sur l'UO Domain Controllers ou la racine du domaine présente un risque élevé quelles que soient les GPO qu'il peut modifier, car il peut lier une GPO existante d'apparence anodine sur laquelle quelqu'un d'autre dispose d'un accès en écriture.
Examiner les autorisations actuelles sur les GPO
Import-Module GroupPolicy
Get-GPO -All | ForEach-Object {
$gpo = $_
Get-GPPermission -Guid $gpo.Id -All |
Where-Object { $_.Permission -in 'GpoEditDeleteModifySecurity','GpoEdit' } |
Select-Object @{n='GPOName';e={$gpo.DisplayName}}, Trustee, Permission
} | Format-Table -AutoSizeExaminer qui peut lier des GPO (accès en écriture à gPLink)
Les droits de liaison se trouvent dans l'ACL de l'objet UO/domaine, pas dans celle de la GPO. Vérifiez en particulier l'UO Domain Controllers et la racine du domaine, qui sont les cibles de liaison ayant le plus d'impact :
$dcOU = (Get-ADDomain).DomainControllersContainer
$domainRoot = (Get-ADDomain).DistinguishedName
foreach ($target in @($dcOU, $domainRoot)) {
Write-Host "== $target ==" -ForegroundColor Cyan
(Get-Acl -Path "AD:\$target").Access |
Where-Object { $_.ObjectType -eq 'f30e3bbe-9ff0-11d1-b603-0000f80367c1' -or $_.ActiveDirectoryRights -match 'WriteProperty|GenericAll|GenericWrite' } |
Select-Object IdentityReference, ActiveDirectoryRights, AccessControlType
}Le GUID f30e3bbe-9ff0-11d1-b603-0000f80367c1 est le GUID de schéma de l'attribut gPLink : ce filtre cible donc l'accès en écriture sur l'attribut de liaison lui-même, ainsi que toute délégation large qui le couvrirait. Supprimez ici tout mandataire autre que Domain Admins ou un groupe d'administration de la stratégie de groupe explicitement mandaté : les droits de liaison sur l'UO Domain Controllers ne doivent pas être délégués largement.
Le problème des cpassword des Group Policy Preferences
Avant MS14-025 (KB2962486, publié le 13 mai 2014), les Group Policy Preferences permettaient aux administrateurs de déployer via des GPO des mots de passe de comptes locaux, des mappages de lecteurs avec identifiants, des tâches planifiées et des services avec mots de passe stockés, en chiffrant le mot de passe avec une clé AES statique que Microsoft avait publiée dans la documentation GPP. Tout utilisateur authentifié du domaine peut lire SYSVOL : toute valeur cpassword qui subsiste est donc déchiffrable trivialement par quiconque a un accès en lecture au partage — le chiffrement n'apporte aucune protection réelle.
Le correctif a empêché l'éditeur GPP d'écrire de nouvelles valeurs cpassword, mais n'a rien fait pour supprimer celles créées auparavant. C'est le constat le plus fréquent dans les environnements AD antérieurs au correctif.
Trouver les valeurs cpassword dans SYSVOL
$sysvolPath = "\\$((Get-ADDomain).DNSRoot)\SYSVOL\$((Get-ADDomain).DNSRoot)\Policies"
Get-ChildItem -Path $sysvolPath -Recurse -Include *.xml -ErrorAction SilentlyContinue |
Select-String -Pattern 'cpassword="[^"]+"' |
Select-Object Path, LineNumber, @{n='Match';e={$_.Matches.Value}}GPP les stocke dans des fichiers XML spécifiques selon le type de préférence — Groups.xml (comptes locaux), Services.xml, ScheduledTasks.xml, DataSources.xml et Drives.xml sont les plus courants. La recherche ci-dessus les détecte tous, puisqu'elle parcourt chaque fichier XML de l'arborescence Policies.
Corriger
- Pour chaque résultat, ouvrez la GPO correspondante dans la console de gestion des stratégies de groupe et supprimez l'élément de préférence en cause (Local Users and Groups, Scheduled Tasks, Drive Maps ou Services, selon le cas) plutôt que de modifier le XML à la main.
- Changez l'identifiant partout où il était utilisé. Retirer le cpassword de la GPO ne change pas le mot de passe réel sur les systèmes cibles : considérez chaque valeur découverte comme un identifiant compromis et renouvelez-le.
- Confirmez la suppression :
Get-ChildItem -Path $sysvolPath -Recurse -Include *.xml -ErrorAction SilentlyContinue |
Select-String -Pattern 'cpassword="[^"]+"' | Measure-ObjectUn résultat vide confirme qu'il ne reste aucune entrée cpassword. Relancez ce contrôle périodiquement : une sauvegarde restaurée ou une ancienne GPO réimportée peut en réintroduire une en silence.
Autorisations de SYSVOL et revue des scripts
SYSVOL contient aussi les scripts de démarrage, d'arrêt, d'ouverture et de fermeture de session référencés par les GPO. Quiconque dispose d'un accès en écriture au dossier de scripts concerné peut modifier du code qui s'exécute avec les privilèges SYSTEM (scripts de démarrage/arrêt) sur chaque ordinateur ciblé.
$scriptsPath = "\\$((Get-ADDomain).DNSRoot)\SYSVOL\$((Get-ADDomain).DNSRoot)\scripts"
(Get-Acl -Path $scriptsPath).Access |
Select-Object IdentityReference, FileSystemRights, AccessControlTypeLa référence attendue est : Administrators (qui contient Domain Admins et Enterprise Admins), SYSTEM et CREATOR OWNER en Contrôle total, et Authenticated Users et Server Operators en Lecture et exécution uniquement. Toute autorisation d'écriture plus large constitue un constat. Comparez aussi périodiquement les hachages des fichiers de scripts avec une référence saine, afin de détecter les modifications non autorisées en dehors des fenêtres de changement habituelles.
Sauvegarde des GPO et contrôle des changements
Traitez les GPO comme de l'infrastructure as code : sauvegardez-les avant chaque changement et comparez les modifications dans le temps, plutôt que de les découvrir après coup.
# Sauvegarder toutes les GPO dans un dossier daté
$backupPath = "D:\GPOBackups\$(Get-Date -Format yyyy-MM-dd)"
New-Item -Path $backupPath -ItemType Directory -Force | Out-Null
Backup-GPO -All -Path $backupPath
# Générer un rapport complet à comparer avec la référence précédente
Get-GPO -All | ForEach-Object {
Get-GPOReport -Guid $_.Id -ReportType Xml -Path "$backupPath\$($_.DisplayName -replace '[\\/:*?"<>|]','_').xml"
}Stockez les exports de rapports dans un système de gestion de versions afin que les modifications des paramètres des GPO, et pas seulement des liaisons, apparaissent sous forme de différences vérifiables. Restaurez une sauvegarde précise avec Restore-GPO -Guid <id> -Path <backupPath> si un changement doit être annulé.
Ce qui casse
- Restreindre la délégation de modification/liaison des GPO : tout groupe de support ou d'administration de site qui gère aujourd'hui lui-même les changements de GPO pour son UO perd cette capacité et a besoin d'un circuit de demande formel, ou d'une délégation étroite limitée à sa propre UO (jamais l'UO Domain Controllers ni la racine du domaine).
- Supprimer les éléments GPP basés sur cpassword : les comptes locaux, tâches planifiées ou mappages de lecteurs qui dépendaient de cet élément GPP ne sont plus configurés de manière centralisée ; vous devez remplacer le mécanisme (LAPS pour les mots de passe d'administrateur local, un déploiement de tâches planifiées correctement sécurisé, ou des mappages de lecteurs par stratégie de groupe sans identifiants intégrés) avant de supprimer l'ancienne préférence, pas après.
- Resserrer les autorisations du dossier de scripts SYSVOL : casse tout flux dans lequel du personnel non administrateur dépose ou modifie directement des scripts d'ouverture de session/de démarrage sur le partage au lieu de passer par le contrôle des changements.
- Réserver les droits gPLink aux seuls Domain Admins : les administrateurs de GPO régionaux ou départementaux délégués qui lient aujourd'hui leurs propres GPO devront désormais faire intervenir un Domain Admin pour les liaisons, même s'ils conservent les droits de modification sur leurs propres GPO.
Pour les contrôles Tier 0 voisins, consultez Durcissement des contrôleurs de domaine et Durcissement de Kerberos.
Questions fréquentes
La vulnérabilité cpassword des Group Policy Preferences est-elle toujours d'actualité ?
Oui. MS14-025 a empêché l'éditeur GPP de créer de nouvelles entrées cpassword en 2014, mais n'a pas supprimé rétroactivement celles qui existaient déjà dans SYSVOL. Les domaines en service depuis avant 2014 en contiennent encore fréquemment, oubliées dans d'anciennes GPO que personne n'a revues.
Qui devrait être autorisé à lier des GPO à l'UO Domain Controllers ?
Les Domain Admins uniquement, dans la plupart des environnements. Lier une GPO à l'UO Domain Controllers équivaut à exécuter du code sur chaque DC : l'accès en écriture à gPLink à cet endroit doit donc être aussi strictement limité que l'appartenance aux Domain Admins elle-même.
Comment trouver les autorisations déléguées sur les GPO sans parcourir chaque GPO à la main ?
Utilisez Get-GPO combiné à Get-GPPermission dans une boucle, ou Get-GPOReport pour un export XML/HTML que vous pouvez comparer dans le temps. Les deux sont intégrés au module PowerShell GroupPolicy et ne nécessitent aucun outil supplémentaire.
Durcissement de la stratégie de groupe et de SYSVOL