Photo by Brands&People / Unsplash
Visualiser les permissions AD avec ADACLScanner

Visualiser les permissions AD avec ADACLScanner

Published on 11 Jul 2023

Bastien Perez
Bastien Perez

Clap

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

Attention, n'utilisez les commandes suivantes que si vous savez ce que vous faites ! Ces commandes ne sont *pas* des commandes d'ADACLScanner!
$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

Attention, n'utilisez les commandes suivantes que si vous savez ce que vous faites ! Ces commandes ne sont *pas* des commandes d'ADACLScanner!
$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
}

Comments

banner-Bastien Perez
Bastien Perez

Freelance Microsoft 365 - Active Directory - Modern Workplace

France