Classification: TLP:WHITE | Intelligence Type: Infostealer & Credential Theft Campaigns | Pulse Count: 2 | Report Date: 2026-10-26
Threat Summary
Two distinct but complementary credential theft campaigns are active in the wild. The LunexStealer operation represents a sophisticated, multi-stage infostealer campaign specifically targeting Ukrainian-speaking users through deceptive CAPTCHA pages. Its unique tradecraft involves Bring Your Own Vulnerable Driver (BYOVD) attacks using AMD's PDFWKRNL.sys to disable kernel-level security monitoring before payload deployment.
Simultaneously, the Shai-Hulud (and related Miasma) campaign demonstrates a supply chain attack evolution, compromising 42 GitHub repositories across 11 legitimate owners to distribute malicious npm packages. This operation uses compiled native addons with runtime decryption to evade CI/CD detection, specifically targeting developer environments to steal credentials and establish persistent access through GitHub Actions abuse and cPanel exploitation.
Collective Objective: Mass harvesting of browser credentials, session tokens, and developer secrets for monetization on dark web markets or follow-on targeted attacks. The Ukrainian targeting in Lunex suggests potential geopolitical motivation or testing in a conflict zone, while the npm supply chain indicates sophisticated initial access brokerage.
Threat Actor / Malware Profile
LunexStealer (LunexLoader / PDFWKRNL)
Distribution: Fake CAPTCHA verification pages (likely malvertising or compromised Ukrainian websites) Attack Chain:
- Stage 1: Social engineering via fake CAPTCHA
- Stage 2: BYOVD deployment of
PDFWKRNL.sys(CVE-2023-20598 — AMD Platform Security Processor driver vulnerability) - Stage 3: Kernel-level security product disabling (EDR/AV blinding)
- Stage 4: LunexStealer payload execution
Payload Behavior:
- Targets 7 Chromium-based browsers (Chrome, Edge, Brave, Opera, Vivaldi, Yandex, Chromium)
- Custom SQL queries to extract cookies, saved credentials, autofill data
- Browser hijacking and Native Messaging Host manipulation for persistence
- Ukrainian language pack detection for targeted execution
Anti-Analysis:
- BYOVD to terminate security processes at kernel level
- Vulnerable driver signed by AMD (legitimate certificate abuse)
Shai-Hulud / Miasma (testmetest operation)
Distribution: Compromised GitHub repositories (42 repos across 11 owners) leading to malicious npm packages Attack Vector: Supply chain via typosquatting and repository hijacking
Payload Behavior:
- Native Addon Camouflage: Compiled Node.js native addons (
.nodebinaries) that decrypt hidden payloads at runtime - Polymorphic Wrappers: Dynamic payload decryption to evade static analysis
- GitHub Actions Abuse: Malicious workflow files to steal CI/CD secrets and tokens
- cPanel Exploitation: Web hosting control panel compromise for persistence
- ShellPanel: Web shell deployment for remote access
Persistence Mechanisms:
- GitHub repository hooks
- npm package lifecycle scripts (
preinstall,postinstall) - Compromised cPanel accounts for infrastructure hosting
Anti-Analysis:
- Extensive environment checks to detect CI/CD environments (delays execution)
- Runtime decryption of malicious code
- Legitimate-looking package names and documentation
IOC Analysis
LunexStealer Indicators
- CVE-2023-20598: AMD PSP driver vulnerability exploited for BYOVD. Patch management systems should flag systems with
PDFWKRNL.sysversion < 5.0.0.0 - File Hashes (MD5/SHA1/SHA256): Multiple stage payloads and drivers. The SHA256
6e8b49cf...represents the LunexLoader or PDFWKRNL driver - Domains:
teamwork-recover-password.com— C2 or phishing infrastructure mimicking legitimate teamwork platformswhatsappbusineses.com— Typosquatting domain targeting WhatsApp Business users (note the misspelling: 'busineses')
Shai-Hulud Indicators
- IPv4
43.228.157.68: C2 server for exfiltrated npm credentials and GitHub tokens - CVE-2026-41940: Likely a vulnerability in cPanel or related web hosting software exploited for initial access
- File Hashes: Multiple SHA256 hashes representing polymorphic npm package payloads and compiled native addons
Operationalization Strategy
For SOC Teams:
- Hash Reputation: Submit all hashes to VirusTotal, Hybrid Analysis, or internal sandbox for detonation and behavioral analysis
- Domain/IP Blocking: Add domains to DNS sinkhole and IP to firewall blocklists (note: IP
43.228.157.68appears to be a VPS, likely bulletproof hosting) - Driver Blocking: Use Microsoft's Vulnerable Driver Blocklist or custom WDAC policies to block
PDFWKRNL.sys - npm Audit: Scan
package-lock.jsonandnode_modulesfor the provided SHA256 hashes usingnpm auditor custom scripts
Tooling:
- OTX Direct Connect: Auto-import indicators into SIEM via AlienVault OTX API
- YARA: Develop rules for LunexStealer SQL extraction patterns and Shai-Hulud native addon decryption stubs
- THOR/LOKI: Run APT scanner sweeps with these IOCs across developer workstations and Ukrainian-targeted user segments
Detection Engineering
Sigma Rules
---
title: LunexStealer BYOVD Driver Load - PDFWKRNL
id: 9f8e7d6c-5b4a-3c2d-1e0f-9a8b7c6d5e4f
status: experimental
description: Detects the loading of the vulnerable AMD PDFWKRNL.sys driver used in LunexStealer BYOVD attacks to disable security monitoring
author: Security Arsenal Threat Intelligence
date: 2026/10/26
references:
- https://www.ontinue.com/resource/lunex-unmasked-a-new-information-stealer-deployed-through-byovd
logsource:
category: driver_load
product: windows
definition: 'Sysmon Event ID 6 or Windows Security Event 4672'
detection:
selection:
ImageLoaded|endswith: '\PDFWKRNL.sys'
condition: selection
falsepositives:
- Legitimate AMD software installations (rare in enterprise environments without AMD hardware)
level: high
tags:
- attack.defense_evasion
- attack.t1562.001
- cve.2023.20598
---
title: LunexStealer Browser Credential Access
id: 8e7d6c5b-4a3c-2d1e-0f9a-8b7c6d5e4f3a
status: experimental
description: Detects LunexStealer attempting to access browser credential databases via SQL queries
author: Security Arsenal Threat Intelligence
date: 2026/10/26
references:
- https://www.ontinue.com/resource/lunex-unmasked-a-new-information-stealer-deployed-through-byovd
logsource:
category: process_creation
product: windows
detection:
selection_img:
Image|endswith:
- '\chrome.exe'
- '\msedge.exe'
- '\brave.exe'
- '\opera.exe'
- '\vivaldi.exe'
selection_cmd:
CommandLine|contains:
- 'Login Data'
- 'Cookies'
- 'Web Data'
- 'SELECT * FROM logins'
- 'sqlite3'
condition: all of selection_*
falsepositives:
- Legitimate browser forensics tools (rare)
- IT admin password recovery activities
level: high
tags:
- attack.credential_access
- attack.t1555.003
- attack.t1005
---
title: Shai-Hulud npm Supply Chain - Suspicious Native Addon Execution
id: 7d6c5b4a-3c2d-1e0f-9a8b-7c6d5e4f3a2b
status: experimental
description: Detects execution of Node.js native addons from temporary or npm cache directories, indicative of Shai-Hulud supply chain compromise
author: Security Arsenal Threat Intelligence
date: 2026/10/26
references:
- https://research.jfrog.com/post/beyond-testmetest-42-hijacked-github-repos/
logsource:
category: process_creation
product: windows
detection:
selection:
Image|endswith: '\node.exe'
CommandLine|contains:
- 'node_modules'
- '.node'
- 'preinstall'
- 'postinstall'
filter_paths:
CommandLine|contains:
- '\Temp\'
- '\AppData\Local\npm-cache\'
- '\AppData\Roaming\npm\'
condition: selection and not filter_paths
falsepositives:
- Legitimate npm package installations (requires baseline tuning)
- Developer build activities
level: medium
tags:
- attack.initial_access
- attack.t1195.002
- attack.t1059.007
KQL (Microsoft Sentinel)
// LunexStealer & Shai-Hulud Multi-Stage Detection Hunt
// Author: Security Arsenal Threat Intelligence
// Date: 2026-10-26
// Coverage: Driver loads, browser access, network IOCs, and npm execution
// Hunt 1: LunexStealer BYOVD Driver Load
let VulnerableDrivers = datatable(DriverName:string, Hash:string) [
"PDFWKRNL.sys", "6e8b49cf70bf854e8c59c7d27cefa89406caf8978461190dabb86dafcd8554e1",
"PDFWKRNL.sys", "3f4c9025125027e307b7e52dd577303b",
"PDFWKRNL.sys", "f329ae0fdf1e198bea6ba787e59cb73f90714002"
];
DeviceEvents
| where TimeGenerated > ago(7d)
| where ActionType == "DriverLoad" or (ActionType == "ProcessCreated" and FileName contains "driver")
| extend DriverName = tostring(split(FileName, "\\")[-1])
| where DriverName in~ (VulnerableDrivers | project DriverName)
| project TimeGenerated, DeviceName, DriverName, FileName, FolderPath, InitiatingProcessAccountName
| join kind=leftouter (DeviceProcessEvents | where TimeGenerated > ago(7d) | project DeviceName, ProcessId, ProcessCommandLine, AccountName) on DeviceName
| where ProcessCommandLine contains "PDFWKRNL" or FileName contains "PDFWKRNL"
| summarize by DeviceName, DriverName, FolderPath, ProcessCommandLine, AccountName
// Hunt 2: LunexStealer Network IOCs
union isfuzzy=true
(DeviceNetworkEvents
| where TimeGenerated > ago(7d)
| where RemoteIP == "43.228.157.68"
| where RemoteUrl has_any ("teamwork-recover-password.com", "whatsappbusineses.com")
| project TimeGenerated, DeviceName, RemoteIP, RemoteUrl, InitiatingProcessFileName, InitiatingProcessCommandLine),
(DeviceEvents
| where TimeGenerated > ago(7d)
| where ActionType == "DnsQueryToUrl" or ActionType == "NetworkConnectionToUrl"
| where RemoteUrl has_any ("teamwork-recover-password.com", "whatsappbusineses.com")
| project TimeGenerated, DeviceName, RemoteUrl, InitiatingProcessFileName))
| summarize Connections = count(), FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated) by DeviceName, RemoteUrl, RemoteIP, InitiatingProcessFileName
| where Connections > 3
// Hunt 3: Shai-Hulud npm Native Addon Execution
DeviceProcessEvents
| where TimeGenerated > ago(7d)
| where FileName =~ "node.exe"
| where ProcessCommandLine has_any (".node", "preinstall", "postinstall", "testmetest", "shai-hulud", "miasma")
| where ProcessCommandLine has_any ("Temp", "npm-cache", "AppData")
| extend SuspiciousPath = iff(ProcessCommandLine has "Temp", "Temp Execution", "npm-cache")
| project TimeGenerated, DeviceName, AccountName, ProcessCommandLine, SuspiciousPath, InitiatingProcessFileName
| summarize by DeviceName, AccountName, ProcessCommandLine, SuspiciousPath
// Hunt 4: Browser Database Access (LunexStealer)
DeviceProcessEvents
| where TimeGenerated > ago(7d)
| where ProcessCommandLine has_any ("Login Data", "Cookies", "Web Data", "sqlite3", "logins")
| where FileName in~ ("chrome.exe", "msedge.exe", "brave.exe", "opera.exe", "vivaldi.exe", "sql.exe", "sqlite3.exe")
| where not(InitiatingProcessFileName in~ ("explorer.exe", "svchost.exe", "chrome.exe")) // Exclude parent browsers
| project TimeGenerated, DeviceName, FileName, ProcessCommandLine, FolderPath, AccountName, InitiatingProcessFileName
| summarize by DeviceName, FileName, ProcessCommandLine, AccountName
PowerShell IOC Hunt Script
#Requires -RunAsAdministrator
<#
.SYNOPSIS
Security Arsenal IOC Hunt - LunexStealer & Shai-Hulud
.DESCRIPTION
Hunts for indicators of compromise related to LunexStealer BYOVD campaign and Shai-Hulud npm supply chain attack.
Checks for vulnerable drivers, suspicious files, network connections, and npm artifacts.
.NOTES
Author: Security Arsenal Threat Intelligence
Date: 2026-10-26
Requires: Administrative privileges for driver and registry checks
#>
param(
[switch]$ExportCsv,
[string]$OutputPath = "C:\Temp\IOCHunt_$(Get-Date -Format 'yyyyMMdd_HHmmss').csv"
)
$Results = @()
# IOC Definitions
$LunexHashes = @(
"3f4c9025125027e307b7e52dd577303b",
"41ff3ecd1458b0bf86e1b4891636213e",
"b96d75a000367c200958089728fc5cb8",
"6e8b49cf70bf854e8c59c7d27cefa89406caf8978461190dabb86dafcd8554e1",
"f329ae0fdf1e198bea6ba787e59cb73f90714002"
)
$ShaiHuludHashes = @(
"17614e98b613b17d0e1bb7125ab203715dd397661b897d8d18dbb77864c1839f",
"3dc40fc55302664c07c9d9182ffd95910aeb366fcd417fbdad0a90cdeb8ea69e",
"783a4ac906cc9b2eaf5cd13408ea95db6ce52a46d9af11aad1a5b167af69589f",
"7ad216b3afd2f40a147c80733c7309fb3d3a7f52ee78149c8e51672cfb617d07",
"8506042b383ab46545c27a402eb2dc973696a93af71181b175b1d87972843a43",
"9d83919bfdb0e14018f1a6f2b8b6586de59b60dfdcfbdb5ae1a1556c23cc4793"
)
$MaliciousDomains = @("teamwork-recover-password.com", "whatsappbusineses.com")
$C2IP = "43.228.157.68"
Write-Host "[*] Starting IOC Hunt for LunexStealer and Shai-Hulud..." -ForegroundColor Cyan
# 1. Check for vulnerable driver (PDFWKRNL.sys)
Write-Host "[*] Checking for vulnerable AMD PDFWKRNL.sys driver..." -ForegroundColor Yellow
$DriverPaths = @("$env:SystemRoot\System32\drivers\PDFWKRNL.sys", "$env:SystemRoot\SysWOW64\drivers\PDFWKRNL.sys")
foreach ($Path in $DriverPaths) {
if (Test-Path $Path) {
$FileInfo = Get-Item $Path
$Hash = (Get-FileHash -Path $Path -Algorithm SHA256).Hash
$Results += [PSCustomObject]@{
Type = "Driver"
Indicator = "PDFWKRNL.sys"
Path = $Path
Hash = $Hash
Risk = "CRITICAL - BYOVD Driver"
Malware = "LunexStealer"
}
Write-Host "[!!!] FOUND VULNERABLE DRIVER: $Path" -ForegroundColor Red
}
}
# 2. Check loaded drivers
Write-Host "[*] Checking loaded drivers for PDFWKRNL..." -ForegroundColor Yellow
$LoadedDrivers = driverquery /fo csv | ConvertFrom-Csv | Where-Object { $_.'Module Name' -like "*PDFWKRNL*" }
if ($LoadedDrivers) {
$Results += [PSCustomObject]@{
Type = "Loaded Driver"
Indicator = "PDFWKRNL"
Path = $LoadedDrivers.'Module Name'
Hash = "N/A"
Risk = "CRITICAL - Active BYOVD"
Malware = "LunexStealer"
}
Write-Host "[!!!] PDFWKRNL DRIVER IS LOADED" -ForegroundColor Red
}
# 3. Check network connections to C2
Write-Host "[*] Checking for network connections to C2 IP $C2IP..." -ForegroundColor Yellow
$NetConnections = Get-NetTCPConnection -State Established -ErrorAction SilentlyContinue | Where-Object { $_.RemoteAddress -eq $C2IP }
if ($NetConnections) {
foreach ($Conn in $NetConnections) {
$Process = Get-Process -Id $Conn.OwningProcess -ErrorAction SilentlyContinue
$Results += [PSCustomObject]@{
Type = "Network Connection"
Indicator = $C2IP
Path = "PID: $($Conn.OwningProcess) - $($Process.ProcessName)"
Hash = "N/A"
Risk = "HIGH - Active C2 Communication"
Malware = "Shai-Hulud/Lunex"
}
}
Write-Host "[!!!] ACTIVE CONNECTION TO C2 DETECTED" -ForegroundColor Red
}
# 4. Check DNS cache for malicious domains
Write-Host "[*] Checking DNS cache for malicious domains..." -ForegroundColor Yellow
foreach ($Domain in $MaliciousDomains) {
$DnsCache = Get-DnsClientCache -Name $Domain -ErrorAction SilentlyContinue
if ($DnsCache) {
$Results += [PSCustomObject]@{
Type = "DNS Cache"
Indicator = $Domain
Path = "Cached Resolution"
Hash = "N/A"
Risk = "MEDIUM - Domain Resolution"
Malware = "LunexStealer"
}
Write-Host "[!] Domain found in DNS cache: $Domain" -ForegroundColor Magenta
}
}
# 5. Hunt for file hashes in common locations
Write-Host "[*] Hunting for malicious file hashes in Temp and Downloads..." -ForegroundColor Yellow
$SearchPaths = @("$env:TEMP", "$env:USERPROFILE\Downloads", "$env:APPDATA\npm-cache", "$env:LOCALAPPDATA\npm-cache")
$AllHashes = $LunexHashes + $ShaiHuludHashes
foreach ($Path in $SearchPaths) {
if (Test-Path $Path) {
$Files = Get-ChildItem -Path $Path -Recurse -File -ErrorAction SilentlyContinue | Where-Object { $_.Length -lt 50MB } # Limit size for performance
foreach ($File in $Files) {
try {
$Hash = (Get-FileHash -Path $File.FullName -Algorithm SHA256 -ErrorAction SilentlyContinue).Hash
if ($AllHashes -contains $Hash) {
$MalwareType = if ($LunexHashes -contains $Hash) { "LunexStealer" } else { "Shai-Hulud/npm" }
$Results += [PSCustomObject]@{
Type = "File Hash"
Indicator = $Hash.Substring(0,16) + "..."
Path = $File.FullName
Hash = $Hash
Risk = "HIGH - Malicious File"
Malware = $MalwareType
}
Write-Host "[!!!] MALICIOUS FILE FOUND: $($File.FullName)" -ForegroundColor Red
}
} catch { }
}
}
}
# 6. Check for suspicious npm packages (Shai-Hulud indicators)
Write-Host "[*] Checking for suspicious npm global packages..." -ForegroundColor Yellow
$NpmGlobal = npm list -g --depth=0 2>$null | Select-String -Pattern "testmetest|shai-hulud|miasma"
if ($NpmGlobal) {
$Results += [PSCustomObject]@{
Type = "npm Package"
Indicator = "testmetest/shai-hulud"
Path = "Global npm"
Hash = "N/A"
Risk = "HIGH - Malicious Package"
Malware = "Shai-Hulud"
}
}
# 7. Check GitHub Actions workflow files (if repo present)
Write-Host "[*] Checking for suspicious GitHub Actions workflows..." -ForegroundColor Yellow
$WorkflowPath = "$env:USERPROFILE\*\.github\workflows\*.yml"
$SuspiciousWorkflows = Get-ChildItem -Path $WorkflowPath -Recurse -ErrorAction SilentlyContinue | Select-String -Pattern "curl|wget|invoke-webrequest|iex|downloadstring" -List
if ($SuspiciousWorkflows) {
foreach ($Workflow in $SuspiciousWorkflows) {
$Results += [PSCustomObject]@{
Type = "GitHub Workflow"
Indicator = "Suspicious command execution"
Path = $Workflow.Path
Hash = "N/A"
Risk = "MEDIUM - Supply Chain Risk"
Malware = "Shai-Hulud"
}
}
}
# 8. Check browser native messaging hosts (Lunex persistence)
Write-Host "[*] Checking Native Messaging Hosts registry..." -ForegroundColor Yellow
$RegPaths = @(
"HKCU:\Software\Google\Chrome\NativeMessagingHosts",
"HKLM:\Software\Google\Chrome\NativeMessagingHosts",
"HKCU:\Software\Microsoft\Edge\NativeMessagingHosts"
)
foreach ($RegPath in $RegPaths) {
if (Test-Path $RegPath) {
$Keys = Get-ChildItem -Path $RegPath -ErrorAction SilentlyContinue
foreach ($Key in $Keys) {
$Value = Get-ItemProperty -Path $Key.PSPath -Name "(Default)" -ErrorAction SilentlyContinue
if ($Value.'(Default)' -match "teamwork|whatsapp|recover|password") {
$Results += [PSCustomObject]@{
Type = "Registry"
Indicator = "NativeMessagingHost"
Path = $Key.PSPath
Hash = "N/A"
Risk = "HIGH - Browser Persistence"
Malware = "LunexStealer"
}
Write-Host "[!!!] SUSPICIOUS NATIVE MESSAGING HOST: $($Key.PSChildName)" -ForegroundColor Red
}
}
}
}
# Summary and Export
Write-Host "`n[*] Hunt Complete. Found $($Results.Count) potential IOCs." -ForegroundColor Cyan
if ($Results.Count -gt 0) {
$Results | Format-Table -AutoSize
if ($ExportCsv) {
$Results | Export-Csv -Path $OutputPath -NoTypeInformation
Write-Host "[*] Results exported to: $OutputPath" -ForegroundColor Green
}
# Immediate recommendations
Write-Host "`n[IMMEDIATE ACTIONS REQUIRED]" -ForegroundColor Red
Write-Host "1. Isolate affected systems from network" -ForegroundColor Yellow
Write-Host "2. Reset all browser-stored credentials" -ForegroundColor Yellow
Write-Host "3. Review GitHub repository access tokens if npm packages detected" -ForegroundColor Yellow
Write-Host "4. Deploy driver blocklist for PDFWKRNL.sys" -ForegroundColor Yellow
} else {
Write-Host "[*] No IOCs detected. System appears clean." -ForegroundColor Green
}
return $Results
Response Priorities
Immediate (0-4 Hours)
- Network Blocking: Block C2 IP
43.228.157.68and domainsteamwork-recover-password.com,whatsappbusineses.comat perimeter and DNS level - Driver Mitigation: Deploy Microsoft's Vulnerable Driver Blocklist or WDAC policy to prevent
PDFWKRNL.sysloading (specifically block AMD PSP driver versions vulnerable to CVE-2023-20598) - Hash Blocking: Import all provided file hashes into EDR blocklists (MD5, SHA1, SHA256)
- npm Audit: Immediately audit all
package-lock.jsonandnode_modulesdirectories for the identified SHA256 hashes or packages communicating with43.228.157.68 - Hunt Execution: Run the provided KQL queries and PowerShell script across all endpoints, prioritizing Ukrainian-speaking user segments and developer workstations
24 Hours
- Credential Reset: Force password resets for all users who may have executed fake CAPTCHA pages or used browsers on infected systems (LunexStealer exfiltrates saved credentials)
- Token Revocation: Rotate all GitHub Personal Access Tokens (PATs), npm tokens, and CI/CD secrets if Shai-Hulud infection is suspected
- Session Invalidation: Invalidate all active browser sessions and OAuth tokens for potentially compromised users (cookies may have been stolen)
- GitHub Audit: Review organization GitHub repositories for unauthorized workflow modifications or new collaborators matching the "testmetest" pattern
1 Week
- Driver Hardening: Implement Application Control (WDAC/AppLocker) policies to only allow signed drivers from approved vendors, preventing BYOVD attacks
- Browser Isolation: Deploy browser isolation technology for high-risk users (Ukrainian targeting suggests geopolitical risk) to prevent drive-by credential theft
- Supply Chain Security: Implement npm package signing verification, use
npm audit signatures, and deploy private npm registries with strict allow-listing for developer workstations - CI/CD Hardening: Enforce GitHub Actions OIDC (OpenID Connect) for cloud authentication instead of long-lived secrets, and implement branch protection rules requiring code review for workflow changes
- Detection Tuning: Deploy Sigma rules to SIEM and tune false positives based on legitimate developer activity
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.