Skip to main content
cd ../config-traps
risk/register/admincount-drift-grants-ghost-tier-0-rights.html
Active Directory Access Controlhigh severityActive Directory

adminCount Drift Grants Ghost Tier-0 Rights

Severity
high
Reviewed
22 Jul 2026
Remediation
~20 minutes
Overview

A helpdesk account added to Domain Admins for a migration keeps adminCount=1 after removal, so its ACL stays protected and inheritance from the OU stays blocked. Group membership reviews find nothing because the account left the group weeks ago, yet the elevated Active Directory ACL template stays put on every domain controller.

Operational summary

At a glance

Symptom
An account leaves Domain Admins or another protected group but the security descriptor and adminCount marker are never manually reset.
Likely cause
adminCount remains set to 1 and ACL inheritance stays disabled after an account is removed from a protected group.
Impact
The account keeps a stale, inheritance-blocked ACL that ignores later OU-level permission changes while remaining invisible to group-membership-based access reviews.
Verification signal
Re-run the detection test and a controlled negative-path test.
Safe correction
Query for adminCount=1 accounts with no current protected group membership and reset both the attribute and the inheritance flag as part of the offboarding workflow.
Rollback or recovery
Restore the exported configuration if the new control blocks required production traffic, then narrow the policy before redeployment.

The Trap

adminCount attribute drift after removal from a protected group. Whenever an account is added to Domain Admins, Enterprise Admins, Schema Admins, Account Operators, Backup Operators, Server Operators, Print Operators, or Administrators, SDProp sets adminCount=1 on that account and copies AdminSDHolder’s access control list onto it, disabling ACL inheritance from the parent OU. Active Directory does not automatically clear adminCount or re-enable inheritance when the account is later removed from every protected group. The attribute and the protection flag persist until an administrator explicitly resets them.

The Default State

The usual sequence is a contractor or on-call engineer added temporarily to Domain Admins for a server migration or a domain controller promotion, then removed from the group once the task finishes. No follow-up job clears adminCount or restores inheritance. The account passes every routine check: dsa.msc shows a normal group membership tab, and the user object no longer appears in any privileged group listing. The residual ACL sits invisibly on the object’s security descriptor, untouched because build runbooks treat group removal as the end of the offboarding step.

The Blast Radius

The object is now a shadow Tier-0 account. Its nTSecurityDescriptor still carries the AdminSDHolder template: inheritance disabled, explicit deny entries for Account Operators, explicit allow entries tied to Domain Admins and Enterprise Admins. When the security team later tightens delegated OU permissions, for example revoking helpdesk password-reset rights across a whole OU, that new access control entry never propagates to this account because inheritance is blocked at the object level. It silently keeps whatever rights the old AdminSDHolder copy granted. In the other direction, an LDAP sweep for (adminCount=1) gives an attacker a ready-made target list of every account that has ever touched a protected group, regardless of current membership, since the flag is a permanent marker of past privilege rather than present privilege. Password policy changes, Kerberos delegation settings, and SPN hardening scripts written against OU-based inheritance quietly skip these objects because they were never designed to touch protected accounts directly.

The Lead Mechanic Fix

Run a recurring query to find drift: Get-ADUser -LDAPFilter "(&(adminCount=1)(!(memberOf=CN=Domain Admins,CN=Users,DC=corp,DC=example)))" -Properties adminCount,memberOf. For every account that matches and holds no current protected group membership, clear the marker and restore inheritance in two steps: Set-ADObject -Identity $dn -Clear adminCount followed by dsacls $dn /P:N to remove the protected flag and allow OU-level ACEs to flow down again. Tie this directly to the group-removal step in your privileged access workflow, PIM or JIT tooling, rather than leaving it as a manual afterthought that gets skipped under deadline pressure.

03

Apply the safer control

Before you change production

Confirm the affected scope, export the current configuration, and test the replacement control in a non-production environment first.

Fix commands and configuration

Get-ADUser -LDAPFilter "(&(adminCount=1)(!(memberOf=CN=Domain Admins,CN=Users,DC=corp,DC=example)))" -Properties adminCount,memberOf
Set-ADObject -Identity $dn -Clear adminCount
dsacls $dn /P:N
04

Verify, roll back or escalate

Verify

Re-run the detection test and a controlled negative-path test. Confirm the unsafe behaviour is blocked while approved traffic still succeeds.

Rollback

Restore the exported configuration if the new control blocks required production traffic, then narrow the policy before redeployment.

Escalate

Escalate when the blast radius is uncertain, the control cannot be tested safely, or remediation requires an outage or security exception.

After remediation

Further reading stays below the corrective workflow and is selected by platform, category and shared technical keywords.

Discover more

Connected KBY resources