ADPWD-002: Fine-Grained Password Policy Enumeration
- Plataforma
- Active Directory
- Categoría
- AD Password & Lockout Policies
- Severidad
- Medium
- Pilar de Zero Trust
- Identity (peso 1)
- Fixtures de referencia
- 2
- Cobertura de ramas
- Observada: los fixtures prueban los veredictos que ejercitan
- Procedencia
- baseline
Qué comprueba
The check binds to CN=Password Settings Container,CN=System,DC=domain,DC=tld and enumerates every msDS-PasswordSettings object via Get-ADFineGrainedPasswordPolicy -Filter *. For each PSO it reads the policy attributes: - msDS-PasswordSettingsPrecedence (lower wins) - msDS-MinimumPasswordLength - msDS-MinimumPasswordAge / msDS-MaximumPasswordAge - msDS-PasswordHistoryLength - msDS-PasswordComplexityEnabled - msDS-PasswordReversibleEncryptionEnabled - msDS-LockoutThreshold / msDS-LockoutDuration / msDS-LockoutObservationWindow - msDS-PSOAppliesTo (forward link to user and global security group principals) It then resolves the resultant PSO for each privileged principal by reading msDS-ResultantPSO on the user object (or computing it from msDS-PSOApplied plus group memberships) and compares the resultant settings against the recommended baseline. PSOs are stored as objectClass msDS-PasswordSettings; the container itself cannot be renamed, moved, or deleted, but custom Password Settings Containers under CN=System are also enumerated because PSOs in custom containers are silently ignored by the Resultant Set of Policy logic and represent a configuration error.
Por qué importa
The Default Domain Policy controls password requirements for every account that is not covered by a PSO. FGPPs were introduced specifically so that privileged accounts can be held to a stricter standard than standard users, and so that service accounts can be given a long minimum length without forcing the same on humans. Two failure modes are common in production: 1. The domain has no PSO at all. Every account inherits the Default Domain Policy, typically 7 to 8 character minimum, 90 day rotation, and a low lockout threshold. krbtgt, Domain Admins, and Tier 0 service accounts are then subject to the same weak floor as every contractor and intern. An attacker spraying common passwords against the domain has the same probability of success against a Domain Admin as against any other user. 2. A PSO exists but with weaker settings than the Default Domain Policy, and a high precedence value places it ahead of stronger policies for some principals. Because msDS-PasswordSettingsPrecedence resolves by lowest-number-wins and ties are broken by the smallest GUID, a stale, forgotten, or attacker-planted PSO with precedence 1 can override every other policy in the domain. The PSO is not visible in Group Policy Management Console and does not appear in gpresult output, so it is routinely missed during audits. Attackers who reach a principal with Write Property on a PSO, Create Child on the Password Settings Container, or GenericAll on the domain root can plant a weak PSO and use it as persistence: future credential resets land at a password length the attacker can brute force, and the change does not appear in any GPO report.
Ruta de ataque
1. Reconnaissance: from a low-privilege authenticated session, the attacker enumerates the Password Settings Container with a plain LDAP query. Any authenticated user can read PSO objects unless the default DACL has been hardened. Tools include Get-ADFineGrainedPasswordPolicy, PowerView Get-DomainPSO, ldapsearch, and BloodHound (which collects PSO target edges in recent versions). 2. Gap identification: the attacker enumerates Domain Admins, Enterprise Admins, krbtgt, and Tier 0 service accounts. For each, msDS-ResultantPSO is read. Accounts where the attribute is empty fall to the Default Domain Policy. The attacker reads the Default Domain Policy values (Get-ADDefaultDomainPasswordPolicy) and confirms whether the floor permits an effective password spray. 3. Password spraying: with a known weak minimum length, the attacker sprays a small candidate list (Season+Year, Company123!, etc.) at a low rate against the gap accounts using kerbrute, Rubeus brute, MailSniper, or a custom Kerberos pre-auth tool. Spraying via Kerberos AS-REQ avoids the noisy 4625 events that classic SMB spraying produces. 4. Persistence via planted PSO: an attacker who has obtained Write on the Password Settings Container or on an existing PSO modifies msDS-PSOAppliesTo to include a target group, or creates a new PSO with precedence 1, minimum length 4, complexity disabled, and reversible encryption enabled (msDS-PasswordReversibleEncryptionEnabled = TRUE causes the next password change to be stored in a recoverable form, readable via DCSync or NTDS dump). 5. Detection evasion: because PSOs are objects in CN=System and not Group Policy objects, they do not appear in Group Policy Management Console, gpresult, or in the Security Compliance Toolkit baseline diffs. Defenders relying only on GPO snapshots will not see the change.
Cómo lo evalúa Guerrilla
Guerrilla uses the Active Directory module to call Get-ADFineGrainedPasswordPolicy -Filter * -Properties * against a writable DC, falling back to a direct LDAP search of (objectClass=msDS-PasswordSettings) under CN=System when RSAT is unavailable. For each PSO it captures precedence, every policy attribute, and the resolved msDS-PSOAppliesTo principals (group names and SIDs). It then enumerates the standard privileged groups (Domain Admins, Enterprise Admins, Schema Admins, Account Operators, Server Operators, Backup Operators, Print Operators, BUILTIN\Administrators, plus the krbtgt account) and reads msDS-ResultantPSO on each member. The check reports four states per finding: no PSO exists in the domain; a PSO exists but does not cover privileged accounts; a privileged account is covered by a PSO weaker than the Default Domain Policy; or a PSO has msDS-PasswordReversibleEncryptionEnabled set to TRUE. Output includes the PSO distinguishedName, precedence, and a side-by-side comparison of resolved settings against the recommended baseline.
Valor recomendado
All FGPPs documented with their precedence, target groups, and policy settings. At minimum, a strict FGPP for privileged accounts and a standard FGPP for regular users
Remediación
Enumerate all FGPPs using Get-ADFineGrainedPasswordPolicy -Filter *. Document each policy's precedence value, target groups, and settings. Verify that privileged accounts are covered by a stricter policy than standard users. Create FGPPs if only the Default Domain Policy exists
Veredictos probados con fixtures
Cada veredicto de esta tabla está probado por un fixture de referencia en la suite de pruebas que valida el módulo. La tabla se deriva de la última ejecución en verde; no puede editarse a mano.
| Escenario | Veredicto esperado |
|---|---|
| clean | PASS |
| throttled | Not Assessed |
Mapeos a marcos de referencia
- NIST SP 800-53
- IA-5(1), AC-2
- ANSSI
- R34
- CIS AD Benchmark
- 5.1.2
- MITRE ATT&CK
- T1110.001