# From `cmd.exe` to a Kusto Row in 90 Seconds: How Sysmon and Defender for Endpoint Actually Work

> The seven-layer production EDR pipeline -- kernel callback, ETW publisher, MsSense.exe, SenseCncProxy, Kusto, KQL -- traced end to end for Sysmon and Defender for Endpoint.

*Published: 2026-05-13*
*Canonical: https://paragmali.com/blog/from-cmdexe-to-a-kusto-row-in-90-seconds-how-sysmon-and-defe*
*License: CC BY 4.0 - https://creativecommons.org/licenses/by/4.0/*

---
<TLDR>
Modern Windows EDR is a seven-layer production pipeline. A kernel callback fires, a user-mode aggregator labels the event, an ETW publisher (Sysmon) or a TLS-pinned cloud forwarder (`SenseCncProxy.exe`) ships it, and within seconds the event surfaces as a row in a Kusto table that the analyst queries with KQL. Sysmon (Russinovich and Garnier, August 2014) is the configurable kernel-callback-then-publish reference: twenty-nine event IDs, three canonical configurations (SwiftOnSecurity, the post-rename `NextronSystems/sysmon-config`, and `olafhartong/sysmon-modular`), Antimalware-PPL hardening since v15 in June 2023. Microsoft Defender for Endpoint (Windows Defender ATP preview March 2016, MDE rename September 2020, Microsoft Defender XDR portal late 2023) is the commercial cloud-correlated counterpart: `MsSense.exe` runs as Antimalware-PPL, shares the `WdFilter.sys` / `WdBoot.sys` / `WdNisDrv.sys` Defender Antivirus kernel surface, and lands events in six `Device*` Advanced Hunting tables with 30-day in-portal retention, extended via the Microsoft Sentinel Defender XDR connector. For MDE-licensed shops with a detection-engineering team, the community pattern is Hartong's `sysmonconfig-mde-augment.xml` -- Sysmon as a complement, not a duplicate. The pipeline's four structural ceilings (pre-driver-load horizon, observation-vs-enforcement latency, MDE schema truncation, kernel-mode adversary primitive) are documented and unclosed; FalconForce's 2022 CVE-2022-23278 disclosure and InfoGuard Labs' 2025 certificate-pinning bypass bookend an adversarial arc the field has not yet ended.
</TLDR>

## 1. From `cmd.exe` to a Kusto Row in Ninety Seconds

At 9:14 a.m. on a Monday, a SOC analyst named Maya watches a `DeviceProcessEvents` row light up in the Advanced Hunting console of Microsoft Defender XDR. The `FileName` is `powershell.exe`. The `ProcessCommandLine` reads `powershell.exe -enc JABzAD0A...`. The `InitiatingProcessFileName` is `WINWORD.EXE`. The `Timestamp` is three seconds ago [@deviceprocessevents-table].

By 9:15:44 Maya has pivoted to `DeviceNetworkEvents`, found an outbound connection from the same `InitiatingProcessId` to a previously-unknown IP on TCP/443, clicked **Isolate device** in the device page, and the endpoint is off the network. Ninety seconds, end to end. Email triage of the original message; a quarantine on the inbound `.docm`; and -- by the time the user's coffee has cooled -- a brand-new IOC in the tenant's custom indicator list.

This article is the rewind. We walk Maya's ninety seconds backwards through the seven pipeline layers that made the triage possible -- starting in ring zero, ending in the KQL query you can copy into your own tenant -- and along the way we answer the question every SOC manager has asked at least once: do we deploy Sysmon alongside Defender for Endpoint, or trust Defender alone?

### The seven layers

Maya is looking at a single Kusto row. Behind that row sit seven distinct software components, each of which can fail independently:

1. A **kernel callback** fired inside the `nt!PspInsertProcess` path on the target machine the instant `WINWORD.EXE` called `CreateProcessW` to spawn `powershell.exe`. The callback handler lives inside `WdFilter.sys` (Defender Antivirus's filter driver) and inside `SysmonDrv.sys` if Sysmon is also installed [@pssetcreateex-msdn].
2. A **user-mode aggregator** -- `MsSense.exe` for Defender for Endpoint, or `Sysmon.exe` (the service) for Sysmon -- received the structured callback notification, enriched it with parent-process state, file hashes, signature information, and identity data, and decided whether the event was worth shipping [@mde-ms-learn][@sysmon-ms-learn].
3. An **[ETW publisher](/blog/etw-how-windows-2000s-performance-hack-became-the-edr-substr/)** -- in Sysmon's case the `Microsoft-Windows-Sysmon` provider -- emitted the event to the operating system's tracing bus, and the Sysmon service wrote it to the `Microsoft/Windows/Sysmon/Operational` event log [@sysmon-ms-learn].
4. A **cloud forwarder** -- `SenseCncProxy.exe` -- ran the Defender payload through TLS with certificate pinning out to the regional Defender XDR ingest endpoint [@falconforce-2022].
5. A **cloud sensor pipeline** in Microsoft's regional datacenter (the US for US tenants, the EU for European tenants, the UK for UK tenants) wrote the event into the Advanced Hunting Kusto cluster [@advanced-hunting-overview][@ms-server-endpoints-learn].
6. A **Kusto table** -- `DeviceProcessEvents` -- became queryable within seconds, joined logically across roughly fifty columns to its siblings (`DeviceNetworkEvents`, `DeviceFileEvents`, `DeviceRegistryEvents`, `DeviceImageLoadEvents`, `DeviceEvents`) [@deviceprocessevents-table].
7. A **KQL query** Maya wrote, or one of Microsoft's built-in detection rules, joined the process row to the network row on `(DeviceId, InitiatingProcessId)`, surfaced the C2 callback inside a ninety-second window, and put the device-isolation button on her screen [@advanced-hunting-overview][@sentinel-xdr-connector].

Each of these seven layers is independently failure-prone. Operating an EDR well -- which is what this article is about -- means knowing which layer produced which artifact, which layer can be tampered with, and which layer is the right one to fix when the row does not arrive.

> **Key idea:** Modern Windows EDR is a seven-layer production pipeline: kernel callback, user-mode aggregator, ETW publisher (or cloud forwarder), TLS-pinned cloud transport, regional Kusto ingest, table write, KQL read. Sysmon and Microsoft Defender for Endpoint are two implementations of the same seven layers, with different design philosophies at every layer.

### Why two products, not one

Sysmon and Defender for Endpoint were not designed as a pair. They evolved as competing answers to the same problem -- *when prevention fails, what evidence do you give the responder?* -- on the same operating system, with the same kernel-callback APIs underneath, and with the same Windows Event Tracing bus as the transport layer in the middle. They converged on a shared trust model only in 2023, when both products began running as protected processes [@sysmon-ms-learn][@falconforce-2022].

That convergence is not coincidence. It is the consequence of a decade of architectural pressure pushing both products toward the same answer: collect at the Microsoft-sanctioned kernel-callback boundary, normalize in user mode, ship over a tamper-resistant transport, and surface to the analyst as a queryable column family. The differences are in the configuration grammar, the cloud-side enrichment, and the trust boundary at the publisher edge. The seven layers are the same. To see why, we have to start in 2014, when Sysmon shipped with three event types.

## 2. Twelve Years, Two Arcs, One Convergence

Anton Chuvakin, then a research VP at Gartner, named the category in July 2013. His blog post -- preserved on his personal site after Gartner deleted its analyst blogs in late 2023 -- coined the term *Endpoint Threat Detection and Response* (ETDR) and defined it as "tools primarily focused on detecting and investigating suspicious activities (and traces of such) other problems on hosts/endpoints" [@chuvakin-2013][@wikipedia-edr]. The "T" dropped out of the acronym within eighteen months and the field has been called EDR ever since.

Chuvakin's question -- *what evidence do you give the responder when prevention fails?* -- got two different answers from inside Microsoft over the next decade. One was free, configurable, and ran on every Windows machine the operator wanted to run it on. The other was commercial, cloud-correlated, and only worked if you paid for it. Both started in the same place: at the supported kernel-callback boundary that Microsoft had been steadily building out since Windows XP.

### The Sysmon arc: August 2014 to March 2026

Mark Russinovich gave session HTA-T07R at RSA US 2014 -- *Malware Hunting with the Sysinternals Tools* -- and the methodology he taught (process-tree pivoting, autoruns enumeration, real-time monitoring of file and registry writes) had a natural conclusion: somebody should ship a Sysinternals tool that did all of that, continuously, into the Windows event log [@russinovich-rsa-2014]. The tool shipped in August 2014, written by Russinovich and Thomas Garnier, also of Microsoft. ZDNet's contemporaneous coverage captured the introduction: "Sysmon, written by Russinovich and Thomas Garnier, also of Microsoft, is the 73rd tool in the set... Note: For public release, Sysmon has been reset to version 1.00" [@zdnet-sysmon-2014]. The launch SKU had three event types: process create (EID 1), file-create-time change (EID 2), and network connect (EID 3).

The design philosophy is captured in a single sentence Microsoft Learn still prints on the Sysmon download page -- a sentence whose framing of Sysmon as a publisher that refuses to do detection and refuses to hide is the entire foundation of the SwiftOnSecurity-NextronSystems-Hartong configuration lineage that §5 unpacks; the verbatim quote lands as the §4 PullQuote [@sysmon-ms-learn]. Every detection-engineering corpus in the Windows field -- SwiftOnSecurity's config, Florian Roth's fork, Olaf Hartong's modular system, the SigmaHQ rule base, the Threat Hunter Playbook -- is downstream of that one design choice.

The version history reads as capability accretion, not architectural change. Sysmon v6 in February 2017 added registry events (EIDs 12-14), process-access (10), file-create (11), pipe events (17-18), file-create-stream-hash (15), and the *ServiceConfigurationChange* (16) audit of Sysmon's own settings [@sysinternals-blog-v6]. (EID 7 ImageLoad arrived earlier, in Sysmon v2.0 -- the §4 catalogue places it correctly.) Sysmon v10 in June 2019 added DNS-query observation via ETW *consumption* of `Microsoft-Windows-DNS-Client`; the v10 release date is recorded in the community-curated *Sysmon Version History* repository, explicitly marked "Outdated" past v11.10 because its maintainer stopped updating it [@sysmon-version-history]. v13 added ClipboardChange and ProcessTampering. v14 in August 2022 added the first *preventive* event -- FileBlockExecutable (EID 27) -- making Sysmon something subtly more than a publisher [@diversenok-2022][@hartong-sysmon14-medium].

The architectural inflection landed in **June 2023 with Sysmon v15**, when the Sysmon service began running as a protected process. BleepingComputer's contemporaneous coverage notes that the service ran as `PROTECTED_ANTIMALWARE_LIGHT` and the schema bumped to 4.90 with the new `FileExecutableDetected` event ID 29 [@bleepingcomputer-sysmon15][@hartong-sysmon15-medium]. The Microsoft Learn page now states the change verbatim: "*The service runs as a protected process, thus disallowing a wide range of user mode interactions*" [@sysmon-ms-learn]. The latest published release at the time of writing is **v15.2 on March 26, 2026** (per the Sysmon download page's *Published* by-line), with twenty-nine event types plus EID 255 (Error) [@sysmon-ms-learn].

### The MDE arc: March 2016 to late 2023

Microsoft announced **Windows Defender Advanced Threat Protection** in a Windows Experience blog post on March 1, 2016 -- *"Today, we announce the next step in our efforts to protect our enterprise customers, with a new service, Windows Defender Advanced Threat Protection"* [@ms-blog-atp-mar2016]. The service was framed as a cloud-correlated detection-and-investigation layer on top of the Windows 10 sensor, "informed by anonymous information from over 1 billion Windows devices" [@ms-blog-atp-mar2016]. The 2016 product was Windows-only, in-portal, and oriented to detection and investigation only.

The Fall Creators Update in October 2017 broadened the product into prevention: "*The Windows Fall Creators Update represents a new chapter in our product evolution as we offer a set of new prevention capabilities designed to stop attacks as they happen and before they have impact. This means that our service will expand beyond detection, investigation, and response, and will now allow companies to use the full power of the Windows security stack for preventative protection*" [@ms-blog-atp-jun2017]. Attack Surface Reduction rules, Exploit Guard, and Application Guard joined the platform. So did the **Advanced Hunting** query surface in 2018 -- KQL on the same `Device*` tables Maya uses in §1.

The cross-platform reach arrived in March 2019 with macOS support (initially as Microsoft Defender ATP) and was extended to networked Linux and macOS discovery by February 2021 [@securityweek-defender-macos][@bleepingcomputer-defender-linux]. The product was renamed twice. The most-cited rename came at **Microsoft Ignite 2020 on September 22, 2020**, when the Microsoft Security blog announced the product family rebrand: "*Microsoft Defender for Endpoint (previously Microsoft Defender Advanced Threat Protection)*" [@ms-unified-siem-xdr-2020]. The same post renamed Microsoft Threat Protection to Microsoft 365 Defender, O365 ATP to Microsoft Defender for Office 365, and Azure ATP to Microsoft Defender for Identity. The second rename was at **Microsoft Ignite 2023 in November 2023**, when Microsoft 365 Defender became **Microsoft Defender XDR**, announced as part of the broader product rebrand at Ignite 2023 [@defender-xdr-ms-learn][@ms-ignite-2023-blog].<Sidenote>The Ignite 2023 rebrand did not change the KQL substrate, the `Device*` schema, or the Sentinel connector contract. It is a marketing relabel on top of a stable cloud surface. Detection engineering teams kept writing queries against `DeviceProcessEvents` exactly as they did the day before the rename.</Sidenote>

### The configuration-lineage arc

A third arc ran in parallel with the two product arcs: the community-maintained Sysmon configurations that turned Sysmon from a kernel-callback publisher into a deployment-ready detection sensor.

The historical root is **SwiftOnSecurity's `sysmon-config` repository**, created on February 1, 2017 per the GitHub REST API [@github-swiftonsecurity-meta]. The README's design intent is succinct: "*This is a Microsoft Sysinternals Sysmon configuration file template with default high-quality event tracing*" [@github-swiftonsecurity]. The repository remains the most-cited Sysmon-configuration starting point in the SOC industry.

Florian Roth, working under the handle `@Neo23x0`, forked SwiftOnSecurity's config in January 2018 (the exact creation date is now obscured by a 2021 rename -- see the sidenote below). The fork added blocking-rule support for Sysmon v14, an actively-maintained set of community pull-request merges, and the *export-block.xml* variant that ships the v14+ FileBlockExecutable rules. The README states the lineage verbatim: "*This is a forked and modified version of @SwiftOnSecurity's sysmon config. ... We merged most of the 30+ open pull requests*" [@github-neo23x0]. The current maintainer roster lists Florian Roth, Tobias Michalski, Christian Burkard, and Nasreddine Bencherchali.

Olaf Hartong's `sysmon-modular` was created on January 13, 2018 per the GitHub REST API [@github-hartong-meta]. The repository takes a different design approach: instead of one monolithic XML config, Hartong ships a per-EID-and-per-technique module library that compiles down into one of several pre-generated artifacts -- `sysmonconfig.xml` (default), `sysmonconfig-with-filedelete.xml` (default plus archive), `sysmonconfig-excludes-only.xml` (verbose), `sysmonconfig-research.xml` (super-verbose, with the warning "*really DO NOT USE IN PRODUCTION!*"), and the load-bearing `sysmonconfig-mde-augment.xml` whose entire design intent is to fill the gaps in Defender for Endpoint's collection surface [@github-hartong-modular].<Sidenote>Olaf Hartong and Henri Hambartsumyan, the two FalconForce researchers who reverse-engineered Defender for Endpoint in 2022 and surfaced CVE-2022-23278, also maintain `olafhartong/sysmon-modular`. This is the dual identity that makes the `sysmonconfig-mde-augment.xml` config uniquely informed: the same people who learned where MDE's collection truncates Sysmon's manifest also published the config that fills those gaps [@falconforce-2022][@github-hartong-modular].</Sidenote>

The Neo23x0 repository was renamed in 2021. The current `https://github.com/Neo23x0/sysmon-config` URL HTTP-301s to `https://github.com/NextronSystems/sysmon-config`, and the GitHub REST API returns a `created_at` of `2021-07-24T06:19:41Z` with a `parent` field pointing to `SwiftOnSecurity/sysmon-config` [@github-nextronsystems-meta]. The content lineage from SwiftOnSecurity is unchanged; only the organizational owner moved from Florian Roth's personal handle to his employer Nextron Systems.

By 2023, then, two product arcs and one configuration arc had converged on the same baseline: kernel callbacks (`PsSetCreateProcessNotifyRoutineEx`, `ObRegisterCallbacks`, `CmRegisterCallbackEx`, Filter Manager minifilters) on the input side; an Antimalware-PPL protected service on the host; an ETW or TLS-pinned cloud transport in the middle; and KQL on `Device*` tables on the reader side. The convergence was structural, not coincidental. To see why both arcs landed in the same place, we have to start at the kernel-callback boundary -- where Sysmon's input lives.

## 3. Sysmon Architecture: Kernel Collection, ETW Emission, Event Log Persistence

If you have ever read that Sysmon is an "ETW-based event source," you have read something that is half-true. The half that is right is the *output* side: Sysmon publishes its events through an ETW provider called `Microsoft-Windows-Sysmon`, and the rest of the system -- including the Windows Event Log service -- subscribes to that provider. The half that is wrong is the *input* side. Sysmon does not get most of its raw observations from ETW. It gets them from five kernel-callback families and one Filter Manager minifilter, with two narrow ETW-consumer exceptions (DNS-Client for EID 22; the WMI activity provider for EIDs 19-21).

This distinction is small enough that most blog posts skip it and big enough that getting it wrong leads to architectural confusion. The split between *collection* (how data enters the Sysmon driver) and *emission* (how data leaves the Sysmon service) is the first thing to get straight before anything else makes sense.

<Definition term="Event Tracing for Windows (ETW)">
The in-kernel, low-overhead, manifest-described tracing infrastructure built into Windows since 2000. Providers publish structured events; controllers start trace sessions and select which providers to enable; consumers receive events live or read them from `.etl` files. Sysmon uses ETW as its *output* bus -- its kernel driver hands events to the user-mode service via a private ETW session -- and as a small input source for the DNS-Client kernel provider (EID 22) and the WMI activity provider (EIDs 19-21).
</Definition>

<Definition term="Kernel callback">
A Microsoft-sanctioned ring-0 API for observing operating-system events without patching the System Service Descriptor Table. The Windows kernel exposes a small set of named callback APIs -- `PsSetCreateProcessNotifyRoutineEx` for process create and exit, `PsSetLoadImageNotifyRoutine` for image load (with a `SystemModeImage` bit that distinguishes kernel drivers from user-mode DLLs), `PsSetCreateThreadNotifyRoutineEx` for thread creation (with a remote-thread flag), `ObRegisterCallbacks` for handle-rights filtering against `PsProcessType` and `PsThreadType`, `CmRegisterCallbackEx` for registry operations, and the Filter Manager minifilter framework for file-system I/O. A driver registers a function pointer; the kernel invokes it on the corresponding event with the structured context. PatchGuard tolerates kernel callbacks; it does not tolerate SSDT patching [@wikipedia-kpp][@pssetcreateex-msdn][@ms-wdk-kernel-callbacks].
</Definition>

<Definition term="Filter Manager minifilter">
The file-system filter-driver framework (`FltMgr.sys`) that hosts minifilter drivers between the I/O manager and the file-system stack. Each minifilter declares an *altitude* (a 16-bit priority) and receives notifications for pre- and post-operation hooks on file create, file write, set-information, and set-security. Both `SysmonDrv.sys` and `WdFilter.sys` are minifilters; they coexist at different altitudes without colliding [@sysmon-ms-learn].
</Definition>

### Five collection mechanisms, one ETW publisher

The Microsoft Learn page for Sysmon enumerates the event IDs and describes them at the *what* level; the *how* (which kernel API actually produced each event) is documented partly in the API references for each callback API and partly in the source code of Sysmon's open Linux port, `microsoft/SysmonForLinux`, which reuses Sysinternals' shared C++ rule-engine for parsing the same XML schema and translating it onto eBPF instead of kernel callbacks [@github-sysmon-linux][@sysmon-ms-learn]. The Windows port is closed source, but Sysinternals' design has been documented enough -- across the RSA 2014 talk, the Diversenok 2022 reverse-engineering writeup, and the SysmonForLinux source -- that the collection-mechanism inventory is unambiguous.

The five mechanisms are:

| Mechanism | API or framework | Sysmon EIDs produced |
|-----------|------------------|----------------------|
| Process-lifetime callback | `PsSetCreateProcessNotifyRoutineEx` | 1 (ProcessCreate), 5 (ProcessTerminate) |
| Image-load callback | `PsSetLoadImageNotifyRoutine` | 7 (ImageLoad); 6 (DriverLoad, distinguished by the `IMAGE_INFO.SystemModeImage` flag on the kernel-mode image) |
| Thread-creation callback | `PsSetCreateThreadNotifyRoutineEx` (with the `PS_CREATE_THREAD_NOTIFY_FLAG_CREATE_REMOTE` flag in `CREATE_THREAD_NOTIFY_INFO`) | 8 (CreateRemoteThread) |
| Object Manager callback | `ObRegisterCallbacks` against `PsProcessType` | 10 (ProcessAccess) |
| Registry callback | `CmRegisterCallbackEx` | 12 (Registry Object Create/Delete), 13 (Registry Value Set), 14 (Registry Key/Value Rename) |
| Filter Manager minifilter | `FltRegisterFilter` against `FltCreate`/`FltClose`/`FltSetInformation` -- ordinary file system, *and* the Named Pipe File System (NPFS, `\Device\NamedPipe`) at a different altitude | 11 (FileCreate), 15 (FileCreateStreamHash), 17 (PipeEvent Created), 18 (PipeEvent Connected), 23 (FileDelete archived), 26 (FileDeleteDetected), 27 (FileBlockExecutable), 28 (FileBlockShredding), 29 (FileExecutableDetected) |

The five-mechanism framing collapses thread-creation and [Object Manager](/blog/the-object-manager-namespace-the-hierarchical-filesystem-und/) callbacks into one architectural family ("process and thread observation via Microsoft-sanctioned callbacks"); a stricter count is six (process-lifetime, image-load, thread-creation, object-handle, registry, minifilter). Either count is defensible; what matters is keeping the API attribution honest: `PsSetCreateThreadNotifyRoutineEx` is the canonical remote-thread observer, `ObRegisterCallbacks(PsProcessType)` is the canonical handle-rights filter, and NPFS minifiltering -- not `ObRegisterCallbacks` -- is what observes named-pipe creation and connection.

The sixth source -- the **ETW consumer** path -- is special. For DNS queries (EID 22), Sysmon does not register a kernel callback. It subscribes as a consumer of the Microsoft-published `Microsoft-Windows-DNS-Client` ETW provider, parses the structured DNS events, and republishes them through its own ETW provider with the Sysmon enrichments applied [@sysmon-version-history]. DNS-Client is the only event Sysmon consumes from a Microsoft-published *kernel* ETW provider; the WmiEvent family (EIDs 19-21) is implemented in a similar consumer style against the WMI activity provider's user-mode tracing surface, which is why the §4 catalogue marks those rows as "WMI ETW provider consumer." Either way, ETW consumption is the input-side exception, not the rule: five kernel-callback families do the bulk of the work, and ETW is the input only for a small, deliberately-chosen set of events.

<Sidenote>The Sysmon ETW provider has the GUID `{5770385F-C22A-43E0-BF4C-06F5698FFBD9}`. Microsoft Learn does not enumerate this GUID on the Sysmon page; the authoritative on-host discovery command is `logman query providers Microsoft-Windows-Sysmon`, which returns the GUID, the keywords mask, and the registered processes. Pavel Yosifovich's community ETW-provider catalogue `EtwExplorer` mirrors the value [@etwexplorer-sysmon-guid], with the on-host `logman` command remaining the authority of last resort.</Sidenote>

### The ProcessCreate path, step by step

The clearest way to see how the pieces fit is to trace one event. Sysmon's process-create handling is the most-quoted EID in the manifest -- it is the EID that produces Maya's row in §1 -- and it follows the canonical kernel-callback pattern that Microsoft codified in `PsSetCreateProcessNotifyRoutineEx`:

```c
// Conceptual pseudocode for SysmonDrv's process-create path.
// Real Sysmon source for Windows is closed; the Linux port is open.
// This is the contract documented in the WDK reference for
// PsSetCreateProcessNotifyRoutineEx.

NTSTATUS SysmonDrvEntry(PDRIVER_OBJECT DriverObject, ...) {
    // 1. Register the create-process callback. PatchGuard tolerates this.
    PsSetCreateProcessNotifyRoutineEx(SysmonProcessCreateCb, FALSE);
    // ... other callbacks registered similarly ...
    return STATUS_SUCCESS;
}

VOID SysmonProcessCreateCb(
    HANDLE  ParentId,
    HANDLE  ProcessId,
    PPS_CREATE_NOTIFY_INFO  CreateInfo  // NULL on process exit
) {
    if (CreateInfo == NULL) {
        // Process exit: emit EID 5 (ProcessTerminate).
        SysmonEmitEventEID5(ProcessId);
        return;
    }
    // Process create. Apply the XML rule engine: does this process
    // match any <Include> rule, after evaluating <Exclude> overrides?
    if (!SysmonRuleMatch(EID_1, CreateInfo)) {
        return;  // Filtered: produce no event.
    }
    // Enrich with parent process, command line, image hash, integrity
    // level, user SID, ProcessGuid, and session identifiers, then ship
    // through the private Microsoft-Windows-Sysmon ETW publisher.
    SysmonEmitEventEID1(CreateInfo);
}
```

Four properties of the path matter. First, the callback is invoked **synchronously** on the thread that issued the `CreateProcessW` call, before the new process's first instruction runs; the parent and child PIDs are both known, but the new process has not yet executed any user-mode code. Second, the callback is **rate-limited only by your rule engine** -- there is no built-in throttle, and a verbose `<Include>` rule on a high-process-turnover host can saturate the ETW session. Third, the callback runs at **IRQL = PASSIVE_LEVEL**, so it can do file I/O (which the driver needs for hashing) but it must do that I/O carefully to avoid deadlock on the very file system it is monitoring. Fourth, the Sysmon service runs as a separate user-mode process; if the service has crashed or been suspended, the driver continues to emit ETW events into a session with no listener and they evaporate.

<Definition term="ProcessGuid">
Sysmon's per-process unique identifier, formatted as a 128-bit GUID and recorded as the `ProcessGuid` field on every event that names a process. Unlike a Windows process ID, the ProcessGuid survives PID reuse and uniquely identifies a process across its lifetime [@sysmon-ms-learn]; SOC tooling commonly joins on `(DeviceId, ProcessGuid)` to reconstruct process trees and avoid the PID-reuse race condition that plagues raw `ProcessId` joins.
</Definition>

### Where the events go

Once the user-mode `Sysmon.exe` service has labelled the event, it does two things. First, it writes the event to the Windows event log -- specifically to `Applications and Services Logs/Microsoft/Windows/Sysmon/Operational` per Microsoft Learn's verbatim statement: "*On Vista and higher, events are stored in `Applications and Services Logs/Microsoft/Windows/Sysmon/Operational`*" [@sysmon-ms-learn]. Second, the same event is also visible to any ETW real-time consumer subscribed to `Microsoft-Windows-Sysmon` -- which is how downstream collectors (Windows Event Forwarding, Splunk's universal forwarder, the Elastic Endpoint integration, Wazuh's Windows agent) actually pick the events up, rather than tailing the event log XML.

<Mermaid caption="Sysmon's collection-and-emission pipeline. Six kernel-side input mechanisms converge on the Sysmon driver; two ETW consumers (DNS-Client kernel provider and WMI activity provider) join them; SysmonDrv.sys republishes events through the Microsoft-Windows-Sysmon ETW provider; the Sysmon.exe service persists events to the Operational event log.">
flowchart LR
    K1["PsSetCreateProcessNotifyRoutineEx"] --> D[SysmonDrv.sys]
    K2["PsSetLoadImageNotifyRoutine"] --> D
    K3["PsSetCreateThreadNotifyRoutineEx"] --> D
    K4["ObRegisterCallbacks (PsProcessType)"] --> D
    K5["CmRegisterCallbackEx"] --> D
    K6["FltRegisterFilter (file system + NPFS)"] --> D
    K7["ETW consumer: DNS-Client + WMI activity"] --> D
    D --> P["ETW publisher: Microsoft-Windows-Sysmon"]
    P --> S[Sysmon.exe service]
    S --> L["Applications and Services Logs / Microsoft / Windows / Sysmon / Operational"]
    P --> R["Real-time ETW consumers (WEF, Splunk UF, Wazuh, Elastic)"]
</Mermaid>

This is the first aha moment. Sysmon is not "ETW based" in the way most blog posts imply. Sysmon is *a kernel driver that uses ETW as its IPC bus to user mode*, and as a special-case consumer for one provider (DNS-Client). The reason Sysmon needed a kernel driver in the first place is that ETW alone could not see what the kernel callbacks see: ETW could not, in 2014, deliver a synchronous parent-PID-and-image-hash structure at process create time. Sysmon's driver does that work; ETW transports the result.

The protected-process gate added in v15 (June 2023) closed the most-trivial blinding attack -- a SYSTEM-privilege process can no longer issue `OpenProcess(PROCESS_TERMINATE)` against the Sysmon service to silence it. Raising the bar to a kernel-mode primitive does not eliminate the attack class, but it does change the cost model. The protected-process gate is the architectural inflection that distinguishes pre-v15 Sysmon (trivially blindable) from post-v15 Sysmon (requires a kernel primitive or a BYOVD chain) [@sysmon-ms-learn][@bleepingcomputer-sysmon15].

Five collection mechanisms, one ETW publisher, one event log. That is the input side. Now the catalogue.

## 4. The Sysmon Event Catalogue: Twenty-Nine IDs and Their Version Gating

Run `sysmon -s` on any v15.2 host and you get an XML schema enumerating twenty-nine event types plus EID 255 (Error). Every detection-engineering corpus in the field -- SwiftOnSecurity's config, Florian Roth's fork, Hartong's modular, the SigmaHQ rule base, the Threat Hunter Playbook -- is downstream of this single schema [@sysmon-ms-learn][@github-sigma][@github-otrf-thp]. Learn the catalogue once and the rest of the Sysmon toolchain unfolds from it.

A naming disambiguation is worth doing first, because the colloquial event names the field uses (and that the topic input for this article uses verbatim) differ from the canonical Microsoft Learn names. "RegistrySet" is a colloquial pun on `RegistryEvent (Value Set)`, EID 13. "DnsQuery" is a colloquial shorthand for `DNSEvent (DNS query)`, EID 22. "NamedPipeConnect" is two events at once: `PipeEvent (Pipe Created)`, EID 17, and `PipeEvent (Pipe Connected)`, EID 18. The article uses the canonical Microsoft Learn names from here on.

> **Note:** Sysmon's manifest names some events as a family with a parenthetical operation: `RegistryEvent (Object create and delete)` (EID 12), `RegistryEvent (Value Set)` (EID 13), `RegistryEvent (Key and Value Rename)` (EID 14). The same pattern applies to the pipe events: `PipeEvent (Pipe Created)` (EID 17) and `PipeEvent (Pipe Connected)` (EID 18). When detection-rule tooling references "EID 12-14" or "EID 17-18", these families are what it means. The colloquial single-name forms used elsewhere in the literature are not wrong; they are just less precise. The MDE schema does not preserve the parenthetical operation suffix; it surfaces these as `ActionType` values inside `DeviceRegistryEvents`.

### The twenty-nine plus one catalogue

The catalogue groups naturally by the collection mechanism that produces each event:

| EID | Canonical name | Collection mechanism | Introduced | Maps to (MDE) |
|-----|----------------|----------------------|------------|---------------|
| 1 | ProcessCreate | `PsSetCreateProcessNotifyRoutineEx` | v1.0 (Aug 2014) | `DeviceProcessEvents` (`ProcessCreated`) |
| 2 | FileCreateTime | Filter Manager | v1.0 (Aug 2014) | `DeviceFileEvents` (`FileCreated`, partial) |
| 3 | NetworkConnect | Internal network-callout | v1.0 (Aug 2014) | `DeviceNetworkEvents` (`ConnectionSuccess`) |
| 4 | ServiceStateChange | Sysmon-internal | v1.0 (Aug 2014) | (Sysmon-only) |
| 5 | ProcessTerminate | `PsSetCreateProcessNotifyRoutineEx` | v1.0 (Aug 2014) | `DeviceProcessEvents` (`ProcessTerminated`) |
| 6 | DriverLoad | `PsSetLoadImageNotifyRoutine` (kernel-mode case via `IMAGE_INFO.SystemModeImage`) | v2.0 (2015) | `DeviceEvents` (`DriverLoad`) |
| 7 | ImageLoad | `PsSetLoadImageNotifyRoutine` | v2.0 (2015) | `DeviceImageLoadEvents` |
| 8 | CreateRemoteThread | `PsSetCreateThreadNotifyRoutineEx` (with `CREATE_REMOTE` flag) | v3.0 (2016) | `DeviceEvents` (truncated) |
| 9 | RawAccessRead | `\Device\Harddisk*` write filter | v3.0 (2016) | (Sysmon-only) |
| 10 | ProcessAccess | `ObRegisterCallbacks` (PsProcessType) | v6.0 (Feb 2017) | `DeviceEvents` (GrantedAccess truncated) |
| 11 | FileCreate | Filter Manager | v6.0 (Feb 2017) | `DeviceFileEvents` |
| 12 | RegistryEvent (Object create/delete) | `CmRegisterCallbackEx` | v6.0 (Feb 2017) | `DeviceRegistryEvents` |
| 13 | RegistryEvent (Value Set) | `CmRegisterCallbackEx` | v6.0 (Feb 2017) | `DeviceRegistryEvents` |
| 14 | RegistryEvent (Key/Value Rename) | `CmRegisterCallbackEx` | v6.0 (Feb 2017) | `DeviceRegistryEvents` |
| 15 | FileCreateStreamHash | Filter Manager | v6.0 (Feb 2017) | (Sysmon-only) |
| 16 | ServiceConfigurationChange | Sysmon-internal | v6.0 (Feb 2017) | (Sysmon-only) |
| 17 | PipeEvent (Pipe Created) | Filter Manager minifilter on NPFS (`\Device\NamedPipe`) | v6.0 (Feb 2017) | (Sysmon-only) |
| 18 | PipeEvent (Pipe Connected) | Filter Manager minifilter on NPFS (`\Device\NamedPipe`) | v6.0 (Feb 2017) | (Sysmon-only) |
| 19 | WmiEvent (filter) | WMI ETW provider consumer | v6.10 (mid-2017) | (Sysmon-only) |
| 20 | WmiEvent (consumer) | WMI ETW provider consumer | v6.10 (mid-2017) | (Sysmon-only) |
| 21 | WmiEvent (consumer-to-filter binding) | WMI ETW provider consumer | v6.10 (mid-2017) | (Sysmon-only) |
| 22 | DNSEvent (DNS query) | ETW consumer of `Microsoft-Windows-DNS-Client` | v10.0 (Jun 2019) | `DeviceNetworkEvents` (`DnsQuery`) |
| 23 | FileDelete (archive) | Filter Manager | v11.10 (Jun 2020) | `DeviceFileEvents` (partial) |
| 24 | ClipboardChange | RDP and Win32 clipboard hooks | v13.0 (2021; disputed) | (Sysmon-only) |
| 25 | ProcessTampering | Image-load and `WriteProcessMemory` heuristic | v13.0 (2021; disputed) | (Sysmon-only) |
| 26 | FileDeleteDetected | Filter Manager (non-archiving) | v13.30 (2022) | `DeviceFileEvents` |
| 27 | FileBlockExecutable | Filter Manager (blocking) | v14.0 (Aug 2022) | (Sysmon-only) |
| 28 | FileBlockShredding | Filter Manager (blocking) | v14.10 (2022) | (Sysmon-only) |
| 29 | FileExecutableDetected | Filter Manager | v15.0 (Jun 2023) | `DeviceFileEvents` |
| 255 | Error | Sysmon-internal | v1.0 (Aug 2014) | (Sysmon-only) |

<Sidenote>The Sysmon Version History repository's "Outdated" disclaimer ("*I didn't find enough time to update this repo - sorry*") means the v12 vs v13 boundary for ClipboardChange and ProcessTampering is community-disputed. The canonical Microsoft Learn page does not enumerate version-introduction metadata per event ID. The dates in the table for EIDs 24 and 25 are best-effort community attributions and should be treated as approximate until Microsoft publishes a per-EID version history [@sysmon-version-history][@sysmon-ms-learn].</Sidenote>

### The design intent, in one sentence

The catalogue exists because Sysmon's design choice -- the one Microsoft Learn still prints today -- explicitly refuses to do detection. The publisher emits structured events; the detection logic is somebody else's problem.

<PullQuote>
Sysmon does not provide analysis of the events it generates, nor does it attempt to hide itself from attackers.
</PullQuote>

This is the sentence that explains the entire SwiftOnSecurity-NextronSystems-Hartong configuration lineage [@sysmon-ms-learn]. If Sysmon refuses to do detection, somebody has to write the rules. Three somebodies did, and they wrote three different sets, and the rest of §5 is about the trade-offs between them.

### What EID 27 is, and what it is not

The 2022 introduction of *FileBlockExecutable* (EID 27) was the first preventive event in Sysmon's history. Olaf Hartong's contemporaneous writeup and Diversenok's independent reproduction both describe what the event does, and the mechanism is more subtle than "the I/O is denied." The Sysmon minifilter intercepts the file-handle *close* operation. If the rule matches and the file content carries an MZ/PE header, Sysmon logs EID 27 and marks the file for deletion via `FILE_DISPOSITION_INFORMATION` [@diversenok-2022][@hartong-sysmon14-medium]. The attacker's `cmd /c copy mimikatz.exe C:\Users\Public\` produces no command-line error. The copy appears to succeed. The file is then deleted at handle-close time. Hartong's writeup captures the user-visible effect verbatim: "*While there is no error on the command line, the file is not written to disk*" [@hartong-sysmon14-medium]. Diversenok's reverse-engineering reads: "*Sysmon monitors and deletes files on closing instead of writing*" [@diversenok-2022]. The closing-time semantics is the structural reason Diversenok's `Bypass #1` (split create-close from open-write-close) works at all; the bypass is incoherent under an `Access Denied`-at-create model and obvious under the close-time-delete model.

This is a confined preventive surface, and it should not be confused with the much larger Defender exploit-protection blocking surface. [Defender exploit protection mitigations](/blog/process-mitigation-policies-cfg-acg-cig-and-the-layer-betwee/) include arbitrary-code-guard, control-flow-guard enforcement, and ASR rules -- they sit inside the Defender Antivirus and MDE stacks. EID 27's blocking is one Sysmon minifilter making a file-create decision; it is not a general-purpose application-allow-list, and it is not a substitute for [Windows Defender Application Control](/blog/wdac--hvci-code-integrity-at-every-layer-in-windows/). Hartong's writeup is explicit about the scope -- "*the FileBlockExecutable event*" -- as is Diversenok's: the introduction reads "*the update introduced the first preventive measure -- the FileBlockExecutable event (ID 27)*" [@diversenok-2022].

Twenty-nine events, four hardening releases, one schema. The catalogue is only useful if you configure Sysmon to emit subsets of it, and configuration is where the field's three lineages diverged.

## 5. Three Canonical Sysmon Configurations

Every production Sysmon deployment in the field is forked from one of three repositories. The lineage matters, and one of the things this article fixes is a common attribution error -- "Florian Roth wrote the canonical Sysmon config" is in widespread circulation, but the canonical *root* is SwiftOnSecurity's repository, and Roth's repo is a 2018 fork of it.

<Definition term="Sigma">
The open-source generic-signature-format authored by Florian Roth and his collaborators at Nextron Systems; the SIEM-and-EDR field's vendor-neutral detection-rule lingua franca. The `SigmaHQ/sigma` repository ships over 3,000 detection rules covering the Windows kernel-callback surface (heavily Sysmon-aware), Linux audit, macOS unified log, AWS CloudTrail, Microsoft 365, and other event sources. Sigma rules are written once and compiled by community converters into the per-tool query languages (KQL for Defender XDR / Sentinel, SPL for Splunk, EQL for Elastic) [@github-sigma].
</Definition>

### SwiftOnSecurity/sysmon-config (February 2017)

The historical root. The pseudonymous account *SwiftOnSecurity* published the first widely-cited Sysmon configuration template on **February 1, 2017** per the GitHub REST API [@github-swiftonsecurity-meta]. The README's design intent is the single sentence still printed at the top of the repo: "*This is a Microsoft Sysinternals Sysmon configuration file template with default high-quality event tracing*" [@github-swiftonsecurity]. The template emphasises clarity over coverage; the XML is heavily commented, and the rule structure follows a deliberately conservative pattern of `<Include>` blocks per technique.

SwiftOnSecurity's config is the most-cited starting point for Sysmon deployments worldwide and the one that detection-engineering tutorials default to. It is also the *parent* of every other Sysmon-config repository on GitHub, in the literal GitHub-fork sense -- the GitHub REST API for both NextronSystems/sysmon-config and (via the historical fork-graph) other community configs returns `SwiftOnSecurity/sysmon-config` as the parent [@github-nextronsystems-meta].

### Neo23x0/sysmon-config, now NextronSystems/sysmon-config (January 2018, renamed 2021)

Florian Roth, working under his GitHub handle `@Neo23x0`, forked SwiftOnSecurity's config in January 2018 and added blocking-rule support for Sysmon v14 plus the merged community pull-request set. The README's design intent reads: "*This is a forked and modified version of @SwiftOnSecurity's sysmon config. ... We merged most of the 30+ open pull requests*" [@github-neo23x0]. The maintainer roster as of the present writing is Florian Roth (`@Neo23x0`), Tobias Michalski (`@humpalum`), Christian Burkard (`@phantinuss`), and Nasreddine Bencherchali (`@nas_bench`).

The repository ships a *blocking* variant, `sysmonconfig-export-block.xml`, that adds `<RuleGroup>` blocks targeting EID 27 (FileBlockExecutable) and EID 28 (FileBlockShredding) for the most common malware-staging file paths. This is the variant SOC teams deploy when they want Sysmon's preventive surface to participate in the response pipeline as a hard block rather than as a detection-only artifact.

<Aside label="A note on the Neo23x0 to NextronSystems URL transition">
The legacy URL `https://github.com/Neo23x0/sysmon-config` now HTTP-301 redirects to `https://github.com/NextronSystems/sysmon-config`. The GitHub REST API for the current repository returns `created_at: 2021-07-24T06:19:41Z` with `parent: SwiftOnSecurity/sysmon-config`, which means the repository as it now exists was created in mid-2021 when Florian Roth moved it from his personal handle to his employer's organization namespace [@github-nextronsystems-meta]. The content lineage from SwiftOnSecurity is unchanged; the move is an organizational one. The exact pre-rename creation date of the original `Neo23x0/sysmon-config` repository is not reliably retrievable from the current API and is best dated as January 2018 based on the README and the fork-history.
</Aside>

### olafhartong/sysmon-modular (January 13, 2018)

Olaf Hartong's `sysmon-modular` was created on January 13, 2018 per the GitHub REST API [@github-hartong-meta]. The repository's design takes a different shape from the monolithic SwiftOnSecurity and NextronSystems configs: instead of one carefully-tuned XML, Hartong publishes a per-EID-per-technique module library that compiles into one of five pre-generated artifacts plus an arbitrary number of custom builds [@github-hartong-modular]. The pre-generated variants are:

- `sysmonconfig.xml` -- the default deployment baseline.
- `sysmonconfig-with-filedelete.xml` -- default plus the EID 23 archive variant of file delete, which preserves the deleted file in `C:\Sysmon\` (volume-cost trade-off; recommend dedicated drive).
- `sysmonconfig-excludes-only.xml` -- the verbose variant, which captures everything except a small set of well-known exclusions; useful for detection-engineering R&D on a single host.
- `sysmonconfig-research.xml` -- the super-verbose variant, with the README's standing warning: "*really DO NOT USE IN PRODUCTION!*" -- this is for live-malware-sample analysis in a sandbox, not for fleet rollout.
- `sysmonconfig-mde-augment.xml` -- the variant whose entire design intent is to augment Microsoft Defender for Endpoint's collection surface "*to have as little overlap as possible*" with what MDE already captures [@github-hartong-modular].

The MDE-augment config is the artifact this article keeps returning to. It is the operational answer -- maintained by a person, not by Microsoft -- to the question of which Sysmon events are worth collecting on a host that already has MDE installed. We will return to its specific contents in §10. For now, the key observation is that this config exists because of a documented absence: Microsoft has not published a per-`ActionType` cross-walk between MDE's `Device*` schema and Sysmon's manifest, so Hartong reverse-engineered one.

### Side-by-side comparison

| Dimension | SwiftOnSecurity/sysmon-config | NextronSystems/sysmon-config (formerly Neo23x0) | olafhartong/sysmon-modular |
|-----------|-------------------------------|-------------------------------------------------|----------------------------|
| Author / org | SwiftOnSecurity (pseudonymous) | Florian Roth + Nextron Systems team | Olaf Hartong (and FalconForce collaborators) |
| Created | Feb 1, 2017 | Forked Jan 2018; renamed Jul 24, 2021 | Jan 13, 2018 |
| Distribution | One monolithic XML | Two XMLs (audit + blocking) | Modular per-technique + five pre-generated builds |
| Design philosophy | Quality starting point, conservative | Community-maintained, blocking-aware | Tunable modular, MITRE ATT&CK-mapped |
| Best used for | First-time Sysmon deployment | Standalone Sysmon at scale | Sysmon alongside MDE, or per-team customization |
| Pre-generated v14+ blocking | No (audit only) | Yes (`sysmonconfig-export-block.xml`) | Yes (built from blocking modules) |
| MDE coexistence variant | No | No | Yes (`sysmonconfig-mde-augment.xml`) |

### Choosing among the three

The detection-engineering trade-off framing is short. Pick SwiftOnSecurity when you want a clean, well-commented starting point and you are not yet sure which events you actually need. Pick NextronSystems when you want a community-maintained baseline that already has the blocking rules for Sysmon v14+. Pick Hartong when you want fine-grained per-technique tunability or, more commonly, when you are running MDE and need Sysmon to augment rather than duplicate it.

Tactical caution worth one inline note: Sysmon supports **one active configuration at a time**. There is no aggregate-multiple-XMLs feature at the driver layer. Hartong's modular approach generates a single merged XML at build time; the production fleet receives that single XML and the driver enforces it. If you are trying to run two configurations side by side -- one for the SOC's hunting, one for the platform team's audit -- pick one, merge the rules, and ship the combined product. The deployment tooling in `sysmon-modular` is built around exactly this constraint.

All three configurations assume the same thing: either Sysmon is the only EDR on the host (a deployment posture that exists in air-gapped, regulatory-no-cloud, or unlicensed environments) or it is augmenting an EDR whose collection surface is known. The augment case is the one where the field has converged on Hartong. To understand why, we have to look at what the *other* EDR -- Microsoft's own -- actually collects on the host.

## 6. Microsoft Defender for Endpoint: The Documented On-Host Surface

Two questions about MDE have very different answers. *What does Microsoft Defender for Endpoint run on this host?* has a primary-source-quality answer from Microsoft Learn. *What does it actually do?* has only a community-observed answer. The documented surface is the user-mode component inventory plus registry hives and event sources. The community-observed surface includes the kernel-callback inventory, the cloud TLS-pinning details, and the inter-process communication paths -- none of which Microsoft has published. Naming both halves with the right citations on each side is one of the few things this article does that other writeups skip.

### The documented surface (Microsoft Learn, primary)

On every onboarded Windows endpoint, Microsoft Defender for Endpoint installs and runs a Windows service named **`Sense`**, whose display name is "Microsoft Defender for Endpoint Service" and whose backing executable is `MsSense.exe`. The on-host troubleshooting page documents the canonical health-check command: `sc query sense` [@sense-troubleshoot]. On Windows Server 2019, Server 2022, Server 2025, and Azure Stack HCI 23H2 or later, MDE is delivered as a *Feature on Demand* with the capability name `Microsoft.Windows.Sense.Client~~~~`. Microsoft documents the verification command verbatim: "*DISM.EXE /Online /Get-CapabilityInfo /CapabilityName:Microsoft.Windows.Sense.Client~~~~*" [@sense-troubleshoot][@ms-server-endpoints-learn].

Onboarding state is recorded under two registry hives that Microsoft Learn names explicitly:

- `HKLM\SOFTWARE\Policies\Microsoft\Windows Advanced Threat Protection` -- the policy-driven configuration surface.
- `HKLM\SOFTWARE\Microsoft\Windows Advanced Threat Protection\Status` -- the run-time onboarding state.

Onboarding diagnostics land in the **`WDATPOnboarding`** event source under the Application event log, with documented event IDs 5, 10, 15, 30, 35, 40, 65, and 70, each of which corresponds to a specific failure mode with a specific resolution procedure [@sense-troubleshoot]. The product installs to `C:\Program Files\Windows Defender Advanced Threat Protection\` (the legacy path is preserved even after the September 2020 rebrand).

The documented surface stops here. Microsoft Learn names `MsSense.exe`, the `Sense` service, the registry hives, the event source, the Feature on Demand, and the four operating systems. Microsoft Learn does *not* publish a kernel-callback inventory for the MDE EDR sensor.

### The community-observed surface

Past the documented boundary, what is in field-published primary sources is the user-mode binary inventory and the cloud-side TLS path. Three companion binaries sit alongside `MsSense.exe`:

- **`SenseCncProxy.exe`** is the cloud-command-and-control proxy. This is the binary that holds the TLS connection out to Defender XDR ingest, applies the certificate-pinning policy, and shuttles agent-bound commands (live-response actions, custom-detection-rule pushes, sensor-configuration updates) back down to `MsSense.exe`.
- **`SenseIR.exe`** is the live-response and investigation actions binary. When a SOC analyst clicks **Run script** or **Collect investigation package** in the Defender XDR portal, `SenseIR.exe` is the process that fulfils the request on the endpoint side.
- **`SenseNdr.exe`** is the network detection and response component, responsible for endpoint-side enrichment of network observations used in the `DeviceNetworkEvents` table.

These binaries are not enumerated on Microsoft Learn in the same way the `Sense` service itself is. They are documented in MDE incident-response runbooks, in third-party reverse-engineering posts, and in the file-system signature data on any onboarded endpoint. The article treats their existence as community-observed. `SenseIR.exe` is corroborated by InfoGuard 2025's reverse-engineering of MDE's live-response cloud path [@infoguard-2025]; `SenseNdr.exe` in particular lacks an explicit community primary writeup as of 2026 -- its role here is inferred from its on-disk binary metadata and the file-system signature data on onboarded endpoints.

The kernel-side surface MDE shares with Defender Antivirus *is* documented in the Defender Antivirus product line [@ms-defender-av-arch]:

- **`WdBoot.sys`** is the **Early-Launch Antimalware (ELAM)** driver. It is the first non-Windows driver to load at boot and gates which non-ELAM drivers are allowed to load after it. It is signed with the **Antimalware Extended Key Usage**, `1.3.6.1.4.1.311.61.4.1` [@ms-learn-elam-sample].
- **`WdFilter.sys`** is the Defender Antivirus file-system minifilter. It sits alongside `SysmonDrv.sys` at a different Filter Manager altitude.
- **`WdNisDrv.sys`** is the Network Inspection System driver, which provides the host-firewall-augmenting NIS layer.

<Definition term="Protected Process Light (PPL)">
A Windows process-protection level, introduced in Vista (as Protected Process, for DRM) and extended in Windows 8.1 (for antimalware), that prevents user-mode debugger attach, code injection, and `OpenProcess` for write from any caller that does not itself run at an equal or higher PPL signer level. Antimalware-PPL (`PROTECTED_ANTIMALWARE_LIGHT`) is the level reserved for security products signed with the Antimalware EKU; `MsSense.exe` and Sysmon v15+ both run at this level.
</Definition>

<Definition term="Early-Launch Antimalware (ELAM)">
The Windows boot-order privilege that lets a driver signed with the Antimalware EKU `1.3.6.1.4.1.311.61.4.1` [@ms-learn-elam-sample] load before any non-ELAM driver and classify subsequent boot-start drivers as `Good`, `Bad`, or `Unknown` so the kernel can decide which to load. The ELAM driver *itself* is measured (along with the bootloader, kernel, and other early-boot artefacts) into TPM PCRs by Windows's *Measured Boot*, which is a separate boot-integrity feature; ELAM's job is to classify, not to measure. Defender Antivirus's `WdBoot.sys` is the canonical ELAM driver. Sysmon's `SysmonDrv.sys` is *not* ELAM-signed; this is the pre-driver-load horizon discussed in §12.
</Definition>

<Definition term="Antimalware EKU">
The Authenticode Extended Key Usage `1.3.6.1.4.1.311.61.4.1` [@ms-learn-elam-sample], issued by Microsoft to security vendors after a code-signing and behavioral review. The EKU gates two distinct things: ELAM signing eligibility (so the driver loads first) and Antimalware-PPL eligibility for the user-mode service (so the service is harder to tamper with). MDE's `MsSense.exe`, Defender Antivirus's `MsMpEng.exe`, and Sysmon v15+ all carry this signature path.
</Definition>

### Antimalware-PPL on MsSense.exe

The `MsSense.exe` service runs as **[Antimalware-PPL](/blog/protected-process-light-when-the-administrator-isnt-enough/)** -- `PROTECTED_ANTIMALWARE_LIGHT` in the kernel data structure. The protection level prevents an attacker with SYSTEM privileges from attaching a user-mode debugger, suspending the service, or injecting code into its address space using ordinary Windows debugging or code-injection APIs. This is the same protection level Sysmon v15+ runs at, and it is the same level Defender Antivirus's `MsMpEng.exe` has run at since Windows 8.1. The structural defense closes user-mode tampering as a class. The residual attack surface is kernel-mode primitives -- which is what FalconForce had to use in 2022 to debug MDE [@falconforce-2022].

### The dispositive reverse-engineering primary: FalconForce 2022

Olaf Hartong and Henri Hambartsumyan, working at FalconForce, published the most-cited reverse-engineering writeup of MDE's on-host architecture in 2022. The post's TL;DR captures both the debug-bypass technique and the cloud vulnerability that resulted from applying it:

<PullQuote>
You can debug MDE running on an endpoint by running `dbgsrv.exe` and raising its PPL protection to WinTcb. This can be used to snoop on data being transmitted by MDE to the cloud. We identified a vulnerability related to missing authorization checks of data sent from the MDE endpoint to the M365 cloud, allowing anyone to send spoofed data to any M365 tenant.
</PullQuote>

The technique is precise [@falconforce-2022]. FalconForce raised the PPL signer level of Windows's PE debug server (`dbgsrv.exe`) to `WinTcb` -- a signer level *higher* than Antimalware-PPL -- and used the elevated debug server to attach to `MsSense.exe`. From inside that debug session they instrumented `SspiCli!EncryptMessage`, the SSPI function MDE's cloud transport uses to wrap each outbound message before TLS encryption, and captured the plaintext payloads. The plaintext capture surfaced **CVE-2022-23278**: a missing-authorization vulnerability in which the M365 cloud trusted whatever device-identifying claims the endpoint asserted, with no cross-check that the asserting endpoint owned the device identity it claimed [@msrc-cve-2022-23278][@nvd-cve-2022-23278]. Microsoft patched the vulnerability on March 8, 2022, with a public acknowledgement to FalconForce: "*Microsoft released a security update to address CVE-2022-23278 in Microsoft Defender for Endpoint. This important class spoofing vulnerability impacts all platforms. We wish to thank Falcon Force for the collaboration on addressing this issue through coordinated vulnerability disclosure*" [@msrc-cve-2022-23278].

> **Note:** The kernel-and-Defender-Antivirus surface MDE shares (`WdBoot.sys` ELAM, `WdFilter.sys` minifilter, `WdNisDrv.sys` NIS) is documented. The specific callback inventory the MDE EDR sensor itself registers is not. The community's best-published primary for what `MsSense.exe` actually does is the FalconForce 2022 reverse-engineering writeup -- and it covers a narrow slice (TLS interception and one cloud-authorization bug), not a full callback list. The Hartong `sysmonconfig-mde-augment.xml` config exists *as a community-curated artifact* precisely because Microsoft has not published a per-`ActionType`-to-per-kernel-callback cross-walk. The most-cited operational config in the field is downstream of a documentation gap. This is the second aha moment of the article.

### Putting the on-host pieces together

<Mermaid caption="Microsoft Defender for Endpoint on-host architecture. The Defender Antivirus kernel drivers (WdBoot ELAM, WdFilter minifilter, WdNisDrv NIS) feed the MsSense aggregator. Companion binaries SenseIR and SenseNdr sit alongside. SenseCncProxy holds the TLS-with-cert-pinning connection to the Defender XDR cloud.">
flowchart TD
    B["WdBoot.sys (ELAM, Antimalware EKU)"] -.boot order.-> F["WdFilter.sys (file minifilter)"]
    B -.boot order.-> N["WdNisDrv.sys (Network Inspection)"]
    F --> M["MsSense.exe (Antimalware-PPL aggregator)"]
    N --> M
    M --> IR["SenseIR.exe (Live Response)"]
    M --> NDR["SenseNdr.exe (Network Detection)"]
    M --> P["SenseCncProxy.exe (cloud forwarder)"]
    P -- "TLS + certificate pinning" --> C["Defender XDR ingest (regional Kusto)"]
</Mermaid>

The picture is asymmetric: the kernel-driver substrate at the top is documented in the Defender Antivirus product line; the user-mode service inventory in the middle is documented for `MsSense.exe` and partly documented for the companion binaries; the cloud transport at the bottom is documented at the API-contract level (TLS, certificate pinning) but the specific endpoints and the on-the-wire payload format are reverse-engineered. The community published primaries -- FalconForce 2022 above the line, InfoGuard Labs 2025 below it -- are how the field knows what they know about the cloud-bound payload. Which is the next layer.

## 7. The Cloud Pipeline: SenseCncProxy.exe to Defender XDR Ingest

The wire between `MsSense.exe` and Microsoft's cloud is TLS with certificate pinning. It is also, twice in the last four years, the place where the most interesting Defender for Endpoint vulnerabilities have lived. The 2022 round closed one of them. The 2025 round is still open as of this article's writing.

### Certificate pinning and the FalconForce 2022 method

`MsSense.exe` does not trust whatever the Windows certificate store says about the chain to Defender XDR ingest. It pins the certificate. FalconForce's bypass is the one §6 already named: raise `dbgsrv.exe` to `WinTcb` PPL, attach the elevated debug server to `MsSense.exe`, instrument `SspiCli!EncryptMessage` to capture the plaintext payload *before* TLS encryption [@falconforce-2022].

<Sidenote>The specific PPL elevation technique is published in the same writeup. PPLKiller's `/enablePPL` patch writes the Antimalware-PPL bit into `dbgsrv.exe`'s `_EPROCESS.Protection` field at the highest signer level (`WinTcb`). The result: a PE debug server running at a PPL level *above* Antimalware-PPL, with `OpenProcess` rights against any Antimalware-PPL target [@falconforce-2022]. This requires SYSTEM plus a kernel primitive, typically delivered via BYOVD.</Sidenote>

The InfoGuard Labs 2025 follow-up took a different route to the same problem. Instead of reading plaintext before TLS encryption, InfoGuard *patches* the certificate-chain validation function in memory so the endpoint certificate is no longer checked at all. Any local TLS-stripping proxy can then intercept the wire. The verbatim patch is two CPU instructions written into `CRYPT32!CertVerifyCertificateChainPolicy`: "`mov eax, 1; ret`" -- which forces the function to return success without performing any actual chain check [@infoguard-2025].

With the pinning gate disabled, InfoGuard's team observed the on-the-wire protocol. The cloud-bound payload goes to two endpoint families: `/edr/commands/cnc` for command-and-control and `/senseir/v1/actions/` for live-response actions. The vulnerability they then disclosed is that both endpoint families accept "data sent from the MDE endpoint to the cloud ... without validating authentication tokens, allowing a post-breach attacker with a machine's ID to hijack the command-and-control channel" [@infoguard-2025]. Microsoft's response, verbatim: "*All findings were reported to the Microsoft Security Response Center (MSRC) in July 2025. However, Microsoft has classified them as low severity and has not committed to a fix*" [@infoguard-2025].

<Aside label="A pattern that has not yet closed">
FalconForce 2022 found a missing-authorization bug in the cloud's trust path. CVE-2022-23278 was patched. InfoGuard Labs 2025 found a different missing-authorization pattern in different cloud endpoints -- different bug, same class -- and the disclosure record says Microsoft has not committed to a fix. The cloud trusts whatever the endpoint claims about itself far enough that the same authorization gap keeps surfacing. The arc that began with the March 2022 spoofing-CVE patch is not closed. This is the third aha moment of the article, surfaced again in §11.
</Aside>

### What the cloud does on arrival

Once `SenseCncProxy.exe` has TLS-shipped the event over the wire to the regional Defender XDR ingest endpoint, two things happen on the cloud side. First, the event lands in the Advanced Hunting Kusto cluster. Microsoft Learn's verbatim freshness claim is: "*Advanced hunting receives this data almost immediately after the sensors that collect them successfully transmit it to the corresponding cloud services*" [@advanced-hunting-overview]. "Almost immediately" is empirically a few seconds in steady state, which is exactly what Maya saw in §1: a row with `Timestamp` three seconds in the past.

Second, the event is replicated for use by Microsoft's built-in detection rules, MITRE-mapped queries, and the cross-domain correlation surface that joins endpoint events to email events, identity events, and cloud-application events. The cross-domain join is one of the most-cited reasons enterprises stay on the licensed product rather than fall back to standalone Sysmon: KQL can join `DeviceProcessEvents` to `EmailEvents` to `IdentityLogonEvents` in one query, and Sysmon-only deployments cannot do that without a separate SIEM doing the cross-source enrichment.

Data residency is documented at the regional level in the MDE configure-server-endpoints page: "*data is stored in the US for customers in the USA; in EU for European customers; and in the UK for customers in the United Kingdom*" [@ms-server-endpoints-learn]. Retention in-portal is the same quota for all geographies: "*Advanced hunting is a query-based threat hunting tool that you use to explore up to 30 days of raw data*" [@advanced-hunting-overview]. Past 30 days, the customer has to extend the retention surface via Microsoft Sentinel's per-table archiving, which is the operational story §9 picks up.

### The event's journey, end to end

<Mermaid caption="An event's journey from kernel callback to Kusto row, annotated with the two community-disclosed interception points: FalconForce 2022's plaintext capture before TLS encryption, and InfoGuard Labs 2025's in-memory certificate-pinning bypass on the same wire.">
sequenceDiagram
    participant K as Kernel callback (WdFilter or SysmonDrv)
    participant S as MsSense.exe (Antimalware-PPL)
    participant P as SenseCncProxy.exe
    participant CP as CRYPT32!CertVerifyCertificateChainPolicy
    participant C as Defender XDR ingest (regional Kusto)
    participant Q as DeviceProcessEvents table
    K->>S: Synchronous callback notification
    Note over S: Enrich (parent PID, hashes, identity, ProcessGuid)
    S->>S: SspiCli!EncryptMessage (FalconForce 2022 plaintext capture point)
    S->>P: IPC to cloud forwarder
    P->>CP: Validate Defender XDR certificate chain
    CP-->>P: Pinned chain OK (InfoGuard 2025 bypass: patch CP to return 0 unconditionally)
    P->>C: HTTPS POST /edr/commands/cnc or /senseir/v1/actions/
    C->>Q: Write into Kusto cluster
    Note over Q: "Almost immediately" -- seconds end to end
    Q-->>K: Queryable via KQL
</Mermaid>

The diagram is annotated with the two community-disclosed interception points because they are the two places the field has actually been able to observe what is on the wire. Between `SspiCli!EncryptMessage` (where the plaintext payload exists) and `CRYPT32!CertVerifyCertificateChainPolicy` (where the certificate chain gets validated), the path is otherwise opaque to external researchers. The Microsoft-published side of the story is the contractual one: TLS, certificate pinning, regional ingest, Kusto cluster, KQL exposure. The reverse-engineered side fills in the rest.

Within seconds, the event appears as a row in `DeviceProcessEvents`. The reader-side schema is where the analyst lives. So: what columns?

## 8. Six `Device*` Tables and One Worked KQL Query

Every detection rule in Microsoft Defender XDR, every hunting query in Microsoft Sentinel, and every analyst pivot Maya does on her console is a KQL query against six load-bearing tables. Knowing those six tables is the price of admission to the Defender XDR field.

<Definition term="KQL (Kusto Query Language)">
Microsoft's data-explorer query language, originally built for Azure Data Explorer (formerly Kusto). KQL reads as a pipeline of operators -- `where`, `project`, `summarize`, `join`, `order by` -- left to right. Advanced Hunting in Microsoft Defender XDR and analytics queries in Microsoft Sentinel both expose the same KQL dialect; the same query text can be moved between the two surfaces with only the table-name namespace changing [@advanced-hunting-overview][@sentinel-xdr-connector].
</Definition>

### The six tables

The six tables that this article calls "load-bearing" are the ones that map most cleanly to Sysmon's manifest and that detection rules join against most often:

- **`DeviceProcessEvents`** -- the canonical reader-side analogue of Sysmon's EID 1 (ProcessCreate) and EID 5 (ProcessTerminate). The schema reference page names roughly fifty columns including `Timestamp`, `DeviceId`, `DeviceName`, `ActionType`, `FileName`, `FolderPath`, `SHA1`, `SHA256`, `MD5`, `FileSize`, `ProcessId`, `ProcessCommandLine`, `ProcessIntegrityLevel`, `ProcessTokenElevation`, `ProcessCreationTime`, `AccountSid`, `AccountName`, `AccountUpn`, `LogonId`, and the full `InitiatingProcess*` family of parent-process columns [@deviceprocessevents-table].
- **`DeviceNetworkEvents`** -- the analogue of Sysmon EID 3 (NetworkConnect) plus EID 22 (DNSEvent) and the MDE-only network-protection telemetry. Columns include `RemoteIP`, `RemotePort`, `RemoteUrl`, `LocalIP`, `LocalPort`, `Protocol`, `RemoteIPType`, and the `InitiatingProcess*` family [@sentinel-xdr-connector].
- **`DeviceFileEvents`** -- the analogue of Sysmon EIDs 11 (FileCreate), 15 (FileCreateStreamHash), 23 (FileDelete archived), and 26 (FileDeleteDetected).
- **`DeviceImageLoadEvents`** -- the analogue of Sysmon EID 7 (ImageLoad).
- **`DeviceRegistryEvents`** -- the analogue of Sysmon EIDs 12-14 (RegistryEvent family).
- **`DeviceEvents`** -- the miscellaneous catch-all. [AMSI](/blog/amsi-the-100-microsecond-window-where-defender-catches-a-bas/) scan results, exploit-protection events, ASR rule fires, Network Protection blocks, and other MDE-specific events that do not fit cleanly into any of the per-event-class tables surface here as `ActionType` discriminators.

Past the six core tables there are siblings the article does not walk in detail but that detection engineers query alongside: `DeviceLogonEvents` (interactive, remote-interactive, network logons), `DeviceFileCertificateInfo` (Authenticode signer information), `DeviceInfo` and `DeviceNetworkInfo` (asset and posture). The cross-domain tables that the Defender XDR portal exposes -- `AlertInfo`, `AlertEvidence`, `IdentityLogonEvents`, `EmailEvents`, `CloudAppEvents` -- are also queryable from the same surface, and the cross-domain join is one of the load-bearing reasons SOC teams move queries from a standalone SIEM into Advanced Hunting [@sentinel-xdr-connector].

### Sysmon EID to MDE table cross-walk

The cross-walk is the table detection engineers actually need at their desk. Every row is a Sysmon EID, the MDE table the analogous event lands in, the `ActionType` discriminator inside that table, and a fidelity rating relative to Sysmon's manifest -- because the MDE schema does *not* surface every Sysmon field, and the fidelity gaps are where Hartong's MDE-augment config earns its keep.

| Sysmon EID | MDE table | ActionType | Fidelity vs Sysmon | Hartong-augment disposition |
|------------|-----------|------------|--------------------|------------------------------|
| 1 ProcessCreate | DeviceProcessEvents | ProcessCreated | Full | Drop (MDE covers) |
| 3 NetworkConnect | DeviceNetworkEvents | ConnectionSuccess | Full | Drop |
| 7 ImageLoad | DeviceImageLoadEvents | ImageLoaded | Full | Drop |
| 8 CreateRemoteThread | DeviceEvents | RemoteThreadCreated | Truncated (no SourceImage hash) | Keep verbose |
| 9 RawAccessRead | (none) | -- | Omitted | Keep |
| 10 ProcessAccess | DeviceEvents | OpenProcessApiCall | Truncated (no GrantedAccess mask) | Keep verbose, narrow targets |
| 11 FileCreate | DeviceFileEvents | FileCreated | Full | Drop |
| 12-14 RegistryEvent | DeviceRegistryEvents | RegistryValueSet etc. | Full | Drop |
| 17-18 PipeEvent | (none) | -- | Omitted | Keep |
| 19-21 WmiEvent | (none) | -- | Omitted | Keep |
| 22 DNSEvent | DeviceNetworkEvents | DnsQuery | Full | Drop |
| 23 FileDelete (archive) | DeviceFileEvents | FileDeleted | Partial (no archive) | Keep archive variant on selected paths |
| 26 FileDeleteDetected | DeviceFileEvents | FileDeleted | Full | Drop |
| 27 FileBlockExecutable | (none) | -- | Omitted (MDE has separate prevent surface) | Keep if Sysmon is enforcing |

The fidelity column is the operational answer to "do I need Sysmon if I have MDE?" Where MDE is *Full*, Sysmon duplicates. Where MDE is *Truncated*, Sysmon adds the fields MDE drops. Where MDE is *Omitted*, Sysmon is the only collection mechanism in the host's telemetry surface. This is the cross-walk that Hartong's `sysmonconfig-mde-augment.xml` implements as XML rules.

### The Kusto Hunt: PowerShell instances that called out within sixty seconds of spawn

The single most-frequently-cited hunting query in the Defender XDR field is some variation of the following. The query joins `DeviceProcessEvents` to `DeviceNetworkEvents` on `(DeviceId, InitiatingProcessId)` and surfaces every PowerShell instance that opened an outbound network connection within sixty seconds of being spawned. This is the query that turns Maya's hunch ("that base64-encoded command looks bad") into a SIEM-routable signal:

```kql
// The Kusto Hunt: PowerShell instances that called out within
// 60s of process create, joined on (DeviceId, InitiatingProcessId).
DeviceProcessEvents
| where Timestamp > ago(24h)
| where FileName =~ "powershell.exe" or FileName =~ "pwsh.exe"
| project DeviceId, ProcessId, ProcessCreationTime = Timestamp,
          ParentImage = InitiatingProcessFileName,
          ParentCmd   = InitiatingProcessCommandLine,
          ProcessCmd  = ProcessCommandLine,
          User        = AccountUpn
| join kind=inner (
    DeviceNetworkEvents
    | where Timestamp > ago(24h)
    | where ActionType == "ConnectionSuccess"
    | project DeviceId, InitiatingProcessId, NetTime = Timestamp,
              RemoteIP, RemotePort, RemoteUrl
) on DeviceId, $left.ProcessId == $right.InitiatingProcessId
| where (NetTime - ProcessCreationTime) between (0s .. 60s)
| where RemoteIP !startswith "10."
    and RemoteIP !startswith "192.168."
    and not(RemoteIP matches regex "^172\\.(1[6-9]|2[0-9]|3[0-1])\\.")
| project DeviceId, ProcessCreationTime, NetTime,
          ParentImage, ProcessCmd, RemoteIP, RemotePort, RemoteUrl, User
| order by NetTime desc
```

The query is twelve operative lines and exercises four of KQL's most useful primitives: `join` (on a tuple key), `between` (for time-window matching), `!startswith` and the regex check (for RFC 1918 exclusion), and `project` (for column shaping). The `between (0s .. 60s)` is the crux. A legitimate PowerShell launched by a logon script may also produce a network connection within the same minute -- the filter is necessary but not sufficient. Adding `ParentImage in ("winword.exe", "excel.exe", "outlook.exe")` narrows the hunt to the Office-spawning-PowerShell pattern that fits the Emotet and Qbot families. Adding `RemoteUrl in (~CustomTI)` narrows the hunt further to known-bad indicators from the tenant's threat-intelligence list.

<RunnableCode lang="js" title="The Kusto Hunt: what the join is doing, conceptually">{`
// JavaScript that walks through the *logic* of the KQL hunt.
// The actual query runs in Advanced Hunting; this runs in your browser
// so you can see the join semantics with a small synthetic dataset.

const processEvents = [
  { DeviceId: "D1", ProcessId: 7700, Timestamp: 100,
    FileName: "powershell.exe",
    InitiatingProcessFileName: "WINWORD.EXE",
    ProcessCommandLine: "powershell.exe -enc JABzAD0A..." },
  { DeviceId: "D2", ProcessId: 4422, Timestamp: 200,
    FileName: "powershell.exe",
    InitiatingProcessFileName: "explorer.exe",
    ProcessCommandLine: "powershell.exe -Help" },
];

const networkEvents = [
  { DeviceId: "D1", InitiatingProcessId: 7700, Timestamp: 130,
    ActionType: "ConnectionSuccess",
    RemoteIP: "185.243.115.84", RemotePort: 443 },
  { DeviceId: "D2", InitiatingProcessId: 4422, Timestamp: 215,
    ActionType: "ConnectionSuccess",
    RemoteIP: "10.0.0.5", RemotePort: 443 },
];

function isPrivate(ip) {
  return ip.startsWith("10.")
      || ip.startsWith("192.168.")
      || /^172\\.(1[6-9]|2[0-9]|3[0-1])\\./.test(ip);
}

const hits = [];
for (const p of processEvents) {
  if (!/^powershell\\.exe$|^pwsh\\.exe$/i.test(p.FileName)) continue;
  for (const n of networkEvents) {
    if (n.DeviceId !== p.DeviceId) continue;
    if (n.InitiatingProcessId !== p.ProcessId) continue;
    if (n.ActionType !== "ConnectionSuccess") continue;
    const dt = n.Timestamp - p.Timestamp;
    if (dt < 0 || dt > 60) continue;
    if (isPrivate(n.RemoteIP)) continue;
    hits.push({ DeviceId: p.DeviceId,
                Parent:   p.InitiatingProcessFileName,
                Cmd:      p.ProcessCommandLine,
                RemoteIP: n.RemoteIP,
                Latency:  dt + "s" });
  }
}

console.log(JSON.stringify(hits, null, 2));
// Expected output: one hit on D1 (WINWORD-spawned powershell to public IP);
// D2 is filtered out (RemoteIP is RFC 1918 private).
`}</RunnableCode>

The semantic of the KQL is the semantic of the JavaScript: a relational join on a composite key, filtered by a time-window predicate and a network-class predicate. The KQL query is shorter and faster; the JavaScript is what the join is actually doing. Once a reader internalizes this pattern, the rest of the Advanced Hunting surface unfolds from it -- every other detection in the field is a variant of "join `Device*` table A to `Device*` table B on `(DeviceId, InitiatingProcessId)`, filter by time and content."

<Sidenote>Advanced Hunting per-query quotas are 100,000 rows of returned data and 10 minutes of execution time per call [@advanced-hunting-overview]. The practical workaround for queries that exceed either limit is to pre-filter with a tighter time window (`Timestamp > ago(1h)` instead of `ago(24h)`), or to push the heavy aggregation into a Sentinel scheduled analytics rule that runs every hour and materializes the result table for further hunting.</Sidenote>

The same query, the same columns, the same six tables surface in two different places: the Defender XDR portal itself (at `security.microsoft.com` legacy or `defender.microsoft.com` current), and inside Microsoft Sentinel via the Defender XDR connector. The two surfaces are not the same.

## 9. The Microsoft Sentinel Integration Model

The same KQL query runs in two different places, but the *economics* of the two places are not the same, and that distinction is the one that catches detection engineers off guard. In-portal Advanced Hunting and Microsoft Sentinel both expose the same `Device*` tables. They do not expose them with the same retention, the same join surface, or the same cost.

### The connector contract

Microsoft Sentinel's **Defender XDR connector** (the post-Ignite-2023 successor to the legacy Microsoft 365 Defender connector) streams Microsoft Defender XDR incidents, alerts, and Advanced Hunting events into Sentinel's Log Analytics workspace. Microsoft Learn's verbatim definition is: "*The Defender XDR connector allows you to stream all Microsoft Defender XDR incidents, alerts, and advanced hunting events into Microsoft Sentinel and keeps incidents synchronized between both portals*" [@sentinel-xdr-connector]. The connector exposes per-table streaming, meaning the operator picks which `Device*` tables to bring into Sentinel and pays per-GB ingestion only on those tables.

The connector also handles the legacy-connector transition: when enabled, "*any Microsoft Defender components' connectors that were previously connected are automatically disconnected in the background*" [@sentinel-xdr-connector]. If a tenant was using the legacy Microsoft Defender ATP connector or per-product Defender connectors, those get retired when the unified Defender XDR connector takes over. This is the cleanup detail that catches teams off guard during the migration -- they expect both connectors to coexist for the transition window, and they do not.

### Three asymmetries

The in-portal Advanced Hunting surface and the Sentinel surface differ on three practitioner-level axes:

| Dimension | In-portal Advanced Hunting | Sentinel + Defender XDR connector |
|-----------|----------------------------|------------------------------------|
| Retention | 30 days of raw data per query [@advanced-hunting-overview] | Configurable per-workspace, up to 12 years archive [@sentinel-xdr-connector][@ms-log-analytics-archive] |
| Query surface | Six core `Device*` tables plus cross-domain `AlertInfo` / `EmailEvents` / `IdentityLogonEvents` / `CloudAppEvents` | Six core `Device*` tables (per-table selection) plus the entire Log Analytics workspace -- third-party logs, custom tables, ASIM-normalized data |
| Cost | Included with MDE Plan 2 license | Per-GB Sentinel ingestion (current GA tier) plus per-GB archive |
| Detection authoring | Custom detection rules; in-portal advanced-hunting-to-alert promotion | Scheduled analytics rules; SOAR playbook triggers; automation rules |
| Cross-tenant hunting | Tenant-bound only | Possible via Lighthouse / Sentinel Workspaces aggregation |
| Live response triggers | In-portal action surface | Via Logic Apps / Defender API connector |

The in-portal economics are predictable: the queries are included with the license, the retention is uniform at thirty days, the surface is the six tables plus the cross-domain entity catalogue. The Sentinel economics are flexible but billable: longer retention, more table coverage, more automation, all of which carry per-GB ingestion charges. The choice is operational: which queries does the team need to run on data older than thirty days?

### When each surface is the right one

For the SOC-analyst-driven, real-time threat-hunting workflow that §1 modeled with Maya -- thirty days back, six tables, cross-domain join into `AlertInfo` -- the in-portal Advanced Hunting surface is the obvious fit. For the longer-retention, multi-source, automated-analytic-rule workflow -- where detection engineers want a scheduled rule that joins `DeviceProcessEvents` to a third-party identity log on a normalized schema -- the Sentinel surface is the obvious fit.

The two surfaces are not exclusive. The most-cited operational pattern in 2026 is to keep the in-portal surface as the SOC-analyst hunting console (retention 30 days, no cost) and to run the Defender XDR connector into Sentinel for the subset of tables the team needs longer retention or analytics-rule scheduling on. Per-table selection keeps the per-GB ingestion bill predictable.

<Sidenote>The Sentinel connector preserves table names but namespaces them inside the Log Analytics workspace; `DeviceProcessEvents` in Sentinel is the same shape as `DeviceProcessEvents` in the Defender XDR portal, and most queries port between the two surfaces unchanged. Some columns are renamed at the connector boundary -- the most common gotcha is the time-zone and timestamp representation -- but the join semantics and the cross-walk to Sysmon EIDs do not change.</Sidenote>

### The portal-URL transition

A small operational detail worth naming: the Defender XDR portal lives at both `security.microsoft.com` (legacy, still functional) and `defender.microsoft.com` (current). The new URL was announced as part of the Microsoft 365 Defender to Microsoft Defender XDR rebrand at Ignite 2023 [@defender-xdr-ms-learn][@ms-ignite-2023-blog]. The rebrand changed neither the KQL substrate nor the `Device*` schema; queries written against the legacy URL behave identically against the new URL. This is the disambiguation §1 alluded to in its layer-7 description: the same KQL query, the same tables, against either URL.

Two query surfaces, six tables, twenty-nine Sysmon EIDs, and one operational question every SOC manager has asked at least once: *do we deploy Sysmon alongside Defender for Endpoint, or trust Defender alone?* That is §10.

## 10. Sysmon Plus MDE: Three Coexistence Patterns

This is the operational question of the article. The community has converged on three answers, and one of them is wrong for almost every MDE-licensed environment. The three options, in order of increasing complexity and -- in most enterprise contexts -- decreasing prevalence:

### Option A: Sysmon only, no MDE

Used in air-gapped environments, unlicensed environments, and regulatory contexts that prohibit cloud-side telemetry. Sysmon on its own produces a complete event stream into the local Windows event log, which a downstream collector (Windows Event Forwarding to a central collector, Splunk's Universal Forwarder, Wazuh's Windows agent, the Elastic Endpoint integration) picks up and ships to a customer-controlled SIEM. The trade-off: no cross-tenant correlation, no cloud-side threat-intelligence join, no `EtwTi` (kernel security ETW provider) consumption, no Microsoft-authored detection rules. The customer owns every rule themselves.

This is the right answer in a small set of contexts and the wrong answer in the licensed-enterprise context where MDE is already deployed.

### Option B: MDE only, no Sysmon

The Microsoft-recommended baseline for licensed environments. MDE's `Device*` schema covers the high-value Sysmon EID surface -- 1, 3, 7, 10, 11, 12-14 -- at full or near-full fidelity, and MDE adds the layers Sysmon does not have: cloud-side correlation, cross-domain joins (email, identity, cloud apps), Microsoft-authored built-in detection rules with continuous tuning, the `AlertInfo`/`AlertEvidence` evidence graph, and the SOC-actionable surface (device isolation, live response, automated investigation) [@mde-ms-learn][@ms-mitre-2024-blog].

For most MDE-Plan-2-licensed organizations without a mature detection-engineering team, Option B is the right baseline. The trade-off is that the truncations and omissions in the `Device*` schema -- the `ProcessAccess` GrantedAccess mask Sysmon EID 10 surfaces verbatim that MDE drops, the WMI consumer expressions Sysmon EIDs 19-21 capture that MDE does not surface, the RawAccessRead and PipeEvent classes Sysmon captures that MDE omits entirely -- are not available to the team's custom hunting queries. For an organization without the engineering capacity to build hunting rules on those verbose surfaces, this is rarely a binding constraint.

### Option C: MDE plus tuned Sysmon (Hartong's MDE-augment)

The detection-engineering-community pattern. Run MDE as the primary EDR. Run Sysmon alongside it with `olafhartong/sysmon-modular`'s `sysmonconfig-mde-augment.xml` configuration, whose explicit README design intent is "*intended to augment the information and have as little overlap as possible*" with MDE [@github-hartong-modular]. The augment config drops the EIDs MDE covers cleanly (1, 3, 7, 11, 12-14, 22) and keeps the EIDs MDE truncates or omits (8 with full SourceImage, 9 RawAccessRead, 10 with full GrantedAccess mask, 15 FileCreateStreamHash, 17-18 PipeEvent, 19-21 WmiEvent, 23 with archive variant on narrowly-scoped paths). The result is a Sysmon event-log stream that is purpose-built to complement MDE's Kusto stream, not duplicate it.

> **Key idea:** If you are an MDE-licensed shop with a detection-engineering team and you are *not* running Hartong's `sysmonconfig-mde-augment.xml`, you are paying for two EDRs and getting the coverage of one. The augment config was purpose-built to make Sysmon's verbose-field surface complementary to MDE's cloud-correlation surface, not a duplicate. Standalone Sysmon next to MDE without the augment-specific exclusions is the worst of both worlds: double telemetry volume, double licensing exposure, and no incremental detection coverage.

### Cost and operational complexity

The three options have different operational profiles. The summary table:

| Pattern | License posture | Telemetry volume | Operational complexity | Best used for |
|---------|-----------------|------------------|------------------------|---------------|
| A. Sysmon only | None (free) | Medium (depends on config) | Low (one product, one config) | Air-gapped, regulatory-no-cloud, unlicensed |
| B. MDE only | MDE Plan 1 or Plan 2 | Cloud-controlled (no per-host volume bill) | Low (one product, Microsoft-managed) | Most MDE-licensed orgs without detection-engineering team |
| C. MDE + Hartong augment | MDE Plan 2 + WEF or SIEM | High on Sysmon side (verbose EIDs); low on MDE side | High (two products, modular config, WEF or SIEM forwarder) | Detection-engineering-mature SOCs |

A small operational caution: standalone Sysmon next to MDE without the augment-specific exclusions is the worst of three worlds. The drivers coexist fine at different Filter Manager altitudes, but the event log and downstream collector now carry every Sysmon EID the default config emits plus everything MDE collects on the cloud side. The double-pay problem the KeyIdea calls out is not theoretical; it shows up the first month a SOC team forgets to swap the default `sysmonconfig.xml` for `sysmonconfig-mde-augment.xml`.

The Hartong-augment-with-MDE pattern carries a second cost: the ETW manifest-provider session cap. Windows allows up to eight trace sessions to enable and receive events from the same manifest-based provider [@ms-etw-limits]; the `EtwTi` security provider, Microsoft Defender Antivirus auto-start sessions, and any WPR sessions a developer might spin up all compete for that shared pool. Adding Sysmon's session takes one. On a host with a third-party EDR that already consumes several sessions against the same provider, this can cause silent telemetry loss. Audit `logman query -ets` regularly.

### The volume math

For sizing, assume a typical Windows endpoint generates roughly 20,000 process-create events per day under steady state (developer workstations are in this range; server volumes are higher; air-gapped jump boxes are lower) [@github-tsale-edr-telem]. The Hartong-augment config drops the top three high-volume EIDs (1 ProcessCreate, 7 ImageLoad, 11 FileCreate) that MDE already collects, retaining only the verbose surfaces. That cuts Sysmon volume by roughly 70 to 85 percent relative to a default-config Sysmon deployment, leaving only the verbose-EID stream (8, 10, 17-18, 19-21) MDE does not surface.

This is the operational answer to the question. For organisations with detection-engineering teams, Option C is the default. For organisations without, Option B is the default. Option A is correct in a narrow set of contexts and should be picked on purpose. The next two sections turn from the layered *architecture* to the layered *attack* surface, because every defense has an attacker.

## 11. The Attack Tradition: Telemetry Suppression on Both Halves of the Pipeline

If you run an EDR on a host, you have made a bet that the EDR can survive contact with an attacker who knows it is there. The history of that bet -- on both halves of the pipeline -- is a chronological story with named techniques and named CVEs. Twelve years of attack tradition reduce to a small number of attack classes plus the structural defenses that closed each one.

### Sysmon-side attacks, in order

The earliest tampering technique for Sysmon was the most obvious: stop the driver. Until Sysmon v15 in June 2023, the Sysmon service was a normal Windows service, and a SYSTEM-privilege attacker had several easy options:

- `sc stop sysmon` and `sc delete sysmon` to unload `SysmonDrv.sys`.
- Rewrite the minifilter altitude so Sysmon loads *after* a tamper hook.
- `wevtutil cl Microsoft-Windows-Sysmon/Operational` to erase history.
- Rewrite `SYSTEM\CurrentControlSet\Services\SysmonDrv\Parameters` to re-program Sysmon's filter without restarting it.
- Register a Windows event-channel ACL change to silence `Microsoft-Windows-Sysmon`.

A small family of community-published tools automated this class. The structural defense, before v15, was discipline: keep SYSTEM out of attacker hands.

The **June 2023 v15 protected-process gate is the structural response** to this entire class. Microsoft Learn states the change verbatim: "*The service runs as a protected process, thus disallowing a wide range of user mode interactions*" [@sysmon-ms-learn]. A SYSTEM-privilege attacker can no longer `OpenProcess(PROCESS_TERMINATE)` against `Sysmon.exe`, inject code into the service's address space, or attach a user-mode debugger. The class is not closed -- a kernel primitive still works, and a BYOVD chain that can write `_EPROCESS.Protection` defeats the gate -- but the bar moves from "a `wevtutil` command in a PowerShell window" to "a kernel exploit primitive."

### MDE-side attacks, in order

The MDE-side attack tradition starts at the Antimalware-PPL boundary on `MsSense.exe`. The FalconForce 2022 work this article has already cited multiple times is the dispositive primary [@falconforce-2022]. The verbatim TL;DR -- describing how raising `dbgsrv.exe` to `WinTcb` PPL lets researchers debug MDE and capture cloud-bound payloads, which surfaced a missing-authorization vulnerability allowing spoofed telemetry to any M365 tenant -- landed earlier as the §6 PullQuote and is the framing this section builds on.

The technique used a PPLKiller-class BYOVD chain to raise `dbgsrv.exe` to `WinTcb` PPL, attach to `MsSense.exe`, and capture plaintext payloads via `SspiCli!EncryptMessage` instrumentation. The vulnerability that work disclosed, **CVE-2022-23278**, was patched on March 8, 2022 [@msrc-cve-2022-23278][@nvd-cve-2022-23278]. That patch closed *one* missing-authorization gap in the cloud-side trust model. It did not close the class.

The InfoGuard Labs 2025 follow-up [@infoguard-2025] demonstrated that the broader class is still open. The technique they used was different -- in-memory patching of `CRYPT32!CertVerifyCertificateChainPolicy` to disable certificate-pinning validation, rather than PPL-elevated debugging -- but the vulnerability they surfaced is the same class: cloud endpoints (`/edr/commands/cnc` and `/senseir/v1/actions/`) that do not properly validate authentication tokens on traffic claiming to originate from the endpoint. As §7 documented, the MSRC disposition was low severity, no fix committed -- the operational consequence is that the spoofed-telemetry trust pattern that produced CVE-2022-23278 in 2022 is, three years later, still exploitable along a parallel surface.

The broader attack class -- ETW Threat Intelligence (`EtwTi`) blinding -- has been studied independently of MDE. The structural answer in 2026 is HVCI plus VBL plus Antimalware-PPL plus ELAM (the four-component hardening stack). On a fully-hardened endpoint, the user-mode tamper surface that defined the 2014-to-2020 era of EDR-blinding tradecraft is largely closed; the residual attack surface is kernel-mode adversary primitives. That is the structural ceiling §12 picks up.

### Cross-pipeline attacks

Some attacks affect both halves of the pipeline simultaneously. The most-cited is **BYOVD-driven kernel-callback removal**: a Bring-Your-Own-Vulnerable-Driver chain loads a Microsoft-signed but vulnerable driver, exploits a known CVE in the driver, and from kernel context calls `PsSetCreateProcessNotifyRoutineEx` with a `Remove = TRUE` flag against the EDR sensor's registered callbacks, effectively unhooking both Sysmon and MDE at the kernel-callback layer. The structural defense Microsoft shipped in response is the **Microsoft Vulnerable Driver Blocklist** with HVCI enforcement, which has been on by default since Windows 11 22H2 [@ms-driver-blocklist].

A second cross-pipeline attack is **direct-syscall bypass** of user-mode hook libraries -- but this attack is mostly a relic from the 2010s when EDR vendors relied on `ntdll.dll` user-mode IAT hooks; modern Sysmon and MDE neither register nor depend on user-mode hooks for the kernel-callback events. Direct-syscall malware that bypasses the user-mode hooks of a *third-party* EDR will still produce a Sysmon EID 1 and an MDE `DeviceProcessEvents` row, because the kernel-callback fires whether or not the malware called `NtCreateUserProcess` via `ntdll.dll`.

### The attack-surface lattice

<Mermaid caption="The attack surface on both halves of the pipeline. Top row: user-mode attacks Sysmon and MDE both face. Middle row: structural defenses that closed each class. Bottom row: the residual kernel-mode adversary primitives. The two unresolved open issues are CVE-2022-23278's successor class (InfoGuard 2025) on the MDE cloud side and the BYOVD-against-HVCI residual on the kernel side.">
flowchart TD
    A1["Sysmon-side: sc stop, wevtutil clear, registry altitude swap"] --> D1[Sysmon v15 protected-process gate]
    A2["MDE-side: PPLKiller + dbgsrv WinTcb to attach MsSense"] --> D2["Antimalware-PPL on MsSense.exe"]
    A3["Cloud-side: CVE-2022-23278 spoofed cloud telemetry"] --> D3["MSRC patch March 8 2022"]
    A4["Cloud-side: InfoGuard 2025 cert-pinning bypass + missing auth"] --> O4["OPEN: 'low severity, no fix committed'"]
    A5["Cross-pipeline: BYOVD kernel-callback unhook"] --> D5["HVCI + Vulnerable Driver Blocklist (Win11 22H2+)"]
    D1 --> R["Residual: kernel-mode adversary primitive that defeats HVCI + VBL"]
    D2 --> R
    D5 --> R
    D3 --> R
    O4 -.unclosed.-> R
</Mermaid>

The shape of the lattice is the shape of the field's hardening: every user-mode attack class has a structural defense, and the structural defenses converge on a single residual -- the kernel-mode adversary primitive that defeats HVCI plus the Vulnerable Driver Blocklist. On the cloud side, the InfoGuard 2025 finding is the unresolved item -- the same trust pattern that produced CVE-2022-23278 in 2022 produced a different cluster of missing-authorization bugs three years later. The attack-defense arc is still moving, and the two-sided nature of the pipeline (host + cloud) is why.

Every attack surface has a structural defense. But every defense has a horizon. What is outside the horizon?

## 12. Theoretical Limits: What the Pipeline Cannot See

Sysmon and Microsoft Defender for Endpoint are *observation* pipelines, not enforcement layers. That statement contains four structural ceilings the engineering cannot lift. These are not bugs to be fixed; they are properties of the architecture that follow from the choice of where the pipeline collects.

### Ceiling 1: The pre-driver-load horizon

Both Sysmon's `SysmonDrv.sys` and Defender for Endpoint's `WdBoot.sys` are kernel drivers, but they sit at different points in the boot order. `WdBoot.sys` is ELAM-signed and loads before any non-ELAM driver, which lets it classify subsequent boot-start drivers as `Good`, `Bad`, or `Unknown` for the kernel's load decision. (Measured Boot separately hashes `WdBoot.sys` along with the bootloader and kernel into TPM PCRs; that integrity-attestation channel is a sibling feature, not ELAM's own job.) `SysmonDrv.sys` is `BootStart`-ordered but not ELAM-signed -- it loads early, but not first.

Events that happen before the EDR driver's `DriverEntry` runs are *not observable* by that driver. For Sysmon, that means rootkit-class malware that loads inside the early Windows boot path (UEFI bootkits, boot-record manipulation, very-early kernel modifications) is invisible until after Sysmon catches up. For MDE, the ELAM-signed `WdBoot.sys` closes most of this window for non-ELAM drivers; the residual is anything that runs even earlier -- UEFI-firmware-resident malware, hardware-implant attacks, the very narrow class that targets the pre-ELAM trust boundary itself. The [Measured Boot](/blog/measured-boot-the-tcg-event-log-from-srtm-to-pcr-bound-bitlo/) plus [Secure Boot](/blog/secure-boot-in-windows-the-chain-from-sector-zero-to-userini/) stack (covered in adjacent articles in this series) is what observes the pre-ELAM region. EDR's reach does not extend below the ELAM line.

### Ceiling 2: The observation-vs-enforcement latency gap

Sysmon's kernel-callback to event-log latency is sub-millisecond. The driver runs the rule engine, decides to emit, and writes through the ETW publisher to the Sysmon service. The service writes to the event log. The total path is microseconds in the best case, milliseconds under load.

MDE's end-to-end latency to a queryable Kusto row is *seconds to tens of seconds*. The endpoint side takes microseconds; the TLS hop to regional ingest takes the dominant fraction of a second; the Kusto write and per-tenant indexing takes the rest. Microsoft's own Advanced Hunting documentation phrases the freshness contract carefully: "*Advanced hunting receives this data almost immediately after the sensors that collect them successfully transmit it to the corresponding cloud services*" [@advanced-hunting-overview]. "Almost immediately" is empirically a few seconds in steady state, longer under load, and indefinite when the endpoint cannot reach the cloud.

Any payload that completes its work inside the observation window has executed *before* the SIEM rule could fire. A `mimikatz.exe` invocation that dumps LSA secrets in three milliseconds, exfiltrates them over a covert DNS channel in 800 milliseconds, and exits in another two milliseconds has produced a complete attack chain before MDE's event has reached Kusto, let alone before the Maya-class analyst has glanced at her console. The hybrid responses that blur this boundary -- Sysmon v14's FileBlockExecutable (EID 27), MDE's ASR rules and Network Protection -- are *kernel-callback-time* decisions, not SIEM-rule-time decisions; they run inside the few-microsecond window the driver itself owns, and they are constrained by the rule logic baked into the host configuration rather than by the live correlation logic of the cloud-side detection engine.

### Ceiling 3: MDE schema truncation versus Sysmon manifest

This is the ceiling §8 quantified column-by-column. The `Device*` tables surface a normalized, mostly-complete cross-walk of Sysmon's manifest -- but mostly-complete is not the same as complete. The `ProcessAccess` GrantedAccess mask is the most-cited example: Sysmon EID 10 captures the full 32-bit `PROCESS_ACCESS_MASK` (which discriminates between `PROCESS_QUERY_INFORMATION`, `PROCESS_VM_READ`, `PROCESS_CREATE_THREAD`, and so on -- the canonical malicious patterns are visible in this mask), while MDE's `DeviceEvents` `OpenProcessApiCall` `ActionType` collapses the mask into a coarser categorization. The WmiEvent consumer expressions Sysmon EIDs 19-21 capture verbatim -- which are how WMI-based persistence is detected -- are not surfaced in the `Device*` schema at all. RawAccessRead (EID 9, the canonical disk-level credential-theft observable) is omitted. PipeEvent (EIDs 17-18) is omitted.

Hartong's `sysmonconfig-mde-augment.xml` exists precisely because of this asymmetry. The augment config is a community-curated artifact whose purpose is to fill the schema-truncation gap. The cost: a second telemetry stream on the host. The benefit: detection-engineering visibility into the verbose-EID surface MDE drops.

### Ceiling 4: The kernel-mode adversary primitive

A ring-0 attacker with a working kernel primitive -- a memory-write capability into the kernel data structures, typically delivered via BYOVD against a vulnerable signed driver -- can defeat the pipeline as a consequence of defeating the structural defenses that protect it. Specifically:

- Direct call to `PsSetCreateProcessNotifyRoutineEx` with `Remove = TRUE` unregisters the EDR sensor's callback, after which `CreateProcess` events on that host produce no observable.
- A patch to the `_EPROCESS.Protection` field of `MsSense.exe` or `Sysmon.exe` strips the Antimalware-PPL gate, after which user-mode attacks against the service work again.
- A direct write into the `EtwTi` provider's keyword mask zero-pages the security-event-emission surface, after which the kernel-side `EtwTi` consumer (which several EDRs subscribe to) sees no events even when the underlying behaviour fired.

The "Tampering with Windows Event Tracing" research published by Palantir in 2018 (Matt Graeber's canonical writeup) and the follow-on `EtwTi`-blinding tradition is the published primary for this attack class [@palantir-etw-tampering-2018]. The structural defenses are HVCI plus VBL plus Antimalware-PPL plus ELAM. But the four-component hardening stack does not prevent a kernel-mode adversary primitive from defeating the EDR; it only raises the bar to *needing* a kernel-mode adversary primitive.

<Aside label="Why this is a limit and not a bug">
Observation requires execution overhead, and execution requires the observer to live in the same trust domain as the observed. A kernel-mode observer (Sysmon, MDE) lives in the same kernel trust domain as the kernel-mode attacker; a hypervisor-rooted observer (`EtwTi` running under Virtualization-Based Security) shifts the trust boundary up one level, but does not eliminate it -- the observer-in-VBS is still subject to attacks on the hypervisor itself. There is no architectural place to put the observer that is strictly outside the attacker's reach unless the observer is in different hardware, which is what hardware-rooted Root-of-Trust attestations attempt and what an Anti-Tamper Service Provider (ATSP) is being defined for. EDR sensors will always be co-resident with the adversary at *some* trust boundary. The ceiling is structural.
</Aside>

Four ceilings, four sets of open questions. What is the field working on right now?

## 13. Open Problems and Active Work

Some questions in this article have no answer in 2026. Five of them are where the field will move next.

### The MDE kernel-callback inventory

As §6's aha-moment Callout established, Microsoft has not published a kernel-callback inventory for the MDE EDR sensor, which is the structural reason Hartong's `sysmonconfig-mde-augment.xml` exists as a community-curated artifact rather than a Microsoft-published reference. What §13 adds is the *empirical scaffolding* the community uses in the absence of that inventory: the MITRE Engenuity Round 6 (2024) evaluation results [@ms-mitre-2024-blog] plus the Shen et al. whole-graph re-analysis [@arxiv-shen-2024] are the closest published evidence of which MDE detection paths produced an alert during a known emulated technique. Neither covers an end-to-end kernel-callback enumeration comparable to Sysmon's manifest -- they cover *outputs* (alerts produced) rather than *mechanisms* (callbacks registered). Closing this gap would require either Microsoft to publish a per-`ActionType`-to-per-kernel-callback cross-walk for the `Device*` schema, or the community to fund and publish a reverse-engineered inventory that goes meaningfully past the FalconForce 2022 and InfoGuard 2025 slices. As of 2026, neither has happened.

### Defender XDR built-in detection rule logic

The `AlertInfo` and `AlertEvidence` table schemas are published; the underlying rule logic that produces alerts in these tables is not. Microsoft ships "Microsoft-authored detection rules" as part of Defender XDR Plan 2, and the rules update continuously without an obvious public changelog. The community workaround is to subscribe to the MITRE ATT&CK evaluation rounds (the most recent being Round 6 in 2024 [@ms-mitre-2024-blog][@arxiv-shen-2024]) and infer rule coverage from per-technique detection scores, but this is indirect and lossy. A published rule-logic catalogue would let detection-engineering teams reason about which custom rules are duplicates of Microsoft's authored content and which fill genuine gaps.

### Cross-tenant hunting and data sovereignty

MSSPs (managed-security service providers) routinely need to hunt across multiple customer tenants for shared-IOC observations. Microsoft's official multi-tenant story is Microsoft Defender XDR Multitenant Management (in GA) plus Azure Lighthouse for cross-tenant Sentinel access. Both are functional and both are documented at the operational level. The deeper question -- *what is the GDPR/HIPAA/FedRAMP framework around hunting an IOC observed in Tenant A against telemetry held in Tenant B's regional Kusto cluster?* -- is unsettled. The data-residency commitments Microsoft makes per region [@ms-server-endpoints-learn] do not directly answer the cross-tenant-hunt question. Vendor and customer guidance is still maturing.

### A Microsoft-published reference MDE-augmentation Sysmon config

Hartong's config is the community answer to the question "what Sysmon EIDs should I emit on a host that already has MDE?" There is no Microsoft-published reference equivalent. This is the most surgical near-term improvement Microsoft could make. Publishing such a config -- even as a starting-point template, not a binding recommendation -- would compress an entire detection-engineering conversation into a single endorsed artifact. The political reason it has not happened is partly that Microsoft does not officially recommend running Sysmon alongside MDE; the operational reality is that detection-engineering-mature shops do anyway.

### Cross-platform parity

Sysmon for Linux (`microsoft/SysmonForLinux`, created October 28, 2020 and publicly announced in October 2021) ships an eBPF-based implementation of the same XML schema and emits to syslog [@github-sysmon-linux]. It is a substantial subset of the Windows manifest -- process create, file write, network connect, image load, raw access read -- with the cross-OS shared XML rule grammar going for it, so a detection-engineering team can write one Sigma-aligned rule and run it against both Windows and Linux endpoints with minor token substitutions. Full parity between the Windows kernel-callback Sysmon and the Linux eBPF Sysmon is *not* the design intent; the Linux port intentionally captures only the EIDs that map cleanly onto eBPF observables. `BTFHub` plus `SysinternalsEBPF` (the in-tree CO-RE infrastructure the Linux port uses) make per-kernel-version deployments tractable, but the field has not yet converged on a single canonical Linux config the way it converged on SwiftOnSecurity for Windows.

These five open problems are where the field will move in the next five years. In the meantime, what does the analyst do on Monday morning?

## 14. Seven Things to Do Monday Morning

Everything above has been background. Here is the operational checklist. Each step is anchored to a primary citation. Walk all seven on a single non-production host before fleet rollout; the ninety-second triage walk from §1 is best learned by reproducing it once on your own tenant.

### 1. Verify the MDE sensor service is healthy

Run as Administrator on the endpoint:

```
sc query sense
```

A healthy result shows `STATE: 4 RUNNING` and `WIN32_EXIT_CODE: 0`. If the result is `STATE: 1 STOPPED` or the service is missing entirely, consult the WDATPOnboarding event source in the Application event log for events 5, 10, 15, 30, 35, 40, 65, and 70 -- each has a documented resolution procedure [@sense-troubleshoot]. On Windows Server 2019, 2022, 2025, or Azure Stack HCI 23H2 or later, also verify the Feature on Demand is installed:

```
DISM.EXE /Online /Get-CapabilityInfo /CapabilityName:Microsoft.Windows.Sense.Client~~~~
```

The result should show `State : Installed` and `Version : 10.x.x.x`. If `State : NotPresent`, install the FoD before proceeding.

### 2. Open Advanced Hunting and run the §8 query

Navigate to `defender.microsoft.com` (or the legacy `security.microsoft.com`), expand **Hunting > Advanced hunting**, paste the §8 KQL query, and run it [@advanced-hunting-overview]. On a fresh tenant the query may return zero rows -- that is the correct result for a healthy environment. Tighten the time window if it is slow (`Timestamp > ago(1h)` instead of `ago(24h)`) until the query returns within ten seconds. The point of this step is to confirm the read surface is reachable and that the user has Hunter (or higher) RBAC permission on the tenant.

### 3. If licensed for Sentinel, install the Defender XDR connector

In the Microsoft Sentinel workspace, navigate to **Data connectors**, choose **Microsoft Defender XDR**, and configure per-table streaming [@sentinel-xdr-connector]. Pick the tables your team needs longer retention or analytics-rule scheduling on; leave the others to in-portal Advanced Hunting. Be aware that enabling the connector "*automatically disconnects*" any legacy Microsoft Defender component connectors during enablement; this is the cleanup detail to plan for during migration windows [@sentinel-xdr-connector].

### 4. If deploying Sysmon alongside MDE, start from the augment config

Clone `olafhartong/sysmon-modular`, build the `sysmonconfig-mde-augment.xml` variant, and deploy with:

```
Sysmon64.exe -accepteula -i sysmonconfig-mde-augment.xml
```

Verify the active configuration with `Sysmon64.exe -c` and confirm the rule count matches the augment config's expected output [@github-hartong-modular].

### 5. If deploying Sysmon standalone, start from NextronSystems or modular default

For air-gapped or unlicensed environments, clone `NextronSystems/sysmon-config` (the post-2021-rename successor to `Neo23x0/sysmon-config`) and deploy `sysmonconfig.xml` or, for the blocking-rule variant, `sysmonconfig-export-block.xml` [@github-neo23x0][@github-nextronsystems-meta]. Alternatively, `olafhartong/sysmon-modular`'s default `sysmonconfig.xml` (built from the modular library) is the right choice if you want fine-grained per-technique tuning later [@github-hartong-modular].

### 6. Verify Sysmon v15.2 or later is running

```
Sysmon64.exe -c
```

The output's header line should show the binary version. Anything `v15.x` or later has the protected-process gate enabled [@sysmon-ms-learn][@bleepingcomputer-sysmon15]. Anything older is trivially blindable by a SYSTEM-privilege attacker and is the single biggest deployment-hygiene risk in the Sysmon population today.

### 7. Audit the MDE onboarding registry hives

Compare the live registry values to the expected onboarding state:

```
reg query "HKLM\SOFTWARE\Policies\Microsoft\Windows Advanced Threat Protection"
reg query "HKLM\SOFTWARE\Microsoft\Windows Advanced Threat Protection\Status"
```

Unexpected changes -- particularly a change to the onboarding `OrgId` or to the policy-controlled `Disabled` value -- are an indicator that the tenant or device has been re-targeted, possibly by an attacker who obtained admin-level access and is attempting to re-route the endpoint's telemetry to a different tenant or to disable the MDE sensor entirely [@sense-troubleshoot]. Set up a Sentinel detection rule on `DeviceRegistryEvents` with `RegistryKey contains "Windows Advanced Threat Protection"` to surface this class of tampering automatically.

> **Note:** Walk steps 1 and 2 on a single non-production host before fleet rollout. The ninety-second-triage walk you saw in §1 is best learned by reproducing it once on your own tenant. The cost of getting steps 4-6 wrong (deploying the wrong Sysmon config on a high-volume server fleet) is hours of operational pain; the cost of doing them right on a single test host first is twenty minutes.

<Spoiler kind="hint" label="What if `sc query sense` returns 'service does not exist'?">
The MDE sensor service has not been onboarded on this host. Two common causes: (1) the endpoint is on a Windows Server SKU and the SENSE Feature on Demand has not been installed; run the DISM `Get-CapabilityInfo` check in step 1 to confirm. (2) The onboarding script (the `WindowsDefenderATPLocalOnboardingScript.cmd` or the equivalent Group Policy / Intune / SCCM artifact) has not been run on this host. The MDE settings page in the Defender XDR portal shows the per-device onboarding artifacts under **Settings > Endpoints > Onboarding** for download [@sense-troubleshoot].
</Spoiler>

<MarginNote>The Defender XDR portal also exposes a **device timeline** view that surfaces a chronological event stream per device without requiring KQL. This is the right view for analysts who are still learning the schema; the KQL surface is the right view for repeatable hunts and detection-rule authoring.</MarginNote>

Seven steps, one Monday. The rest of the questions are in the FAQ.

## 15. Frequently Asked Questions

Seven of the questions that come up every time this material is taught.

<FAQ title="Frequently asked questions">
<FAQItem question="Is Sysmon an ETW-based event source?">
Yes on its output side; mostly no on its input side. Sysmon publishes its events through an ETW provider called `Microsoft-Windows-Sysmon`, which is how downstream collectors and the Windows Event Log service consume the data. On its *input* side, Sysmon is a kernel driver that collects via five different mechanisms -- `PsSetCreateProcessNotifyRoutineEx` for process create and exit, `PsSetLoadImageNotifyRoutine` for image load and driver load, `PsSetCreateThreadNotifyRoutineEx` for remote-thread creation, `ObRegisterCallbacks` for cross-process access, `CmRegisterCallbackEx` for registry, and Filter Manager minifilters for ordinary file system and NPFS named pipes. Two exceptions live on Sysmon's input side. The single kernel-ETW consumer is `Microsoft-Windows-DNS-Client` for EID 22 DNSEvent; the WmiEvent family (EIDs 19-21) is implemented in a consumer style against the WMI activity provider's user-mode tracing surface. Calling Sysmon "ETW-based" without that distinction is the most common architectural confusion in the field [@sysmon-ms-learn].
</FAQItem>

<FAQItem question="Does Microsoft Defender for Endpoint replace the need for Sysmon?">
For most organizations licensed for MDE Plan 2 and without a mature detection-engineering team, yes -- MDE alone is the right baseline. For organizations with a detection-engineering team, the community pattern is to deploy MDE *plus* a tuned Sysmon configuration (specifically Olaf Hartong's `sysmonconfig-mde-augment.xml`) that fills the gaps where MDE's `Device*` schema truncates or omits fields that Sysmon's manifest captures verbatim -- the `ProcessAccess` GrantedAccess mask, the full WMI consumer expressions, RawAccessRead, the pipe events, and selected file-delete archival paths. The wrong answer for an MDE-licensed shop with a detection-engineering team is to do nothing on the Sysmon side; the second-wrong answer is to deploy *default* Sysmon alongside MDE, which produces double the telemetry volume for the coverage of one [@github-hartong-modular][@mde-ms-learn].
</FAQItem>

<FAQItem question="What is the difference between DeviceEvents and the other Device* tables?">
The five class-specific `Device*` tables (`DeviceProcessEvents`, `DeviceNetworkEvents`, `DeviceFileEvents`, `DeviceImageLoadEvents`, `DeviceRegistryEvents`) each map onto a single Sysmon EID family and present a normalized, per-class set of columns. `DeviceEvents` is the miscellaneous catch-all: AMSI scan results, exploit-protection events, Defender Antivirus operational events, Attack Surface Reduction rule fires, Network Protection blocks, OpenProcess API calls, and other MDE-specific telemetry surface here under different `ActionType` values. If a row's `ActionType` does not match what you expected, the row is probably in `DeviceEvents` rather than the table you searched first [@advanced-hunting-overview].
</FAQItem>

<FAQItem question="Is Florian Roth's sysmon-config the original?">
No. The historical root is SwiftOnSecurity's `sysmon-config`, created on February 1, 2017 per the GitHub REST API [@github-swiftonsecurity-meta]. Florian Roth (`@Neo23x0`) forked SwiftOnSecurity's repository in January 2018 and added blocking-rule support, community pull-request merges, and the maintainer roster that now includes Tobias Michalski, Christian Burkard, and Nasreddine Bencherchali [@github-neo23x0]. The Neo23x0 repository was renamed to `NextronSystems/sysmon-config` on July 24, 2021 [@github-nextronsystems-meta]; the old URL HTTP-301 redirects to the new one and the content lineage from SwiftOnSecurity is unchanged. Calling Roth's config "the original" is the inverse of the truth; calling it "the canonical actively-maintained fork" is closer.
</FAQItem>

<FAQItem question="Can I run two Sysmon configurations simultaneously?">
No. Sysmon supports one active configuration at a time. There is no aggregate-multiple-XMLs feature at the driver layer. Olaf Hartong's modular workflow generates a single merged XML at build time from a per-technique module library; the production fleet receives that single XML and the driver enforces it. If you want two configurations -- one for the SOC team's hunting, one for the platform team's audit -- merge the rules at build time and ship the combined product [@github-hartong-modular].
</FAQItem>

<FAQItem question="Why is MsSense.exe so hard to debug?">
Because it runs as Antimalware Protected Process Light (`PROTECTED_ANTIMALWARE_LIGHT`), the Windows kernel rejects ordinary user-mode `OpenProcess(PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_DUP_HANDLE)` requests against the process from any caller that does not itself run at an equal or higher signer level. The published reverse-engineering technique (FalconForce 2022) is to raise the Windows PE debug server `dbgsrv.exe` to the `WinTcb` signer level via a PPLKiller-class kernel primitive, then attach the elevated debug server to `MsSense.exe`. That technique requires a kernel-mode primitive (commonly a BYOVD chain), which is itself non-trivial. The protection level is the structural defense; the debug-server technique is the dispositive community workaround [@falconforce-2022].
</FAQItem>

<FAQItem question="How long do Advanced Hunting tables retain data?">
Thirty days of raw data in the Defender XDR portal: "*Advanced hunting is a query-based threat hunting tool that you use to explore up to 30 days of raw data*" [@advanced-hunting-overview]. Beyond thirty days, retention is configurable per workspace via the Microsoft Sentinel Defender XDR connector; the Log Analytics workspace archive tier supports up to twelve years of per-table archive on a per-GB-billed basis [@sentinel-xdr-connector][@ms-log-analytics-archive]. The two surfaces are not exclusive; the common operational pattern is in-portal for the hunting team (30 days, no per-GB cost) plus per-table Sentinel streaming for the analytics-rules team (extended retention, per-GB cost on selected tables).
</FAQItem>
</FAQ>

These are the questions. The seven layers between Maya's `cmd.exe` at 9:14 a.m. and her Kusto row at 9:14:03 are how the answers actually work -- a kernel callback, a user-mode aggregator, an ETW publisher or TLS-pinned cloud forwarder, a regional Kusto ingest, a table write, and a KQL read, with two structural defenses (Antimalware-PPL and the Sysmon v15 protected-process gate) keeping each layer honest. Every other detection-engineering pattern in the Windows field is a configuration of those seven layers, and most of the open problems are at the seams between them.

**See also.** The Sysmon driver's collection layer leans on the kernel-callback APIs documented in the [Windows process mitigations and Object Manager namespace](/blog/) articles in this series. The ETW transport bus that Sysmon publishes onto -- and that `EtwTi` security events surface through -- is the subject of the dedicated ETW article in this series; the article goes deeper on provider GUIDs, manifests, and the eight-trace-session manifest-provider cap that bounds Sysmon's coexistence story in §10. The AMSI primary path that produces `DeviceEvents` `ActionType = "AmsiScriptDetection"` is the subject of the AMSI article; the two pipelines are siblings, not substitutes. And the Sigma rule corpus that compiles down into KQL for Defender XDR / Sentinel hunting is the same Sigma corpus that compiles into Splunk SPL and Elastic EQL -- the vendor-neutral query layer that sits above this article's KQL surface [@github-sigma].

<StudyGuide slug="sysmon-and-defender-for-endpoint-the-production-edr-telemetry-pipeline" keyTerms={[
  { term: "Sysmon", definition: "Sysinternals tool by Russinovich and Garnier (August 2014, latest v15.2 March 2026) that uses Windows kernel callbacks plus a Filter Manager minifilter to collect 29 event types and publishes them via the Microsoft-Windows-Sysmon ETW provider to the Operational event log." },
  { term: "Microsoft Defender for Endpoint (MDE)", definition: "Microsoft's commercial cloud-correlated EDR. Renamed from Windows Defender ATP in September 2020. Runs as the Sense service (MsSense.exe) at Antimalware-PPL, shares the WdBoot ELAM and WdFilter minifilter substrate with Defender Antivirus, and lands events in the Advanced Hunting Kusto cluster." },
  { term: "Microsoft Defender XDR", definition: "The November 2023 rename of Microsoft 365 Defender. The unified portal at defender.microsoft.com that exposes Advanced Hunting on the Device* tables plus the cross-domain entity tables (AlertInfo, EmailEvents, IdentityLogonEvents, CloudAppEvents)." },
  { term: "Advanced Hunting", definition: "The KQL-on-Device*-tables threat-hunting surface in Microsoft Defender XDR. 30 days of raw data, six core tables, the cross-domain entity table set, and a 100,000-row + 10-minute per-query quota." },
  { term: "ProcessGuid", definition: "Sysmon's per-process 128-bit GUID that survives PID reuse and uniquely identifies a process across its lifetime. The canonical join key for process-tree reconstruction." },
  { term: "Antimalware-PPL", definition: "Protected Process Light at the PROTECTED_ANTIMALWARE_LIGHT signer level. Prevents user-mode debugger attach, code injection, and OpenProcess-for-write from any caller not at an equal or higher PPL level. Gates MsSense.exe and Sysmon v15+." },
  { term: "ELAM", definition: "Early-Launch Antimalware. The Windows boot-order privilege that lets an Antimalware-EKU-signed driver (1.3.6.1.4.1.311.61.4.1) load before any non-ELAM driver and gate which non-ELAM drivers load. WdBoot.sys is ELAM; SysmonDrv.sys is not." },
  { term: "DeviceProcessEvents", definition: "The canonical reader-side Kusto table for MDE process-create events. ~50 columns including the InitiatingProcess* parent-process family. The MDE analogue of Sysmon EID 1." },
  { term: "DeviceEvents", definition: "The miscellaneous catch-all Kusto table. AMSI scan results, exploit-protection events, ASR rule fires, OpenProcess API calls, and other MDE-specific events surface here under ActionType discriminators." },
  { term: "Sysmon EID 27 FileBlockExecutable", definition: "Sysmon v14's (August 2022) first preventive event. The minifilter intercepts the file-handle close; if the rule matches and the content carries an MZ/PE header, Sysmon logs EID 27 and marks the file for deletion. The copy command produces no error and appears to succeed -- the file is then deleted at handle-close. Confined preventive surface; not a general-purpose application allowlist." },
  { term: "sysmonconfig-mde-augment.xml", definition: "Olaf Hartong's pre-generated Sysmon configuration that drops the EIDs MDE covers (1, 3, 7, 11, 12-14, 22) and keeps the EIDs MDE truncates or omits (8, 9, 10 verbose, 15, 17-18, 19-21, 23 archive). The detection-engineering-community default for MDE coexistence." },
  { term: "FalconForce 2022 / CVE-2022-23278", definition: "The dispositive published reverse-engineering of MsSense.exe debug techniques (dbgsrv.exe at WinTcb PPL via PPLKiller) and the disclosed cloud spoofing vulnerability patched by Microsoft on March 8 2022." },
  { term: "InfoGuard Labs 2025", definition: "The follow-on reverse-engineering of MDE cloud authorization. In-memory patch of CRYPT32!CertVerifyCertificateChainPolicy (mov eax,1; ret) to bypass certificate pinning, followed by disclosure of missing-authentication on /edr/commands/cnc and /senseir/v1/actions/ endpoints. MSRC classified low severity; no fix committed." }
]} questions={[
  { q: "Why is calling Sysmon 'ETW-based' only half-true?", a: "ETW is Sysmon's *output* bus (Microsoft-Windows-Sysmon ETW provider feeding the user-mode service and downstream collectors), not its primary *input* source. Sysmon's driver collects via kernel callbacks: PsSetCreateProcessNotifyRoutineEx, PsSetLoadImageNotifyRoutine, PsSetCreateThreadNotifyRoutineEx, ObRegisterCallbacks(PsProcessType), CmRegisterCallbackEx, and Filter Manager minifilters (covering both ordinary file system and NPFS named pipes). Two input-side ETW-consumer exceptions exist: Microsoft-Windows-DNS-Client for EID 22 DNSEvent, and the WMI activity provider for EIDs 19-21 WmiEvent." },
  { q: "Why does Hartong's sysmonconfig-mde-augment.xml exist as a community artifact rather than a Microsoft-published reference?", a: "Microsoft does not publish a per-ActionType-to-per-kernel-callback cross-walk for the MDE EDR sensor. The community knows the Device* reader-side schema and the user-mode component inventory (Sense, MsSense.exe, SenseCncProxy.exe, SenseIR.exe, SenseNdr.exe), but not the kernel-callback inventory. Hartong reverse-engineered which Sysmon EIDs MDE truncates or omits and built the augment config to fill the gap." },
  { q: "What architectural change does Sysmon v15 (June 2023) introduce, and what attack class does it close?", a: "Sysmon v15 runs the user-mode service as PROTECTED_ANTIMALWARE_LIGHT, disallowing a wide range of user-mode interactions. The closed attack class is the SYSTEM-privilege user-mode tamper surface: sc stop, wevtutil clear of the Operational log, code injection into Sysmon.exe, ordinary debugger attach, and OpenProcess(PROCESS_TERMINATE). The residual attack surface is kernel-mode primitives, typically delivered via BYOVD." },
  { q: "Where in the seven-layer pipeline does FalconForce 2022 intercept Defender for Endpoint?", a: "Between layers 2 and 4. FalconForce raised dbgsrv.exe to WinTcb PPL (defeating layer 2's Antimalware-PPL protection on MsSense.exe), attached the elevated debug server to MsSense, and instrumented SspiCli!EncryptMessage to capture plaintext payloads before the TLS-with-cert-pinning transport (layer 4) ran. The plaintext capture surfaced CVE-2022-23278, which Microsoft patched March 8 2022." },
  { q: "What are the four structural ceilings the EDR pipeline cannot lift?", a: "(1) The pre-driver-load horizon: events before the EDR driver's DriverEntry are invisible; the ELAM boundary is the upstream bound. (2) The observation-vs-enforcement latency gap: Sysmon kernel-callback to event-log is sub-ms; MDE end-to-end to Kusto is seconds. (3) MDE schema truncation: ProcessAccess GrantedAccess masks, WMI consumer expressions, RawAccessRead, and PipeEvent are not surfaced in the Device* tables verbatim. (4) The kernel-mode adversary primitive: an attacker with a kernel write capability defeats HVCI + VBL + PPL + ELAM as a consequence of defeating the defenses themselves." },
  { q: "Which Sysmon configuration is the correct starting point for a new deployment?", a: "Depends on the deployment posture. For air-gapped / regulatory-no-cloud / unlicensed: NextronSystems/sysmon-config or olafhartong/sysmon-modular's default sysmonconfig.xml. For MDE-licensed environments with a detection-engineering team: olafhartong/sysmon-modular's sysmonconfig-mde-augment.xml. For MDE-licensed environments without a detection-engineering team: do not deploy Sysmon -- run MDE alone. The wrong starting point in any context is default Sysmon alongside MDE without the augment config." }
]} />
