Back to Intelligence

Lunex MaaS BYOVD Campaign Targeting Ukraine: Kernel Callback Manipulation via AMD PDFWKRNL.sys (CVE-2023-20598) — OTX Detection Pack

SA
Security Arsenal Team
October 6, 2026
9 min read

Threat Summary

AlienVault OTX pulse data identifies an active Malware-as-a-Service (MaaS) operation, Lunex, conducting targeted intrusions against users in Ukraine. The campaign chains a two-stage payload architecture — LunexLoader and LunexStealer — delivered through fake CAPTCHA lure pages, a social-engineering vector that has become the dominant initial-access method for commodity infostealer operations since 2024.

What elevates this campaign above standard stealer activity is its use of a Bring Your Own Vulnerable Driver (BYOVD) technique. LunexLoader drops and loads PDFWKRNL.sys, a legitimately signed AMD driver vulnerable to CVE-2023-20598, which exposes kernel memory read/write primitives to unprivileged user-mode processes. The loader then performs a particularly sophisticated maneuver: it retrieves Windows kernel debugging symbols directly from Microsoft's public Symbol Server and uses them to dynamically resolve the addresses of security-relevant kernel callbacks (process creation notify routines, thread callbacks, object manager callbacks, and minifilter registrations). It then zeros these callback structures in kernel memory, effectively blinding EDR and antivirus products without ever touching their user-mode binaries, files, or services — bypassing tamper protection entirely.

With telemetry blinded, LunexStealer is deployed with a dual objective: credential harvesting (browser-stored passwords, session tokens, autofill data) and cryptocurrency wallet theft. Persistence is established via a malicious browser Native Messaging Host registration, a stealthy mechanism that survives reboots and blends into legitimate browser configuration.

The IOC set accompanying the pulse also bundles a broader exploitation toolkit of public CVEs (CVE-2021-4034 / PwnKit, CVE-2022-30190 / Follina, CVE-2022-26134 / Confluence RCE, CVE-2022-21894 / BlackLotus Secure Boot bypass, CVE-2021-3493, CVE-2017-7921, CVE-2021-21974), suggesting the operators maintain lateral-movement and privilege-escalation capability beyond the initial phishing kill chain.

Assessment: This is a financially motivated MaaS operation with nation-state-grade evasion tradecraft, geographically focused on Ukraine. Organizations with Ukrainian operations, users, or partner networks should treat this as a high-priority hunt target.

Threat Actor / Malware Profile

LunexLoader (Stage 1)

  • Distribution: Fake CAPTCHA pages (ClickFix-style lures) instructing victims to run malicious commands or download executables, targeting Ukrainian-language users.
  • Payload behavior: Drops the vulnerable signed AMD driver PDFWKRNL.sys and loads it via service creation (CreateService/NtLoadDriver patterns).
  • Exploitation: Abuses CVE-2023-20598 — an insufficient access-control flaw in the AMD PDFWKRNL driver allowing arbitrary physical memory access from user mode.
  • EDR evasion: Resolves ntoskrnl.exe symbols by downloading PDBs from msdl.microsoft.com/download/symbols, dynamically locating callback arrays (e.g., PspCreateProcessNotifyRoutine, PspCreateThreadNotifyRoutine, PspLoadImageNotifyRoutine) and zeroing entries registered by security products. This is a kernel callback manipulation technique that defeats tamper protection because security-agent files are never modified.

LunexStealer (Stage 2)

  • Objective: Credential theft and cryptocurrency wallet theft — browser credential stores, cookies/session tokens, and wallet extension data (e.g., MetaMask, Phantom, Exodus paths).
  • C2 communication: HTTPS-based beaconing and staged exfiltration to MaaS-operated infrastructure; typical of stealer panels using encrypted archives for bulk upload.
  • Persistence: Registers a Native Messaging Host manifest in browser extension configuration directories and associated registry keys (HKCU\Software\Google\Chrome\NativeMessagingHosts\*, equivalent for Edge/Firefox), ensuring re-execution through the browser's native messaging API.
  • Anti-analysis: Kernel-level telemetry suppression inherited from the loader stage; symbol-resolution logic avoids hardcoded offsets, surviving PatchGuard-adjacent detection and OS build variance.

IOC Analysis

The pulse contains 40 indicators, dominated by CVE identifiers — meaning the primary operational value is vulnerability exposure mapping, not static blocklisting. Key guidance for SOC teams:

  • CVE-2023-20598 is the crown jewel: hunt for PDFWKRNL.sys loads regardless of version, since the vulnerable driver is legitimately signed and will pass signature checks. Maintain a vulnerable driver blocklist (Microsoft's recommended Driver SI policy / loldrivers.io dataset) and alert on any load of hashes listed there.
  • The bundled CVEs (CVE-2021-4034, CVE-2022-30190, CVE-2022-26134, CVE-2022-21894) should be cross-referenced against your vulnerability management platform to confirm patch posture on internet-facing Confluence instances, Windows endpoints (Follina/MSDT), and Secure Boot configurations.
  • File-hash and network IOCs (from the full 40-indicator pulse) should be ingested into your SIEM/EDR via OTX DirectConnect or the OTX API pulse export, with retro-hunts run across 90 days of process, network, and DNS telemetry.
  • Tooling: OTX DirectConnect agents for SIEM ingestion; loldrivers.io + Sigma's vulnerable driver rules for BYOVD coverage; YARA rules from the referenced PolySwarm analysis for LunexStealer payload detection; Sysmon Event IDs 6 (driver load), 7 (image load), and 1 (process creation) as the core telemetry substrate.

Detection Engineering

YAML
---
title: Vulnerable AMD PDFWKRNL Driver Load - BYOVD LunexLoader
id: 7c1a2e4d-3b8f-4a1e-9d2c-5f6e7a8b9c01
status: experimental
description: Detects loading of the AMD PDFWKRNL.sys driver abused by LunexLoader via CVE-2023-20598 for BYOVD kernel callback manipulation. Alert on any load of this driver on non-AMD systems or from non-standard paths.
author: Security Arsenal Threat Intelligence
references:
  - https://blog.polyswarm.io/lunex-uses-byovd-to-disable-security-monitoring-and-deploy-persistent-stealer
  - https://www.cve.org/CVERecord?id=CVE-2023-20598
date: 2026/10/06
logsource:
  category: driver_load
  product: windows
detection:
  selection_name:
    ImageLoaded|endswith: '\pdfwkrnl.sys'
  filter_amd_legit:
    ImageLoaded: 'C:\Windows\System32\drivers\PDFWKRNL.sys'
  condition: selection_name and not filter_amd_legit
falsepositives:
  - Legitimate AMD platform driver installations on AMD hardware (tune filter to hardware inventory)
level: high
tags:
  - attack.defense_evasion
  - attack.t1068
  - attack.t1562.001
---
title: Kernel Symbol Download From Microsoft Symbol Server By Non-Debug Process
id: 8d2b3f5e-4c9a-5b2f-ae3d-6a7f8b9c0d12
status: experimental
description: Detects processes other than legitimate debuggers retrieving kernel PDB symbols from Microsoft's Symbol Server - a technique used by LunexLoader to resolve and zero EDR kernel callbacks.
author: Security Arsenal Threat Intelligence
references:
  - https://blog.polyswarm.io/lunex-uses-byovd-to-disable-security-monitoring-and-deploy-persistent-stealer
date: 2026/10/06
logsource:
  category: process_creation
  product: windows
detection:
  selection_img:
    Image|endswith:
      - '\powershell.exe'
      - '\pwsh.exe'
      - '\cmd.exe'
      - '\rundll32.exe'
      - '\regsvr32.exe'
      - '\wscript.exe'
      - '\cscript.exe'
      - '\mshta.exe'
  selection_cl:
    CommandLine|contains:
      - 'msdl.microsoft.com'
      - 'download/symbols'
      - 'ntkrnlmp.pdb'
      - 'ntoskrnl.pdb'
  condition: all of selection_*
falsepositives:
  - Rare; legitimate symbol downloads are typically performed by windbg.exe, kd.exe, or symchk.exe which are excluded from the image list
level: high
tags:
  - attack.defense_evasion
  - attack.t1562.001
  - attack.t1027
---
title: Suspicious Browser Native Messaging Host Registration - LunexStealer Persistence
id: 9e3c4a6f-5d0b-6c3a-bf4e-7b8a9c0d1e23
status: experimental
description: Detects creation or modification of browser Native Messaging Host registry keys and manifest files by non-browser processes, a persistence mechanism used by LunexStealer.
author: Security Arsenal Threat Intelligence
references:
  - https://blog.polyswarm.io/lunex-uses-byovd-to-disable-security-monitoring-and-deploy-persistent-stealer
date: 2026/10/06
logsource:
  category: registry_set
  product: windows
detection:
  selection_key:
    TargetObject|contains:
      - '\Google\Chrome\NativeMessagingHosts\'
      - '\Microsoft\Edge\NativeMessagingHosts\'
      - '\Mozilla\NativeMessagingHosts\'
  filter_browsers:
    Image|endswith:
      - '\chrome.exe'
      - '\msedge.exe'
      - '\firefox.exe'
      - '\msiexec.exe'
  condition: selection_key and not filter_browsers
falsepositives:
  - Enterprise software installers registering legitimate native messaging hosts (password managers, SSO agents) - baseline and whitelist per environment
level: medium
tags:
  - attack.persistence
  - attack.t1176
  - attack.t1546
KQL — Microsoft Sentinel / Defender
// Lunex Campaign Hunt: BYOVD driver load + symbol server retrieval + native messaging persistence
// Microsoft Sentinel / Defender XDR - run across last 30 days
let VulnDrivers = dynamic(["pdfwkrnl.sys"]);
let SymbolHosts = dynamic(["msdl.microsoft.com"]);
union isfuzzy=true
(DeviceEvents
 | where TimeGenerated > ago(30d)
 | where ActionType == "DriverLoad" or (ActionType == "FileCreated" and FileName has_any (VulnDrivers))
 | where FileName has_any (VulnDrivers) or FolderPath has "pdfwkrnl"
 | project TimeGenerated, DeviceName, ActionType, FileName, FolderPath, SHA256, InitiatingProcessFileName, InitiatingProcessCommandLine),
(DeviceNetworkEvents
 | where TimeGenerated > ago(30d)
 | where RemoteUrl has_any (SymbolHosts) and RemoteUrl has "symbols"
 | where InitiatingProcessFileName !in~ ("windbg.exe","kd.exe","symchk.exe","devenv.exe","procmon.exe","procexp.exe")
 | project TimeGenerated, DeviceName, InitiatingProcessFileName, InitiatingProcessCommandLine, RemoteUrl, RemoteIP),
(DeviceRegistryEvents
 | where TimeGenerated > ago(30d)
 | where RegistryKey has "NativeMessagingHosts"
 | where InitiatingProcessFileName !in~ ("chrome.exe","msedge.exe","firefox.exe","msiexec.exe")
 | project TimeGenerated, DeviceName, ActionType, RegistryKey, RegistryValueName, RegistryValueData, InitiatingProcessFileName, InitiatingProcessCommandLine),
(DeviceProcessEvents
 | where TimeGenerated > ago(30d)
 | where ProcessCommandLine has_any ("NtLoadDriver","pdfwkrnl","\\.\\PDFWKRNL","PspCreateProcessNotifyRoutine","PspCreateThreadNotifyRoutine")
 | project TimeGenerated, DeviceName, FileName, ProcessCommandLine, InitiatingProcessFileName)
| sort by TimeGenerated desc
PowerShell
# Lunex IOC Hunt Script - Security Arsenal Threat Intelligence
# Checks for: vulnerable AMD driver presence, native messaging persistence, stealer wallet-target artifacts
# Run elevated on endpoints; output JSON per host for SIEM ingestion.

$report = [ordered]@{ Host = $env:COMPUTERNAME; Time = (Get-Date -Format o); Findings = @() }

# 1. BYOVD: hunt for PDFWKRNL.sys anywhere on disk + loaded driver check
$driverHits = Get-ChildItem -Path "C:\Windows","C:\Users","C:\ProgramData" -Recurse -Filter "pdfwkrnl.sys" -ErrorAction SilentlyContinue
foreach ($d in $driverHits) {
    $hash = (Get-FileHash $d.FullName -Algorithm SHA256).Hash
    $report.Findings += [ordered]@{ Type="BYOVD_Driver"; Path=$d.FullName; SHA256=$hash; Severity="Critical" }
}
$loaded = Get-CimInstance Win32_SystemDriver -ErrorAction SilentlyContinue | Where-Object { $_.PathName -match "pdfwkrnl" }
if ($loaded) { $report.Findings += [ordered]@{ Type="BYOVD_Driver_Loaded"; Path=$loaded.PathName; State=$loaded.State; Severity="Critical" } }

# 2. Persistence: suspicious Native Messaging Host registrations
$nmhRoots = @(
  "HKCU:\Software\Google\Chrome\NativeMessagingHosts",
  "HKCU:\Software\Microsoft\Edge\NativeMessagingHosts",
  "HKCU:\Software\Mozilla\NativeMessagingHosts",
  "HKLM:\Software\Google\Chrome\NativeMessagingHosts"
)
foreach ($root in $nmhRoots) {
    if (Test-Path $root) {
        Get-ChildItem $root -ErrorAction SilentlyContinue | ForEach-Object {
            $manifest = (Get-ItemProperty $_.PSPath).'(default)'
            if ($manifest -and (Test-Path $manifest -ErrorAction SilentlyContinue)) {
                $m = Get-Content $manifest -Raw -ErrorAction SilentlyContinue
                $report.Findings += [ordered]@{ Type="NativeMessagingHost"; Key=$_.PSPath; Manifest=$manifest; Content=$m; Severity="Medium" }
            }
        }
    }
}

# 3. Stealer targeting: crypto wallet extension data recently accessed/copied (heuristic)
$walletPaths = @("$env:LOCALAPPDATA\Google\Chrome\User Data\Default\Local Extension Settings\nkbihfbeogaeaoehlefnkodbefgpgknn") # MetaMask
foreach ($w in $walletPaths) {
    if (Test-Path $w) {
        $recent = Get-ChildItem $w -Recurse -ErrorAction SilentlyContinue | Where-Object { $_.LastWriteTime -gt (Get-Date).AddDays(-7) }
        if ($recent) { $report.Findings += [ordered]@{ Type="WalletData_RecentModification"; Path=$w; Files=($recent.FullName -join ";"); Severity="High" } }
    }
}

# 4. Symbol server retrieval artifacts in DNS cache
$dns = Get-DnsClientCache -ErrorAction SilentlyContinue | Where-Object { $_.Entry -match "msdl.microsoft.com" }
if ($dns) { $report.Findings += [ordered]@{ Type="SymbolServer_DNS"; Entries=($dns.Entry -join ";"); Severity="High" } }

$report | ConvertTo-Json -Depth 5

Response Priorities

Immediate (0–4h):

  • Deploy the Microsoft Vulnerable Driver Blocklist (Driver SI policy) in enforce mode if not already active; explicitly add PDFWKRNL.sys hashes from the loldrivers dataset.
  • Run the KQL hunt and PowerShell sweep across all endpoints, prioritizing assets used by Ukrainian personnel or handling crypto/credential material.
  • Block msdl.microsoft.com/download/symbols egress for non-engineering endpoints at the proxy — legitimate symbol resolution should be confined to IR/debug workstations.
  • Ingest the full 40-indicator OTX pulse into the SIEM and execute 90-day retro-hunts.

Within 24 hours:

  • Because LunexStealer harvests browser credentials and session tokens, any host with a confirmed or suspected hit requires forced enterprise-wide credential reset for that user (not just the local machine): revoke active sessions, rotate cookies-derived tokens (M365, Google Workspace, VPN), and invalidate SSO sessions.
  • Audit crypto wallet exposure: users with browser wallet extensions on affected hosts should treat wallets as compromised and migrate funds to fresh keys.
  • Validate EDR kernel callback integrity — some EDRs expose health telemetry on callback registration; an unexpected deregistration is itself a detection signal.

Within 1 week:

  • Enable Memory Integrity (HVCI) and Credential Guard via Intune/GPO; HVCI significantly raises the cost of BYOVD kernel-memory abuse.
  • Restrict driver installation to administrators and enforce Attack Surface Reduction rules blocking vulnerable driver loads (ASR rule: block abuse of exploited vulnerable signed drivers).
  • Harden browser policy: enterprise-manage extension allowlists and monitor/restrict Native Messaging Host registration via policy where feasible.
  • Patch audit against the bundled CVE set (CVE-2022-30190 MSDT mitigation, CVE-2022-26134 Confluence, CVE-2022-21894 Secure Boot DBX update).

Related Resources

Security Arsenal Incident Response Managed SOC & MDR Services AlertMonitor Threat Detection From The Dark Side Intel Hub

Is your security operations ready?

Get a free SOC assessment or see how AlertMonitor cuts through alert noise with automated triage.