Ghost in LSASS: Inside the KslKatz Credential Dumping Framework

Ghost in LSASS: Inside the KslKatz Credential Dumping Framework

Original text by S1lkys

The GitHub project KslKatz introduces a credential-dumping tool designed for red-team operations and security research on Windows systems. The project combines techniques from multiple tools—most notably KslDump and GhostKatz—to extract credentials from the lsass.exe process, which stores authentication secrets used by Windows. Instead of relying on common approaches such as direct process dumping or well-known APIs, the tool leverages a kernel driver (KslD.sys) that performs low-level memory reads to access LSASS memory. This method helps bypass many user-mode security mechanisms and endpoint detection systems that monitor typical credential-dumping behavior. By interacting with the driver, the tool can retrieve sensitive authentication data while avoiding standard security hooks or access checks. The project demonstrates how kernel-assisted techniques can significantly improve stealth when extracting credentials from Windows systems. Such tooling is typically used in penetration testing or adversary simulation to evaluate defensive controls and detection capabilities surrounding credential-theft techniques targeting LSASS memory. 

https://github.com/S1lkys/KslKatz

Extract MSV1_0 NT hashes and WDigest cleartext passwords from PPL-protected LSASS using only Microsoft-signed components. No third-party driver. Everything ships pre-installed with Windows Defender.

Developed in close collaboration with opus.

Overview

KslKatz combines two proven techniques into a single standalone executable:

  1. KslD.sys BYOVD for kernel/physical memory access, bypassing PPL protection on LSASS
  2. GhostKatz-style local signature scanning for resolving lsasrv.dll and wdigest.dll internals without expensive remote memory scans

The result is a tool that reads LSASS credentials through physical memory using only a Microsoft-signed driver that is already present on disk, requires no internet access, no additional files, and cleans up after itself.

What Gets Extracted

PackageDataCondition
MSV1_0NT Hash, LM Hash, SHA1 Hash per logon sessionAlways available after interactive logon
WDigestCleartext password (UTF-16)Requires WDigest caching enabled (registry, GPO, or in-memory patch)

Demo Output

C:\> KslKatz.exe
[*] Windows Build 20348
[*] Setting up KslD driver...
  Deploying embedded driver to vKslD.sys...
  Driver deployed and verified
[+] Driver loaded
[*] KASLR bypass (SubCmd 2)...
  idtr=0xfffff8000b6cb000 cr3=0x6d5000
  ntoskrnl=0xfffff8000bc1f000
[*] Finding lsass.exe...
  Handle to SYSTEM (PID 4), our PID=5452, handle=0x124
  Handle table: 35540 entries
  SYSTEM EPROCESS=0xffffe60d6e099040
  Offsets: PID=0x440 Links=0x448 Name=0x5a8
[*] Walk ActiveProcessLinks from SYSTEM to find lsass.exe
  lsass.exe PID=724 DTB=0x1269e000
  PEB=0x3ab715f000 LDR=0x7ffb7e033140
[*] Finding lsasrv.dll...
  lsasrv.dll base=0x7ffb7ae80000 size=0x190000
[*] Extracting LSA encryption keys...
  LSA keys found
[*] Finding LogonSessionList...
[*] Extracting MSV1_0 credentials...
[*] Checking WDigest...
[*] Finding wdigest.dll in lsass...
  wdigest.dll base=0x7ffb7a3e0000 size=0x51000
  l_LogSessList at 0x7ffb7a42a5c8 (RVA=0x4a5c8)
[*] Restoring driver configuration...
  Removed deployed vKslD.sys
======================================================================
 MSV1_0 CREDENTIALS
======================================================================
[+] 2 credential(s):

  YOURDOM\admin
    NT:   aad3b435b51404eeaad3b435b51404ee

  YOURDOM\svc_backup
    NT:   31d6cfe0d16ae931b73c59d7e0c089c0

======================================================================
 WDIGEST CREDENTIALS (Cleartext)
======================================================================
[+] 1 credential(s):

  YOURDOM\admin
    Password: Summer2025!

======================================================================
[*] Total: 2 MSV1_0, 1 WDigest

The Vulnerability

KslD.sys is a kernel driver shipped as part of Microsoft Defender. It is Microsoft-signed, loaded as a trusted kernel module, and exposes a device object \\.\KslD accessible from usermode via CreateFileW.

Microsoft ships two versions of this driver side by side:

VersionSizeLocationMmCopyMemoryStatus
Patched~82 KBdrivers\wd\KslD.sysNulled outActive (ImagePath points here)
Vulnerable~333 KBdrivers\KslD.sysFunctionalSitting on disk, never removed

The patched version deliberately clears the MmCopyMemory function pointer during initialization, disabling SubCmd 12. The vulnerable version stores it. Both binaries are Microsoft-signed and trusted by the OS. Defender platform updates drop the patched version into the wd\ subdirectory and update ImagePath, but the old vulnerable version is never deleted from the drivers\ directory.

KslKatz simply switches ImagePath back to the vulnerable version via ChangeServiceConfigW and restarts the service.

Why the old driver is still on disk

Microsoft’s public documentation shows that KB4052623 delivers Defender platform updates, including a historical move of Defender drivers to System32\drivers\wd\. Windows servicing keeps WinSxS-backed component-store files via NTFS hard links and only removes superseded component versions during cleanup. On tested systems, this explains why the newer 82 KB KslD.sys arrives through the Defender platform-update path while the older 333 KB System32\drivers\KslD.sys remains as the current CBS-backed component-store copy until explicitly superseded by a newer CBS version.

The Read Primitive

The core of the vulnerability is SubCmd 12, an unrestricted MmCopyMemory() wrapper exposed to usermode:

// IOCTL 0x222044, SubCmd 12
struct IoReadInput {
    DWORD  SubCmd;       // 12
    DWORD  Reserved;     // 0
    QWORD  Address;      // Target virtual or physical address
    QWORD  Size;         // Number of bytes to read
    DWORD  Flags;        // 1 = Physical, 2 = Virtual
    DWORD  Padding;
};
// Output: raw memory contents, up to Size bytes

Flag
ModeDescription
1PhysicalReads any physical address via MmCopyMemory. Not subject to PPL, EPROCESS protection, or any usermode API restriction. This is the PPL bypass primitive.
2VirtualReads kernel virtual addresses directly. Used for walking kernel structures (EPROCESS, IDT, ntoskrnl) without manual page table translation.

SubCmd 2 provides additional information leaks:

// IOCTL 0x222044, SubCmd 2
// Returns CPU register name/value pairs (8 bytes name + 8 bytes value each)
// Key registers: CR3 (current DTB), IDTR (IDT base), CR0, CR4

he combination of SubCmd 2 (KASLR defeat) and SubCmd 12 (arbitrary read) provides a complete kernel memory introspection capability from usermode.

The Access Control

The driver validates the calling process by comparing its image path against the AllowedProcessName registry value stored under HKLM\SYSTEM\CurrentControlSet\Services\KslD. This value contains a full NT device path like \Device\HarddiskVolume3\ProgramData\Microsoft\Windows Defender\Platform\4.18.x\MsMpEng.exe.

This check is trivially bypassed because the registry value is:

  • Editable by any local administrator
  • Not protected by Defender’s tamper protection mechanisms
  • Not validated against code signing, binary integrity, or any cryptographic property
  • A plain string comparison with no additional verification

KslKatz writes its own NT device path to AllowedProcessName, restarts the service, and opens the device handle.

The Blocklist Paradox

Microsoft maintains a Vulnerable Driver Blocklist (DriverSiPolicy.p7b) enforced via HVCI to prevent BYOVD attacks. From their documentation:

“The vulnerable driver blocklist is designed to help harden systems against non-Microsoft-developed driversacross the Windows ecosystem.”

Microsoft’s own drivers are excluded from the blocklist by design.

Comments are closed.