ADPRIV-013: Privileged Users Reversible Encryption
- Plataforma
- Active Directory
- Categoría
- AD Privileged Account Security
- Severidad
- Critical
- Pilar de Zero Trust
- Identity (peso 2)
- Fixtures de referencia
- 3
- Cobertura de ramas
- Observada: los fixtures prueban los veredictos que ejercitan
- Procedencia
- baseline
Qué comprueba
The check queries every user object in the domain whose userAccountControl contains the ENCRYPTED_TEXT_PASSWORD_ALLOWED bit (decimal 128, hexadecimal 0x0080) and intersects that result with the privileged population. Privileged is defined as adminCount = 1 (the principal has been stamped by SDProp), or current direct/indirect membership in one of the protected groups enumerated by AdminSDHolder (Domain Admins, Enterprise Admins, Schema Admins, Administrators, Account Operators, Backup Operators, Server Operators, Print Operators, Replicator, Domain Controllers, Read-only Domain Controllers, Enterprise Read-only Domain Controllers, and Key Admins). For each matching account the check records: - sAMAccountName, distinguishedName, objectSid - userAccountControl raw value and the parsed flag set - adminCount - pwdLastSet (the supplementalCredentials Primary:CLEARTEXT package is only populated after the next password change that occurs while the flag is set, so pwdLastSet relative to the flag matters) - whenChanged on the user object - Group membership chain that grants privileged status The check additionally inspects the default domain Password Policy and any Fine-Grained Password Policies (msDS-PasswordSettings objects) for the ReversibleEncryptionEnabled property, and inspects every linked GPO for the "Store passwords using reversible encryption" setting under Computer Configuration > Windows Settings > Security Settings > Account Policies > Password Policy. A GPO that turns on reversible encryption at the policy level is reported as a secondary finding, because it will silently flip the flag on every account in scope at the next password change.
Por qué importa
Reversible encryption is symmetric: the plaintext password is recoverable by anyone who can read both the encrypted blob in supplementalCredentials and the system key (SYSKEY) of any Domain Controller. The two together are obtained by any of the standard credential theft primitives: a copy of ntds.dit and SYSTEM hive, a DCSync against a domain controller using DRSUAPI GetNCChanges, a Volume Shadow Copy of an active DC, an ntdsutil ifm dump, or live LSASS access on a DC. Tools such as Impacket secretsdump.py and Mimikatz lsadump::dcsync /user:<sam> explicitly decode the Primary:CLEARTEXT package and print the actual password. The blast radius is the worst case in identity security. With a real domain admin password in hand, the attacker bypasses every detection that watches for hash-pass, ticket forgery, or DCSync replay: they simply log in. Pass-the-password works against every protocol (Kerberos, NTLM, LDAP simple bind, RDP, SMB, WinRM, OWA, ADFS legacy auth), survives Protected Users membership (which blocks NTLM hash use but does not block correct plaintext authentication), and yields a single credential that the attacker can re-use across the kill chain without leaving the forged-ticket fingerprints that EDR vendors hunt for. Plaintext passwords also frequently turn out to be reused across the user personal accounts and other tenants, giving the attacker post-compromise lateral pivot outside the domain. Microsoft has explicitly deprecated reversible encryption since the Windows 2000 era and the current recommendation is that the flag is never set on any account in production. The only documented legitimate consumer (CHAP authentication for legacy RAS, IIS Digest authentication for Internet-facing IIS prior to Negotiate, and a handful of pre-2003 third party RADIUS plugins) is obsolete and replaced by Kerberos AES, EAP-TLS, or modern federated authentication.
Ruta de ataque
1. Reconnaissance: the attacker enumerates accounts with the flag using either LDAP (userAccountControl:1.2.840.113556.1.4.803:=128) or BloodHound (the HasSPN/ASREP/Sensitive nodes plus a custom Cypher query against the encryptedTextPasswordAllowed property collected by SharpHound 5.x). Get-ADUser -LDAPFilter "(userAccountControl:1.2.840.113556.1.4.803:=128)" -Properties adminCount returns every candidate in seconds. 2. Target selection: the attacker prioritizes any returned principal whose adminCount = 1 or that is a current member of a Tier-0 group, because the Primary:CLEARTEXT package on a Domain Admin is forest-defining loot. 3. Credential capture: the attacker triggers a credential dump. Options include a DCSync from a controlled principal with GetChangesAll rights (Mimikatz lsadump::dcsync /user:<sam> /domain:<fqdn>), a remote secretsdump.py -just-dc-user <sam> <domain>/<user>@<dc> against any DC, an offline parse of a stolen ntds.dit plus SYSTEM hive (secretsdump.py -system SYSTEM -ntds ntds.dit LOCAL), or a live extraction from LSASS on the DC. 4. Plaintext recovery: the tool decodes the supplementalCredentials blob, locates the Primary:CLEARTEXT package, and prints the actual password. No cracking, no rainbow tables, no GPU. Output looks like "CLEARTEXT: P@ssw0rdRevealed!". 5. Authentication: the attacker logs in as the Tier-0 principal via RDP, WinRM, LDAP, or SMB. Because the credential is the real password, every authentication artifact looks legitimate, Protected Users restrictions on NTLM do not apply, and authentication policy silos that key on user identity (not on credential material) are silently satisfied. 6. Persistence and pivot: the attacker often discovers the same password is reused for SaaS administration consoles, cloud IAM, or the personal Microsoft account of the human administrator, extending the breach beyond the on-premises forest.
Cómo lo evalúa Guerrilla
Guerrilla uses an LDAP bitwise-AND extensible match filter to enumerate the flag in a single round trip: Get-ADUser -LDAPFilter "(&(objectClass=user)(userAccountControl:1.2.840.113556.1.4.803:=128))" -Properties userAccountControl,adminCount,pwdLastSet,memberOf,whenChanged. This uses OID 1.2.840.113556.1.4.803 (LDAP_MATCHING_RULE_BIT_AND) so the DC performs the bit test server side rather than the client filtering every account. For each match the check evaluates privileged status in two passes: a fast pass on adminCount = 1, and an authoritative pass that expands the current membership of every group protected by AdminSDHolder (resolved by reading dSHeuristics and the protected-groups list, then walking memberOf one level beyond the well known set so nested groups are captured). This catches accounts that are current Tier-0 even when adminCount has not yet been stamped by the next SDProp run (SDProp executes every 60 minutes by default; a freshly added Domain Admin can be found before the stamp lands). The domain Password Policy is read via Get-ADDefaultDomainPasswordPolicy and the ReversibleEncryptionEnabled property is checked. All Fine-Grained Password Policies are enumerated via Get-ADFineGrainedPasswordPolicy and the same property is checked, along with their AppliesTo (which can target privileged groups). Linked GPOs are parsed via Get-GPOReport -ReportType XML and the SecurityOptions ClearTextPassword key is matched. The check finally inspects supplementalCredentials on every matching account, where present, and reports whether the Primary:CLEARTEXT package is actually populated, which confirms the password has been changed at least once since the flag was asserted and that a real plaintext is currently retrievable.
Valor recomendado
No accounts with reversible encryption enabled, especially not privileged accounts
Remediación
Identify accounts using Get-ADUser -Filter {AllowReversiblePasswordEncryption -eq $true -and AdminCount -eq 1}. Clear the flag and force an immediate password change on all affected accounts. Review password policies to ensure they do not require reversible encryption
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 |
| known-bad | FAIL |
| throttled | Not Assessed |
Mapeos a marcos de referencia
- NIST SP 800-53
- IA-5(1), SC-28
- CIS Benchmark
- 1.1.1
- ANSSI
- R36
- CIS AD Benchmark
- 4.3.4
- MITRE ATT&CK
- T1003.006, T1078.002