Aller au contenu
08 · Sécurité des objets & ACLPartie 1 sur 4Fondamental

Auditer les ACL Active Directory avant un attaquant

Comment repérer les ACL AD dangereuses comme GenericAll et les droits DCSync, nettoyer les indicateurs adminCount obsolètes et utiliser BloodHound en défense.

Florian Amette6 min de lecture

Le durcissement par stratégie de groupe et les correctifs accaparent l'essentiel de l'attention, mais une part énorme des compromissions réelles d'Active Directory ne touche à aucune CVE : elles abusent d'autorisations accordées, héritées ou oubliées. Un compte de service doté de trop de droits, une délégation résiduelle d'un outil de support décommissionné ou un principal de service capable de DCSync peuvent offrir à un attaquant la domination du domaine sans le moindre exploit. Ce guide explique comment trouver et corriger ces chemins avant que quelqu'un d'autre ne le fasse.

Les ACL qui comptent le plus

Les objets Active Directory portent des listes de contrôle d'accès discrétionnaires (DACL), tout comme les fichiers, mais les droits qui comptent pour la sécurité forment un ensemble restreint et bien connu :

DroitCe qu'il permetPourquoi il est dangereux
GenericAllContrôle total de l'objetPermet de réinitialiser des mots de passe, de modifier l'appartenance aux groupes, d'éditer n'importe quel attribut
GenericWriteÉcriture de tout attribut non protégéPermet de définir scriptPath pour exécuter un script d'ouverture de session, de modifier les attributs d'appartenance aux groupes
WriteDACLModification de l'ACL de l'objet lui-mêmeLe bénéficiaire peut s'accorder GenericAll à volonté, contournant toute revue ultérieure
WriteOwnerPrise de possession de l'objetLe nouveau propriétaire obtient implicitement la capacité de s'accorder n'importe quel droit
DS-Replication-Get-Changes + DS-Replication-Get-Changes-AllDemande de données de réplication de l'annuaireEnsemble, ils permettent le DCSync : récupérer les hachages de mot de passe de n'importe quel compte, y compris krbtgt, sans toucher au disque d'un DC

N'importe lequel des quatre premiers droits détenu sur un groupe comme Domain Admins, ou sur l'objet AdminSDHolder lui-même, équivaut à une compromission complète du domaine. Les droits de réplication sont dangereux justement parce qu'ils sont rarement audités : la plupart des administrateurs pensent à vérifier l'appartenance aux groupes, pas les autorisations de réplication sur l'objet domaine.

Auditer les ACL avec PowerShell

Commencez par l'objet racine du domaine lui-même, puisque c'est là que résident les droits DCSync :

PowerShell
$domainDN = (Get-ADDomain).DistinguishedName
$acl = Get-Acl -Path "AD:\$domainDN"

$acl.Access | Where-Object {
    $_.ActiveDirectoryRights -match "ExtendedRight" -and
    ($_.ObjectType -eq "1131f6aa-9c07-11d1-f79f-00c04fc2dcd2" -or  # DS-Replication-Get-Changes
     $_.ObjectType -eq "1131f6ad-9c07-11d1-f79f-00c04fc2dcd2")     # DS-Replication-Get-Changes-All
} | Select-Object IdentityReference, ActiveDirectoryRights, ObjectType

Ces deux GUID ne sont pas le seul chemin vers DCSync : GenericAll, AllExtendedRights (une ACE de droit étendu avec un ObjectType vide) et WriteDACL sur la racine du domaine accordent les mêmes droits ou permettent à leur détenteur de se les accorder. L'audit des droits DCSync détaille la requête complète et les détenteurs attendus par défaut.

Balayez ensuite les droits dangereux sur les UO à forte valeur (Domain Controllers, UO des administrateurs Tier 0, groupes privilégiés) :

PowerShell
$targets = @("OU=Domain Controllers,DC=corp,DC=example,DC=com",
             "CN=Domain Admins,CN=Users,DC=corp,DC=example,DC=com")

foreach ($dn in $targets) {
    Write-Host "== $dn ==" -ForegroundColor Cyan
    (Get-Acl -Path "AD:\$dn").Access |
        Where-Object { $_.ActiveDirectoryRights -match "GenericAll|GenericWrite|WriteDacl|WriteOwner" } |
        Select-Object IdentityReference, ActiveDirectoryRights, AccessControlType
}

Comparez chaque IdentityReference renvoyé à une liste de référence de principaux intégrés (SYSTEM, Enterprise Admins, Domain Admins, Administrators). Tout le reste doit avoir une justification métier documentée.

AdminSDHolder, SDProp et adminCount

Active Directory protège un ensemble fixe de groupes privilégiés (Domain Admins, Enterprise Admins, Schema Admins, Administrators, Account Operators, Backup Operators et quelques autres) grâce à un mécanisme appelé SDProp (SD Propagation). Toutes les 60 minutes, le processus :

  1. Lit l'ACL de l'objet spécial AdminSDHolder.
  2. Applique cette ACL à chaque membre actuel d'un groupe protégé, en écrasant toute personnalisation d'ACL faite directement sur ces comptes.
  3. Définit adminCount=1 sur chaque membre protégé, et ne l'efface pas automatiquement lorsque le compte quitte le groupe protégé.

C'est pourquoi les modifications d'autorisations faites directement sur l'objet utilisateur d'un Domain Admin ne cessent de disparaître : SDProp les écrase au cycle suivant. C'est aussi pourquoi adminCount=1 devient un marqueur durable, bien qu'imparfait, signifiant « ce compte a été privilégié à un moment donné ».

Pour modifier les autorisations effectives des comptes protégés, modifiez l'ACL d'AdminSDHolder lui-même (avec prudence : elle se propage à tous), et non celle des comptes individuels.

PowerShell
$adminSDHolderDN = "CN=AdminSDHolder,CN=System," + (Get-ADDomain).DistinguishedName
(Get-Acl -Path "AD:\$adminSDHolderDN").Access |
    Where-Object { $_.ActiveDirectoryRights -match "GenericAll|WriteDacl|WriteOwner" } |
    Select-Object IdentityReference, ActiveDirectoryRights

Trouver et nettoyer les objets adminCount=1 obsolètes

Les comptes retirés des groupes privilégiés conservent adminCount=1 et, surtout, conservent l'héritage désactivé sur leur ACL : ils ne reçoivent donc plus les modifications d'autorisations faites au niveau de l'UO, et leur dernière ACL privilégiée connue persiste indéfiniment. C'est un chemin classique d'« administrateur fantôme » : un compte qui semble ordinaire au vu de ses appartenances aux groupes, mais qui porte encore des entrées d'ACL privilégiées résiduelles.

PowerShell
# Trouver les utilisateurs marqués adminCount=1 qui ne sont PAS membres actuels de groupes protégés
$protectedMembers = @()
foreach ($g in "Domain Admins","Enterprise Admins","Schema Admins","Administrators","Account Operators","Backup Operators") {
    $protectedMembers += (Get-ADGroupMember -Identity $g -Recursive -ErrorAction SilentlyContinue).SamAccountName
}

Get-ADUser -Filter "adminCount -eq 1" -Properties adminCount, whenChanged |
    Where-Object { $_.SamAccountName -notin $protectedMembers } |
    Select-Object SamAccountName, DistinguishedName, whenChanged

Pour chaque résultat obsolète : confirmez que le compte n'a réellement plus besoin de droits élevés, puis réactivez l'héritage de l'ACL pour qu'il hérite à nouveau de son UO :

PowerShell
$obj = Get-ADUser -Identity "svc_legacybackup"
$acl = Get-Acl -Path "AD:\$($obj.DistinguishedName)"
$acl.SetAccessRuleProtection($false, $true)  # retirer la protection, hériter du parent
Set-Acl -Path "AD:\$($obj.DistinguishedName)" -AclObject $acl
Set-ADUser -Identity "svc_legacybackup" -Clear adminCount

Procédez par lots avec revue des changements : effacer adminCount sur un compte encore légitimement privilégié (simplement via une appartenance imbriquée que SDProp n'a pas bien détectée) lui retirera des protections dont il a toujours besoin.

Utiliser BloodHound et PingCastle en défense

La revue manuelle des ACL passe mal à l'échelle au-delà de quelques milliers d'objets. Les outils d'évaluation conçus pour les attaquants fonctionnent tout aussi bien tournés vers l'intérieur :

  • BloodHound ingère les ACL AD, les appartenances aux groupes, les données de session et les liaisons de GPO, puis représente les chemins d'attaque sous forme de graphe (« plus court chemin vers Domain Admins »). Exécutez-le en lecture seule, avec un compte de collecte dédié sans droits d'écriture, et traitez le résultat comme un artefact d'audit interne à ne pas laisser traîner : le graphe lui-même est une carte des cibles.
  • PingCastle produit un rapport d'état noté couvrant les objets obsolètes, les mauvaises configurations d'ACL, les risques liés aux approbations et les anomalies d'AdminSDHolder, avec un score de tendance que vous pouvez suivre d'une version à l'autre.

Exécutez-les selon un calendrier récurrent (mensuel est raisonnable pour la plupart des environnements), conservez l'historique des rapports et suivez le nombre de constats « critiques » comme un indicateur, et non comme un simple exercice de nettoyage ponctuel.

Vérification

Après avoir corrigé un constat, relancez exactement la requête qui l'a révélé et confirmez un résultat propre :

PowerShell
# Revérifier les droits équivalents à DCSync (GUID de réplication, AllExtendedRights, GenericAll, WriteDACL) après correction
$domain   = Get-ADDomain
$rootSid  = (Get-ADDomain (Get-ADForest).RootDomain).DomainSID.Value
$expected = @(
    'S-1-5-18',                        # SYSTEM
    'S-1-5-9',                         # Enterprise Domain Controllers
    'S-1-5-32-544',                    # Administrators (built-in)
    "$($domain.DomainSID.Value)-516",  # Domain Controllers
    "$($domain.DomainSID.Value)-512",  # Domain Admins (default WriteDACL)
    "$rootSid-519",                    # Enterprise Admins (default GenericAll)
    "$rootSid-498"                     # Enterprise Read-only Domain Controllers (Get-Changes only)
)
$repl = @([guid]'1131f6aa-9c07-11d1-f79f-00c04fc2dcd2', [guid]'1131f6ad-9c07-11d1-f79f-00c04fc2dcd2')
$acl  = Get-Acl -Path "AD:\$($domain.DistinguishedName)"
$acl.GetAccessRules($true, $true, [System.Security.Principal.SecurityIdentifier]) | Where-Object {
    $r = $_.ActiveDirectoryRights
    $_.AccessControlType -eq 'Allow' -and
    -not $_.PropagationFlags.HasFlag([System.Security.AccessControl.PropagationFlags]::InheritOnly) -and
    $_.IdentityReference.Value -notin $expected -and (
        $r.HasFlag([System.DirectoryServices.ActiveDirectoryRights]::GenericAll) -or
        $r.HasFlag([System.DirectoryServices.ActiveDirectoryRights]::WriteDacl) -or
        ($r.HasFlag([System.DirectoryServices.ActiveDirectoryRights]::ExtendedRight) -and
         ($_.ObjectType -in $repl -or $_.ObjectType -eq [guid]::Empty))
    )
}
# Aucun résultat attendu, hormis les exceptions documentées comme le compte de connecteur AD DS d'Entra Connect

Ce que cela casse

  • L'administration déléguée légitime. Les groupes du support autorisés à réinitialiser les mots de passe dans une UO précise, les équipes applicatives qui gèrent leurs propres comptes de service et les logiciels de sauvegarde qui ont besoin de droits proches de la réplication peuvent tous apparaître comme des « constats ». Les retirer sans revue casse de vrais processus : validez avec un responsable du changement avant de révoquer.
  • Les outils tiers intégrés à AD (sauvegarde, gouvernance des identités, solutions PAM) exigent parfois des droits étendus par conception ; consultez la documentation de l'éditeur avant de retirer les autorisations de leur compte de service.
  • L'automatisation qui compte sur l'effacement d'adminCount : si un script ou un outil de provisionnement s'attend à ce que adminCount reflète l'appartenance actuelle aux groupes en temps réel, il devra tenir compte du cycle d'une heure de SDProp et de l'absence d'effacement automatique.

Associez cet audit aux frontières d'identité décrites dans Tier 0 et accès privilégiés, et refaites-le chaque fois que vous décommissionnez un outil d'administration déléguée ou un processus du support : ce sont les sources les plus fréquentes d'attributions d'ACL orphelines.

Questions fréquentes

Quel est le moyen le plus rapide de savoir qui peut faire un DCSync dans mon domaine ?

Exécutez Get-Acl sur l'objet du contexte de nommage du domaine et filtrez les principaux qui détiennent à la fois DS-Replication-Get-Changes et DS-Replication-Get-Changes-All, ou bien GenericAll, AllExtendedRights ou WriteDACL, qui les incluent ou permettent de les accorder. Par défaut, les contrôleurs de domaine détiennent les deux droits via les groupes Domain Controllers et Enterprise Domain Controllers, le groupe Administrators intégré détient les deux (ce qui couvre Domain Admins et Enterprise Admins), et Enterprise Read-only Domain Controllers ne détient que Get-Changes. Tout autre principal qui détient les deux droits, ou l'un des droits plus larges, peut effectuer un DCSync.

Pourquoi les autorisations que je retire du compte d'un Domain Admin reviennent-elles sans cesse ?

C'est l'effet d'AdminSDHolder et du processus SDProp. Toutes les 60 minutes, SDProp réinitialise l'ACL de chaque membre d'un groupe protégé (Domain Admins, Enterprise Admins, etc.) pour la faire correspondre à l'ACL de l'objet AdminSDHolder, écrasant toute autorisation personnalisée ajoutée directement sur cet utilisateur.

Peut-on retirer sans risque GenericAll et WriteDACL de tous les comptes non administrateurs ?

Pas sans revue préalable. Certaines de ces attributions relèvent d'une administration déléguée légitime, par exemple un groupe d'administration d'UO du support qui a besoin de GenericAll limité à une UO précise. Auditez chaque constat, rattachez-le à un besoin métier explicite et ne retirez que ce qui n'a aucune justification.

Auditer les ACL Active Directory avant un attaquant

Guides associés

Sécurité des objets & ACL

AdminSDHolder et SDProp : nettoyage et surveillance

Établissez une base de l'ACL AdminSDHolder, repérez les comptes adminCount=1 orphelins, réinitialisez leurs ACL, lancez SDProp à la demande et surveillez AdminSDHolder.

Intermédiaire
Stratégie de groupe & SYSVOL

Auditer les autorisations des GPO et les droits gPLink

Identifier qui peut modifier, créer et lier des GPO dans Active Directory : ACL des GPO, droits gPLink sur les UO et sites, Group Policy Creator Owners et filtres WMI.

Intermédiaire