Lunex Stealer – BYOVD Defense Evasion and Browser Credential Theft

Threat Overview

Ontinue published the first detailed binary analysis of the Lunex malware-as-a-service platform on September 24, 2026; The Hacker News highlighted the campaign on September 26. The analyzed four-stage Windows chain begins with a fake CAPTCHA/ClickFix lure that instructs the user to run msiexec, installs an MSI under %LOCALAPPDATA%, bypasses UAC through the auto-elevating CMSTPLUA COM object, loads a vulnerable AMD PDFWKRNL.sys driver, and uses kernel-memory primitives to disable security callbacks without terminating protected products. Lunex then steals Chromium credentials, cookies, tokens, autofill and wallet data, injects a malicious browser extension, and establishes persistent remote filesystem access through Chrome/Edge Native Messaging Hosts backed by PowerShell. Ontinue found 28 operator panels across 13 countries, indicating expansion beyond a single campaign.

References

Impacted Systems

  • Platform: Windows 10 and Windows 11 endpoints; the analyzed loader is 64-bit Windows malware.
  • Initial access: User interaction with a fake CAPTCHA/ClickFix page and execution of an attacker-provided msiexec command.
  • Install context: Per-user MSI under %LOCALAPPDATA%\Programs\Internal Software\Vertification\; initial installation does not require administrator rights.
  • Privilege/driver stage: CMSTPLUA UAC bypass followed by service creation/loading of AMD PDFWKRNL.sys vulnerable to CVE-2023-20598.
  • Targeted applications: Chrome, Edge, Brave, Yandex Browser, Opera, Opera GX, Vivaldi; multiple desktop and browser cryptocurrency wallets.
  • Persistence: Registry Run value, hidden scheduled task psychedelicloveUtils, Chrome and Edge Native Messaging Host key com.lunex.explorer, and malicious browser extension.
  • AMD fixed versions: Adrenalin Edition 23.9.2 or later and PRO Edition 23.Q4 or later for affected product lines. The campaign carries its own vulnerable driver, so an installed newer AMD package alone does not block BYOVD loading.

Why this matters

The campaign combines highly reusable initial-access behavior with kernel-level EDR impairment, session and credential theft, and persistence that survives removal of the main executable. Its browser-focused capabilities create direct risk to cloud accounts, enterprise SaaS sessions, and downstream identity compromise.

Exploitation Status

  • Researcher-confirmed campaign: Ontinue analyzed samples compiled in September 2026 and confirmed active infrastructure.
  • Vulnerability status: AMD previously confirmed CVE-2023-20598 and released fixed driver packages. Lunex abuses a vulnerable signed driver as a BYOVD component.
  • Researcher assessment: Ontinue attributes the platform to a Russian-speaking, financially motivated developer/operator ecosystem with high confidence; this is not a vendor attribution.
  • Observed IOCs: delivery uasputnik.com; payload 107.175.82.242:9000; C2/exfiltration 193.178.159.128 on ports 8000/8080; analyzed hashes documented below.

What this hunt looks for

The hunt content covers available Sentinel telemetry for ClickFix/MSI execution, known hashes and paths, vulnerable-driver loading, service creation, UAC-bypass precursors, Microsoft symbol retrieval by unusual parents, persistence, browser data access, known infrastructure, and rare outbound destinations.

Required logs

Conclusions are limited to data sources and retention available in Microsoft Sentinel. Strong visibility requires Microsoft Defender XDR endpoint process, file, registry, driver/service, scheduled-task, and network events. Windows Security Events alone will not show all file, browser, registry, or network behavior. Absence of matching activity does not confirm absence of infection on endpoints without complete EDR telemetry.

1. First Pass – ClickFix or Remote MSI Installation Chain

DeviceProcessEvents
| where TimeGenerated >= ago(30d)
| where FileName =~ "msiexec.exe"
| where ProcessCommandLine has_any ("http://", "https://", "/qn", "/quiet", "uasputnik.com", "elita.msi")
| project TimeGenerated, DeviceName, AccountName, FileName, ProcessCommandLine, InitiatingProcessFileName, InitiatingProcessCommandLine, InitiatingProcessParentFileName, SHA256
| order by TimeGenerated desc

2. Known Lunex File Hashes and Artifacts

let Hashes = dynamic(["38e90affe37342ee36917cdc535fe9bf04589afa8430eb8d1ba1016adcfc1878","bf14cd6c3328ebd08e940478b5d1da04e9e5aa576d045d41950bf4f1e2456dd8","6e8b49cf70bf854e8c59c7d27cefa89406caf8978461190dabb86dafcd8554e1","06f434695f93d7fd11eeff71358ff69fed79d310a66d993bbcc4ff979c117c90"]);
union isfuzzy=true
(
    DeviceFileEvents
    | where TimeGenerated >= ago(30d)
    | where SHA256 in~ (Hashes) or FileName in~ ("elita.msi", "psychedelic.exe", "config.exe", "PDFWKRNL.sys", "psychedeliclove.exe", "wd_tmp.db", "wallet.zip")
    | project TimeGenerated, DeviceName, EvidenceType="File", FileName, FolderPath, SHA256, AccountName=InitiatingProcessAccountName, CommandLine=InitiatingProcessCommandLine
),
(
    DeviceProcessEvents
    | where TimeGenerated >= ago(30d)
    | where SHA256 in~ (Hashes) or FileName in~ ("psychedelic.exe", "config.exe", "psychedeliclove.exe")
    | project TimeGenerated, DeviceName, EvidenceType="Process", FileName, FolderPath, SHA256, AccountName, CommandLine=ProcessCommandLine
)
| order by TimeGenerated desc

3. Vulnerable AMD Driver Drop or Load

union isfuzzy=true
(
    DeviceFileEvents
    | where TimeGenerated >= ago(30d)
    | where FileName =~ "PDFWKRNL.sys" or SHA256 =~ "6e8b49cf70bf854e8c59c7d27cefa89406caf8978461190dabb86dafcd8554e1"
    | project TimeGenerated, DeviceName, EvidenceType="DriverFile", FileName, FolderPath, SHA256, InitiatingProcessFileName, InitiatingProcessCommandLine, InitiatingProcessAccountName
),
(
    DeviceEvents
    | where TimeGenerated >= ago(30d)
    | where ActionType has "Driver" or ActionType has "Service"
    | where FileName =~ "PDFWKRNL.sys" or AdditionalFields has "PDFWKRNL"
    | project TimeGenerated, DeviceName, EvidenceType=ActionType, FileName, FolderPath, SHA256, InitiatingProcessFileName, InitiatingProcessCommandLine, InitiatingProcessAccountName
)
| order by TimeGenerated desc

4. Suspicious Kernel Driver Service Creation

union isfuzzy=true
(
    DeviceProcessEvents
    | where TimeGenerated >= ago(30d)
    | where FileName in~ ("sc.exe", "powershell.exe", "pwsh.exe")
    | where ProcessCommandLine has_any ("create", "New-Service", "Start-Service")
    | where ProcessCommandLine has_any (".sys", "PDFWKRNL", "type= kernel")
    | project TimeGenerated, DeviceName, AccountName, FileName, ProcessCommandLine, InitiatingProcessFileName, InitiatingProcessCommandLine
),
(
    SecurityEvent
    | where TimeGenerated >= ago(30d)
    | where EventID == 7045
    | where ServiceFileName endswith ".sys" or ServiceFileName has "PDFWKRNL"
    | project TimeGenerated, DeviceName=Computer, AccountName=SubjectUserName, FileName=ServiceName, ProcessCommandLine=ServiceFileName, InitiatingProcessFileName="", InitiatingProcessCommandLine=""
)
| order by TimeGenerated desc

5. CMSTPLUA UAC-Bypass and PEB-Masquerade Indicators

DeviceProcessEvents
| where TimeGenerated >= ago(30d)
| where ProcessCommandLine has_any ("3E5FC7F9-9A51-4367-9063-A120244FBEC7", "Elevation:Administrator!new") or InitiatingProcessCommandLine has_any ("3E5FC7F9-9A51-4367-9063-A120244FBEC7", "Elevation:Administrator!new")
| project TimeGenerated, DeviceName, AccountName, FileName, FolderPath, ProcessCommandLine, InitiatingProcessFileName, InitiatingProcessFolderPath, InitiatingProcessCommandLine
| order by TimeGenerated desc

6. Kernel Symbol Download by Unusual Parent Process

DeviceProcessEvents
| where TimeGenerated >= ago(30d)
| where FileName =~ "curl.exe"
| where ProcessCommandLine has_any ("msdl.microsoft.com/download/symbols", "ntkrnlmp.pdb", "Microsoft-Symbol-Server/10.1700.661.0")
| where InitiatingProcessFileName !in~ ("windbg.exe", "windbgx.exe", "symchk.exe", "devenv.exe")
| project TimeGenerated, DeviceName, AccountName, ProcessCommandLine, InitiatingProcessFileName, InitiatingProcessCommandLine, InitiatingProcessFolderPath
| order by TimeGenerated desc

7. Lunex Persistence – Run Key and Native Messaging Hosts

DeviceRegistryEvents
| where TimeGenerated >= ago(30d)
| where RegistryKey has_any ("\\Software\\Microsoft\\Windows\\CurrentVersion\\Run", "\\Software\\Google\\Chrome\\NativeMessagingHosts\\com.lunex.explorer", "\\Software\\Microsoft\\Edge\\NativeMessagingHosts\\com.lunex.explorer")
| where RegistryValueName has_any ("UserStarts", "com.lunex.explorer") or RegistryKey has "com.lunex.explorer"
| project TimeGenerated, DeviceName, ActionType, RegistryKey, RegistryValueName, RegistryValueData, InitiatingProcessAccountName, InitiatingProcessFileName, InitiatingProcessCommandLine
| order by TimeGenerated desc

8. Hidden Scheduled Task and Browser-Termination Behavior

DeviceProcessEvents
| where TimeGenerated >= ago(30d)
| where ProcessCommandLine has_any ("psychedelicloveUtils", "taskkill /F /IM chrome.exe", "taskkill /F /IM msedge.exe", "taskkill /F /IM brave.exe", "taskkill /F /IM opera.exe") or (FileName =~ "schtasks.exe" and ProcessCommandLine has_all ("/create", "/sc", "onlogon"))
| project TimeGenerated, DeviceName, AccountName, FileName, ProcessCommandLine, InitiatingProcessFileName, InitiatingProcessCommandLine
| order by TimeGenerated desc

9. Known Lunex Delivery and C2 Infrastructure

let IPs = dynamic(["107.175.82.242","193.178.159.128"]);
let Domains = dynamic(["uasputnik.com","account-sams-club.com","teamwork-recover-password.com","namshi-uae.com","whatsappbusineses.com","ibraq-perfumes.com"]);
DeviceNetworkEvents
| where TimeGenerated >= ago(30d)
| where RemoteIP in (IPs) or RemoteUrl has_any (Domains)
| project TimeGenerated, DeviceName, LocalIP, RemoteIP, RemotePort, RemoteUrl, InitiatingProcessAccountName, InitiatingProcessFileName, InitiatingProcessCommandLine, InitiatingProcessSHA256
| order by TimeGenerated desc

10. Rare Direct-IP HTTP Connections From User-Space Binaries

let BaselineStart = ago(30d);
let RecentStart = ago(7d);
let Baseline = DeviceNetworkEvents
| where TimeGenerated between (BaselineStart .. RecentStart)
| where RemotePort in (80, 8000, 8080, 8081, 9000)
| summarize by DeviceName, RemoteIP, RemotePort, InitiatingProcessFileName;
DeviceNetworkEvents
| where TimeGenerated >= RecentStart
| where RemotePort in (80, 8000, 8080, 8081, 9000)
| where isnotempty(RemoteIP)
| join kind=leftanti Baseline on DeviceName, RemoteIP, RemotePort, InitiatingProcessFileName
| summarize FirstSeen=min(TimeGenerated), LastSeen=max(TimeGenerated), Connections=count(), URLs=make_set(RemoteUrl, 20), Commands=make_set(InitiatingProcessCommandLine, 10) by DeviceName, RemoteIP, RemotePort, InitiatingProcessFileName
| order by Connections desc

Detection Notes

  • Queries 1, 3, 6, and 7 provide the best behavioral coverage. Hashes and infrastructure can change across Lunex operators.
  • DeviceEvents driver actions vary by Defender sensor version. If driver load events are unavailable, correlate the file drop with service creation and subsequent security-control telemetry gaps.
  • The Microsoft symbol server is legitimate. Query 6 is suspicious because of the parent process and command line, not the destination alone.
  • Scheduled-task creation via COM may not produce schtasks.exe; registry/task inventory or DeviceEvents may be required for full coverage.
  • Browser Native Messaging Host persistence can survive deletion of the original stealer binary. Removal must include the registry registration, host manifest/script, scheduled task, Run value, and malicious extension.
  • Expected noise includes legitimate enterprise MSI deployment, software debugging, approved browser integrations, AMD utilities, and authorized scheduled tasks.