core-jmp core-jmpdeath of core jump

From Job Offer to Ring 0: Lazarus, CVE-2026-68820 and FudModule 3.1

Lazarus spent a Windows kernel zero-day in afd.sys on a fake recruiter PDF. CVE-2026-68820 is a local UAF that skips BYOVD controls; FudModule 3.1 then tears down EDR callbacks and Smart App Control. Detect the DLL side-load before ring 0; reboot after KB5121003.

oxfemale September 11, 2026 28 min read 115 reads
Export PDF
From Job Offer to Ring 0: Lazarus, CVE-2026-68820 and FudModule 3.1
Original text: "From Job Offer to Ring 0: Lazarus, CVE-2026-68820 and FudModule 3.1" — author not clearly listed (site: Cyllex), Cyllex (3 September 2026). Primary technical analysis: Check Point Research, 11 August 2026. Code, tables and figures below are reproduced verbatim with attribution captions.
A fake recruiter handshake dissolving into a kernel ring of light
A job PDF, a race in afd.sys, and a rootkit whose only job is to unplug the cameras.
Cover illustration for the Lazarus AFD.sys zero-day analysis
Original cover. Source: original article.

Executive Summary

In August 2026 Check Point Research published the latest wave of Operation Dream Job: North Korea’s Lazarus cluster spent a Windows kernel zero-day on a fake recruiter email. The bug is CVE-2026-68820, a use-after-free in afd.sys (CWE-416), the Ancillary Function Driver under WinSock. Microsoft scored it Important, CVSS 7.0: local, needs code execution first, no remote reach. That number is a lie of omission. The exploit is a driver-free path from a low-privilege PDF reader to SYSTEM and a kernel read/write primitive. From there FudModule 3.1 tears down the callbacks, minifilters and ETW providers your EDR uses to see anything.

Cyllex’s 3 September 2026 post is the defender’s walkthrough of that chain: two delivery variants, an in-memory Graph-API downloader, the race, the rootkit, the Troy backdoor, and compromised Roundcube/WordPress/PrestaShop relays. This draft keeps every table, listing and diagram from that post, then adds the kitchen-table picture (the signed viewer that loads a stranger’s DLL from its own folder), the BYOVD-without-the-D contrast, Check Point’s extra hashes and RelayShell YARA, and a purple-team order of operations that stops at the red line: do not weaponise the race. Detect the DLL load. Confirm the reboot after KB5121003.

A zero-day in the Windows kernel is worth six figures on the open market. Lazarus spent one on a PDF sent to an aerospace engineer who thought he was applying for a job.

Cyllex, 3 September 2026

The Cookie Jar Is the Kernel, the Letter Is the Job Offer

A padlocked jar and a job-offer letter with a second key sliding underneath
You trusted the signed PDF reader. Windows trusted the DLL sitting next to it. That is the whole first hour of the intrusion.
Kitchen table: Dream Job is not a clever exploit. It is a recruiter conversation that lasts two weeks, then a password-protected ZIP, then a viewer that really does open a Lockheed Martin job description. While you read compensation, the side-loaded DLL stages a downloader in RAM. Nothing on screen fails. That is why sender-reputation and “does the PDF render?” both lose.

Check Point tracked the wave from early 2026 against defence, aerospace and aviation, with a preference for shops that build sensors, drones and robotics. Confirmed geography: France, Germany, India, Brazil. At least one compromised French organisation was then used as the sending mailbox for the next wave, so the second round arrived from a real industry-peer address. That defeats SPF/DKIM theatre if you only trust known partners.

A Note on Names: Google’s Cryptonyms

On 24 July 2026 Google Threat Intelligence Group retired Mandiant APTnn / FINnn numbering for a two-word scheme: a memorable first word plus a category word for origin. MITRE still uses APTnn. Google keeps old names searchable. UNC numbers remain for unattributed clusters. Lazarus was not in the first published batch, so Cyllex (and this draft) keep the community name. Practical rule: actor names are aliases. Technique IDs are primary keys.

Category wordMeaningPublished examples
CASTLEPeople’s Republic of ChinaAPT40 → ISLAND CASTLE, APT41 → SPIRE CASTLE
RELICRussiaAPT44 → SANDWORM RELIC, APT29 → ICE RELIC, APT28 → LAKE RELIC
NEPTUNENorth KoreaAPT37 → PLAIN NEPTUNE
IONIranAPT33 → BLEAK ION
COMETFinancially motivated cybercrimeFIN7 → WILD COMET, FIN6 → SQUID COMET
Google Threat Intelligence actor-naming categories. Source: original article.

Two Ways Into the Same Kind of Trouble

Two independent delivery chains into MISTPEN or Troy
Chain 1: archive + side-load + MISTPEN. Chain 2: SEO-poisoned SecurityPDF + Troy. The green arrows land on the third step, before ring 0. Source: original article.

Chain 1 — encrypted archive and a side-loaded DLL

  1. The archive. Password-protected ZIP: a legitimately signed MuPDF-based viewer, an encrypted PDF, and a malicious libmupdf.dll where the viewer expects its real dependency.
  2. The side-load. The user runs the viewer. Windows searches the application directory first. The signed parent loads the attacker’s library. Authenticode on the EXE is genuine because the EXE is genuine. ATT&CK: T1574.001 (Hijack Execution Flow: DLL). The old T1574.002 DLL Side-Loading ID is gone; do not import it.
  3. The decoy. A Lockheed Martin job description renders. Meanwhile the DLL stages MISTPEN in memory. Check Point’s later stages on this chain: recon plugins, a persistence module, the LPE loader, then ForestTiger as the long-term backdoor.

Chain 2 — SecurityPDF and the SEO-poisoned vendor

From July 2026 a second route dropped the suspicious archive. Mail impersonated Enveil, a real privacy-enhancing-technology firm founded by US IC alumni. Lookalike sites envell[.]xyz, enveil[.]online, uxtramine[.]org were ranked so that a victim who searched instead of clicking still landed on attacker infrastructure (T1608.006). Enveil itself was not compromised; only impersonated.

Those sites served SecurityPDF, a MuPDF fork. Check Point: the actor patched File → Open and drag-and-drop. Any PDF is parsed for this marker:

This document is encrypted with sumatrapdf reader!!!!!!!!!!!!

If present, the viewer extracts the appended blob, XOR-decrypts with key 0x39, writes %TEMP%\new.exe, and runs it. That binary reflectively loads Troy. Any other PDF opens normally. Submit the viewer alone to a sandbox and you have a PDF reader. Split the tool and the trigger across hosts so neither half convicts.

For operators: XOR 0x39 is not cryptography; it is a gate. Hunt the marker string in PDF objects and the write of new.exe from a MuPDF-family parent. Check Point hashes for SecurityPDF.exe: 743172aa…8d45d1, db3d69b7…0376d (full values in the IOC table below).

MISTPEN: A Downloader That Lives in Your Tenant

MISTPEN fingerprints the host then either serves FudModule or nothing
The zero-day is never sprayed. Wrong build, no payload. That is why five weeks produced no public sample. Source: original article.

MISTPEN (Mandiant 2024, catalogued under UNC2970) is an in-memory modular downloader. C2 is Microsoft Graph API: AES-encrypted files in OneDrive, separate keys for up and down. No attacker domain, no unusual TLS peer, no newly registered infrastructure. Traffic is to Microsoft, 443, from a Windows host in a Microsoft shop. Blocklists and newly-observed-domain rules are structurally blind.

ModuleFileFunction
GetInfoPluginRelease_GetInfoPlugin_x64.dllHost profile: domain or workgroup, hostname, username, OS version and build
PvPluginRelease_PvPlugin_x64.dllProcess enumeration: PID, PPID, creation timestamp, owning user and domain
OneScreenCaptureOneScreenCapture64.dllMulti-monitor desktop capture, JPEG then Base64
LPE loaderstaged in memoryFingerprint, session key, retrieve and detonate FudModule
MISTPEN on-demand modules. Source: original article.

GetInfoPlugin formats a single wide string Check Point recovered as:

Domain: <domain_or_workgroup>
ComputerName: <hostname>
UserName: <username>
OsInfo: <Windows product name> <build_number>.<UBR>

The LPE loader is selective. Check Point documents a four-stage handshake before the exploit is delivered:

  1. Fingerprint: exact OS build and installed security products.
  2. Request a public key from C2, keyed to that fingerprint (Check Point: a set of four public keys).
  3. Derive a session key with Kyber / ML-KEM; transport under GOST-CBC with a random 16-byte session key prepended, then Base64.
  4. Deploy FudModule via export DestroyEnv. Status messages go back through MISTPEN’s Graph channel via a shared RPC buffer.

Compiler timestamp on the investigated LPE DLL Afd4Eop12_x64.dll: 7 July 2026, 22:07:44 UTC. Strings include enable_god_mode passed. Minimum-version check: Windows 11 26100 (24H2) and 26200 (25H2). The vulnerability itself reaches back through Windows 10 ESU; the observed exploit does not. A sandbox on the wrong build never sees the payload. That discipline is why five weeks of live use stayed quiet.

Kitchen table: They do not mail the skeleton key to every house. They ask what lock you have, then send the key that fits. Your researcher VM is the wrong lock, so you get nothing, and you conclude there is no key.
For operators: A post-quantum KEM wrapped around GOST-CBC is a network tell if you can see the Graph payloads after TLS. You probably cannot. Hunt process identity talking to graph.microsoft.com instead: a PDF viewer or msiexec holding Graph tokens is the signal. Check Point: after LPE, a second MISTPEN is injected as SYSTEM so the same Graph channel continues with EDR already blind.

CVE-2026-68820: A Race Inside afd.sys

Timeline of the afd.sys use-after-free between two unsynchronized paths
Path A never learns Path B freed the object. The exploit’s job is to own that block between free and use. Source: original article.
Classic BYOVD versus exploiting the inbox Microsoft driver
BYOVD without the D: nothing is dropped, nothing is loaded. The vulnerable driver is the network stack.

afd.sys services every user-mode socket. Any process that can open a socket can talk to it, including sandboxed ones. Lazarus already burned CVE-2024-38193 in the same driver (FudModule 2024). CVE-2025-60719 was another AFD UAF, patched November 2025, not attributed here. Check Point tested a fully patched Windows 11 box and confirmed this sample hits a distinct bug.

High level only — neither Cyllex nor Check Point published a PoC, and this draft will not invent one. Two of the driver’s own paths can operate on the same socket state without synchronisation. Win the race, reclaim the freed allocation with attacker data, dereference at t4, and you have arbitrary kernel read/write. That converts to SYSTEM by rewriting the process token. CWE-416. ATT&CK T1068, not a T1548 sub-technique (those are UAC/sudo/macOS).

BYOVD without the D

The last decade of kernel defence assumed a third-party .sys would arrive: Microsoft’s vulnerable-driver blocklist, HVCI, driver-load telemetry, hunts for unexpected files in C:\Windows\Temp. Exploiting afd.sys skips the arrival. The driver is already resident, already Microsoft-signed, already required for TCP/IP. Every control that watches for a bad driver observes nothing.

CVSS 7.0 undersells the campaign value: it is local and needs prior code exec, yes. In this operation the prior code exec is a recruiter PDF. The LPE is the last honest step before FudModule unplugs the cameras.

DateEvent
Early July 2026In-the-wild exploitation begins as a zero-day
28 July 2026Reported to MSRC by Check Point Research
31 July 2026Microsoft confirms the vulnerability
5 August 2026CVE-2026-68820 assigned
11 August 2026Patched on Patch Tuesday; added to CISA KEV the same day
Disclosure timeline. Sources disagree on June vs July start; Cyllex follows Check Point, BleepingComputer, and the five-weeks-before-patch framing. Source: original article.

Fixes: KB5121003 (Windows 11 → builds 26100.9168 and 26200.9168), KB5120249 (Windows 10 ESU). Because the fix replaces a kernel driver, install is not remediated until reboot. Dashboards that count “patched” on MSI install will lie.

FudModule 3.1: Unplugging the Cameras

An unplugged security camera next to a still-running laptop
The EDR process is still there. Nobody is telling it anything. That is data-only rootkit work.

FudModule is not persistence and not a backdoor. It is a data-only kernel rootkit whose job is unobservability. v3.1 is injected into SYSTEM msiexec.exe (two-hop: services.exe → msiexec). Gen Digital documented v3 in 2024; 3.1 keeps most of that teardown and adds Smart App Control tampering.

  • Callback teardown. Process, thread, image-load notify callbacks; object and registry callbacks. EDR still runs. It is not told.
  • Minifilter removal by altitude band. File-activity visibility for whole product classes, gone.
  • ETW blinding. Check Point: 94 provider GUIDs, matching the first 94 of Gen’s published 95, same order. NT Kernel Logger session killed.
  • Crash-dump suppression first. No dump, no bugcheck announcement.
  • Driver selection engine with preserve/kill rules so the host stays up.
  • WFP stage when Kaspersky is present and Symantec is absent — per-vendor branching.
  • Privileged handle forgery rather than requesting handles.

Shared log strings with v3, almost word-for-word: GetGodMode failed, GetSystemHandle passed., CreateRemoteProcess passed., RemoteDllExecute passed., the ClearVaccine* family. Removed: dedicated Defender stage against MsMpEng.exe (orphaned string SuspendDefender passed.; Gen’s YARA still has SuspendDefender skipped.) and PPL stripping of AhnLab asdsvc.exe. Defender is still blinded, via the generic suppressor.

The version bump: Smart App Control

Inside the SYSTEM msiexec child, the remote stub sets VerifiedAndReputablePolicyState to zero, then NtSetSystemInformation with information class 0xA4 and option 0x10000000. Windows re-reads code-integrity policy in place. No reboot, no policy file change on disk, the machine stops enforcing a control it still believes is on. ATT&CK T1553. Do not treat SAC as a load-bearing control against a kernel primitive.

VerifiedAndReputablePolicyState = 0;
NtSetSystemInformation(/* class */ 0xA4, /* option */ 0x10000000, ...);

Troy: 17 Commands and a PDB Left On

Troy is a newly documented 64-bit DLL RAT. Name from an unstripped PDB, which is both a hunting artefact and a look at the build box. ESET previously saw E:\Work\Troy\... in another Lazarus UAV-sector sample; this one is more specific:

E:\HK\Tool_Module\Troy_Handle\1Troy_Create_Dll_Tool\x64\Release\Test_Dll.pdb

Startup: iterate three hardcoded C2 URL/port pairs until the response is CONNECTED, challenge-response auth, then register with client id plus profile (user directory, account, Windows version, IPv4, cwd). Tasks are Base64. Results go back as:

{"to":"<channel>","msg":"<base64>"}

Large results are chunked. Check Point notes SET_CONFIG writes eight fields but only the idle interval takes effect at runtime; stored servers are not re-read and the port stays hardcoded to 80.

CommandCapability
WAITKeepalive no-op
DRIVESEnumerate mounted volumes
LIST|<path>Directory listing with timestamps
OPEN|<exe> [args]Launch executable, hidden window
DELETE|<path>Recursive file or folder delete
ZIPDOWNLOAD|<src>|<dst>PowerShell Compress-Archive, then upload
DOWNLOAD|<src>|<dst>Chunked file exfil
UPLOAD|<src>|<dst>Write a file to disk
CMD|<commandline>Interactive shell, 10-second watchdog
mem <dllpath> <pid>Reflective DLL injection, arch-matched
pk <pid>Terminate process by PID
sleep <N>One-shot delay, N minutes
DEFAULTSLEEPRevert to configured beacon interval
GET_CONFIG / SET_CONFIGRead or update eight stored config fields
pv / pvdProcess listing; pvd adds WMI command lines
Troy command set. Source: original article.

Injection is textbook: RWX in the remote process, write loader and payload, RtlCreateUserThread. Absent on purpose: no credential dump, no built-in lateral movement, no domain enum. Espionage against one engineer’s workstation, not ransomware prep. Check Point still saw ForestTiger as the long-term implant on the MISTPEN chain; Troy is the SecurityPDF chain’s hands-on tool.

RelayShell: Someone Else’s CMS Is the C2

Operator reaches the victim through VPN and a pool of compromised web relays
No attacker domain to block. Every hop the victim sees ends on a legitimate third-party site. Source: original article.

No attacker-owned C2 in the classic sense. Relays are compromised Roundcube, WordPress and PrestaShop hosts running a PHP webshell Check Point named RelayShell. At least 17 distinct relay identifiers. Operators egress via commercial VPN (ExpressVPN observed). Roundcube path: dark-web credential leaks, then CVE-2025-49113 (CVSS 9.9 authenticated PHP object deserialisation RCE in upload.php, patched in 1.5.10 / 1.6.11, on CISA KEV since February 2026). The relay pool cost a dump and a public exploit.

Two passwords, two modes. Victim mode: new PHP session, decrypt hidden config with a custom substitution cipher (backbone URL + unique PID), POST to the backbone to announce the session. Operator mode: pick latest .ses, connectivity check, upload/delete with Base64 paths, pull logs. After both sides are up, send/receive is file-based: <session_id><object>.log with 1 = victim, 2 = operator. No long-lived socket. If you run internet-facing Roundcube/WordPress/PrestaShop, those files under the webroot are your hunt, not theirs.

Kitchen table: They did not rent a server with a scary domain. They left notes in someone else’s shop window and both sides walk by to read them. Blocking the shop does not help if you do not know which shop. Hunting your own window for .ses files does.

ATT&CK Mapping (the IDs Other Write-ups Get Wrong)

Cyllex checked the live matrix. T1574.001 is now “Hijack Execution Flow: DLL”; T1574.002 is gone. Kernel LPE is T1068, not T1548.

StageTechniqueATT&CK ID
Recruiter approach over LinkedIn or messagingPhishing: Spearphishing via ServiceT1566.003
Mail with malicious attachment or linkSpearphishing Attachment, LinkT1566.001, T1566.002
Fake Enveil sites ranked in searchStage Capabilities: SEO PoisoningT1608.006
Lookalike vendor domainsAcquire Infrastructure: DomainsT1583.001
Victim opens archive or installs SecurityPDFUser Execution: Malicious FileT1204.002
SecurityPDF posing as a real viewerMasquerading: Match Legitimate Name or LocationT1036.005
libmupdf.dll beside a signed binaryHijack Execution Flow: DLLT1574.001
XOR and AES payload unpackingDeobfuscate/Decode Files or InformationT1140
MISTPEN and Troy staged in memoryReflective Code LoadingT1620
Host, process and AV profilingSystem Info, Process, Security Software DiscoveryT1082, T1057, T1518.001
Multi-monitor screenshotsScreen CaptureT1113
AFD.sys zero-day to SYSTEMExploitation for Privilege EscalationT1068
FudModule into SYSTEM msiexec, Troy memProcess InjectionT1055
Callbacks, minifilters, ETW torn downImpair Defenses: Disable/Modify Tools, Indicator BlockingT1562.001, T1562.006
Smart App Control policy state resetSubvert Trust ControlsT1553
Kernel-resident concealmentRootkitT1014
Graph API and OneDrive command channelWeb Service: Bidirectional CommunicationT1102.002
RelayShell on hijacked CMS and webmailWeb Shell, Compromise InfrastructureT1505.003, T1584
Troy CMD and ZIPDOWNLOADWindows Command Shell, PowerShellT1059.003, T1059.001
Archive and exfil over C2Archive via Utility, Exfiltration Over C2 ChannelT1560.001, T1041
On-disk persistence after rebootRegistry Run Keys, Scheduled TaskT1547.001, T1053.005
Operator egress through commercial VPNProxy: Multi-hop ProxyT1090.003
Full-chain ATT&CK map. Source: original article.

Where the Detection Window Actually Is

Intrusion split into a detection window above the exploit and a blind zone below
Everything you can catch is above the red line. Below it, events are never generated. Source: original article.

Once T1068 succeeds and FudModule is resident, endpoint telemetry stops being evidence. Hunts return clean because the data was never born. Any strategy that depends on catching the rootkit after landing has already lost. The question collapses to: can you see the chain before ring 0?

  • Anomalous image loads. A MuPDF-family binary loading a DLL from its own directory whose signer does not match the vendor. Highest-value signal, fires first.
  • Process lineage. A document viewer spawning new.exe or any unsigned child. Legitimate readers do not create executables.
  • Graph API from the wrong process. graph.microsoft.com / login.microsoftonline.com from something that is not Office, OneDrive, or a known LoB app. You cannot block the destination. Identify the caller.
  • SYSTEM msiexec.exe with no MSI. Implausible parent, no installer on the command line: FudModule’s injection target.
  • Telemetry going quiet. Absence of expected ETW/EDR events on a host that used to emit them. The one signal that survives the rootkit. Almost nobody instruments it.
  • Smart App Control state changes with no policy deployment.
  • Server-side artefacts: .ses and <id>1.log / <id>2.log under Roundcube/WordPress/PrestaShop webroots; Roundcube auths from unexpected ASNs just before.

The best detection opportunity in this whole intrusion is a DLL load inside a PDF reader, about five minutes in, long before any of it looks like an attack.

Cyllex

How to Emulate This Kill Chain (Without the Zero-Day)

Reading an advisory is not a test of your environment. Run behaviours in order so you learn the first visible hop, not a flat checklist. Do not weaponise CVE-2026-68820. Be sceptical of any tool that offers to.

  1. Delivery and execution. Emulate T1574.001, T1204.002, T1036.005 with a benign side-loaded library next to a signed binary. If image-load does not fire here, later does not matter.
  2. Discovery and collection. T1082, T1057, T1518.001, T1113. Cheap, noisy, often unalerted. Many teams learn here that screen capture is silent.
  3. Cloud-service C2. T1102.002 against a legitimate cloud endpoint from an unusual process. Correlate in Sentinel/MDE and in whatever holds the web-server tail.
  4. Escalation and evasion, simulated only. Safe proxies for T1068, T1055, T1562.001, T1553: an unprivileged handle that should not open, a benign injection into a lab SYSTEM process, a reversible tamper with a test ETW provider, a SAC state read. Not the race.
  5. Score per technique, not per campaign. A pass/fail for “Lazarus” is useless. Verdicts per ID, with the events that prove them.

Emulation does not tell you whether hosts were vulnerable to the AFD race. That is inventory plus reboot after KB5121003. It does tell you whether the surrounding behaviours are visible. Most organisations were patched within days of 11 August. Far fewer can prove they would have seen an unsigned DLL load into a signed PDF viewer on 3 July.

ATT&CK Enterprise matrix in detection mode with per-technique colours
What the answer should look like: per-technique verdicts on the matrix. Lab exercise from a Cyllex build, not this campaign. Cells that matter here: T1574.001, T1068, T1562.001. Source: original article.

Cyllex positions this post as the spec for a pre-release emulation profile. That is product context, not a finding. The detection argument stands without the product.

What Actually Reduces Exposure

  • Patch, then confirm the reboot. KB5121003 / KB5120249. Report reboot compliance, not install compliance.
  • Alert on missing telemetry. ETW providers and EDR agents that go silent on a previously chatty host. Against a suppression rootkit, absence is the signal.
  • Do not rely on Smart App Control alone. Pair with WDAC and ASR rules that constrain what a document viewer may spawn.
  • Attribute cloud egress to processes. Blocking graph.microsoft.com is not an option. Ask which binaries legitimately hold Graph tokens.
  • Harden internet-facing CMS and webmail. Roundcube ≥ 1.5.10 or 1.6.11, MFA on webmail, hunt your own webroots for stray .ses/.log. Your marketing WordPress is somebody’s relay.
  • Brief the people being targeted. Defence/aerospace/drone/robotics engineers, a recruiter conversation that runs two weeks, sometimes from a compromised peer mailbox. Generic phishing training does not cover that.

A five-week zero-day window means patching was never available as a control. What was available, the entire time, was noticing that a signed PDF reader had loaded a DLL nobody signed. Go and find out whether yours would have.

Cyllex

Indicators (Cyllex table, then Check Point’s fuller set)

TypeIndicator
Domainsenvell[.]xyz, enveil[.]online, uxtramine[.]org
IP addresses135.181.67[.]203, 135.181.185[.]158
Side-loaded DLLlibmupdf.dll (malicious build, beside a signed MuPDF viewer)
MISTPEN modulesRelease_GetInfoPlugin_x64.dll, Release_PvPlugin_x64.dll, OneScreenCapture64.dll
Dropped executablenew.exe (written by SecurityPDF)
PDF trigger markerThis document is encrypted with sumatrapdf reader!!!!!!!!!!!!
Troy PDB pathE:\HK\Tool_Module\Troy_Handle\1Troy_Create_Dll_Tool\x64\Release\Test_Dll.pdb
FudModule 3.1 SHA-2563b6378df8442e63a6ed7317075913e4720847a510d95022d4a8347b2637c245d
Troy sample SHA-256590fb6ae19480d694e08ee85859cad8066f2f87e7e5abba2960c6d115e1615d6
Webshell artefacts*.ses, <session_id>1.log, <session_id>2.log under a webroot
Cyllex IOC table. Follow VirusTotal links from the original post rather than hitting attacker hosts. Source: original article.

Malpedia: FudModule (Lazarus, prior write-ups and YARA), MISTPEN (UNC2970; the family predates this campaign, only this delivery is new). Troy had no Malpedia entry at Cyllex’s publish time. NVD: CVE-2026-68820. Additional SHA-256 from Check Point’s IOC section, not in the Cyllex table, reproduced here as an addition:

FamilySHA-256 (Check Point)
SecurityPDF.exe743172aab606974b054a64561534ae66baa3a840657f79d7c6fa18350e8d45d1
SecurityPDF.exedb3d69b7eeda2e35e23006bf4b7e206281fce809584207214fc213f9bc30376d
Troy68d4fba7b1300a59cd6212c08910a260cd71b40cd9f51cac933030a68faac0bb
Troya738059ce07c951c31ab2da3d93d8f69bff32f9b7d933dbf5943441b9cc99075
RelayShell21c3ad4838c4324bc5f081021da5fb2e9073d0c9304087811c21eb47c9e22762
RelayShellcc4e06aa378a190f71384c03023bb3d18a6d66e297d46701220e132963d2e222
ForestTiger72dccae85e062f541fecad9ec7a18a3123e7ae5ac5d53c91709b53a46dbbd289
Subset of Check Point hashes. The CPR post lists more loader/MISTPEN/PDF-payload hashes; use that page for the full set.

RelayShell YARA from Check Point Research (verbatim):

rule lazarus_relayshell
{
  meta:
    author = "@_CPResearch_"
    description = "Lazarus RelayShell Webshell"
    target_entity = "file"
    hash = "21c3ad4838c4324bc5f081021da5fb2e9073d0c9304087811c21eb47c9e22762"
  strings:
    $str1 = "'PqCWom'"
    $str2 = "'a84038'"
    $str3 = "'biwbih'"
    $str4 = "'ddf7acea'"
    $str5 = "'enRU904U'"
    $str6 = "'fou2rm'"
    $str7 = "'kurhiW'"
    $str8 = "'qcrgl'"
    $str9 = "'rlzbiw'"
    $str10 = "'tmmvr1'"
    $str11 = "'win386'"
    $str12 = "\"biwbih\""
    $str13 = "\"PqCWom\""
    $str14 = "\"a84038\""
    $str15 = "\"ddf7acea\""
    $str16 = "\"enRU904U\""
    $str17 = "\"fou2rm\""
    $str18 = "\"kurhiW\""
    $str19 = "\"qcrgl\""
    $str20 = "\"rlzbiw\""
    $str21 = "\"tmmvr1\""
    $str22 = "\"win386\""
    $str23 = "D9hWnVEqdgzJ67/B8euS0yKCIMrw5jc:fGUX3AakLH2oYQRp"
  condition:
    3 of ($str*)
}

Operator Notes the Original Left Implicit

  • Do not write or run an AFD race PoC against production. The patch is the control. The detection gap is the DLL load.
  • Image-load: Sysmon Event 7 (if you still collect it; many shops dropped it for volume) or equivalent EDR module-load. Filter: signed parent, unsigned or differently signed DLL, path = parent directory, parent name matches PDF/MuPDF/Sumatra/SecurityPDF.
  • new.exe from a viewer: Sysmon 1 / 4688 parent-child. ASR rules that block Office/PDF children from creating executables are the cheap prevent.
  • Graph from the wrong process: Defender for Endpoint deviceNetworkEvents or equivalent, join to process. Not a DNS block.
  • Silent host: baseline daily ETW provider volume per device, alert on a drop. That is the post-rootkit signal.
  • Webroots: find /var/www -name ‘*.ses’ -o -name ‘*1.log’ -o -name ‘*2.log’ is a start, not a complete hunt. Also Roundcube version and leaked-credential resets.
For operators: FudModule targeting only 26100/26200 means a 23H2 box was out of scope for this exploit build, not safe. The vulnerability class in AFD is a serial. Inventory builds, reboot after KB5121003, and still hunt the side-load because the next FudModule will pick a new IOCTL.

What Check Point Saw That Cyllex Compressed

Cyllex is the defender’s cut. Check Point is the RE cut. A few facts that matter once you are hunting, and that the shorter post only implied.

ForestTiger is still on the MISTPEN chain

After recon, persistence, and FudModule, MISTPEN’s long-term backdoor on chain 1 is ForestTiger, a previously documented Lazarus family, not Troy. Troy is chain 2. If your hunt is only for the Troy PDB, you will miss the ZIP-and-side-load victims. ForestTiger historically used compromised WordPress and SharePoint; this wave shifted C2 toward Roundcube. Same actor, two implants, two channels. Correlate by victimology and timing, not by a single hash family.

SecurityPDF patches two open paths

The trojan is not a new viewer from scratch. It is MuPDF with File → Open and drag-and-drop hooked. That means a user who never uses the Open dialog and only double-clicks a PDF from Explorer still hits the marker check if the shell association launches this binary. Hunt both: the viewer as a downloaded EXE named like a security product, and the association change if they installed it.

MISTPEN persistence is a later module

Cyllex emphasises the in-memory footprint. Check Point is explicit that after the host looks like a real target, MISTPEN receives a persistence module that drops on disk so the downloader survives reboot. That is T1547.001 / T1053.005 in the ATT&CK table. Hunt Run keys and scheduled tasks created by a PDF-viewer lineage, not only in-memory loaders. The “no disk footprint” claim is true for the first hours, not for a host that passed fingerprinting.

The LPE sample looks like FudModule 2024 on purpose

Afd4Eop12_x64.dll’s main is similar to the 2024 variant; strings still say god mode. The exploit is new; the post-exploit is a maintained product. Targeting narrowed to 26100/26200. If you still have 23H2 or Windows 10 ESU unpatched, you are in the vulnerability set even if this build of the exploit would have refused you. Patch the class, not the sample.

RelayShell is not a command shell

Operators do not get a PHP system() box. They get a drop-box. Victim implant and operator browser both write files. Backbone URL is another RelayShell. Taking down one node costs them one of seventeen. Your win is finding the files, the version of Roundcube, and the reused password, not sinking a C2 domain that does not exist.

Hunting Queries You Can Actually Run

These are ours, not Cyllex’s. They encode the pre-ring-0 window. Tune table names to your SIEM. Do not paste them into production without a volume check.

# Sysmon 7 / EDR module load: signed PDF parent, DLL from same directory
DeviceImageLoadEvents
| where FileName has_any ("libmupdf.dll","mupdf.dll")
    or InitiatingProcessFileName has_any ("SecurityPDF","SumatraPDF","mupdf")
| where FolderPath startswith InitiatingProcessFolderPath
| where InitiatingProcessSigner != Signer or isempty(Signer)
# Viewer spawning new.exe
DeviceProcessEvents
| where InitiatingProcessFileName has_any ("SecurityPDF.exe","SumatraPDF.exe")
| where FileName =~ "new.exe" or FolderPath has @"\Temp\"
# Graph API from a process that should not hold a token
DeviceNetworkEvents
| where RemoteUrl has_any ("graph.microsoft.com","login.microsoftonline.com")
| where InitiatingProcessFileName !in ("OUTLOOK.EXE","WINWORD.EXE","EXCEL.EXE","OneDrive.exe","Teams.exe","Msedge.exe")
| where InitiatingProcessFileName has_any ("SecurityPDF","mupdf","msiexec","new.exe")
# SYSTEM msiexec with no MSI on the command line
DeviceProcessEvents
| where FileName =~ "msiexec.exe" and ProcessIntegrityLevel == "System"
| where ProcessCommandLine !has ".msi" and ProcessCommandLine !has "/i"

Webroot hunt on a Linux CMS host, as a starting point, not a complete audit:

find /var/www /usr/share/nginx /home/*/public_html -type f \(
  -name '*.ses' -o -name '*1.log' -o -name '*2.log'
\) 2>/dev/null
For operators: Sysmon 7 is loud. If you dropped it, ask your EDR vendor for an equivalent image-load event with signer fields. Without that event you cannot see T1574.001, which is the only cheap win in this campaign.

Why Five Weeks Is the Number That Should Anger You

MSRC got the bug on 28 July. Patch Tuesday was 11 August. Exploitation started early July. For those five weeks the only available controls were the ones that do not need a Microsoft update: image-load, child-process, Graph-by-process, Roundcube hygiene. If your programme treats “we patch in 14 days” as the kernel-LPE story, this campaign is the counterexample. KEV listing on the same day as the patch is Microsoft and CISA telling civilian agencies to move. It does not resurrect telemetry FudModule already deleted on a host that was hit in July.

Sources disagree on June versus July for first exploitation. Cyllex follows the majority (Check Point timeline, BleepingComputer, five-weeks-before-patch). If your IR timeline needs a conservative start, use early June and hunt side-loads from then. False positives on PDF readers are cheaper than missing a Dream Job box that has been quiet since June.

What This Is Not

  • It is not a remote worm. CVE-2026-68820 is local. The remote part is a human opening a job PDF.
  • It is not ransomware. Troy does not dump LSASS or walk the domain. The goal is files off a specific engineer.
  • It is not BYOVD in the 2021 sense. No third-party .sys. Your blocklist did not get a vote.
  • It is not “undetectable.” It is undetectable after DestroyEnv. Before that it is a DLL next to a signed EXE.
  • It is not an Enveil breach. The brand was stolen for SEO. Do not page their CISO; page your aerospace hiring managers.
  • Emulation is not a substitute for patch inventory. Cyllex is explicit. So is this draft.

A Short Ring-0 Glossary for People Who Do Not Live in WinDbg

  • Ring 0 is kernel mode. User apps are ring 3. A kernel R/W primitive lets ring 3 edit ring 0 memory, including the token that says who you are.
  • afd.sys is the kernel half of Winsock. Sockets are not “just user mode.”
  • Use-after-free (CWE-416): one path frees an object, another path still has a pointer, a third allocation (yours) lands in the hole.
  • Data-only rootkit: no new kernel code, just unlinked lists and zeroed function pointers. PatchGuard is less angry; your EDR is more blind.
  • ETW is the firehose Defender, Sysmon-adjacent tools and hunting queries drink from. Kill 94 GUIDs and the hose is dry.
  • Smart App Control is a reputation gate on Windows 11. Setting its policy state to zero from the kernel is not a Group Policy change you will see in GPResult.

Key Takeaways

  • Lazarus spent a kernel zero-day on a fake job PDF. The expensive part was not the lure. It was the five weeks before Patch Tuesday.
  • CVE-2026-68820 is a local AFD.sys UAF. CVSS 7.0 hides that it skips every BYOVD control you bought after 2021.
  • The exploit is fingerprint-gated. Sandboxes on the wrong build never receive it. Absence of a sample is not absence of exploitation.
  • FudModule 3.1 does not persist you. It unplugs callbacks, minifilters, 94 ETW GUIDs, crash dumps, and Smart App Control without a reboot.
  • After ring 0, hunts return clean because events were never generated. The window is the unsigned DLL in the signed viewer, minutes in.
  • C2 is Graph/OneDrive or someone else’s Roundcube. There is no attacker domain to block. There are .ses files in your webroot.
  • Patch is necessary and insufficient until reboot. Emulation should not include the race. It should include the side-load.

Defensive Recommendations

  1. Ship KB5121003 / KB5120249 and measure reboot, not MSI install. Unrebooted hosts are still in the KEV set.
  2. Alert on MuPDF/PDF viewers loading a same-directory DLL with a signer mismatch. That is T1574.001 and the best pre-ring-0 catch.
  3. Block document processors from spawning new.exe / unsigned children (ASR / WDAC). Chain 2 dies there even if the viewer is allowed.
  4. Tag Graph and login.microsoftonline.com traffic by process. Investigate PDF readers and msiexec holding tokens.
  5. Treat ETW/EDR silence as an incident, not as health. Baseline, then alert on drop.
  6. Assume Smart App Control can be switched off from the kernel. Complement with WDAC.
  7. Patch Roundcube, MFA webmail, hunt .ses and <id>N.log on every internet CMS you own. You are potential Lazarus infrastructure.
  8. Train defence and aerospace engineers on two-week recruiter lures and mail from compromised peer domains, not just generic phishing.

Conclusion

Dream Job is an old play. What is new is spending a kernel race in a Microsoft inbox driver so the rest of the play becomes invisible. Cyllex’s point, and Check Point’s, is that the SOC question is not “would we have caught FudModule?” — after DestroyEnv, there is nothing to catch. The question is whether a signed PDF reader loading libmupdf.dll from its own folder would have lit anything up on 3 July, when patching was not a control that existed. Go find out. Then reboot the boxes that think they already did.

Original text: “From Job Offer to Ring 0: Lazarus, CVE-2026-68820 and FudModule 3.1” by author not clearly listed (site: Cyllex) at Cyllex. Primary analysis: Check Point Research.

oxfemale Vulnerability research, reverse engineering, and exploit development.
// Discussion