← All posts

Stop LSASS Credential Theft: Auditing LSA Protection and Credential Guard on Windows

Mimikatz and procdump both target one process: LSASS. Here is how credential dumping actually works, and how to verify LSA Protection (RunAsPPL) and Credential Guard are really turned on across your machines.

Almost every Windows intrusion that turns one compromised laptop into a domain-wide problem passes through the same chokepoint: the Local Security Authority Subsystem Service, lsass.exe. LSASS is where Windows keeps the credential material for everyone currently (and recently) signed in — NTLM hashes, Kerberos tickets and keys, and on misconfigured machines, cleartext passwords. Pop one box as admin, read LSASS memory, and you walk away with hashes you can pass, tickets you can replay, and sometimes passwords you can type straight into the next machine. MITRE ATT&CK tracks this as T1003.001 (OS Credential Dumping: LSASS Memory), and it is the engine behind lateral movement in the overwhelming majority of real ransomware and hands-on-keyboard incidents.

The good news: Microsoft ships two strong, free mitigations — LSA Protection and Credential Guard. The bad news: on most fleets they are either off, half-configured, or silently disabled by a hardware or policy gap, and nobody is checking. This post covers how the dump actually happens, exactly how to verify both protections, and how to make sure they stay on.

How LSASS gets dumped

The attacker needs administrative (or SeDebugPrivilege) rights, then opens a handle to lsass.exe with read access and copies its memory. The classic tooling:

The key insight for defenders is that the method varies but the target never does. Everything ends in a handle to LSASS with PROCESS_VM_READ. Both Microsoft mitigations attack that single step.

Mitigation 1: LSA Protection (RunAsPPL)

LSA Protection runs LSASS as a Protected Process Light (PPL). Once enabled, the OS refuses to grant a memory-read handle to any process that is not itself running at an equal-or-higher protection level — so an ordinary admin-level Mimikatz or procdump can no longer open LSASS, even with SeDebugPrivilege. It works on virtually all modern hardware with no virtualization requirement, which makes it the first thing to turn on.

The setting lives in one registry value:

# Enable LSA Protection (UEFI-locked on reboot)
reg add "HKLM\SYSTEM\CurrentControlSet\Control\Lsa" /v RunAsPPL /t REG_DWORD /d 1 /f

# Verify it
reg query "HKLM\SYSTEM\CurrentControlSet\Control\Lsa" /v RunAsPPL

On Windows 11 22H2 and later a value of 2 enables protection without the UEFI lock (easier to roll back); 1 is the locked, stronger form. Either non-zero value means it is on. After a reboot you can confirm LSASS actually launched protected:

Get-CimInstance Win32_Process -Filter "Name='lsass.exe'" | Select-Object Name, ProcessId
# Then check the protection level (PsProtectedSignerLsa) with a tool like
# Process Explorer (Protection column) or Process Hacker.
RunAsPPL is not a silver bullet — a kernel-mode driver (the BYOVD technique) can strip the PPL flag — but it eliminates the entire class of user-mode dumpers that make up the bulk of real attacks.

Mitigation 2: Credential Guard

Credential Guard goes further by using virtualization-based security (VBS) to move the secrets out of the normal LSASS process entirely, into an isolated trustlet (LSAIso) that the regular OS — and therefore any attacker in it — cannot read at all. It requires Secure Boot, VBS, and a TPM, and on clean Windows 11 Enterprise/Education 22H2+ installs that meet the hardware bar it is now on by default. But upgraded machines, VMs, and Pro/Home editions frequently do not have it, so you must verify rather than assume.

The authoritative check is the running state, not just the policy key:

# Is Credential Guard actually RUNNING? (2 == Credential Guard)
$dg = Get-CimInstance -ClassName Win32_DeviceGuard `
  -Namespace root\Microsoft\Windows\DeviceGuard
$dg.SecurityServicesConfigured   # what policy asked for
$dg.SecurityServicesRunning      # what is actually enforced now

If SecurityServicesRunning contains 2, Credential Guard is live. The policy registry value (HKLM\SYSTEM\CurrentControlSet\Control\LSA\LsaCfgFlags: 1 = on with UEFI lock, 2 = on without lock) tells you what was requested, but a machine can have the flag set and still not run it because the hardware prerequisites are missing. That gap — "configured but not running" — is exactly the kind of false sense of security an audit exists to catch.

The setting people forget: WDigest cleartext

For years, WDigest cached plaintext passwords in LSASS, which is why old Mimikatz output showed cleartext. Modern Windows defaults this off, but Group Policy drift or a careless hardening "tweak" can turn it back on. Confirm it is disabled:

reg query "HKLM\SYSTEM\CurrentControlSet\Control\SecurityProviders\WDigest" /v UseLogonCredential
# UseLogonCredential should be 0 (or absent). 1 means cleartext is being cached -> fix it.

While you are at it, enable Microsoft Defender's attack-surface-reduction rule "Block credential stealing from the Windows local security authority subsystem (lsass.exe)" (9e6c4e1f-7d60-472f-ba1a-a39ef669e4b2), which blocks the read attempt as a second layer even where PPL is not present.

Detecting an attempt in progress

Prevention can fail, so watch for the dump too. A Sysmon configuration that logs Event ID 10 (ProcessAccess) targeting lsass.exe with high-access masks (0x1010, 0x1410, 0x1438) catches handle opens; alert on rundll32.exe or procdump.exe touching LSASS, and on any new *.dmp the size of LSASS appearing in a temp directory. These are exactly the signals a process-lineage and event-log audit surface automatically.

Where this fits in WinSentinel

Checking RunAsPPL, Credential Guard's running state, WDigest, and the relevant ASR rule by hand is a five-command chore that nobody repeats weekly — and the dangerous case is the machine that quietly drifted from "protected" back to "exposed." WinSentinel's credential-protection auditing rolls all of it into one scored check, and like every one of its 33 modules it is completely free on a single machine: the CLI, the audit, one-click remediation for what is fixable, scheduled re-scans, and PDF reports, all local, with no node cap and no time limit. Run winsentinel --audit and it will tell you in seconds whether your LSASS is actually protected or just assumed to be.

What is paid is the fleet problem. If you are responsible for fifty or five hundred machines, WinSentinel Pro rolls every node's credential posture into one place: which machines have LSA Protection off, where Credential Guard is configured-but-not-running, and a drift alert the moment any box regresses — plus remote "scan now" dispatch and compliance rollups across the estate. The single-machine depth is identical either way; Pro solves the org-wide question of seeing every endpoint at once instead of SSHing into them one by one.

If you have never confirmed that LSA Protection is on across your machines, start with the one reg query above on the box in front of you. It takes ten seconds, and it is the difference between "an attacker who lands here gets one machine" and "an attacker who lands here gets the domain."

Browse all 33 audit modules →  ·  Read: Finding exposed secrets before attackers do →