# CreateAny

## Summary

|                            |                                      |
| -------------------------- | ------------------------------------ |
| **FSProtect ACL Alias**    | CreateAny                            |
| **AD Alias**               | Create all child objects             |
| **Affected Object Types**  | OUs, Domains, Containers             |
| **Exploitation Certainty** | Certain                              |
| **AD Right**               | CreateChild                          |
| **AD Permission Guid**     | 00000000-0000-0000-0000-000000000000 |

## Description

The `CreateAny` permission in Active Directory allows an account to create any type of child object within a designated container. This includes users, groups, computers, and Organizational Units (OUs). When properly configured, this permission facilitates efficient administrative operations, enabling swift organizational adjustments, such as onboarding new personnel, forming temporary groups for specific projects, or restructuring directory hierarchies to meet evolving business needs.

However, if misconfigured or obtained by unauthorized principals, the `CreateAny` permission introduces severe security risks. An attacker can create arbitrary objects—users, groups, computers, and nested OUs—altering the directory structure to hide malicious accounts, bypass monitoring controls, and facilitate lateral movement. These unauthorized modifications may result in privilege escalation, persistent access, and widespread compromise of the domain’s confidentiality, integrity, and availability.

## Identification

### PowerShell

#### Active Directory Module

Using the ActiveDirectory PowerShell module, you can enumerate `CreateAny` entries.

**1.** Find-CreateAny function

```powershell
function Find-CreateAny {
    [CmdletBinding()]
    param ( [string]$Target = $null, [string]$SearchBase = $null, [string]$OutputPath = "CreateAny.csv", [switch]$ExcludeAdmins = $false)
    Import-Module ActiveDirectory
    Write-Host "Scanning for explicit 'CreateChild' (any object class) ACEs..."
    $AccessControlType   = [System.Security.AccessControl.AccessControlType]::Allow
    $ActiveDirectoryRights = [System.DirectoryServices.ActiveDirectoryRights]::CreateChild
    $AnyObjectGuid       = [Guid]::Empty   # 00000000-0000-0000-0000-000000000000
    $ExcludedSIDs = @()
    if ($ExcludeAdmins) {
        Write-Host "Excluding default administrative groups and built-in accounts."
        try {
            $ExcludedSIDs += (New-Object System.Security.Principal.NTAccount "NT AUTHORITY\SYSTEM").Translate([System.Security.Principal.SecurityIdentifier]);$ExcludedSIDs += (New-Object System.Security.Principal.NTAccount "NT AUTHORITY\SELF").Translate([System.Security.Principal.SecurityIdentifier])
            $ExcludedSIDs += (New-Object System.Security.Principal.NTAccount "BUILTIN\Account Operators").Translate([System.Security.Principal.SecurityIdentifier])
            $ExcludedSIDs += (New-Object System.Security.Principal.NTAccount "BUILTIN\Administrators").Translate([System.Security.Principal.SecurityIdentifier]);$ExcludedSIDs += (New-Object System.Security.Principal.NTAccount "NT AUTHORITY\ENTERPRISE DOMAIN CONTROLLERS").Translate([System.Security.Principal.SecurityIdentifier])
            # CREATOR OWNER
            $ExcludedSIDs += [System.Security.Principal.SecurityIdentifier]::new("S-1-3-0")
            foreach ($g in "Domain Admins","Enterprise Admins","Schema Admins","Cert Publishers","Group Policy Creator Owners","Domain Controllers","Key Admins","Enterprise Key Admins","DnsAdmins","RAS and IAS Servers") {
                try { $ExcludedSIDs += (Get-ADGroup -Identity $g -ErrorAction Stop).SID } catch {}
            }
        } catch {
            Write-Warning "Some default admin groups could not be resolved for exclusion."
        }
    }
    $foundAcls = New-Object System.Collections.Generic.List[object]
    $objectsToScan = @()
    try {
        if ($Target) {
            Write-Host "Targeting single object: '$Target'"
            $obj = Get-ADObject -Identity $Target -Properties distinguishedName -ErrorAction Stop
            if ($obj) { $objectsToScan = @($obj) } else { Write-Output "Object '$Target' not found."; return }
        } else {
            if (-not $SearchBase) {
                $SearchBase = (Get-ADDomain).DistinguishedName
            }
            Write-Host "Querying objects under: $SearchBase"
            $objectsToScan = Get-ADObject -SearchBase $SearchBase -LDAPFilter "(|(objectClass=organizationalUnit)(objectClass=container)(objectClass=domainDNS)(objectClass=computer)(objectClass=user)(objectClass=group))" -Properties distinguishedName -ResultSetSize $null -ErrorAction Stop
        }
    } catch {
        Write-Error "Failed to retrieve AD objects: $($_.Exception.Message)"
        return
    }
    foreach ($obj in $objectsToScan) {
        $ObjectDistinguishedName = $obj.DistinguishedName
        try {
            $acl = Get-Acl -Path "AD:$ObjectDistinguishedName"
            foreach ($ace in $acl.Access) {
                if ($ace.IsInherited) { continue }
                $hasCreateChild = (($ace.ActiveDirectoryRights -band $ActiveDirectoryRights) -ne 0)
                if ($ace.AccessControlType -eq $AccessControlType -and
                    $hasCreateChild -and
                    $ace.ObjectType -eq $AnyObjectGuid) {
                    $isExcluded = $false
                    if ($ExcludeAdmins -and $ExcludedSIDs.Count -gt 0) {
                        try {
                            $aceSid = $ace.IdentityReference.Translate([System.Security.Principal.SecurityIdentifier])
                            if ($ExcludedSIDs -contains $aceSid) { $isExcluded = $true }
                        } catch {
                            Write-Warning "Could not translate SID for $($ace.IdentityReference.Value)"
                        }
                    }
                    if (-not $isExcluded) {
                        $foundAcls.Add([PSCustomObject]@{
                            'Vulnerable Object' = $ObjectDistinguishedName
                            'Internal Threat'   = $ace.IdentityReference.Value
                        })
                    }
                }
            }
        } catch {
            Write-Warning "Could not retrieve ACL for '$ObjectDistinguishedName': $($_.Exception.Message)"
        }
    }
    if ($foundAcls.Count -gt 0) {
        try {
            $foundAcls | Sort-Object -Unique 'Vulnerable Object','Internal Threat' |
                Export-Csv -Path $OutputPath -NoTypeInformation -Encoding UTF8
            Write-Output "$($foundAcls.Count) Results exported to '$OutputPath'."
        } catch {
            Write-Error "Failed to export CSV: $($_.Exception.Message)"
        }
    } else {
        Write-Output ("No explicit 'CreateChild (any object class)' ACEs found" + ($(if($ExcludeAdmins){" (after exclusions)"})))
    }
}
```

**2.** Scan all OUs and containers in the domain

```powershell
Find-CreateAny
```

**3.** Scan a specific object

```powershell
Find-CreateAny -Target "OU=UsBranch,DC=forestall,DC=labs"
```

**4.** To exclude default admin ACLs to improve visibility

```powershell
Find-CreateAny -ExcludeAdmins
```

#### .NET Directory Services

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

**1.** Find-CreateAnySimple function

```powershell
function Find-CreateAnySimple {
    [CmdletBinding()]
    param ([string]$Target = $null,[string]$OutputPath = "CreateAny.csv",[switch]$ExcludeAdmins = $false)
    $CreateAnyGuid = [guid]"00000000-0000-0000-0000-000000000000"
    $AccessControlType = [System.Security.AccessControl.AccessControlType]::Allow
    $ActiveDirectoryRights = [System.DirectoryServices.ActiveDirectoryRights]::CreateChild
    $entries = @()
    if ($Target) {
        Write-Verbose "Binding to target object: $Target"
        try {
            $entries += New-Object System.DirectoryServices.DirectoryEntry("LDAP://$Target")
        }
        catch {
            Write-Error "Could not bind to '$Target': $_"
            return
        }
    } else {
        Write-Verbose "Binding to RootDSE to enumerate all objects..."
        try {
            $root = New-Object System.DirectoryServices.DirectoryEntry("LDAP://RootDSE")
            $baseDN = $root.Properties["defaultNamingContext"][0]
            $searcher = New-Object System.DirectoryServices.DirectorySearcher([ADSI]"LDAP://$baseDN")
            $searcher.Filter = "(objectClass=*)"
            $searcher.PageSize = 1000
            [void]$searcher.PropertiesToLoad.Add("distinguishedName")
            $results = $searcher.FindAll()
            foreach ($res in $results) {
                try {
                    $entries += $res.GetDirectoryEntry()
                }
                catch {
                    Write-Warning "Failed to bind to result entry: $_"
                }
            }
        }
        catch {
            Write-Error "Failed to enumerate objects: $_"
            return
        }
    }
    $ExcludedSIDs = @()
    if ($ExcludeAdmins) {
        Write-Verbose "Preparing list of excluded well-known and domain-specific admin group SIDs..."
     $wellKnownAccounts = @( "NT AUTHORITY\SYSTEM", "NT AUTHORITY\SELF", "BUILTIN\Administrators",  "BUILTIN\Account Operators", "NT AUTHORITY\ENTERPRISE DOMAIN CONTROLLERS")
        foreach ($account in $wellKnownAccounts) {
            try {
                $ExcludedSIDs += (New-Object System.Security.Principal.NTAccount($account)).Translate([System.Security.Principal.SecurityIdentifier])
            }
            catch {
                Write-Warning "Failed to resolve SID for $account"
            }
        }
        $ExcludedSIDs += [System.Security.Principal.SecurityIdentifier]::new("S-1-3-0")  # Creator Owner
        $domainAdminGroups = @( "Domain Admins","Enterprise Admins", "Schema Admins","Group Policy Creator Owners","Cert Publishers","Domain Controllers", "Key Admins", "Enterprise Key Admins","DnsAdmins","RAS and IAS Servers")
        try {
            $domainContext = New-Object System.DirectoryServices.DirectoryEntry("LDAP://RootDSE")
            $defaultNamingContext = $domainContext.Properties["defaultNamingContext"][0]
            $domainDN = "LDAP://$defaultNamingContext"
            foreach ($groupName in $domainAdminGroups) {
                try {
                    $searcher = New-Object System.DirectoryServices.DirectorySearcher([ADSI]$domainDN)
                    $searcher.Filter = "(&(objectClass=group)(sAMAccountName=$groupName))"
                    $searcher.SearchScope = "Subtree"
                    $result = $searcher.FindOne()
                    if ($result) {
                        $group = $result.GetDirectoryEntry()
                        $sid = New-Object System.Security.Principal.SecurityIdentifier($group.Properties["objectSid"][0], 0)
                        $ExcludedSIDs += $sid
                    }
                }
                catch {
                    Write-Warning "Failed to resolve group: $groupName"
                }
            }
        }
        catch {
            Write-Warning "Could not resolve domain context for exclusion."
        }
    }
    $results = foreach ($entry in $entries) {
        $dn = $entry.Path.Replace("LDAP://", "")
        Write-Verbose "Inspecting ACL for $dn"
        try {
            $acl = $entry.ObjectSecurity
            $aces = $acl.GetAccessRules($true, $true, [System.Security.Principal.SecurityIdentifier])
        }
        catch {
            Write-Warning "Failed to read ACL for $dn : $_"
            continue
        }
        foreach ($ace in $aces) {
            if (
                $ace.AccessControlType -eq $AccessControlType -and
                ($ace.ActiveDirectoryRights -band $ActiveDirectoryRights) -and
                ($ace.ObjectType -eq $CreateAnyGuid) -and
                -not $ace.IsInherited
            ) {
                if ($ExcludeAdmins) {
                    try {
                        $sid = $ace.IdentityReference.Translate([System.Security.Principal.SecurityIdentifier])
                        if ($ExcludedSIDs -contains $sid) { continue }
                    }
                    catch {
                        Write-Warning "Failed to resolve SID for exclusion check: $($_.Exception.Message)"
                        continue
                    }
                }
                $who = try {
                    $ace.IdentityReference.Translate([System.Security.Principal.NTAccount]).Value
                } catch {
                    $ace.IdentityReference.Value
                }

                [PSCustomObject]@{
                    'Vulnerable Object' = $dn
                    'Internal Threat'   = $who
                }
            }
        }
    }
    if ($results) {
        $results | Sort-Object 'Vulnerable Object', 'Internal Threat' -Unique | Export-Csv -Path $OutputPath -NoTypeInformation -Encoding UTF8
        Write-Host "Found $($results.Count) CreateChild ACEs. Exported to $OutputPath"
    } else {
        Write-Host "No explicit CreateChild permissions found."
    }
}
```

**2.** Scan all containers in the domain

```powershell
Find-CreateAnySimple
```

**3.** Scan a specific container in the domain

```powershell
Find-CreateAnySimple -Target "CN=Backup Operators,CN=Builtin,DC=forestall,DC=labs"
```

**4.** To exclude default admin ACLs to improve visibility

```powershell
Find-CreateAnySimple -ExcludeAdmins
```

### Active Directory Users and Computers

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

**2.** Right-click the object name.

**3.** Select `Properties` from the context menu.

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

**5.** Click the `Advanced` button to open the Advanced Security Settings dialog.

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

**7.** Click `Edit` to modify the selected ACE.

**8.** In the permissions list, locate and check the option `Create all child objects`.

**9.** Click `OK` to save your changes and close the dialogs.

![Active Directory Users and Computers](/files/yLf4bkTv8gkSj88wfxyq)

## Exploitation

For exploitation details on creating user and computer objects, see [CreateUser](https://gitlab.com/forestall/fsprotect-knowledge-base/-/blob/main/edges/CreateUser/README.md) and [CreateComputer](https://gitlab.com/forestall/fsprotect-knowledge-base/-/blob/main/edges/CreateComputer/README.md).

## Mitigation

Dangerous Access Control Entries should be removed by following the steps below.

**1.** Open `Active Directory Users and Computers`, and activate `Advanced Features` option.

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

**3.** In this tab, click the `Advanced` button and open the suspicious Access Control Entry.

**4.** Remove the rights marked as dangerous.

**5.** Click `OK` and `Apply` to save the changes.

![Active Directory Users and Computers](/files/yLf4bkTv8gkSj88wfxyq)

## Detection

Adding new Access Control Entries to Active Directory objects modifies the `ntSecurityDescriptor` attribute of those objects. These changes can be detected with Event IDs 5136 and 4662 to identify suspicious 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> |
| 4724     | An attempt was made to reset an account's password. | Subject, TargetAccount                   | <https://learn.microsoft.com/en-us/previous-versions/windows/it-pro/windows-10/security/threat-protection/auditing/event-4724> |                                                                                            |
| 4722     | A user account was enabled.                         | Subject, TargetAccount                   | <https://learn.microsoft.com/en-us/previous-versions/windows/it-pro/windows-10/security/threat-protection/auditing/event-4722> |                                                                                            |
| 5137     | A directory service object was created.             | ObjectDN, ObjectClass                    | <https://learn.microsoft.com/en-us/windows/security/threat-protection/auditing/event-5137>                                     |                                                                                            |
| 4720     | A user account was created.                         | Subject, NewAccountName                  | <https://learn.microsoft.com/en-us/windows/security/threat-protection/auditing/event-4720>                                     |                                                                                            |
| 4741     | A computer account was created.                     | Subject, TargetAccount                   | <https://learn.microsoft.com/en-us/windows/security/threat-protection/auditing/event-4741>                                     |                                                                                            |
| 4727     | A security-enabled global group was created.        | Subject, GroupName                       | <https://learn.microsoft.com/en-us/windows/security/threat-protection/auditing/event-4727>                                     |                                                                                            |
| 4731     | A security-enabled local group was created.         | Subject, GroupName                       | <https://learn.microsoft.com/en-us/windows/security/threat-protection/auditing/event-4731>                                     |                                                                                            |
| 4754     | A security-enabled universal group was created.     | Subject, GroupName                       | <https://learn.microsoft.com/en-us/windows/security/threat-protection/auditing/event-4754>                                     |                                                                                            |

## References

* [Security Considerations for Directory - IBM Docs](https://www.ibm.com/docs/en/db2/11.5?topic=directory-security-considerations)
* [Access Control and Object Creation - Microsoft Docs](https://learn.microsoft.com/en-us/windows/win32/ad/access-control-and-object-creation)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.forestall.io/fsprotect/edges/ad/createany.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
