ADACLScanner est un outil en PowerShell, créé par Robin Granberg (ex PFE Microsoft et aujourd'hui chez Semperis). L'outil est disponible sur https://github.com/canix1/ADACLScanner
Cet outil est utilisé pour auditer les autorisations Active Directory, les exporter au format CSV/HTML, les comparer avec une exportation précédente ou avec un autre domaine ou avec les autorisations par défaut.Il permet aussi de connaître les autorisations d'un utilisateur ou d'un groupe, le propriétaire d'un objet, la date de dernière modification des droits, les droits hérités, etc.
Il peut être exécuté avec une interface graphique (GUI) ou en ligne de commande.Le projet est toujours actif, et Robin prend le temps de corriger les erreurs signalées via Github.
Utilisation ligne de commandes
-RecursiveFind
: This parameter will search any nested groups to show all security prinicpals that have access.
-RecursiveObjectType
: Ce paramètre filtre les groupes imbriqués pour n'afficher que les utilisateurs qui y ont accès.
-FilterTrustee
: Filtre ACL pour les chaînes de caractères correspondantes dans Trustee Exemple 1 -FilterTrustee "user1" (domaine\ est nécessaire)
-Owner
: Obtenir les propriétaires
Exemples de recherche
ACL personnalisés sur toutes les OU et tous les conteneurs
$res = .\ADACLScan.ps1 -Base (Get-ADRootDSE).defaultNamingContext -Scope subtree -Filter "(|(objectClass=organizationalUnit)(objectClass=container))" -SkipDefaults -ShowCriticalityColor -Output HTML -Show
# To view the result and exlucde groupPolicyContainer
$res | Where-Object ObjectClass -ne 'groupPolicyContainer'
AdminSDHolder ACL et date de dernière modification
.\ADACLScan.ps1 -Base "CN=AdminSDHolder,CN=System,$((Get-ADRootDSE).defaultNamingContext)" -SDDate -ShowCriticalityColor -Show -Output HTML
Obtenir les droits d'un utilisateur/groupe spécifique
.\ADACLScan.ps1 -Base (Get-ADRootDSE).defaultNamingContext -Scope subtree -Filter "(|(objectClass=organizationalUnit)(objectClass=container))" -SkipDefaults -SkipBuiltIn -ShowCriticalityColor -Output HTML -Show -EffectiveRightsPrincipal domain\user
Droits sur les GPOs
.\ADACLScan.ps1 -GPO -Scope subtree -ShowCriticalityColor -Output HTML -Show -RecursiveFind
Obtenir les propriétaires
.\ADACLScan.ps1 -Base (Get-ADRootDSE).defaultNamingContext -Owner -Scope subtree -Filter '(objectClass=*)' | Where-Object {$_.Access -eq 'Owner'}
Obtenir les permissions Deny
Rechercher les permissions autorisation Deny
(peut être utile pour vérifier ManagedBy ou d'autres attributs utiles cachés).
.\ADACLScan.ps1 -Base (Get-ADRootDSE).defaultNamingContext -Scope subtree -Filter '(objectClass=*)' | Where-Object {$_.Access -eq 'Deny'}
SID non résolus - tous les naming context et propriétaires
⚠️ Le temps d'exécution dépend du nombre d'objets⚠️
[System.Collections.Generic.List[PSObject]]$unresolvedSIDArray = @()
foreach($nc in (Get-ADRootDSE).namingcontexts){
$unresolvedSID = .\ADACLScan.ps1 -Base $nc -Scope subtree -Filter '(objectClass=*)' -Owner -FilterTrustee 'S-1-5*'
$unresolvedSID | ForEach-Object {
$unresolvedSIDArray.add($_)
}
}
SID non résolus - tous les objets de la partition domaine
⚠️ Le temps d'exécution dépend du nombre d'objets⚠️
$unresolvedSIDArray = .\ADACLScan.ps1 -Base (Get-ADRootDSE).defaultNamingContext -Scope subtree -Filter '(objectClass=*)' -Owner -FilterTrustee 'S-1-5*'
SID non résolus sur OUs et conteneurs uniquement
⚠️ Le temps d'exécution dépend du nombre d'objets⚠️
$unresolvedSIDArray= .\ADACLScan.ps1 -Base (Get-ADRootDSE).defaultNamingContext -Scope subtree -Filter '(|(objectClass=organizationalUnit)(objectClass=container))' -Owner -FilterTrustee 'S-1-5*'
SID non résolus sur GPO uniquement
⚠️ Le temps d'exécution dépend du nombre d'objets⚠️
[System.Collections.Generic.List[PSObject]]$unresolvedSIDArray = @()
$unresolvedSID = .\ADACLScan.ps1 -GPO -Scope subtree -Owner -FilterTrustee 'S-1-5*'
$unresolvedSID | ForEach-Object {
$unresolvedSIDArray.add($_)
}
SID non résolus sur partitions DNS intégrées à AD
$adIntegratedDNSNC = (Get-ADRootDSE).namingContexts | Where-Object {$_ -like 'DC=DomainDNSZones*' -or $_ -like 'DC=ForestDNSZones*'}
[System.Collections.Generic.List[PSObject]]$unresolvedSIDArray = @()
foreach($nc in $adIntegratedDNSNC){
$unresolvedSID = .\ADACLScan.ps1 -Base $nc -Scope subtree -Filter '(objectClass=*)' -Owner -FilterTrustee 'S-1-5*'
$unresolvedSID | ForEach-Object {
$unresolvedSIDArray.add($_)
}
}
Utilisation avancées des résultats
Si vous souhaitez supprimer les SID inconnus ou modifier le propriétaire , vous pouvez utilisez les commandes suivantes.
Supprimer SID inconnus
$DNWithUnresolvedSID = ($unresolvedSIDArray | Where-Object {$_.Access -ne 'Owner'}).Object
foreach ($dn in $DNWithUnresolvedSID){
$acl = Get-Acl "AD:\$dn"
$aclsToDelete = $acl.Access | Where-Object {$_.IdentityReference -like 'S-1-5*'}
foreach($aclToDelete in $aclsToDelete){
$acl.RemoveAccessRule($aclToDelete)
}
Set-Acl -Path "AD:\$dn" -AclObject $acl
}
Modifier propriétaire
$DNWithUnresolvedSIDOwner = ($unresolvedSIDArray | Where-Object {$_.Access -eq 'Owner'}).Object
$newOwner = New-Object System.Security.Principal.Ntaccount("Domain Admins")
foreach ($dn in $DNWithUnresolvedSIDOwner){
$acl = Get-Acl "AD:\$dn"
$acl.SetOwner($newOwner)
Set-Acl -Path "AD:\$dn" -AclObject $acl
}
Clap
Comments