Windows Server Security

The case against using Microsoft’s Local Administrator Password Solution (LAPS)

Microsoft’s Local Administrator Password Solution (LAPS) makes it easy for administrators to securely manage the local account passwords on all their domain-joined computers. But that doesn’t mean its security isn’t open to being challenged. While LAPS has been available since 2015, there has been lots of chatter on the Microsoft TechNet social network, suggesting that the difficulties of using it haven’t all been ironed out. This was brought home to me in a discussion I had with colleague Mark Van Noy who manages the virtual desktop infrastructure at the University of Colorado Boulder in Colorado. Mark piqued my interest in the subject when he emailed me the following comment recently. Mark said that “Microsoft’s LAPS storing the password in clear text with the computer’s AD record has been bothering me for a while now. So, I decided to write up a proof-of-concept PowerShell script on how this could potentially be exploited. My PowerShell does not leverage any component of LAPS; it is straight-up AD accessed information using knowledge of how LAPS works.” I asked Mark for a copy of his script and a brief writeup describing how to use it, and Mark responded with the following, which I’m sharing here for the benefit of our TechGenix readers.

Installing and configuring LAPS

Microsoft’s LAPS is a tool created to remediate the problem of using the same password across multiple servers. LAPS can also significantly help with ensuring greater password complexity by generating up to 64-character passwords randomly for each computer it manages and automatically generating new passwords on a schedule. On the surface, this is a great tool that prevents some of the most common security risks to infrastructure resources: low complexity passwords that get reused and infrequently changed. Functionally, the tool actually does do just what it states it will do, and installing it is straightforward: The Word documentation that comes with LAPS does an excellent job of walking through how to install and configure LAPS. The LAPS installer needs to be run on each client machine, most likely servers, that will be managed. Since the installer is a conventional MSI, it is simple to distribute and perform a silent install. At least one management computer also needs to have the remaining tools installed to it. From the management computer, a simple PowerShell command that comes with the package is used to extend the Active Directory Schema. The documentation also walks through four custom GPOs that can be applied to managed computers as well as how to secure the OU’s of the managed systems. Finally, there is a short section on enabling auditing of password access. The shortcoming of the auditing is that the 4662 event ID logs the updated AD schema GUID of the password object, which is not human-readable and makes the audit relatively obscure. The documentation’s example shows that CONTOSO\Administrator accessed {bo4b21db-0992-4551-a813-4d8e2a27ff1e}, which probably will not raise any red flags when scanning security logs unless additional tools that recognize that GUID are used.

My concern with LAPS

This brings me to the concern I have with LAPS. The schema extension ties the computer’s local administrative password directly to the AD computer record in plain text. This is the digital equivalent of writing the password on a sticky note and placing it on the monitor. Perhaps a better metaphor would be placing the password for each server on a label placed on each server then claiming it is highly secure because the datacenter is locked. Placing the security credentials with the object they are protecting is questionable at best.

I am certainly no hacker. Not a white hat or black hat; I do not even like wearing hats. However, when I saw what looked like a glaring security issue, I began trying to think of how that might be exploited by someone with ill intent. I wrote a short PowerShell script called Get-LAPSPasswords.ps1 (see listing at the end of this article) as a proof of concept of what I suspect hacker types might do. The script first checks to see if the AD schema has been extended to include LAPS:

If so, then every computer object is iterated over, and any record that has a readable password then has the computer name, password, IP address, and Distinguished Name printed to the screen:

I see this kind of script being used in an attack, such as phishing, where an account has already been compromised. It is an easy way to effortlessly find out what, if any, systems the compromised account has access to. It would be trivially easy to extend this kind of dump to place a key logger or other malicious software onto any systems found to grow an attack. Also, while probably not the most efficient way of pulling the information from the AD, I did measure that it took just under sixteen minutes to touch every record in a domain of over 25,000 computer objects.
In a properly secured environment with zealously guarded administrative accounts running with least privilege, LAPS is likely an excellent tool to help secure resources. Like all security measures and practices, all tools are only as strong as their weakest link. I have lost track of how many compromises I have read about where a Domain Admin or similar credentials were compromised. With that in mind, if LAPS simply encrypted the passwords in the AD while they are at rest, that would certainly help.

Listing of Get-LAPSPasswords.ps1 script

f<#
.SYNOPSIS
Displays information on all computers in the Active Directory that have a
readable LAPS password set.
.DESCRIPTION
Checks to see if the Active Directory schema has been updated to support
Microsoft LAPS. If it has then it pulls in all computer objects in the
Active Directory and stores them in a collection variable. Finally, the
collection is iterated over and any computers where a LAPS password is
set and readable will be returned including the LAPS password. If the
computer object does not have a LAPS password set or the user account the
script is run under lacks appropriate permissions to read the password then
the computer's information will not be returned. Since computer and
password information is stored in the same place with LAPS enabled,
this script shows all the information needed to log in as Administrator
for all computers the account that runs the script has access to that are
managed by LAPS.
 
.EXAMPLE
.\Get-LAPSPasswords.ps1
 
Scans the Active Directory for any computers with LAPS passwords readable
by the user whom executes the script.
 
.NOTES
FileName:  Get-LAPSPasswords.ps1
Author:   Mark Van Noy
Oganization: University of Colorado Boulder
Created:   06/04/2020
 
Version history:
1.0.0 - (06/04/2020) Script created
#>
 
 
# Just to be safe. Was not required on test computer.
Import-Module ActiveDirectory
function Check-SchemaSupportsLAPS()
{
# Set a boolean flag to indicate if LAPS extensions exist in the schema.
$schemaLAPS = $false
# Check to see if the schema has been updated.
$schema = [directoryservices.activedirectory.activedirectoryschema]::getcurrentschema()
$optionalProperties = $schema.FindClass("computer").OptionalProperties | Select name,oid
$mandatoryProperties = $schema.FindClass("computer").MandatoryProperties | Select name,oid
# Based on the LAPS documentation the extensions are expected in the OptionalProperties
foreach ($property in $optionalProperties)
{
if (($property.Name -eq "ms-Mcs-AdmPwd") -and ($property.oid -eq "1.2.840.113556.1.8000.2554.50051.45980.28112.18903.35903.6685103.1224907.2.1"))
{
$schemaLAPS = $true
}
}
# Just in case something unusual happened with the Schema, check MandatoryProperties.
if (!$schemaLAPS)
{
foreach ($property in $mandatoryProperties)
{
if (($property.Name -eq "ms-Mcs-AdmPwd") -and ($property.oid -eq "1.2.840.113556.1.8000.2554.50051.45980.28112.18903.35903.6685103.1224907.2.1"))
{
$schemaLAPS = $true
}
}
}
# Let the end user know if the Schema has not been extended to support LAPS
if (!$schemaLAPS)
{
Write-Host -ForegroundColor Red "LAPS Schema extentsions are not present."
}
return $schemaLAPS
}
function Get-Computers()
{
# Need to specify properties or it is too slow with too many returned results.
# If ms-Mcs-AdmPwd does not exist in the Schema and is specified Get-ADComputer will error out.
$all_Computers = Get-ADComputer -Filter * -Properties DNSHostName, ms-Mcs-AdmPwd, IPv4Address, IPv6Address, DistinguishedName
# It can take a long time to get all computers so let end user know we are done.
Write-Host -ForegroundColor Green "All domain computer objects have been gathered"
# Iterate through ALL computers in the active directory and return the
# LAPS password for any computers the user is entitled to view.
foreach ($computer in $all_Computers)
{
# If the ms-Mcs-AdmPwd field exists proceed returning information.
if ($computer.'ms-Mcs-AdmPwd')
{
Write-Host -NoNewline $computer.DNSHostName, "`t"
Write-Host -ForegroundColor Yellow $computer.'ms-Mcs-AdmPwd'
Write-Host -NoNewline $computer.IPv4Address, "`t"
Write-Host $computer.IPv6Address
Write-Host $computer.DistinguishedName, "`r`n`r`n[------------]`r`n"
}
}
}
# LAPS also uses ms-Mcs-AdmPwdExpirationTime that could be useful for attackers
# to know how soon the passwords they have gathered will be rotated.
# SO add the ms-Mcs-AdmPwdExpirationTime to the property list and output if
# knowing the password rotation is important to you.
# If the Schema has been extended to support LAPS then start looking for computers.
if (Check-SchemaSupportsLAPS)
{
Get-Computers
}

Featured image: Shutterstock

Mitch Tulloch

Mitch Tulloch is Senior Editor of both WServerNews and FitITproNews and is a widely recognized expert on Windows Server and cloud technologies. He has written more than a thousand articles and has authored or been series editor for over 50 books for Microsoft Press and other publishers. Mitch has also been a twelve-time recipient of the Microsoft Most Valuable Professional (MVP) award in the technical category of Cloud and Datacenter Management. He currently runs an IT content development business in Winnipeg, Canada.

Share
Published by
Mitch Tulloch

Recent Posts

Enterprise considerations when purchasing laptops

You're tasked with purchasing and provisioning laptops for a bunch of users at your company.…

1 day ago

IKEA experiencing internal phishing attacks

IKEA is currently in a state of disarray thanks to an internal reply-chain email attack.

1 day ago

How to Fix Exchange Mailbox Corruption?

If transaction logs get corrupt, deleted or the server shuts down before the logs are…

2 days ago

2.4GHz or 5GHz WiFi: Which one to choose?

WiFi is not just for laptops and smartphones. It is also an essential part of…

2 days ago

Is cloud security an illusion?

Migrating your infrastructure into the cloud boosts your security and helps you avoid cyberattacks. Or…

3 days ago

How to delete a sprint when using Azure DevOps

The process of trying to delete a sprint in Azure DevOps is not straightforward. This…

3 days ago