AdminSDHolder, SDProp, and adminCount: Permission behavior for privileged accounts
AdminSDHolder is a permission template for protected accounts and groups. The periodic protection cycle on the PDC Emulator restores that template and disables inheritance. adminCount=1 can remain after membership ends; it proves neither current protected-group membership nor effective authorization. Protection scope and the SIDs enabled in a logon token are different questions.
1. Core mechanism
The decision comes down to two places: the DACL in the protected object's nTSecurityDescriptor and the SDProp process that periodically synchronizes this DACL. SDProp runs on the domain controller that holds the domain's PDC Emulator FSMO role and copies the permissions of the AdminSDHolder (CN=AdminSDHolder,CN=System,DC=...) object to the protected account/groups. The boundary of this lesson is this protection cycle: ACE scope mechanics are at 05.05, actual membership scope of management identities is at 05.07, delegation public access check is at 05.01.
Interfaces and specifications
- AdminSDHolder object: CN=AdminSDHolder,CN=System,DC=<dc>,DC=<dc>; The owner is the Domain Admins group of the domain; Enterprise Admins and Administrators can also make/own changes (Appendix C).
- SDProp: runs every 60 minutes by default on PDCE; Compares the DACL of AdminSDHolder with the DACL of protected objects, if different, writes back the protected object according to AdminSDHolder; Disables inheritance.
- AdminSDProtectFrequency: DWORD under HKLM\SYSTEM\CurrentControlSet\Services\NTDS\Parameters; range 60–7200 seconds; If deleted, it returns to 60 minutes; Reducing production increases the LSASS burden on PDCE.
- Manual execution: RunProtectAdminGroupsTask = 1 on rootDSE LDAP modify (with Ldp.exe) triggers SDProp immediately, does not affect the scheduled run.
- adminCount attribute: SDProp is set to 1 on the objects it protects; It marks that an object IS protected, it does not automatically return to 0 when unsubscribed.
- Windows Security channel: 5136 (with appropriate SACL) for AdminSDHolder DACL or adminCount change, Audit Directory Service Changes; domain controller only.
AdminSDHolder is a template, SDProp is a cloner
On an ordinary object, permissions are determined by inheritance and ACEs written to that object or the OU above it. In protected accounts and groups, a corrector intervenes. AdminSDHolder is a single object located in the domain's System container, and its DACL is the template for the question "how should protected objects be protected?"
SDProp is the process that implements this template. By default, PDC runs every 60 minutes on the DC in the Emulator role, comparing the permissions of AdminSDHolder with the permissions of protected objects, and if there is a difference, writes back the permissions of the protected object according to AdminSDHolder.
So manually changing the DACL of a protected object is not permanent. In our example, an administrator in outreason.example adds a delegation ACE to a Domain Admins member's object; At the latest in the next SDProp cycle, if this ACE is not in the AdminSDHolder template, it will be rolled back.
This lesson follows the SDProp terminology used by Microsoft Learn Appendix C for the periodic protected-account cycle. Microsoft publications distinguish related descriptor-propagation operations differently; do not infer a universal process-hosting or scheduler model from the name.
What objects are protected
Protection is not arbitrary; Appendix C lists the protected groups: Account Operators, Administrator, Administrators, Backup Operators, Domain Admins, Domain Controllers, Enterprise Admins, Enterprise Key Admins, Key Admins, Krbtgt, Print Operators, Read-only Domain Controllers, Replicator, Schema Admins, and Server Operators.
Protected-account enumeration includes direct and transitive membership through security or distribution groups. This scope determines which directory objects receive protection; it is not a token-privilege list. A nested distribution-group path can place a user in protection scope without placing the parent protected-group SID in that user’s access token.
The list varies by version and configuration (some groups can be deprotected with dsHeuristics, for example), but the core idea remains constant: a handful of highly privileged groups and their members are excluded from ordinary delegation rules.
Inheritance is turned off on protected objects
Appendix C clearly states that permission inheritance is disabled in protected groups and accounts. Even if objects are moved to a different location in the directory, they do not inherit permissions from their new parent objects.
This is a strong structural observable indicator, but it is not evidence on its own. An ordinary user object's DACL typically carries "auto-inherited" (AI flag in SDDL), while a protected object's DACL typically carries "protected" (P flag in SDDL) and no AI. However, inheritance can also be turned off manually, and orphaned objects retain the P flag (after membership expires); so the P flag alone does not prove the result 'under active SDProp protection'.
To verify active protection, the P flag is read with the following four signals: (1) the object's current transitive membership in a protected group, (2) comparison of the object's DACL with the AdminSDHolder template (match), (3) adminCount value and change history, (4) last SDProp revision traces via 5136. Looking at the P flag alone without this correlation will cause one to think that a manually closed inheritance or an orphaned object is 'actively protected'.
Inheritance is also turned off in AdminSDHolder itself; so that permission changes on parent objects do not break the template. Keeping the template stable is essential for consistent application of protection.
adminCount is a history record, not the current status
When SDProp protects an object, it sets the adminCount attribute to 1. This value marks the object as being scoped by AdminSDHolder/SDProp. The problem is that the reversal is not automatic: adminCount does not automatically revert to 0 when a user is removed from the protected group.
This has two consequences. First, an object with adminCount=1 may no longer be in any privileged group; The flag is from the past. Second, that object's DACL still remains with the AdminSDHolder template and inheritance turned off; SDProp doesn't fix it anymore, but it doesn't undo the previous state either. This is the case of "orphaned adminCount".
Separate three observations: current protected-group membership, residual adminCount/DACL protection and the actual caller token used for an access check. Enabled security-group SIDs and the requested operation determine authorization in that context. A residual flag proves neither privilege nor successful access.
Reading the protected DACL in the example
The object we are monitoring is a Domain Admins member. Its DACL differs from that of an ordinary user in two ways: the DACL is protected (inheritance off) and its content matches the AdminSDHolder template. In the SDDL in Artifact we see this with the D:P flag and template ACEs.
This reading answers a practical question: "why did the delegation I added to this object disappear?" The answer is that SDProp writes the object back according to AdminSDHolder. If the added ACE is not in the template, it is deleted in the loop; Delegation made without understanding protection is silently withdrawn.
The reverse is also true: if an ACE is added to the AdminSDHolder template, that ACE propagates to all protected objects in the next cycle. This is a powerful and dangerous lever; Changing the template has a much broader impact than changing individual objects.
State and data flow
- A user is added to the Domain Admins group; This group is protected according to Appendix C.
- The user's object is protected at the latest in the next SDProp cycle (default 60 min in PDCE).
- SDProp writes the user's DACL according to the AdminSDHolder template, turns off inheritance (P) and sets adminCount to 1.
- An administrator manually adds a delegation ACE to this object; ACE is not available in the AdminSDHolder template.
- The next SDProp loop compares the object's DACL with AdminSDHolder, sees the difference, and writes the object back according to the template; The manually added ACE is deleted.
- The user is then removed from Domain Admins; Membership ends, but adminCount remains 1 and DACL remains protected.
- SDProp no longer fixes this object as active; but it does not revert the previous protected state (orphaned adminCount).
- Review protection scope from current direct/transitive membership, protection history from adminCount/DACL, and effective authorization from the actual token and access-check context. These observations are not interchangeable.
2. Exploitation
Broken trust assumption
The assumption that is broken is: "Any account with adminCount=1 is privileged and protected; with adminCount=0 is secure." In reality, adminCount is a history flag: it may be left behind (the membership is over but the flag remains) or an account can be controlled indirectly via the AdminSDHolder template. Two-way confusion leads to both overlooking the true Tier-0 surface and assuming exclusivity where none exists.
Technical prerequisites
- To change the AdminSDHolder template: Domain Admins, who owns the object, or Enterprise Admins/Administrators level authority. This is already a high privilege; the mechanism is not an upgrade but a permanence lever.
- For the Orphaned adminCount scenario: an account that was in a protected group in the past and was later removed. No additional authorization required; This is a hygiene/visibility issue.
- SDProp is running: PDCE must be accessible; If the DC carrying role is disabled, the cycle is delayed and manual/automatic correction is not applied.
- At least one SDProp cycle (default 60 min) or manual trigger with RunProtectAdminGroupsTask for the template change to propagate.
Exploitation mechanism
There are two separate misreading mechanisms. The first is persistence: the AdminSDHolder DACL is a single template, and SDProp writes it back to all protected objects; An ACE added to the template leaves permanent access to all protected accounts without touching individual objects, and manually cleared object ACEs are reshaped according to the template in the next cycle. Second is visibility: adminCount=1 marks an object as protected, but it inflates the 'privileged account' inventory as it does not return to 0 when membership expires; In the opposite direction, the delay between a deprotected or newly added account and the flag misleads the actual status reading from adminCount. The protocol works correctly in both; What is wrong is to synchronize the flag with the current authority and the template with individual objects.
Why template change has broad impact
AdminSDHolder is a single object but its effect is all protected accounts. Because the SDProp loop copies the template to each protected object, an ACE added to the template becomes a distributed, self-healing access.
Therefore, when an unexpected ACE is seen on a protected object, the first place to look is not that object, but AdminSDHolder. If the deleted ACE on the object comes back, the source is almost certainly in the template.
The same feature applies to legitimate administration: the correct way to apply an aggregate permission to protected objects is to edit the AdminSDHolder and not the individual objects. The power of leverage makes it both a powerful management tool and a high-value target.
Two faces of Orphaned adminCount
Accounts with adminCount=1 but not in any protected groups will incorrectly inflate the privileged account inventory. These accounts are not actually privileged; It just was once. Thinking they are still Tier-0 distracts from the real risk.
The flip side is more subtle: the DACL of these accounts still remains protected (inheritance turned off). So ordinary delegation and inheritance rules do not work as expected on these objects; If an administrator tries to grant permission via inheritance, the result may be surprising.
Correct reading separates two sources: current privilege is read from current group membership, protection history is read from adminCount and DACL protected flag. Whether an account is truly Tier-0 is determined by membership, not adminCount.
Where it remains ineffective or limited
Changing the AdminSDHolder template already requires very high privilege; This is not a privilege escalation, but the permanence of the acquired privilege. The threat model is not "how to become a Domain Admin", but "how to stay hidden after becoming a Domain Admin".
SDProp only works on protected objects; ordinary accounts and groups are excluded from this cycle and their delegation is subject to the normal rules at 05.05. Protection covers the surface listed in Appendix C, not the entire directory.
adminCount itself does not grant access; It's just a sign. Setting it to 0/1 does not add or delete privileges. Since real authority always resides in the DACL and membership, cleanup is completed by verifying the DACL and membership, not by fixing adminCount.
3. Defense & Detection
Telemetry scope
- Audit Directory Service Changes Success on a domain controller generates 5136 for an AdminSDHolder DACL or an object adminCount change when the object SACL has matching Write auditing for the changed attribute.
- Since AdminSDHolder is a single, high-value object, placing the SACL on it first is the most direct way to capture template changes.
- adminCount change (0->1 or manually 1->0) is a separate signal to monitor the protected-object lifecycle; read with changes to membership in protected groups (4728/4732/4756, 05.07).
- All these records occur only in the domain controller; The DC in the PDCE role is particularly important as this is where SDProp operates.
- The 5136 change record does not by itself state “SDProp ran”; infer the protection cycle from covered changes such as a protected object DACL returning to the template or adminCount becoming 1.
Events and relevant fields
- 5136 / ObjectDN: changed object. DN for AdminSDHolder starts with CN=AdminSDHolder,CN=System,DC=...; Filtering this value isolates template changes.
- 5136 / AttributeLDAPDisplayName: changed attribute. In template monitoring, nTSecurityDescriptor is searched, in protection-status monitoring, adminCount is searched.
- 5136 / AttributeValue: new value. Raw SDDL for nTSecurityDescriptor, 1 or 0 for adminCount. It is not visible which ACE is added until you parse the SDDL.
- 5136 / OperationType: %%14674 Value Added, %%14675 Value Deleted. adminCount and DACL changes typically produce a binary (delete/insert) pair.
- 5136 / SubjectUserName and SubjectUserSid: principal who made the change. AdminSDHolder change is expected to be done by very few people; this field is compared to the whitelist.
- adminCount queried from the directory: 1 is a protection-history marker, not proof of current authorization. Compare current protected-group membership separately from enabled token SIDs.
Why manually added ACE disappears
An ACE added to a protected object that has no counterpart in the AdminSDHolder template is deleted in the next SDProp cycle. This is not a bug, but designed behavior: SDProp synchronizes the protected object to the template.
So most of the time the root cause of the 'my delegation is lost' complaint is that the object is protected. The solution is not to write ACE to the object again; either to exclude the object from protection (if possible and appropriate) or to handle permission at the template level.
On the observation side, this cycle appears as 5136 pairs where the same ACE is added (admin) and deleted (SDProp). Recognizing the pattern prevents the guard behavior from being mistaken for a 'weird bug'.
Reading adminCount with membership
Separate three observations: current protected-group membership, residual adminCount/DACL protection and the actual caller token used for an access check. Enabled security-group SIDs and the requested operation determine authorization in that context. A residual flag proves neither privilege nor successful access.
Separating the two prevents twofold errors: assuming non-existent privilege because adminCount=1, or looking at adminCount and missing a true Tier-0 account (unless its membership is new, the flag has not been written yet).
The practical audit query overlaps two lists: (1) current members in protected groups, (2) objects with adminCount=1. Those in the second list but not in the first are 'orphaned', and those in the first list but not yet marked are SDProp delay.
Detection logic · Sigma
title: AdminSDHolder sablonu (nTSecurityDescriptor) veya adminCount degisti
id: 6b2f4a17-9c3d-4e21-bb0a-0d5f7c9e1a44
status: experimental
description: >
AdminSDHolder nesnesinin security descriptor'inin veya herhangi bir nesnenin
adminCount attribute'unun degistigi 5136 kayitlarini arar. Sablon degisikligi tum
korumali hesaplara yayilabilecegi icin yuksek onceliklidir; adminCount degisikligi
koruma yasam dongusunu izler. Tek basina kotu niyet kaniti degildir.
logsource:
product: windows
service: security
detection:
adminsdholder_acl:
EventID: 5136
ObjectDN|startswith: 'CN=AdminSDHolder,CN=System,'
AttributeLDAPDisplayName: 'nTSecurityDescriptor'
admincount_change:
EventID: 5136
AttributeLDAPDisplayName: 'adminCount'
condition: adminsdholder_acl or admincount_change
fields:
- ObjectDN
- AttributeLDAPDisplayName
- AttributeValue
- SubjectUserName
falsepositives:
- Mesru Tier-0 yonetimi: AdminSDHolder sablonunun planli guncellenmesi
- Korumali gruplara uye ekleme/cikarma sonrasi SDProp kaynakli adminCount degisimi
level: highQuery assumptions
- 5136 is generated only if there is Write auditing in the SACL of the relevant object. If this SACL is not configured on AdminSDHolder and protected objects, the rule sees nothing.
- AttributeValue is the raw SDDL for nTSecurityDescriptor; Which trustee/right is added must be parsed in the backend. The value for adminCount is 1/0.
- The ObjectDN|startswith filter targets AdminSDHolder; The DN format must be validated in the backend that uses a different language/normalization.
- adminCount changes can be caused by both SDProp (0->1) and manual cleaning (1->0); the rule sees both, SubjectUserName and context make the distinction.
- This rule has not been run on a real SIEM; field names and event semantics are based on the primary source and should be verified against the schema of the version used.
False positives
- Planned Tier-0 administration: Legitimate updating of the AdminSDHolder template produces this record and is an expected change.
- It is normal for SDProp to write adminCount=1 to the new member after a membership change in protected groups.
- AdminCount 1->0 is a maintenance job that is expected to be done by the administrator during privileged account cleanup.
- Negative example: If Domain Admins membership is added but there is no SACL, 5136 is not generated at all; No alarm does not mean 'no change'. The rule is a layer of visibility, not proof.
Hardening
- Add Write auditing to the SACL of the AdminSDHolder object; You can't manage template changes without seeing them. This is a prerequisite for protected-surface inspection.
- Save the AdminSDHolder DACL as a known-good base and compare regularly; Because each ACE added to the template is propagated to all protected accounts, deviations are reviewed with a high priority.
- Inventory current protected-group membership separately from effective token privileges. Review adminCount=1 objects outside current protection scope as residual protection; check DACL/inheritance deliberately rather than assuming the flag grants rights.
- Reducing SDProp interval (AdminSDProtectFrequency) in production; changing the default 60 minutes outside the test increases the LSASS load on the PDCE. Trigger manually with RunProtectAdminGroupsTask when fast verification is required.
- Verification step: add a test account to a protected group, after the SDProp loop (or manual trigger) see with 5136 and attribute query that the account's DACL is protected, inheritance is closed, and adminCount is 1; then exit and observe orphaned adminCount behavior.
- Direct delegation to protected objects; If there is a permission that needs to be permanent, apply it through the AdminSDHolder template and with justification, otherwise it will be revoked in the next cycle.
Read the examples
READ THE EXAMPLE TOGETHER
SYNTHETIC TEACHING EXAMPLEWhich entries describe access, audit or integrity rules?
DACL of a protected object: inheritance off (protected) (SDDL)
A · Generic AllAllow entry. The mask scopes the allow/deny entry for its trustee. Effective access cannot be concluded without the request, token, order and object type.
A · Generic AllAllow entry. The mask scopes the allow/deny entry for its trustee. Effective access cannot be concluded without the request, token, order and object type.
A · Generic AllAllow entry. The mask scopes the allow/deny entry for its trustee. Effective access cannot be concluded without the request, token, order and object type.
A · Read Property, Read Property, List Children, List Object, READ_CONTROLAllow entry. The mask scopes the allow/deny entry for its trustee. Effective access cannot be concluded without the request, token, order and object type.
Reading an entry is different from concluding that someone can access the object. The request, token, ACE order and object type also matter.
This view explains SDDL entries; it does not run the Windows access decision. SACL audit and mandatory-label entries do not replace DACL permissions.
Scope of this example
Synthetic SDDL; Security descriptor representing an object (for example, a Domain Admins member) in AdminSDHolder protection for outreason.example. The critical observation is the DACL flag: D:P, meaning inheritance is disabled (protected). An ordinary user object typically carries D:AI (auto-inherited), while a protected object carries P and no AI. The P flag is a strong structural indicator for active SDProp protection, but it is not proof in itself: inheritance can also be turned off manually, and orphaned objects protect P; active protection is verified by correlating current protected-group transitive membership, AdminSDHolder DACL comparison, and adminCount/history. ACEs indicate limited read rights for Generic All and Authenticated Users for Domain Admins (DA), Enterprise Admins (EA), and Built-in Administrators (BA); These are representative template permissions, not an exact copy of the AdminSDHolder DACL of an actual domain. Values such as adminCount and SDProp range are not included in SDDL; they are at the attribute/registry level and are explained separately in the lesson. Parser sections decode the DACL flag (P) and ACEs; It does NOT calculate access decisions.
Open the raw record · SDDL
O:DAG:DAD:P(A;;GA;;;DA)(A;;GA;;;EA)(A;;GA;;;BA)(A;;RPRPLCLORC;;;AU)Two reality checks
- Assumption: If the adminCount attribute of an account is 1, that account is privileged and protected.
- In fact: adminCount=1 merely marks that the object was once scoped by AdminSDHolder/SDProp. When a user is removed from the protected group, this value does not automatically return to 0 and the DACL remains protected (orphaned adminCount). Therefore, the current privilege is read from the current group membership, not from adminCount; An account with adminCount=1 may not be in any privileged groups today.
- Assumption: The delegation ACE I write to a protected account is permanent; I changed the ACL.
- In fact: On objects protected by AdminSDHolder, SDProp writes back the DACL on the PDCE according to the default AdminSDHolder pattern every 60 minutes, keeping inheritance off. A manually added ACE that has no equivalent in the template is deleted in the next iteration. If a permanent permission is desired, the AdminSDHolder template should be addressed, not the object; otherwise the delegation is quietly withdrawn.
YOUR TURN
Work through this story.
Go beyond recall: change a condition, read evidence, explain the reason for a decision.
1 / 3 · PREDICT
Which conclusion does adminCount=1 not establish by itself?
A hint
A historical marker differs from current protected membership.
Read the answer reasoning
Current privileged membership and effective token permissions.
Correct. The marker can remain after membership ends; current membership and context are read separately.
2 / 3 · READ EVIDENCE
Which follow-up is appropriate for this table?
- Account
- IYELABS\tunahan
- adminCount
- 1
- DACL protected
- true — teaching snapshot
- Güncel protected group membership / Current protected group membership
- not observed
- Active token
- not observed
A hint
An inheritance marker is not the user token’s membership list.
Read the answer reasoning
Examine current direct/transitive membership and the token actually used.
Correct. Protection history, current scope and effective privilege are different questions.
3 / 3 · EXPLAIN
Explain why an ACE on a protected account can disappear in the next protection cycle.
A hint
Distinguish active protection scope from the AdminSDHolder template.
Read the answer reasoning
For an account in active protection scope, the periodic cycle can compare its DACL with AdminSDHolder and reapply the template, removing an ACE not present there. A former account retaining only adminCount=1 is not assumed to remain in active protection scope.
- I described comparison between the template and the account DACL.
- I distinguished active membership from a leftover adminCount marker.
Your explanation is not automatically graded. Compare the checkpoints with your answer.
Open the case terminal · PowerShell / CMD
Training simulation · Commands and outputs belong to this case.
Read the file DACL on FS01; effective access requires a separate evaluation.
Run the prepared script as supplied, or try the everyday commands below.
Ctrl / ⌘ + Enter: run · Shift + Enter: new line
PS C:\Users\tunahan>
Long output: scroll inside the terminal to read more.
Curious? Try everyday commands
Tap a command, then Run. User and network details follow the selected sample computer.
Recent commands in this session
These are learning practices; they do not affect certification exam scores.
Sources
- Microsoft · Appendix C: Protected Accounts and Groups in Active Directory
Protected Groups list; AdminSDHolder (CN=AdminSDHolder,CN=System,DC=...), Domain Admins ownership; SDProp default 60 minutes on the PDCE; inheritance disabled on protected objects; AdminSDProtectFrequency 60-7200 seconds (HKLM\SYSTEM\CurrentControlSet\Services\NTDS\Parameters); manual trigger with RunProtectAdminGroupsTask.; adminCount remains 1 after removal unless manually changed - Microsoft · ACE strings (SDDL)
DACL flags (P = SE_DACL_PROTECTED, AI = SE_DACL_AUTO_INHERITED) and ACE field order; GA rights abbreviation. - Microsoft · 5136(S) A directory service object was modified
Subcategory Audit Directory Service Changes; SACL Write auditing prerequisite; EventData fields ObjectDN, AttributeLDAPDisplayName, AttributeValue, OperationType, SubjectUserName.; Audit Directory Service Changes Success on DC; no Failure event - Microsoft · Reducing the Active Directory Attack Surface
Direct/transitive protected-group membership, adminCount=1, stale flag after removal, and SDProp/ACL behavior. - AdminSDHolder and SDProp terminology
First-party terminology distinctions; lesson follows Learn Appendix C for its bounded cycle. - Access Tokens
Token SID context versus directory membership/protection state.