One thing I've recommended in every penetration test report I've written is LAPS. It's a highly effective (and free!) way to significantly raise the bar for attackers looking to spread around your network using local Administrator credentials.

The majority of the material in here is gathered from Harmj0y and PyroTek3's blogs. This is just a post for me to muddle through what they've already written and understand things a bit better. Here's a brain dump.

About LAPS

Microsoft's Local Administrator Password Solution is a free product that provides a way to enforce a unique password for every managed system and a way for authorized users to view those passwords.

LAPS has two major components: an Active Directory schema extension, which adds the ms-Mcs-AdmPwd (clear-text password) and ms-Mcs-AdmPwdExpirationTime (date/time LAPS should force a password change on the client) attributes to all computer objects, and the LAPS client, which is on the receiving end of the password changes.

Of key importance in LAPS is the delegation rights for the two schema attributes, most importantly ms-Mcs-AdmPwd.

Deploy Overview

The required steps in a LAPS deploy are:

  1. Extend the schema using the LAPS installer.
  2. Install the client on all in-scope machines.
  3. Delegate permission for all computers to update the two attributes on their own computer objects (SELF:WRITE).
  4. Delegate permission for a select group of users to view ms-Mcs-AdmPwd (clear-text password) and enforce a password change (by clearing the ms-Mcs-AdmPwdExpirationTime attribute) on the computer objects.
  5. Configure a GPO to enable LAPS and set the appropriate password parameters (length, expiry, complexity).

LAPS Attribute Notes

The ms-Mcs-AdmPwd attribute is only viewable to Domain Admins by default while the ms-Mcs-AdmPwdExpirationTime attribute is viewable by all users. The latter design choice means that any domain user can determine:

Hunting for LAPS on the Client

If a computer is managed by LAPS, a DLL will be present and detectable by the following methods:

# PowerShell
Get-ChildItem 'C:\Program Files\LAPS\CSE\Admpwd.dll'

Hunting for LAPS on the Domain

It's possible to find LAPS computers using this one-liner:

Get-ADComputer -Filter {ms-Mcs-AdmPwdExpirationTime -like '*'} -Properties ms-Mcs-AdmPwdExpirationTime

With this information, we get not only a list of managed computers, but the ability to determine when their password will next change:


It's possible to change this date to some point in the future if the 'Do not allow password expiration time longer than required by policy' GPO setting is not configured or disabled.

Hunting for All LAPS Delegates

PowerView provides the easiest way of doing this using the following one-liner:

Get-NetOU -FullData
| Get-ObjectAcl -ResolveGUIDs
| Where-Object { ($_.ObjectType -like 'ms-Mcs-AdmPwd') -and ($_.ActiveDirectoryRights -match 'ReadProperty') }
| ForEach-Object { $_ | Add-Member NoteProperty 'IdentitySID' $(Convert-NameToSid $_.IdentityReference).SID; $_}

With this information, we can then do something like the following to give us the full list of admins:

$LAPSAdmins = Get-ADGroup GROUPNAME | Get-ADGroupMember -Recursive
$LAPSAdmins += Get-ADGroup GROUPNAME2 | Get-ADGroupMember -Recursive
$LAPSAdmins += Get-ADGroup GROUPNAME3 | Get-ADGroupMember -Recursive
$LAPSAdmins | Select Name,DistinguishedName | Sort Name -Unique | Format-Table -Auto

Hunting for a Specific LAPS Delegate

Now shit is getting nesty.

Get-NetComputer -ComputerName COMPUTERNAME -FullData 
| Select-Object -ExpandProperty DistinguishedName
| ForEach-Object { $_.SubString($_.IndexOf('OU')) }
| ForEach-Object {Get-ObjectAcl -ResolveGUIDs -DistinguishedName $_}
| Where-Object {($_.ObjectType -like 'ms-Mcs-AdmPwd') -and ($_.ActiveDirectoryRights -match 'ReadProperty')}
| ForEach-Object {Convert-NameToSid $_.IdentityReference}
| Select-Object -ExpandProperty SID
| Get-ADObject

This monstrosity does the following: