ADPWD-007: Aplicación del historial de contraseñas
- Plataforma
- Active Directory
- Categoría
- AD Password & Lockout Policies
- Severidad
- Medium
- 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
El historial de contraseñas impide que los usuarios reutilicen cíclicamente las mismas contraseñas. Sin suficiente profundidad de historial, los usuarios pueden alternar entre un pequeño conjunto de contraseñas, anulando el beneficio de seguridad de los requisitos de rotación de contraseñas
Por qué importa
Password history is the only AD control that prevents trivial password reuse on rotation. Without it (pwdHistoryLength = 0) a user can satisfy a forced reset by setting the password back to the value it had ten seconds ago. With a shallow history (1 to 5) a user with knowledge of a rotation requirement can rotate through a handful of throwaway passwords and land back on the original. In both cases, every other control that depends on rotation invalidating a leaked credential (post-incident password resets, scheduled rotations on shared service accounts, mandatory resets after a phishing event) is silently defeated. The blast radius is largest in three scenarios. First, after a credential dump (DCSync, NTDS.dit extraction, LSASS scrape) the IR team typically forces a domain-wide reset; if pwdHistoryLength is low, users restore previous passwords and the attacker hashes from the dump remain valid. Second, on privileged service accounts whose password is known to multiple administrators, weak history lets a departing admin re-establish a password they know. Third, weak history undermines the assumption behind detection rules built around AS-REP roasting and Kerberoasting: if a service account password rotates but reverts to an old offline-cracked value, the offline crack stays valid.
Ruta de ataque
1. Discovery: the attacker queries the domain policy via LDAP (Get-ADDomain, or a direct search for pwdHistoryLength and minPwdAge on the domain object). PSOs are enumerated under the Password Settings Container. No special rights are required; any authenticated user can read these attributes. 2. Targeting: the attacker (or, more commonly, an insider) identifies an account whose password they once knew, or a service account whose old password is documented in a runbook or chat log. 3. Cycling: if minPwdAge is 0 and pwdHistoryLength is low, the attacker (operating as the compromised user) issues N+1 password changes in rapid succession (net user, Set-ADAccountPassword, or the SAMR password change RPC) to push the original value out of the history buffer, then sets the password back to the originally known value. The account now has a known password and the reset has been defeated. 4. Post-IR persistence: after an incident-response domain-wide reset, the attacker who still controls one compromised endpoint waits for the user to log in, captures the new password via keylogger or LSASS, then performs the cycle attack to restore a password that matches an older NTLM hash already in their possession (useful for offline Pass-the-Hash and lateral movement). 5. Service-account abuse: on a shared service account, an operator who knows the old password cycles forward and back to defeat the mandated rotation, keeping their out-of-band copy valid. This is a frequent finding in audits of privileged service accounts that lack gMSA conversion.
Cómo lo evalúa Guerrilla
Guerrilla uses Get-ADDomain to read pwdHistoryLength, minPwdAge, maxPwdAge, lockoutThreshold, and pwdProperties in a single bind, then enumerates Get-ADFineGrainedPasswordPolicy -Filter * to pull every PSO and its msDS-PasswordHistoryLength, msDS-MinimumPasswordAge, and msDS-PasswordSettingsPrecedence. Each value is compared to a recommended floor of 24 (history) and 1 day (minimum age). A finding is emitted per scope (domain or PSO) with the observed value, the recommended value, the precedence (for PSOs), and the AppliesTo set so triage can identify which users are affected. The check does not require Domain Admin: read of msDS-PasswordSettings is restricted by default, but the check tolerates AccessDenied on individual PSOs and reports them as Unknown rather than failing the run. For change detection, security teams should pair this check with Event ID 4739 (Domain Policy was changed) and 4719 (System audit policy was changed) forwarded from every DC, plus DS object auditing (4662) on the domain object and on CN=Password Settings Container to surface ad-hoc PSO modifications.
Valor recomendado
Historial de contraseñas que recuerde al menos las 24 contraseñas anteriores
Remediación
Configure en la Default Domain Policy: Computer Configuration > Policies > Windows Settings > Security Settings > Account Policies > Password Policy > 'Enforce password history' = 24 passwords remembered. Asegúrese también de que 'Minimum password age' esté establecido en al menos 1 día para evitar el ciclado rápido a través del historial
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)
- CIS Benchmark
- 1.1.1
- ANSSI
- R34
- CIS AD Benchmark
- 5.2.3
- MITRE ATT&CK
- T1110.001