Why static hash and binary-name detection fails against modern credential dumping, and how detection engineers write resilient telemetry rules targeting Windows kernel object handle grants.
The Illusion of Name and Hash-Based Detection
For years, security operations centers (SOCs) relied on signature-based alerts to detect credential dumping. If a process named mimikatz.exe appeared in the process execution tree, or if a binary matched a known SHA-256 hash from VirusTotal, a high-severity alert fired.
Adversaries adapted almost instantly: 1. Binary Renaming & Compilation: Recompiling open-source offensive tools with novel compiler flags changes the hash completely. Renaming procdump.exe to svchost.exe or notepad.exe bypasses naive string-matching filters. 2. Bring Your Own Vulnerable Driver (BYOVD): Attackers drop signed, vulnerable third-party drivers (e.g., Process Explorer, kernel debugging drivers) to terminate security hooks and read memory from kernel space directly. 3. Living-off-the-Land Binaries (LOLBins): Attackers leverage native Windows utilities like comsvcs.dll via rundll32.exe:
rundll32.exe C:\Windows\System32\comsvcs.dll, MiniDump <lsass_pid> C:\Windows\Temp\lsass.dmp full
- Reflective Injection & API Unhooking: Custom loaders allocate memory directly inside a legitimate process (like
taskhostw.exe), manually resolve system calls via direct SSNs (System Service Numbers), and dump LSASS memory without touching disk.
If you are hunting for file names, command-line arguments, or hashes, you are playing defense at the bottom of David Bianco’s Pyramid of Pain.
To reliably detect credential dumping, detection engineers must move up the pyramid to TTPs (Tactics, Techniques, and Procedures)—specifically, instrumenting the operating system kernel to observe the exact access rights requested when any process opens a handle to the Local Security Authority Subsystem Service (lsass.exe).
Anatomy of an LSASS Handle Request
The Local Security Authority Subsystem Service (lsass.exe) enforces security policies on Windows, authenticates users, and manages security tokens. To prevent re-prompting users for credentials across domain resources, LSASS caches credential material in memory:
- Kerberos tickets (TGT, TGS)
- NTLM hashes
- Plaintext credentials (if WDigest or legacy SSPs are enabled)
- DPAPI master keys
To dump or read this cached memory from user mode, any process—whether it is Mimikatz, ProcDump, Cobalt Strike, or a legitimate administrative tool—must first obtain an open process handle to LSASS using the Win32 API OpenProcess or NtOpenProcess.
HANDLE hProcess = OpenProcess(
PROCESS_VM_READ | PROCESS_QUERY_INFORMATION,
FALSE,
lsassPID
);
When OpenProcess is called, the Windows Object Manager verifies whether the caller’s access token possesses the appropriate permissions (typically requiring SeDebugPrivilege). If permitted, the kernel constructs an entry in the calling process’s Handle Table and grants a specific bitmask representing the Granted Access Mask.
The Critical Granted Access Bits
In the Windows kernel, process handle access rights are represented as a 32-bit integer:
| Constant | Value | Why Attackers Need It | | :— | :— | :— | | PROCESS_VM_READ | 0x0010 | Permits reading the virtual memory of LSASS via ReadProcessMemory or NtReadVirtualMemory. Required to extract hashes or create a minidump. | | PROCESS_VM_WRITE | 0x0020 | Permits writing into LSASS memory (used in code injection or DLL injection). | | PROCESS_VM_OPERATION | 0x0008 | Permits modifying the address space (allocating memory or altering page protections). | | PROCESS_CREATE_PROCESS | 0x0080 | Used to spawn child processes or clone address space. | | PROCESS_QUERY_INFORMATION | 0x0400 | Permits reading process attributes, tokens, and exit codes. Required by MiniDumpWriteDump. | | PROCESS_QUERY_LIMITED_INFORMATION | 0x1000 | Minimal query rights used by monitoring agents. | | PROCESS_ALL_ACCESS | 0x1FFFFF | All possible access rights. Lazy offensive tools often request this by default. |
Regardless of whether an adversary renames their tool, packs it with UPX, or injects it into explorer.exe, they cannot read memory from LSASS without receiving PROCESS_VM_READ (0x0010) or PROCESS_ALL_ACCESS.
Telemetry Engineering: Sysmon Event ID 10
To capture process handle requests at scale, Microsoft Sysinternals Sysmon (System Monitor) provides Event ID 10: ProcessAccess.
Unlike command-line logging (Event ID 1) which only logs when a process launches, Event ID 10 logs the exact moment any process interacts with another target process, recording:
SourceImage: The process opening the handle.TargetImage: The process whose handle is being opened (C:\Windows\system32\lsass.exe).GrantedAccess: The hexadecimal bitmask representing the exact rights granted by the kernel.CallTrace: The user-mode stack trace showing which DLLs and functions led to the handle request.
Example Sysmon Event ID 10 Telemetry Record
<Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event">
<System>
<Provider Name="Microsoft-Windows-Sysmon" Guid="{5770385F-C22A-43E0-BF4C-06F5698FFBD9}" />
<EventID>10</EventID>
<TimeCreated SystemTime="2026-09-08T01:14:22.8410291Z" />
<Computer>FIN-WKSTN-042.internal.corp</Computer>
</System>
<EventData>
<Data Name="RuleName">technique_id=T1003.001,technique_name=LSASS_Memory</Data>
<Data Name="SourceImage">C:\Users\Public\svchost.exe</Data>
<Data Name="SourceProcessId">6412</Data>
<Data Name="TargetImage">C:\Windows\system32\lsass.exe</Data>
<Data Name="TargetProcessId">688</Data>
<Data Name="GrantedAccess">0x1010</Data>
<Data Name="CallTrace">C:\Windows\SYSTEM32\ntdll.dll+9d5c4|C:\Windows\System32\KERNELBASE.dll+2c834|C:\Users\Public\svchost.exe+14b2</Data>
</EventData>
</Event>
In the event above:
- Notice
SourceImageisC:\Users\Public\svchost.exe(a classic imposter path). GrantedAccessis0x1010(PROCESS_QUERY_LIMITED_INFORMATION (0x1000)+PROCESS_VM_READ (0x0010)).- The
CallTraceshows direct execution from unbacked memory insvchost.exetransitioning throughKERNELBASE.dll!OpenProcessintontdll.dll!NtOpenProcess.
Crafting the Detection Logic
1. Bitwise Mask Matching
A common mistake in SIEM correlation rules is checking for exact string matches like GrantedAccess = "0x1010". Attackers can combine arbitrary flags (e.g. 0x1410, 0x1F3FFF, 0x1FFFFF) to evade exact string matches while still receiving read access.
Your detection rule must perform a bitwise AND operation: $$\text{GrantedAccess} \ \& \ \text{0x0010} \neq 0$$
2. Sigma Rule Definition
Here is a production-grade Sigma rule that detects unauthorized processes requesting memory read access to lsass.exe:
title: Suspicious LSASS Process Handle Access with Memory Read Rights
id: b83f1201-382a-4a2e-9d22-dc9024f28031
status: production
description: |
Detects process handle requests to lsass.exe containing PROCESS_VM_READ (0x0010) or
PROCESS_ALL_ACCESS (0x1FFFFF) access masks, excluding known benign enterprise agents.
author: Cynthia Schomp (securemyass.com)
references:
- https://attack.mitre.org/techniques/T1003/001/
- https://securemyass.com/catching-lsass-dumping-handle-rights/
tags:
- attack.credential_access
- attack.t1003.001
logsource:
product: windows
service: sysmon
detection:
selection:
EventID: 10
TargetImage|endswith: '\system32\lsass.exe'
GrantedAccess|contains:
- '0x1010'
- '0x1410'
- '0x1038'
- '0x1438'
- '0x143a'
- '0x1fffff'
filter_benign:
SourceImage|startswith:
- 'C:\Program Files\Windows Defender\'
- 'C:\Program Files\CrowdStrike\'
- 'C:\Program Files\SentinelOne\'
- 'C:\Program Files\Tanium\'
SourceImage|endswith:
- '\MsMpEng.exe'
- '\CsAgent.exe'
- '\SentinelAgent.exe'
condition: selection and not filter_benign
falsepositives:
- Enterprise Endpoint Detection and Response (EDR) agents
- Anti-virus engines performing active process validation
- Diagnostic and memory profilers run by authorized domain administrators
level: high
Analyzing CallTrace for Advanced Evasion
Sophisticated adversaries using tools like Dumpert, SafetyKatz, or custom C2 implants often attempt to defeat user-mode API hooks installed by AV/EDR products by invoking direct system calls (syscall instruction in inline assembly) rather than calling through kernel32!OpenProcess.
When direct syscalls are executed:
- The standard user-mode hooks in
kernel32.dllorKERNELBASE.dllare bypassed. - However, Sysmon operates at the kernel driver layer (
SysmonDrv.sys) viaObRegisterCallbacks. Sysmon intercepts the handle creation withinObpCreateHandleinsidentoskrnl.exe. - The
CallTracelogged in Sysmon Event ID 10 will show something suspicious: an abrupt transition directly from the caller’s memory intontdll.dllor directly into the kernel, without the standard transition frames throughKERNEL32.DLL->KERNELBASE.DLL.
High-Fidelity CallTrace Heuristics
- Unknown or Unbacked Memory:
If the CallTrace contains UNKNOWN(...) instead of a valid DLL name on disk, memory was allocated dynamically (e.g. via VirtualAlloc), typical of shellcode reflective loaders:
UNKNOWN(00007FF7B0A21200)|C:\Windows\SYSTEM32\ntdll.dll+9d5c4
- Missing KERNELBASE Transition:
Legitimate Windows applications always invoke OpenProcess via KERNEL32.DLL -> KERNELBASE.DLL. A call trace jumping straight from executable code into ntdll.dll strongly correlates with manual syscall stubbing.
Defensive Engineering Playbook
To eliminate or severely restrict credential dumping across your infrastructure, implement the following defense-in-depth controls:
- Enable LSA Protection (RunAsPPL):
Configuring LSASS to run as a Protected Process Light (PPL) prevents non-protected processes from obtaining PROCESS_VM_READ handles, even if the caller has local SYSTEM privileges.
# Enforce RunAsPPL via registry
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Lsa" -Name "RunAsPPL" -Value 1 -Type DWord
- Enable Credential Guard:
Leverage Virtualization-Based Security (VBS) to isolate the LSA secrets into an isolated virtual container (Isolated User Mode / VSM) where even kernel-level read access cannot extract plaintext keys. 3. Audit and Alert on SeDebugPrivilege: Regular enterprise users have no operational reason to possess SeDebugPrivilege. Audit any process assigning or enabling this privilege on standard endpoints. 4. Deploy Sysmon Event ID 10 with Precise Filters: Do not disable Event ID 10 due to volume concerns. Filter out high-volume benign callers (like MsMpEng.exe) at the driver configuration layer so your SIEM ingestion stays lean and high-fidelity.
Summary
Detection engineering is not about collecting static indicators of compromise. Hashes are transient; file names are easily spoofed; command-line flags can be obfuscated.
By grounding your detection architecture in kernel-enforced primitives—like object access rights and handle creation telemetry—you force adversaries to confront architectural physics rather than superficial signatures.
Need to harden your web application entry points and pre-boot PHP execution layers against credential theft? Read our guide on Hardening WordPress in Docker with Traefik.