ADPRIV-011: Privileged Users Password Not Required

Plataforma
Active Directory
Categoría
AD Privileged Account Security
Severidad
Critical
Pilar de Zero Trust
Identity (peso 3)
Fixtures de referencia
3
Cobertura de ramas
Observada: los fixtures prueban los veredictos que ejercitan
Procedencia
baseline

Qué comprueba

The check enumerates the set of privileged principals in the domain and inspects their userAccountControl attribute. The protected set is defined as: - Members of the protected groups stamped by SDProp (Domain Admins, Enterprise Admins, Schema Admins, Administrators, Account Operators, Backup Operators, Print Operators, Server Operators, Domain Controllers, Read-only Domain Controllers, Replicator, Cert Publishers, Key Admins, Enterprise Key Admins) - Any object with adminCount=1 (current or orphaned protected ACE) - Members of AdminSDHolder-tracked groups resolved recursively, including nested groups and foreign-security-principals For each principal the check reads userAccountControl and tests for the PASSWD_NOTREQD bit using a bitwise AND with 0x0020 (32). The LDAP filter used is (&(objectCategory=person)(objectClass=user)(adminCount=1)(userAccountControl:1.2.840.113556.1.4.803:=32)) which leverages the LDAP_MATCHING_RULE_BIT_AND OID so the DC evaluates the bit test rather than returning every protected user. The check also records pwdLastSet (where pwdLastSet=0 combined with PASSWD_NOTREQD is the literal blank-password case), pwdLastSet age, lastLogonTimestamp, Enabled state (UAC bit 0x0002), DONT_EXPIRE_PASSWORD (UAC bit 0x10000), and the source group that placed the account in the protected set. Findings are emitted per-principal with the full UAC integer, the decoded flag list, and the path that brought the account into scope.

Por qué importa

PASSWD_NOTREQD is a SAM-level override of password policy. When the flag is set, the password change codepath in the LSA skips the complexity, length, and history checks defined in the Default Domain Policy and any Fine-Grained Password Policy that would otherwise apply. The account can then be set to a blank password through LDAP, SAMR, or net user, and Kerberos pre-authentication and NTLM authentication will both succeed with that blank password. Pre-authentication with an empty password yields a valid TGT, NTLM authentication with the LM/NT hash of an empty string (AAD3B435B51404EEAAD3B435B51404EE / 31D6CFE0D16AE931B73C59D7E0C089C0) succeeds against SMB, LDAP, and HTTP services that accept NTLM, and tools such as crackmapexec, nxc, and impacket all check for this hash automatically during spray operations. The flag is also frequently set by legacy provisioning scripts, third party identity products, and migration tools (ADMT in particular sets PASSWD_NOTREQD on staged accounts), and it is a known attacker persistence primitive: an adversary with WriteProperty on userAccountControl can set the flag, blank the password, authenticate at will, and then clear the flag to evade casual auditing. On any account with adminCount=1, the result is direct, unauthenticated, and trivially scripted access to a Tier-0 identity, which is the single highest impact misconfiguration in Active Directory after a compromised krbtgt.

Ruta de ataque

1. Enumeration: from any authenticated context the attacker queries every account with the PASSWD_NOTREQD bit set using a single bitwise LDAP filter. Get-ADUser -LDAPFilter "(&(adminCount=1)(userAccountControl:1.2.840.113556.1.4.803:=32))" -Properties userAccountControl, pwdLastSet returns the candidate set. The same query is exposed by BloodHound (the dontreqpreauth and passwordnotreqd properties), by ldapsearch, and by PowerView Get-DomainUser -PreauthNotRequired -or- -SPN style filters. 2. Candidate triage: the attacker prioritises principals that are Enabled, have adminCount=1, and have pwdLastSet old enough that the password is unlikely to have been rotated by an interactive admin since the flag was set. A pwdLastSet of 0 is the smoking gun: the account has literally never had a password set. 3. Authentication attempt with empty password: the attacker tries an empty-password authentication against SMB, LDAP, and Kerberos. Examples: nxc smb <dc> -u <sam> -p "", crackmapexec ldap <dc> -u <sam> -p "", impacket-getTGT <domain>/<sam>: with no password, and Rubeus asktgt /user:<sam> /password:"". Any one of these returning success confirms the blank-password case. 4. Authentication with the empty-string NT hash: if the account refuses an empty password string but accepts NTLM, the attacker uses the static NT hash of the empty string (31D6CFE0D16AE931B73C59D7E0C089C0) for pass-the-hash via nxc, crackmapexec, impacket-psexec, or Rubeus asktgt /user:<sam> /rc4:31D6CFE0D16AE931B73C59D7E0C089C0. 5. Password spray fallback: if the account does have a non-empty password but the PASSWD_NOTREQD flag has bypassed policy, the password is almost always trivial (Password1, Welcome1, the sam account name, the company name). A short spray (Spray-AD, kerbrute passwordspray) lands the credential without lockout risk because pre-auth failures do not always increment badPwdCount in the same way as interactive failures. 6. Privilege use: with valid credentials for a Tier-0 account, the attacker runs DCSync (mimikatz lsadump::dcsync /user:krbtgt or impacket-secretsdump -just-dc), forges a Golden Ticket, and establishes long-term persistence. Where the attacker introduced the flag themselves (WriteProperty primitive on userAccountControl), they clear PASSWD_NOTREQD after the credential is captured so that routine audits do not flag the account.

Cómo lo evalúa Guerrilla

Guerrilla executes a single LDAP query against a writable DC using the LDAP_MATCHING_RULE_BIT_AND OID to ask the DC to evaluate the bit test server-side: (&(objectClass=user)(userAccountControl:1.2.840.113556.1.4.803:=32)). The result set is then filtered to the protected population by joining against the SDProp-protected groups and against any object with adminCount=1. The bit test approach is preferred over enumerating every user and testing the flag client side because it is constant-time on the DC, returns only the affected accounts, and works correctly in domains with hundreds of thousands of users. For each match the check reads userAccountControl, pwdLastSet, lastLogonTimestamp, adminCount, memberOf, and primaryGroupID in the same LDAP call to minimise round trips. The pwdLastSet value is interpreted: a value of 0 means the password has never been set (the account is in the literal blank-password state), and any non-zero value combined with PASSWD_NOTREQD is still a Critical finding because the flag itself defeats policy. The check is LDAP-only and does not require RSAT or domain-joined execution, so it runs from a Privileged Access Workstation against a remote forest over LDAPS.

Valor recomendado

No privileged accounts with PASSWD_NOTREQD flag set

Remediación

Identify accounts using Get-ADUser -Filter {PasswordNotRequired -eq $true -and AdminCount -eq 1}. Clear the PASSWD_NOTREQD flag immediately and set a strong password on all identified accounts. Investigate how this flag was set as it may indicate compromise

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.

Escenarios de veredicto de ADPRIV-011
EscenarioVeredicto esperado
cleanPASS
known-badFAIL
throttledNot Assessed

Mapeos a marcos de referencia

NIST SP 800-53
IA-5(1), AC-2
ANSSI
R36
CIS AD Benchmark
4.3.2
MITRE ATT&CK
T1078.002