ADACL-006: ForceChangePassword Rights

Platform
Active Directory
Category
AD ACL & Delegation
Severity
High
Zero Trust pillar
Identity (weight 3)
Golden fixtures
3
Branch coverage
Observed: fixtures prove the verdicts they exercise
Provenance
baseline

What it checks

The check parses the nTSecurityDescriptor attribute of user objects in Active Directory and inspects every Access Control Entry (ACE) that grants the extended right with ObjectType GUID 00299570-246d-11d0-a768-00aa006e0529 (User-Force-Change-Password). For each match, it resolves the trustee SID, evaluates whether the principal is a member of a Tier 0 or approved helpdesk group, and flags ACEs granted to standard users, Authenticated Users, Domain Users, Everyone, or any custom group not explicitly whitelisted. Both explicit ACEs on the user object and inherited ACEs propagated from the parent OU are considered.

Why it matters

Force-Change-Password is the most direct privilege escalation primitive in Active Directory short of full GenericAll. Unlike credential theft, it requires no interaction with the target, no cracking, and no kerberoasting. The attacker simply rewrites the password, authenticates as the victim, and inherits every group membership, ACL grant, and SPN-bound resource the victim has. When the delegation lands on Tier 0 paths (Domain Admins, Enterprise Admins, schema-modifying groups) or on accounts with Kerberos delegation, the blast radius extends to full domain compromise. BloodHound treats ForceChangePassword as a first-class attack edge precisely because it is reliable, fast, and leaves minimal forensic residue beyond a 4724 event.

Attack path

1. Reconnaissance: the operator runs SharpHound or BloodHound.py with the default collection method. The ForceChangePassword edge is collected from the DACL of every user object. 2. Pathfinding: in BloodHound the analyst queries shortest path to Domain Admins (or to any high-value target). ForceChangePassword edges appear as a single hop. 3. Execution: from a Windows host the attacker runs Set-DomainUserPassword (PowerView), net user, or Set-ADAccountPassword. From Linux, net rpc password, samba-tool user setpassword, or Impacket's net.py and changepasswd.py against MS-SAMR or MS-LSAD. 4. Authentication: the attacker logs on as the now-controlled account, requests a TGT, and pivots. If the victim is a service account with constrained or unconstrained delegation, the attacker chains into Kerberos abuse (S4U2Self, RBCD). 5. Persistence: the password reset is logged but rarely alerted on outside Tier 0. Many environments still permit reset-then-revert workflows that hide the action inside legitimate helpdesk noise.

How Guerrilla assesses it

Guerrilla performs an authenticated LDAP query against every object of class user (including computer-derived users and inetOrgPerson). For each object it reads nTSecurityDescriptor with the OWNER_SECURITY_INFORMATION and DACL_SECURITY_INFORMATION control flags, then walks each ACE. ACEs of type ACCESS_ALLOWED_OBJECT_ACE_TYPE with the ObjectType GUID 00299570-246d-11d0-a768-00aa006e0529 and an ActiveDirectoryRights value of ExtendedRight are surfaced. The trustee SID is resolved to a sAMAccountName and cross-referenced against the configured allowlist (default: Domain Admins, Enterprise Admins, Account Operators, and named helpdesk groups). Any unmatched principal generates a finding.

Recommended value

ForceChangePassword limited to authorized helpdesk and admin groups only; not granted to non-privileged accounts

Remediation

Enumerate all principals with User-Force-Change-Password extended right on user objects. Verify each delegation is intentional and scoped appropriately. Remove rights from any principal that does not have a documented operational need. Use OU-scoped delegation rather than domain-wide grants.

Fixture-proven verdicts

Every verdict below is proven by a golden fixture in the module's gating test suite. This table derives from the last green run; it cannot be edited by hand.

Verdict scenarios for ADACL-006
ScenarioExpected verdict
cleanPASS
known-badFAIL
throttledNot Assessed

Framework mappings

NIST SP 800-53
AC-6, IA-5(1)
ANSSI
vuln_permissions_resetpassword
MITRE ATT&CK
T1098, T1078.002