ADGPO-023: LAPS GPO Configuration

Plataforma
Active Directory
Categoría
AD Group Policy
Severidad
High
Pilar de Zero Trust
Governance (peso 2)
Fixtures de referencia
3
Cobertura de ramas
Observada: los fixtures prueban los veredictos que ejercitan
Procedencia
baseline

Qué comprueba

For each GPO returned by Get-GPO -All, the check parses Get-GPOReport -ReportType Xml and looks for LAPS configuration in three places. (1) Legacy Microsoft LAPS Administrative Template settings under HKLM\Software\Policies\Microsoft Services\AdmPwd: AdmPwdEnabled (REG_DWORD, must be 1), PasswordComplexity (REG_DWORD, must be 4 for large+small+numbers+specials), PasswordLength (REG_DWORD, must be >= 24), PasswordAgeDays (REG_DWORD, must be <= 30), AdminAccountName (REG_SZ, the local account to manage), and DoNotAllowPwdExpirationTimeProtection (REG_DWORD, must be 0 so end-of-life protection is enforced). (2) Windows LAPS Administrative Template settings under HKLM\Software\Microsoft\Policies\LAPS and HKLM\Software\Policies\Microsoft Windows\LAPS: BackupDirectory (REG_DWORD, 1=AAD, 2=AD), PasswordComplexity, PasswordLength, PasswordAgeDays, PasswordExpirationProtectionEnabled, AdministratorAccountName, EncryptionEnabled (REG_DWORD, must be 1 on 2016+ domains), and ADPasswordEncryptionPrincipal. (3) Registry preferences pushing the same keys via Group Policy Preferences. The check also queries every computer object via Get-ADComputer -Filter * -Properties ms-Mcs-AdmPwdExpirationTime, msLAPS-PasswordExpirationTime, msLAPS-EncryptedPassword, OperatingSystem and correlates: a machine in scope of a LAPS GPO must have a populated expiration attribute that is in the future and within the configured PasswordAgeDays. The schema itself is validated: the check confirms the ms-Mcs-AdmPwd, ms-Mcs-AdmPwdExpirationTime, msLAPS-Password, msLAPS-PasswordExpirationTime, and msLAPS-EncryptedPassword attributes exist in the schema and that ACL delegation has been applied so SELF can write the password and only authorized principals can read it (this overlaps with ADACL coverage of LAPS read rights).

Por qué importa

A shared local Administrator password is the single most reliable lateral-movement primitive in an Active Directory environment. An attacker who dumps the local SAM on one workstation (Mimikatz sekurlsa::logonpasswords, or simply lsadump::sam) recovers the local Administrator NT hash, then pass-the-hashes to every other workstation that shares the password. From a single user-tier compromise this typically yields domain-wide workstation control in minutes, and from there the path to a Tier-0 credential (cached domain admin, unconstrained delegation host, service account on a server) is short. LAPS breaks this chain by giving every host a unique, randomly generated local Administrator password rotated on a fixed cadence. The protection only holds when four conditions are all true: the CSE is installed on every targeted host, a GPO with the correct settings is linked and in scope, the password actually rotates (the expiration attribute is populated and in the future), and the read ACL on ms-Mcs-AdmPwd or msLAPS-Password is restricted to Tier-0 break-glass principals plus the SELF principal that needs write rights. Common failure modes that ADGPO-023 catches: the GPO is configured but the CSE was never deployed, so passwords never rotate; the policy is enabled only on a subset of OUs and the remaining hosts still share a baseline image password; PasswordComplexity is set to 3 (no specials) or PasswordLength is left at the default 14; PasswordAgeDays is set to 365 making the credential effectively static; DoNotAllowPwdExpirationTimeProtection is enabled, which lets a compromised principal block rotation by manipulating the expiration attribute; the policy points at AdministratorAccountName = Administrator but the host was renamed during build; encryption (Windows LAPS) is disabled so the password sits in clear in AD and is replicated to every DC in clear; or the GPO covers Domain Controllers, which is unsupported and causes DC password churn.

Ruta de ataque

1. Discovery: with any domain-authenticated context, the attacker enumerates LAPS posture. Get-ADComputer -Filter * -Properties ms-Mcs-AdmPwdExpirationTime, msLAPS-PasswordExpirationTime returns the list of hosts. Any computer with a null expiration attribute is either out of scope or has a broken CSE, and is a prime target for SAM-based lateral movement. 2. Read-rights enumeration: Get-LapsADPassword (Windows LAPS) or Get-AdmPwdPassword (legacy) returns the cleartext password for every host the current principal can read. PowerView Get-DomainObjectAcl -SearchBase "DC=corp,DC=contoso,DC=com" filtered for ms-Mcs-AdmPwd or msLAPS-Password identifies which principals have ReadProperty and ExtendedRight ControlAccess. Over-broad delegation (Authenticated Users, Domain Users, a helpdesk group with thousands of members) immediately yields cleartext local admin on every host. 3. Targeting hosts that LAPS does not cover: the attacker filters Get-ADComputer for null msLAPS-PasswordExpirationTime, intersects with LastLogonTimestamp within 30 days, and gets a list of live machines that share the build-image local admin password. A single SAM dump on one of them yields the shared hash. 4. Targeting hosts where rotation broke: msLAPS-PasswordExpirationTime in the past indicates the CSE is no longer running. The current password is whatever was last set, often months old, and may already be known to a prior helpdesk turnover. The attacker uses Get-LapsADPassword to retrieve it (if delegated) or dumps SAM after a foothold. 5. Expiration-attribute abuse: if DoNotAllowPwdExpirationTimeProtection is 0 (recommended) the attacker who controls a host cannot push rotation forever, but if the policy disables that protection the attacker writes a far-future value into msLAPS-PasswordExpirationTime to freeze rotation indefinitely while they keep using the known password. 6. Backdoor account: if AdministratorAccountName points at a custom account, the attacker can create a same-named local account on a host they control and exfiltrate the LAPS-managed credential for that account. They can also enumerate which custom account is being managed and target it specifically. 7. Clear text in AD (legacy): without Windows LAPS encryption, ms-Mcs-AdmPwd is a confidential attribute but is stored in cleartext on every DC. An attacker with DCSync (Replicating Directory Changes All) or with NTDS.dit access pulls every local admin password in the domain in one operation.

Cómo lo evalúa Guerrilla

Guerrilla imports the GroupPolicy, ActiveDirectory, and (where available) LAPS PowerShell modules. It calls Get-GPO -All -Domain $env:USERDNSDOMAIN, then for each GPO calls Get-GPOReport -Guid $gpo.Id -ReportType Xml and parses the result with [xml] cast. It searches GPO.Computer.ExtensionData.Extension for RegistrySettings (Administrative Templates) and for RegistryPreferences (GPP) whose Key matches Software\Policies\Microsoft Services\AdmPwd, Software\Microsoft\Policies\LAPS, or Software\Policies\Microsoft Windows\LAPS. For each matched setting it records GpoName, GpoId, RegistryKey, ValueName, Value, Type, and Link scope (parsed from GPO.LinksTo). The check then queries the schema with Get-ADObject -SearchBase (Get-ADRootDSE).schemaNamingContext to confirm both legacy (ms-Mcs-AdmPwd, ms-Mcs-AdmPwdExpirationTime) and Windows LAPS (msLAPS-Password, msLAPS-PasswordExpirationTime, msLAPS-EncryptedPassword, msLAPS-EncryptedPasswordHistory, msLAPS-EncryptedDSRMPassword) attributes are present. For every computer in scope it calls Get-ADComputer -Filter "OperatingSystem -notlike *Server*Domain Controller*" -Properties ms-Mcs-AdmPwdExpirationTime, msLAPS-PasswordExpirationTime, msLAPS-EncryptedPassword, OperatingSystem, LastLogonTimestamp, DistinguishedName, then computes Coverage = (computers with a future expiration attribute) / (computers in scope of a LAPS GPO), Stale = computers with an expiration attribute in the past, Missing = computers with no expiration attribute at all, and OutOfScope = computers in OUs not covered by any LAPS GPO. ACL coverage for the password attribute is read via Get-Acl AD:"CN=Computer,DC=corp..." filtered for the ms-Mcs-AdmPwd / msLAPS-Password ExtendedRight GUIDs (legacy 4c164200-20c0-11d0-a768-00aa006e0529 for ReadProperty on confidential attributes; Windows LAPS uses ControlAccessRight {0e1f7b3a-...}). Output rows include GpoName, AdmPwdEnabled, PasswordComplexity, PasswordLength, PasswordAgeDays, EncryptionEnabled, AdministratorAccountName, LinkScope, CoveragePercent, StaleCount, MissingCount, ReadPrincipals, and a Notes field enumerating each baseline deviation.

Valor recomendado

LAPS enabled via GPO on all domain-joined systems with 24-character passwords and 30-day maximum age

Remediación

Install the LAPS CSE on all managed systems via GPO software installation or SCCM. Configure LAPS GPO settings: Enable local admin password management, set password complexity to large letters + small letters + numbers + specials, set password length to 24 or more characters, and set password age to 30 days or less. Verify LAPS is functioning by checking ms-Mcs-AdmPwdExpirationTime attributes.

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 ADGPO-023
EscenarioVeredicto esperado
cleanPASS
known-badWARN
throttledNot Assessed

Mapeos a marcos de referencia

NIST SP 800-53
AC-6, IA-5(1), CM-6
ANSSI
vuln_no_laps
MITRE ATT&CK
T1078.003, T1021