GenericAll

Summary

FSProtect ACL Alias

GenericAll

AD Alias

Full Control

Affected Object Types

All Objects

Exploitation Certainty

Certain

AD Right

GenericAll

AD Permission Guid

00000000-0000-0000-0000-000000000000

Description

The GenericAll permission in Active Directory grants an account complete control over a specified directory object. With this permission, an account can perform any action—ranging from reading and modifying all attributes to managing security settings and delegating permissions. This level of authority is sometimes necessary in administrative scenarios that require full management rights over an object, such as transferring ownership, performing extensive configuration changes, or executing high-level system maintenance tasks.

However, if misconfigured or assigned to unauthorized users, the GenericAll permission introduces substantial security vulnerabilities. An attacker who gains this permission can manipulate critical directory objects by altering security configurations, modifying object attributes, or even deleting objects outright. Such exploitation can lead to unauthorized access, complete privilege escalation, and persistent control over essential network resources. In extreme cases, the attacker may leverage GenericAll to subvert the intended security architecture of the Active Directory environment, resulting in a widespread compromise of system integrity and trust.

Identification

PowerShell

Active Directory Module

Using the ActiveDirectory PowerShell module, you can enumerate GenericAll entries.

1. Find-GenericAll function

function Find-GenericAll {
    [CmdletBinding()]
    param ([string]$Target = $null,[string]$SearchBase = $null,[string]$OutputPath = "GenericAllAcls.csv",[switch]$ExcludeAdmins = $false)
    Import-Module ActiveDirectory
    Write-Host "Gathering Active Directory objects and inspecting ACLs for explicit GenericAll permissions..."
    $ExcludedSIDs = @()
    if ($ExcludeAdmins) {
        Write-Host "Excluding default administrative groups and built-in accounts."
        $ExcludedSIDs += (New-Object System.Security.Principal.NTAccount "NT AUTHORITY\SYSTEM").Translate([System.Security.Principal.SecurityIdentifier]),
        (New-Object System.Security.Principal.NTAccount "NT AUTHORITY\SELF").Translate([System.Security.Principal.SecurityIdentifier]),
        (New-Object System.Security.Principal.NTAccount "BUILTIN\Account Operators").Translate([System.Security.Principal.SecurityIdentifier]),
        (New-Object System.Security.Principal.NTAccount "BUILTIN\Administrators").Translate([System.Security.Principal.SecurityIdentifier]),
        (New-Object System.Security.Principal.NTAccount "BUILTIN\Terminal Server License Servers").Translate([System.Security.Principal.SecurityIdentifier]),
        (New-Object System.Security.Principal.NTAccount "NT AUTHORITY\ENTERPRISE DOMAIN CONTROLLERS").Translate([System.Security.Principal.SecurityIdentifier])
        $ExcludedSIDs += [System.Security.Principal.SecurityIdentifier]::new("S-1-3-0");
        try {
            $ExcludedSIDs += (Get-ADGroup -Identity "Domain Admins").SID;$ExcludedSIDs += (Get-ADGroup -Identity "Enterprise Admins").SID
            $ExcludedSIDs += (Get-ADGroup -Identity "Schema Admins").SID;$ExcludedSIDs += (Get-ADGroup -Identity "Cert Publishers").SID
            $ExcludedSIDs += (Get-ADGroup -Identity "Group Policy Creator Owners").SID;$ExcludedSIDs += (Get-ADGroup -Identity "Domain Controllers").SID
            $ExcludedSIDs += (Get-ADGroup -Identity "Key Admins").SID;$ExcludedSIDs += (Get-ADGroup -Identity "Enterprise Key Admins").SID
            $ExcludedSIDs += (Get-ADGroup -Identity "DnsAdmins").SID;$ExcludedSIDs += (Get-ADGroup -Identity "RAS and IAS Servers").SID
        }catch {Write-Warning "Could not resolve one or more default domain admin groups. They might not be filtered from results."}}
    $AccessControlType = [System.Security.AccessControl.AccessControlType]::Allow;$ActiveDirectoryRights = [System.DirectoryServices.ActiveDirectoryRights]::GenericAll
    $foundAcls = @();$objectsToScan = @()
    try {
        if ($Target) {
            Write-Host "Searching for permissions on specific object: '$Target'."
            $specificObject = Get-ADObject -Identity $Target -Properties nTSecurityDescriptor -ErrorAction Stop
            if ($specificObject) { $objectsToScan += $specificObject} else {Write-Output "Object '$Target' not found.";return}} else {
            $adObjectParams = @{
                Filter    = "*"
                Properties = "nTSecurityDescriptor"
                ErrorAction = "Stop"
            }
            if ($SearchBase) {
                $adObjectParams.Add("SearchBase", $SearchBase)
                Write-Host "Searching for all objects within '$SearchBase'."} else {
                $adObjectParams.Add("SearchBase", (Get-ADRootDSE).DefaultNamingContext)
                Write-Host "Searching for all objects in the domain."}
            $objectsToScan = Get-ADObject @adObjectParams}
        if (-not $objectsToScan) {Write-Output "No objects found matching the criteria.";return }
        foreach ($obj in $objectsToScan) {
            $ObjectDistinguishedName = $obj.DistinguishedName
            try {
                $acl = Get-Acl -Path "AD:$ObjectDistinguishedName" 
                foreach ($ace in $acl.Access) {
                    $isExcluded = $false
                    if ($ExcludeAdmins) {
                        try {
                            if ($ExcludedSIDs -contains $ace.IdentityReference.Translate([System.Security.Principal.SecurityIdentifier])) {
                                $isExcluded = $true
                            }}catch {Write-Warning "Could not translate SID for exclusion check: $($ace.IdentityReference.Value). Error: $($_.Exception.Message)"}}
                    if ($ace.AccessControlType -eq $AccessControlType -and($ace.ActiveDirectoryRights -eq $ActiveDirectoryRights) -and ($ace.ObjectType -eq [Guid]::Empty) -and-not $ace.IsInherited -and -not $isExcluded) {
                        $foundAcls += [PSCustomObject]@{
                            'Vulnerable Object' = $ObjectDistinguishedName
                            'Permission Holder' = $ace.IdentityReference.Value }}}}
            catch {Write-Warning "Could not retrieve ACL for '$ObjectDistinguishedName': $($_.Exception.Message)"}} }catch {Write-Error "Failed to retrieve Active Directory objects: $($_.Exception.Message)";return}
    if ($foundAcls.Count -gt 0) {
        $exclusionMessage = if ($ExcludeAdmins) { " (excluding default admin groups and built-in accounts)" } else { "" }
        Write-Host "Found $($foundAcls.Count) object(s) with explicit GenericAll permissions$exclusionMessage."
        try {
            $foundAcls | Sort-Object -Unique 'Vulnerable Object', 'Permission Holder' | Export-Csv -Path $OutputPath -NoTypeInformation -Encoding UTF8
            Write-Output "Results exported successfully to '$OutputPath'"
        }
        catch {Write-Error "Failed to export results to CSV file '$OutputPath': $($_.Exception.Message)"}} else {
        $exclusionMessage = if ($ExcludeAdmins) { " (excluding default admin groups and built-in accounts)" } else { "" }
        Write-Output "No Active Directory objects found with explicit GenericAll permissions$exclusionMessage."}}

2. Scan all domain objects

Find-GenericAll

3. Scan a specific object

Find-GenericAll -Target "CN=Users,DC=forestall,DC=labs"

4. To exclude default admin ACLs to improve visibility

Find-GenericAll -ExcludeAdmins

5. Using SearchBase to limit the scope

Find-GenericAll -SearchBase 'CN=Users,Dc=Forestall,DC=Labs' 

.NET Directory Services

By leveraging PowerShell’s built-in .NET DirectoryServices namespace, you can enumerate GenericAll entries without relying on any external modules or dependencies.

1. Find-GenericAllSimple function

function Find-GenericAllSimple {
    [CmdletBinding()]
    param([string]$Target = $null,[string]$OutputPath = "GenericAllAcls.csv",[switch]$ExcludeAdmins)
    $Allow  = [System.Security.AccessControl.AccessControlType]::Allow;$GenAll = [System.DirectoryServices.ActiveDirectoryRights]::GenericAll
    try { $baseDN = ([ADSI]"LDAP://RootDSE").defaultNamingContext } catch { Write-Error "RootDSE read failed: $_"; return }
    $Excluded = [System.Collections.Generic.HashSet[string]]::new()
    if ($ExcludeAdmins) {
        foreach ($n in "NT AUTHORITY\SYSTEM","NT AUTHORITY\SELF","BUILTIN\Account Operators","BUILTIN\Administrators","NT AUTHORITY\ENTERPRISE DOMAIN CONTROLLERS","CREATOR OWNER") {
            try { $Excluded.Add(((New-Object System.Security.Principal.NTAccount $n).Translate([System.Security.Principal.SecurityIdentifier])).Value) | Out-Null } catch {}
        }
        foreach ($g in "Domain Admins","Enterprise Admins","Schema Admins","Cert Publishers","Domain Controllers","Key Admins","Enterprise Key Admins") {
            try {$de   = [ADSI]"LDAP://CN=$g,CN=Users,$baseDN";$sid  = New-Object System.Security.Principal.SecurityIdentifier($de.Properties["objectSID"][0],0);$Excluded.Add($sid.Value) | Out-Null} catch {}}}
    $dns = @()
    if ($Target) {$dns = @($Target)
    } else {try {
            $ds = New-Object System.DirectoryServices.DirectorySearcher(([ADSI]"LDAP://$baseDN"))
            $ds.Filter = "(objectClass=*)"; $ds.PageSize = 1000; $ds.PropertiesToLoad.Clear(); [void]$ds.PropertiesToLoad.Add("distinguishedName")
            $dns = $ds.FindAll() | ForEach-Object { if ($_.Properties["distinguishedname"]) { $_.Properties["distinguishedname"][0] } }
        } catch { Write-Error "Directory search failed: $_"; return }}
    $rows = foreach ($dn in $dns) {
        if (-not $dn) { continue }
        try { $obj = [ADSI]"LDAP://$dn"; $acl = $obj.ObjectSecurity.GetAccessRules($true,$true,[System.Security.Principal.SecurityIdentifier]) } catch { Write-Warning "ACL read failed for $dn – skipping."; continue }
        foreach ($ace in $acl) {
            if (($ace.AccessControlType -eq $Allow) -and (-not $ace.IsInherited) -and (($ace.ActiveDirectoryRights -eq $GenAll) -ne 0)) {
                $sid = $ace.IdentityReference.Value
                if ($ExcludeAdmins -and $Excluded.Contains($sid)) { continue }
                $who = try { $ace.IdentityReference.Translate([System.Security.Principal.NTAccount]).Value } catch { $sid }
                [PSCustomObject]@{ 'Vulnerable Object' = $dn; 'Permission Holder' = $who }}}}
    if ($rows) {$rows | Export-Csv -Path $OutputPath -NoTypeInformation -Encoding UTF8;Write-Host "Exported $($rows.Count) entr$(if($rows.Count -eq 1){'y'}else{'ies'}) to $OutputPath"} else {Write-Host "No objects found with explicit GenericAll permissions."}}

2. Scan all domain objects

Find-GenericAllSimple

3. Scan a specific object

Find-GenericAllSimple -Target "CN=Users,DC=forestall,DC=labs"

4. To exclude default admin ACLs to improve visibility

Find-GenericAllSimple -ExcludeAdmins

Active Directory Users and Computers

1. Open Active Directory Users and Computers on your Windows server.

2. Right-click on the Object name.

3. Select Properties from the context menu.

4. In the Properties window, navigate to the Security tab.

5. In the Security Settings window, locate and select the relevant Access Control Entry (ACE) for the user or group you wish to configure.

6. In the permissions list, locate and check the option Full control.

7. Click OK to save your changes and close the dialogs.

Exploitation

User

You can reset a user’s password to gain full control over the user object—see the ForceChangePassword edge for complete abuse details. You can write to the AddKeyCredentialLink attribute on a user, enabling an attacker to create Shadow Credentials and authenticate as that principal via Kerberos PKINIT—see the AddKeyCredentialLink edge. Alternatively, you can write to the “servicePrincipalNames” attribute to perform a targeted kerberoasting attack—see the abuse section under the WriteSPN edge for more information.

Group

You can take full control of a group to directly modify its membership. See the Abuse Information section under the AddMember edge for complete abuse details.

Computer

You can read a computer object’s LAPS password—see the LapsPassword edge for details. You can write to the AddKeyCredentialLinkattribute on a computer, enabling an attacker to create Shadow Credentials and authenticate as the computer via Kerberos PKINIT—see the AddKeyCredentialLink edge for more information. You can take full control of a computer object to perform a Resource-Based Constrained Delegation attack—see the AddAllowedToAct edge for more information.

Domain Object

You can take full control of the domain object (the head object of the Default Naming Context) to grant DS-Replication-Get-Changes and DS-Replication-Get-Changes-All rights. See the DCSync edge documentation for abuse details.

GPO

You can take full control of a GPO to modify its settings, which will then apply to its targeted users and computers. Select the target object, open the gpedit GUI, and inject a malicious policy—such as an immediate scheduled task with item‑level targeting—into the GPO. Wait at least two hours for the Group Policy Client to retrieve and execute the new policy. See the GPOWrite edge documentation for abuse details.

Certificate Template

When an attacker has GenericAll permissions over a Certificate Template, they can modify its settings to introduce the ESC1 vulnerability. This misconfiguration can then be exploited to escalate privileges and ultimately gain Domain Admin rights.

For more details, see WriteCertificateTemplates.

Delegated Managed Service Account

If an attacker has GenericAll permissions over a dMSA object, they can modify the PrincipalsAllowedToRetrieveManagedPassword property to include their own account. This grants the ability to retrieve the managed service account’s password.

Example:

Set-ADServiceAccount -Identity MyAppSvc -PrincipalsAllowedToRetrieveManagedPassword adam

Once added, the attacker can read the password. For more abuse details, see the ReadGMSAPassword edge.

Mitigation

Access Control Entries identified as dangerous objects should be removed by following the steps below.

1. Open Active Directory Users and Computers

2. Double-click the affected object and open the Security tab.

3. Remove the rights marked as dangerous objects.

4. Click the OK and Apply buttons to save changes.

Detection

Adding new Access Control Entries to Active Directory objects changes the ntSecurityDescriptor attribute of the objects themselves. These changes can be detected with the 5136 and 4662 Event IDs to identify dangerous object modifications.

Event ID
Category
Description
Fields/Attributes
References

5136

Audit Directory Service Changes

A directory service object was modified.

ntSecurityDescriptor

https://learn.microsoft.com/en-us/windows/security/threat-protection/auditing/event-5136

4662

Audit Directory Service Access

An operation was performed on an object.

AccessList, AccessMask

https://learn.microsoft.com/en-us/windows/security/threat-protection/auditing/event-4662

References

Last updated

Was this helpful?