§ AU

FudModule v3.1 Zeroes the Crash Dump Block Before Anything Else

Microsoft patched a bug in a core Windows networking driver on 11 August 2026 that North Korean operators had already been using since at least early July. CVE-2026-68820 sits in afd.sys, the kernel piece behind Windows sockets, and it lets code that is already running on the machine promote itself to SYSTEM. Microsoft’s own scoring says that code needs some privileges but not administrator rights, and no user has to click anything. That scope limit still matters: nobody breaks in with this. What makes it worth your afternoon is what Lazarus did next — they used it to install a new build of FudModule, a rootkit whose whole job is blinding the machine’s own recording equipment, and whose loader will not run below Windows 11 build 26100 (the observed samples handle 26100 and 26200). Patch and the door closes, but patching is not cleaning: a machine that was already hit stays compromised until somebody works the incident. And if you think you have one of these, your normal triage order is wrong, because the first thing the rootkit does is break the crash dump path, and most of what it touches afterward lives in places a standard DFIR checklist quietly assumes are honest.

Precisely: CWE-416, and Microsoft’s CNA entry scores it CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:U/C:H/I:H/A:H, 7.0: local, high attack complexity, low privileges required, no user interaction. Read PR:L carefully, because this is not admin-to-SYSTEM. Microsoft’s own advisory data puts it as “a locally authenticated attacker could run a specially crafted application on an affected system to trigger a race condition,” with “user interaction is not required.” Read AC:H in the same breath, though, because Microsoft explains that metric in the same record: “successful exploitation of this vulnerability requires an attacker to win a race condition.” An ordinary low-privilege foothold is a precondition for SYSTEM here, not an automatic escalation. The race is in afd.sys; Check Point Research describes concurrent access to a socket’s state in which “one code path can access memory after it has already been released by another,” yielding a kernel read/write primitive and then SYSTEM. Moshe Marelus and David Driker of Check Point Research are credited by Microsoft, which lists both by name in the acknowledgments of its August 2026 security update record (Check Point’s own writeup is bylined to the research team and names neither in the body, and The Register reported the credit at the time); Check Point’s timeline gives 28 July to MSRC, confirmed 31 July, CVE assigned 5 August, fixed 11 August, in a Patch Tuesday whose size the trade press counts differently (Tenable says 398 CVEs, BleepingComputer 400, The Register 421; I can’t reconcile the three from what they publish, so take the range and move on). Note that Check Point’s two public statements on exploitation don’t quite line up: the writeup says the vulnerability was in use “since at least early July 2026,” while the company’s threat-intelligence director told The Register his analysts first saw it attacked at the beginning of June. For hunting purposes take the earlier of the two: scope your retrospective search back to early June, because a floor that turns out to be too early costs you query time, and one that turns out to be too late costs you the intrusion. FudModule v3.1 keeps most of the v3 suppression suite: crash-dump suppression executed before everything else, the 94-GUID ETW kill list, minifilter removal by altitude band, process/thread/image notify callback teardown, object and registry callbacks, termination of the NT Kernel Logger, privileged-handle forgery, and a WFP stage that fires only when Kaspersky is present and Symantec is absent. It also drops two v3 stages (the dedicated Defender stage that suppressed monitoring of MsMpEng.exe, and the PPL stripping aimed at AhnLab’s asdsvc.exe), so Defender is now blinded through the generic security-product suppression path like any other vendor rather than by name. New in 3.1 is Smart App Control tampering: from a SYSTEM-level msiexec.exe child reached by a two-hop spawn through services.exe, the stub sets VerifiedAndReputablePolicyState to zero and calls NtSetSystemInformation class 0xA4 with option 0x10000000 to force an in-place code integrity policy reload. The loader carries an explicit minimum-version check for 26100 (24H2) with explicit support for 26200 (25H2).

TL;DR

  • CVE-2026-68820, a use-after-free race in afd.sys patched 11 August 2026, is scored PR:L (low privileges, not administrator) and yields kernel read/write and SYSTEM. It is not initial access. Lazarus used it to drop FudModule v3.1, whose loader only runs on Windows 11 builds 26100 and 26200; patching closes that door and does nothing about a host that was already compromised.
  • FudModule is data-only and performs its kernel tampering from user space, so there is no FudModule driver file and no service to load, and therefore no Sysmon Event 6 attributable to it. Any kernel-compromise detection built on driver-load telemetry returns clean on an infected host. Don’t substitute CodeIntegrity 3033 for that signal; Microsoft documents 3033 as a signature and policy-validation event, not a driver load.
  • Crash-dump suppression runs first, so don’t expect a deliberate bugcheck to hand you the dump you wanted — the machine can still crash and reboot, and what you destroy is the uncaptured volatile state. Acquire from the hypervisor instead, and know your platform: on vSphere that means a snapshot with memory (which excludes guest quiescing); on Hyper-V it means a Standard checkpoint or saved state, because the default Production checkpoint invokes guest VSS and captures no memory at all.
  • Targeted ETW teardown clears IsEnabled per-GUID rather than tearing down the surrounding session, so session-presence checks can stay green while the events stop, and the detection becomes a volume cliff. The durable principle is correlating expected-telemetry-absent with independent evidence the host is alive (AD auth, DHCP, proxy, EDR last-seen); the gap threshold and the alert volume are properties of your fleet, so measure them per endpoint class rather than adopting mine.
  • The Smart App Control tamper (SYSTEM msiexec.exe two hops under services.exe, VerifiedAndReputablePolicyState zeroed, NtSetSystemInformation class 0xA4 reload) may leave a durable registry artifact or a purely runtime change that makes CM-6 config scans lie. Capture CI\Policy, CI\Protected‘s mirror, SacLearningModeSwitch and citool.exe -lp before you reboot, and treat any disagreement as an anomaly to investigate rather than a validated FudModule signature.

The same driver, the second time

This is the second afd.sys use-after-free Lazarus has burned in two years. CVE-2024-38193 was the first, and it carried FudModule v3.0. Before that, CVE-2024-21338 (appid.sys, the AppLocker driver) carried v2. The trend is worth hunting against: across v1 to v3.1 this crew has moved from bringing a vulnerable third-party driver toward finding privilege-escalation bugs in drivers that ship with Windows, which spares them the whole BYOVD problem of getting a flagged driver loaded in the first place. Read that as a trend and not as a policy, though. Four data points establish a direction of travel; they do not establish that Lazarus has retired BYOVD or that every future revision arrives with a fresh inbox-driver zero-day.

Which kills a whole family of hunts you may have standing. FudModule is data-only. Gen Digital’s teardown puts it plainly, it “executes entirely from user space.” There is no malicious driver on disk. No service key under CurrentControlSet\Services. No Event 6 driver load, nothing for your vulnerable-driver blocklist to catch. If your kernel-compromise detection strategy is built on driver-load telemetry, it returns clean on an infected host and it will keep returning clean.

One correction to a shortcut I have used myself, since it changes what an empty result means: CodeIntegrity 3033 is not a driver-load event. Microsoft documents it as a code-integrity validation failure: a revoked signature, a Lifetime Signing certificate that expired, or code compiled with Code Integrity Guard trying to load code that doesn’t meet CIG’s requirements. It “should occur alongside a 3077 event if caused by App Control policy.” The events that speak to driver loading and signing are 3001, 3004, 3023 and 3082. Absence of 3033 tells you nothing about whether a driver loaded, so don’t file it next to Event 6 as though the two are the same kind of silence.

Acquisition, in the order that survives

Crash-dump suppression running first is the detail that should reorder your runbook. Gen’s v3.0 analysis gives the mechanism: the rootkit locates the data sections of crashdmp.sys and ntoskrnl.exe, scans the kernel’s data section for the pointer into crashdmp.sys, the global named CrashdmpDumpBlock, and “then zeroes out this pointer which effectively prevents the system from generating a crash dump.” Check Point says v3.1 still does it, and still does it before everything else.

Be precise about what that costs you, because the intuitive version overshoots. The bugcheck itself is not disabled. Microsoft’s documentation for forcing a system crash from the keyboard says the system “calls KeBugCheck and issues Bug check 0xE2: MANUALLY_INITIATED_CRASH,” and that “unless crash dumps are disabled, a crash dump file is then written,” which is exactly the condition FudModule has arranged. So NotMyFault, the CrashOnCtrlScroll trick, or a deliberate KeBugCheckEx can still stop and restart the machine; what they will not hand you is the dump. You lose the uncaptured volatile state, not every forensic artifact on the host, and you lose it after taking the one action guaranteed to clear memory.

So:

If the host is virtualized, acquire the volatile state from the hypervisor before you touch anything inside the guest — but the words “checkpoint” and “snapshot” hide a platform difference that will silently cost you the memory image, and on one platform will drag you back inside the guest while doing it.

On vSphere, you have to explicitly select Snapshot the virtual machine’s memory; that option is what “captures the state of the virtual machine memory and the virtual machine power settings,” and it produces the .vmsn plus .vmem pair you actually want. Broadcom’s documentation also settles the quiescing question for you: you can quiesce the guest file system “only when the virtual machine is powered on and the Snapshot the virtual machine’s memory check box is deselected.” The two are mutually exclusive, so selecting memory rules quiescing out by construction, which is the outcome you wanted anyway: VMware Tools quiescing executes code inside the guest, and that is the boundary you are trying to stay outside of.

On Hyper-V the trap is the default. Microsoft documents that Production checkpoints are selected by default, that they use “Volume Shadow Copy Service or File System Freeze on a Linux virtual machine,” and that with them “no snapshot of the virtual machine memory state is taken.” A Standard checkpoint is the one that “takes a snapshot of the virtual machine and virtual machine memory state.” So the reflexive right-click-and-Checkpoint on a suspected FudModule host does both wrong things at once: it invokes VSS inside the compromised guest and gives you no memory. Set the VM to Standard first (Set-VM -Name <vm> -CheckpointType Standard), or save the VM’s state instead, but keep the two straight, because they are different operations that leave different artifacts. A Standard checkpoint preserves the checkpoint’s runtime and configuration state along with an .avhdx differencing-disk chain hanging off the .vhdx. Saving state writes the VM’s runtime-state files (.vmrs on 2016 and later, .bin/.vsv on 2012 R2 and earlier) and does not create a checkpoint chain at all. Both get you memory from outside the guest, which is the point; just don’t go hunting for an AVHDX that a saved state was never going to produce, and confirm the exact file set against your own Hyper-V version before you write the collection procedure.

Done that way, this is the only acquisition on the list that happens outside the trust boundary the rootkit owns. Be precise with yourself about what that buys you: the memory in the snapshot is still memory the rootkit has been editing for however long it has been resident, and every structure it zeroed is zeroed in your image too. What you gain is that the act of capture is not performed by code the attacker controls. Take it, and budget for it rather than treating it as free. Broadcom notes that capturing memory state makes the operation “take longer to complete” and that “you might also see a momentary lapse in response over the network”; how much longer depends on how much RAM the guest has and how fast the datastore underneath it is, so on a large VM this is a change-window conversation, not a few seconds of pause.

Physical hosts are worse and you should say so out loud in the ticket. Live acquisition with a driver-based tool still gets you something usable in practice, since the rootkit is suppressing telemetry and callbacks rather than actively filtering physical memory reads, at least as documented, but it is a best-effort image taken from inside a machine where an attacker holds arbitrary kernel read/write. Plan for the tool itself failing, too. Your acquisition driver has to load and run on a host where the adversary can edit kernel memory at will and where FudModule already ships a driver-selection engine with per-class keep and kill rules, so a load that hangs, errors, or silently does nothing is a plausible outcome rather than a shock. (The SAC tamper is not the mechanism to fear here — that one sets the policy state to zero, which is permissive. The concern is the general one: kernel read/write beats your driver.) If acquisition fails, record that as an observation with its timestamp and error rather than discarding it as a tooling problem, and fall back to the hypervisor path above wherever the host is virtualized. Grab pagefile.sys and hiberfil.sys from the offline disk image afterward if they are there at all; hibernation is disabled on plenty of fleets and EncryptPagingFile is set on some. Don’t assume, though, that what they hold predates the compromise. The page file is live backing storage for modified pages and keeps being written the whole time the machine is up, and hiberfil.sys reflects whatever the most recent hibernation or Fast Startup cycle captured, so either can carry material from before, during or after the intrusion, and dating what you recover is part of the work rather than a property of the file. What is true is that nothing in the published analysis suggests any FudModule revision goes back to scrub pages already flushed, so the material that is there is worth recovering.

Before you pull the plug, three live queries are worth more than the entire disk image. fltmc filters and fltmc instances, diffed against a known-good host on the same build and the same EDR version. Collect them — but I need to walk back how confidently I first described what a difference there proves. Gen’s analysis describes FudModule walking _FLT_VOLUME.Callbacks.OperationsLists, unlinking the _CALLBACK_NODE entries for filters it wants gone (by driver name, or by a DefaultAltitude falling in the anti-virus or activity-monitor bands), and additionally wiping “the whole _FLT_INSTANCE.CallbackNodes array in the corresponding _FLT_INSTANCE structures.” What it does not describe anywhere is detaching or unregistering the instance itself. Those are different objects, and Filter Manager’s enumeration reports attachment, so a filter whose callbacks have been surgically neutered may well still enumerate as attached and present. Treat a missing instance as a strong anomaly worth chasing, not as the documented FudModule artifact, and validate the actual enumeration behavior in a lab, on the builds you actually run, before you write it into a runbook as a hard tell.

Then citool.exe -lp for live code integrity policy state, which has shipped in-box since Windows 11 22H2, so it is present on any build this loader will run on. We’ll come back to it. Capture all three to a text file on removable media with a timestamp before you image.

Don’t make the EDR vendor’s “collect forensic package” button your first or only acquisition. It executes inside the compromised kernel’s blast radius, underneath an agent whose callbacks may have been unregistered and whose providers may have been switched off, so the parts of it that depend on live kernel visibility can quietly agree with the attacker. That is an argument for preserving out-of-band volatile state first and treating the package as potentially incomplete, not for skipping it. Plenty of what it collects (disk artifacts, configuration, service and network state, whatever the vendor holds cloud-side) is unaffected by any of this and is worth having.

Absence is the detection, and absence is expensive

The ETW attack has two shapes and they behave differently in your index. The generic one zeroes EtwpActiveSystemLoggers, a bitfield where each bit marks an active system logger, which stops those system-logger paths generating events. That is the scope of it, and I overstated it as “everything stops” in an earlier version of this post, three paragraphs before correctly explaining why that isn’t so. The targeted one walks EtwpGuidHashTable, finds each _ETW_GUID_ENTRY for the providers on the hardcoded list, clears ProviderEnableInfo.IsEnabled and zeroes the mask fields in the attached _ETW_REG_ENTRY structures, so EtwEventEnabled returns false forever for those GUIDs.

That second one is the nasty case operationally. The published mechanism disables selected providers by editing their ETW enable state, not by tearing down the surrounding trace session, so the session can plausibly still be there, and a check that asks “is my session running” can come back green while events for those GUIDs simply stop being generated. Confirm that against your own stack rather than taking it from me: what logman query -ets shows you on a host in this condition is exactly the sort of thing to establish in a lab, because the answer determines whether your session-health monitoring is load-bearing or decorative. The same caution applies to which providers matter to you. Gen names Microsoft-Windows-Threat-Intelligence as an example of a provider that makes suspicious operations visible, and notes that security products also define their own providers and consumers. Whether your EDR leans on that provider, on a vendor-specific one, or on kernel callbacks that this rootkit attacks separately is a question for your vendor, not something to generalize. What survives the vendor differences is the possible shape of the failure: an agent can stay present and keep heartbeating to the console while a telemetry source underneath it has been switched off. Whether yours does is again vendor architecture. The transferable point is about your dashboard rather than about FudModule: an agent-health view that measures process liveness or console connectivity alone cannot tell you that the visibility underneath it is gone.

So the detection is a volume cliff, and volume-cliff detection is where most teams get hurt on the first deployment. The naive version in Splunk:

| tstats count where index=wineventlog earliest=-24h by host, _time span=5m
| timechart span=5m sum(count) by host

Run that against a real fleet with a short gap threshold and it will bury you, because the benign explanations are endless: laptop lids closing, WEF subscription hiccups, non-persistent VDI pools recycling, the overnight patch window. I’m deliberately not going to hand you a threshold or an expected alert count, because there is no universal endpoint event rate that makes those numbers transferable: workstations, servers, VDI, kiosks and specialized fleets all behave differently, and a number I made up would read as measurement. Derive them: start deliberately short during validation, measure the false positives by endpoint class, then set production thresholds from your own baseline. What does transfer is the shape of the tuning. Raise the gap threshold off the floor, exclude hosts that just booted, carve out the maintenance window and the VDI pool explicitly. Then the one that actually makes the rule work: join against independent proof the host is still online. AD authentication, DHCP lease renewal, proxy traffic, EDR last-seen. The alert you want is this host is demonstrably up and its Windows telemetry went to zero, and that correlation is the durable part of the detection whatever your numbers turn out to be.

Same rule, per-provider, is stronger and harder to build. If you’re forwarding via WEF, break the count out by SourceName or by channel and alert on a specific channel going silent while the host’s overall event volume holds. Sysmon’s own process-create stream (EventCode=1) is a decent canary, because on most interactive or service-bearing hosts process creation is close to continuous. Establish what “close to continuous” means on your own quiet hosts before you set the window, since an idle kiosk and a busy terminal server are not the same animal. In the Elastic equivalent this is a data_stream.dataset gap-detection job, with ingestion health as the extra confounder, though not in the way I first described it. Elastic’s default is not a silent drop: pipeline processing stops when a processor fails, and what happens to the document from there depends on how you configured ignore_failure, on_failure, a drop processor, or a failure store. Elastic’s documentation is explicit about the stop and about those handlers, but the pages I can read stop short of spelling out what an unhandled failure does to the indexing request itself — so confirm that against your own stack and version, because the answer decides whether a dropped document shows up as an ingest error your shipper can see or only as data that never arrives. So a parse or pipeline problem can absolutely manufacture something that looks like a dataset going quiet, but it is a configuration-dependent behavior rather than a default one. Check ingest-pipeline and failure-store health against the gap before you call it provider suppression.

Here’s the knotty part, and I’d rather state it awkwardly than cleanly: the 94-GUID list is static and hardcoded, which means providers registered after Gen published the 95-entry list are, in principle, outside it, and Check Point notes the v3.1 set “match[es] the first 94 entries of Gen’s published 95-GUID list, in identical order,” so one entry got dropped somewhere between revisions. That tempts you toward standing up a custom provider as a canary. It’s a reasonable instinct and it plausibly works against the targeted technique, since that path only touches GUIDs on the list. Test it separately against the generic path before you rely on it, though, and don’t assume the answer. Gen describes EtwpActiveSystemLoggers as a bit field in which each bit marks whether a particular system logger is active, and clearing it as the way to stop those loggers generating events; that is not the same claim as “every arbitrary custom provider and session on the box goes quiet regardless of how it is configured.” The published analysis doesn’t establish the broader version, and I shouldn’t have written it as though it did. Two techniques, two separate lab tests, and a canary that survives one of them is still worth having — just don’t let anyone report it upward as coverage.

The msiexec.exe hunt is easier and worth running today. SYSTEM-integrity msiexec.exe with services.exe as the parent, no /i, /x, /qn or package path on the command line, and no corresponding MsiInstaller events in the Application log inside the same window. Exclude /V before you run it, or the rule fires on stock Windows: MSIServer, the Windows Installer service itself, is msiexec.exe /V running as SYSTEM under services.exe with no package on the command line, and it matches every other clause. What Check Point verifies here is the lineage: the unusual two-hop spawn through services.exe into a SYSTEM msiexec.exe. That is the part worth anchoring a hunt on. The volume you should expect afterwards is a local question. Software distribution via SCCM or Intune produces SYSTEM msiexec.exe continuously, and package arguments plus MsiInstaller transaction events are good supporting evidence for sorting it out, but build those exclusions from your own baseline rather than assuming every legitimate deployment path presents an identical command line and event pair.

The registry value that goes one way

Smart App Control state lives in two places, and that’s what makes the v3.1 tamper interesting for evidence purposes. VerifiedAndReputablePolicyState under HKLM\SYSTEM\CurrentControlSet\Control\CI\Policy holds the current mode (0 off, 1 enforce, 2 evaluation). A mirror value, VerifiedAndReputablePolicyStateMinValueSeen, lives under the CI\Protected subkey. Per n4r1b’s reversing of the boot path, winload compares the two at boot and reconciles them, which is the machinery behind the behavior everyone learned first: that turning SAC off is a one-way trip.

That rule is now stale, and if you write a 2026 assessment finding on it you will be wrong. Microsoft’s testing guidance still says switching to Off or On “is a one-way operation” outside Evaluation mode, and the SAC overview still lists a clean install as a requirement. But Microsoft shipped a supported toggle anyway. The change was disclosed in the January 2026 release notes (KB5074105) and began rolling out in March, and the Windows Insider release notes for builds 26100.8106 and 26200.8106 state it plainly: “You can turn Smart App Control (SAC) on or off without needing a clean install.” Microsoft’s own support FAQ now says the same thing: “recent Windows updates allow Smart App Control to be re-enabled without requiring a clean installation.” And the Application Control for Windows page, updated on 31 March 2026, after the toggle began rolling out, still carries the flat statement that “once you turn Smart App Control off, it can’t be turned on without resetting or reinstalling Windows.” So the split is three Microsoft pages still teaching the old rule (the testing guidance, the SAC overview, and Application Control for Windows) against two documenting the new behavior, the Insider release notes and the support FAQ, with the most recently revised page of the five sitting on the wrong side of it. It is a gradual rollout rather than a flag day, and the builds it landed on are exactly the 26100/26200 pair this loader targets. Interpret SAC state against the suspect machine’s actual build and servicing state, not against the rule you learned in 2022.

Check Point’s writeup says the stub sets the policy state to zero and forces an in-place reload; it does not say whether the write landed in the registry or in kernel memory, and the distinction changes your evidence handling completely. If the registry value was written, you have a durable, timestamped artifact: the CI\Policy key’s last-write time in the SYSTEM hive, plus whatever is sitting unreplayed in SYSTEM.LOG1/SYSTEM.LOG2. That’s one of the very few disk artifacts on this whole incident that the rootkit both created and probably didn’t bother to sanitize. If instead the state was patched in kernel memory and only the live CI policy reloaded, then the registry says 1 while the machine behaves like 0, and every config-state scan you have (SCAP, your STIG checker, the CM-6 evidence in your assessment package) is reporting a control as enforced when it is not.

Either way there is a collection step worth running on a suspect host before you reboot it. Capture VerifiedAndReputablePolicyState under HKLM\SYSTEM\CurrentControlSet\Control\CI\Policy, its VerifiedAndReputablePolicyStateMinValueSeen mirror under CI\Protected, SacLearningModeSwitch under HKLM\SOFTWARE\Microsoft\Windows Defender (the value sits directly under the Defender key, not beneath a Smart App Control subkey, which is an easy place to go looking one level too deep), and what citool.exe -lp reports live. Those are the four values Microsoft’s own testing procedure manipulates and reads, so they are the ones that describe the machine’s SAC state. CI\Protected is ACL’d away from ordinary access, so budget for reading it out of the offline hive rather than from a live reg query. Worth pulling alongside them: the CodeIntegrity Operational log’s policy-activation events (3099 for a policy loaded, 3101 and 3102 bracketing a refresh, 3105 for a refresh attempt), because an in-place policy reload is exactly the operation those events describe, and whether the class 0xA4 call surfaces there is a cheap thing to settle in a lab and a valuable thing to know beforehand.

What I will not do is tell you what a specific mismatch proves. My first instinct was to read the pattern off the boot logic: mirror higher than the policy value means a downgrade that hasn’t survived a reboot, citool disagreeing with the registry means a kernel-only patch. That inference is tidy enough to be dangerous. Nobody has demonstrated those patterns for v3.1 on 26100/26200, Check Point doesn’t say whether the state change landed in the registry or only in runtime state, and the reconciliation behavior itself sits on top of a servicing change that just moved. Treat disagreement between any of those four values as an anomaly that demands investigation, not as a FudModule signature. There is a sharper reason for that caution than my own uncertainty, and it sits on Microsoft’s own App Control page: the documented, supported way for an administrator to turn SAC off across an organization’s endpoints is to set VerifiedAndReputablePolicyState under CI\Policy and then run CiTool.exe -r. That is the same value the rootkit zeroes, followed by the same kind of policy refresh. So a zeroed policy state with a fresh reload behind it is not by itself evidence of anything hostile. It is equally the fingerprint of a sanctioned configuration change, and you will have to separate them on context: who made the change, from what process lineage, under what account, with what change record. And note the structural problem with citool in particular: it is an in-guest observation on a host where the attacker holds arbitrary kernel read/write, so it is evidence, not an independent trust anchor. Capture the values regardless, because you cannot capture them after the reboot.

One honest caveat on how much this matters: SAC is frequently not in play on a managed fleet at all, and Microsoft is specific about why. From the Application Control for Windows page: “Smart App Control starts in evaluation mode and switches off within 48 hours for enterprise managed devices unless the user turns it on first.” The support FAQ lists “your device is enterprise-managed or developer-mode has been configured” among the reasons it gets switched off, and Microsoft positions App Control for Business, not SAC, as the administratively managed application-control technology. So the tamper is most interesting on consumer and lightly managed Windows 11 machines where SAC is actually active, which is a per-device fact to establish, not something to infer from management posture alone.

I’d stop short of the next step, which I took in the first version of this and shouldn’t have: concluding that Lazarus built the capability for the unmanaged endpoint. Check Point documents who was targeted: the defense sector worldwide with an emphasis on aerospace and aviation, organizations working on military technologies including surveillance sensors, drones and robotics, with victims in Western Europe, India and Brazil. It says nothing about the management posture of the machines involved. The observation that stands on its own is narrower and still uncomfortable: this is a capability whose blast radius is largest exactly where centralized telemetry is thinnest.

Where this lands in 800-53

Control What the rootkit does to it, and what you do about it
AU-9 The ETW provider teardown is a direct attack on protection of audit information. Your compensating control is forwarding latency: events already in the SIEM survive; events never generated do not. Shorten WEF batch intervals on high-value channels so the loss window is smaller.
AU-5 Response to Audit Logging Process Failures. The volume-cliff rule is a strong mechanism supporting AU-5, since it detects the failure and can alert on it, but the control reads “alert [personnel] within [time period] … and take the following additional actions,” so the query is part of the implementation and the defined response actions are the rest of it. Worth checking whether your shop has this marked satisfied on the strength of agent-health monitoring, which we just established measures the wrong thing.
SI-4 Callback removal and minifilter callback tampering can blind host-based monitoring while the security agent itself remains present and reporting. Any SI-4 assessment that accepts “EDR agent installed and reporting” as evidence is weak here.
SI-7 SAC/App Control is the integrity mechanism; the CI policy reload is the tamper. On managed hosts prefer a centrally governed App Control for Business policy over SAC, because it gives you explicit policy management and policy-related telemetry rather than a per-device consumer toggle. Don’t extend that to “harder for this attacker to flip”: against an adversary holding arbitrary kernel read/write that’s an assumption nobody has tested, and it isn’t a claim Check Point makes.
CM-6 Config-state evidence from a host with kernel R/W is unreliable by construction. Worth writing into the incident procedure so nobody re-baselines from a compromised machine.
SI-2 Patch. 26100/26200 are the builds the observed loader will run on, which is the rootkit’s own gate rather than the CVE’s affected-version list. Apply the 11 August fixes across everything MSRC lists as affected.

What to do

Patch, obviously. Then go find whether your absence-detection actually works, because that’s the control this attack was designed against and it’s the one most likely to be marked “implemented” on the strength of a dashboard that goes green when a host is compromised. Run a deliberately short version of the volume-cliff query against yesterday’s data and see how many hosts already look dark. Expect the first pass to be dominated by benign explanations; the tuning work you do sorting that out, and the thresholds you derive from your own fleet rather than from a blog post, are the actual deliverable here.

And if you find a candidate on 26100 or 26200, take the memory image from the hypervisor before you do anything else — on vSphere a snapshot with memory selected, on Hyper-V a Standard checkpoint or saved state rather than the default Production checkpoint, which would run VSS inside the guest and capture no memory at all.

Sources


This post was engineered and validated through a multi-agent AI workflow — drafted, adversarially reviewed by several independent models, checked against primary sources, and given a human review before publishing. See an inaccuracy, or found this useful? Leave a comment below — corrections and feedback are read and shape what comes next.

Leave a comment