SprySOCKS Windows Variants — WIN_DRV / WIN_PLUS (FishMonger)
svchost.exe); the stealthier WIN_DRV ships a kernel-mode driver acting as a rootkit — hiding files, processes, registry keys, and network connections, and rerouting traffic from any open port to the backdoor's hidden port when a packet marker appears (port-knocking covert channel). Both retain the Linux C2 protocol/encryption over TCP, UDP, and WebSocket, and run 30+ espionage commands. Defensive hunt & harden pack — no offensive code.Executive Summary
SprySOCKS first surfaced in 2023 as a Linux-only espionage backdoor. On June 16, 2026, ESET disclosed two previously undocumented Windows variants — labeled WIN_DRV and WIN_PLUS — attributed to the China-nexus FishMonger group, publicly linked to the I-Soon contractor. Both Windows builds preserve the Linux predecessor's C2 protocol and encryption, ship a hardcoded C2 configuration in each sample, communicate over TCP, UDP, and WebSocket, and expose 30+ commands (system reconnaissance, process/service management, file operations, SOCKS proxy, upload/download, interactive console).
WIN_PLUS establishes itself through the Windows Print Spooler (spoolsv.exe) as an entry point: a malicious print-processor loader executes and injects into svchost.exe. WIN_DRV is the stealthier build — delivered via a DLL side-loading chain triggered by a scheduled task, it loads an encrypted kernel-mode driver (a DriverLoader decrypts and maps a RawWNPF-style network filter driver) that acts as a rootkit: it hides files, processes, registry keys, and network connections, and performs TCP traffic diversion — when a packet carrying a specific marker/byte sequence hits any open port, the driver quietly reroutes it to the backdoor's hidden listening port. This port-knocking covert channel lets operators reach the implant without exposing a dedicated listening port to scans or netflow.
Because WIN_DRV's rootkit suppresses the very telemetry an analyst would pivot on, the durable hunt surface is the delivery and load behavior that precedes the rootkit installing: the Print Spooler / print-processor load chain, the scheduled-task → DLL side-load lineage, the kernel driver written to disk and the kernel-mode service install (including BYOVD-style unsigned/vulnerable driver loads), and any pre-rootkit listening-port / WebSocket / UDP beacon artifacts. Atomic IOCs (hashes, driver filenames) are useful but perishable; the load-chain behavior is the high-leverage break.
.sys written to disk from a non-standard path), Q2 (new kernel-mode ServiceInstalled / driver load, BYOVD angle), and Q4 (Print Spooler / print-processor load → svchost for WIN_PLUS). Treat the scheduled-task → DLL side-load lineage (Q3) and anomalous listening-port / WebSocket beacons (Q5/Q6) as corroboration. Driver/rootkit telemetry has gaps (see §15) — promote the disk-write and service-install hunts, don't wait for network signal.Source Review & Web Hunter Notes
| Tier | Source | Key Finding | Carry |
|---|---|---|---|
| 1 · Vendor research | ESET — SprySOCKS Windows variants (Jun 16, 2026) | Two new Windows ports WIN_DRV / WIN_PLUS; kernel-driver rootkit; port-knock traffic diversion; retained Linux C2 protocol/encryption; 30+ commands; FishMonger / I-Soon attribution | yes |
| 1 · Press (vendor-sourced) | The Hacker News — coverage of ESET report | Driver filenames (RawWNPF / DriverLoader .dat), WIN_DRV sample hash, Print Spooler entry (WIN_PLUS), DLL side-load + sched-task (WIN_DRV), TCP/UDP/WebSocket C2 | yes |
| 2 · Press | Infosecurity Magazine / Dark Reading / SC World | Corroborate kernel-driver rootkit + covert channel; targeting of government bodies in Honduras, Taiwan, Thailand, Pakistan (telemetry 2023-2024) | partial |
Decisions: behavior-anchored — the rootkit hides files/procs/registry/network, so post-install telemetry is unreliable; hunt the pre-rootkit load chain (driver disk-write, kernel-mode service install, Print Spooler / print-processor load, scheduled-task → DLL side-load) which the rootkit cannot retroactively erase from EDR. Atomic IOCs (sample hash, .dat driver names) are included for blocklisting but treated as perishable. Network hunts (listening ports, WebSocket/UDP beacons) are weakened by the port-knock diversion and are framed as corroboration, with the gap flagged honestly in §15.
Hunt Brief & Attack Chain
Working hypothesis: FishMonger lands a Windows host and deploys SprySOCKS — either WIN_PLUS (Print Spooler print-processor loader injecting svchost.exe) or the stealthier WIN_DRV (scheduled-task-triggered DLL side-load that drops and loads an encrypted kernel driver acting as a rootkit, then opens a port-knock covert channel for hardcoded TCP/UDP/WebSocket C2 and runs 30+ espionage commands).
| Step | Behavior | Telemetry | Hunt Angle |
|---|---|---|---|
| 1 · Initial foothold | FishMonger access (exploited service / valid accounts) | ProcessRollup2; logon | N4; out of scope |
| 2a · WIN_PLUS load | Print Spooler print-processor loader → inject svchost.exe | ProcessRollup2; module load | Q4; N1 |
| 2b · WIN_DRV load | Scheduled task → DLL side-load chain | ScheduledTaskRegistered; ProcessRollup2 | Q3; N2 |
| 3 · Driver drop | Encrypted kernel driver .sys/.dat written to disk | PeFileWritten; FileCreateInfo | Q1; N3 |
| 4 · Rootkit install | Kernel-mode service install / driver load (BYOVD-style) | ServiceInstalled; DriverLoad | Q2; N3 |
| 5 · Covert C2 | Port-knock packet marker reroutes traffic to hidden port | NetworkListenIP4; netflow | Q5; N5 |
| 6 · Operate | 30+ commands; SOCKS proxy; WebSocket/UDP beacons; file ops | NetworkConnectIP4; ProcessRollup2 | Q6 / Q7 / Q8 |
Consolidated IOC Table
.dat driver names rotate. The load-chain behavior (driver disk-write, kernel-mode service install, Print Spooler load, sched-task → DLL side-load) is the durable surface. Copy-ready blocks in §10.| Type | Value | Conf | Action | Context |
|---|---|---|---|---|
| Behavior | Kernel driver / encrypted .sys|.dat written to disk from non-standard path | high | detect | Pre-rootkit — flagship |
| Behavior | New kernel-mode service install / unsigned-vulnerable driver load (BYOVD) | high | detect | Rootkit install |
| Behavior | Print Spooler (spoolsv.exe) print-processor loader → svchost injection | medium | hunt | WIN_PLUS entry |
| Behavior | Scheduled task triggering a DLL side-load chain | medium | hunt | WIN_DRV entry |
| Behavior | Port-knock: traffic rerouted to hidden port on packet marker; TCP/UDP/WebSocket C2 | medium | hunt | Covert channel |
| SHA256 | 68aec5085599e8a272767f50da66c83a6582e4e16ed97c209f65f81538b0c028 | medium | detect | WIN_DRV sample (perishable) |
| Filename | KW1B5206BDC1743FP.dat (RawWNPF driver); KX1B5206BDC1743DD.dat (DriverLoader) | low | hunt | Likely per-build; pattern only |
Affected Surface & Telemetry Matrix
| Surface | Required Telemetry | Priority | Gap Risk |
|---|---|---|---|
| Windows servers / endpoints | Process lineage + module load (svchost / spoolsv) | Critical | Low — process telemetry |
| Kernel / driver layer | Driver load + kernel-mode ServiceInstalled events | Critical | High — driver-load telemetry is uneven; rootkit hides post-install |
| Filesystem | PeFileWritten / FileCreateInfo for .sys/.dat writes | High | Low-Med — catch before rootkit hides files |
| Scheduled tasks | ScheduledTaskRegistered | Medium | Medium — WIN_DRV side-load trigger |
| Egress / listeners | NetworkListenIP4 / NetworkConnectIP4 + netflow | Medium | High — port-knock diversion + rootkit conn hiding |
ATT&CK Mapping
| Tactic | Technique | Observed Behavior | Query / Control |
|---|---|---|---|
| Persistence / Priv Esc | T1543.003 — Create/Modify System Process: Windows Service | Kernel-mode service install for the driver | Q2; N3 |
| Privilege Esc / Defense Evasion | T1547.012 — Print Processors | WIN_PLUS print-processor loader via Spooler | Q4; N1 |
| Defense Evasion | T1014 — Rootkit | Kernel driver hides files/procs/registry/network | Q1, Q2 (pre-install) |
| Defense Evasion | T1574.002 — DLL Side-Loading | WIN_DRV sched-task-triggered side-load chain | Q3; N2 |
| Defense Evasion / Priv Esc | T1068 — Exploitation for Priv Esc (BYOVD) | Unsigned/vulnerable driver load to reach kernel | Q2 |
| Persistence / Execution | T1053.005 — Scheduled Task | Sched task triggers WIN_DRV side-load | Q3; N2 |
| Execution / Defense Evasion | T1055 — Process Injection | Print-processor loader injects svchost.exe | Q4 |
| Command & Control | T1205.001 — Traffic Signaling: Port Knocking | Packet-marker reroute to hidden backdoor port | Q5; N5 |
| Command & Control | T1095 / T1071 — Non-App-Layer / App-Layer (UDP, WebSocket) | Hardcoded C2 over TCP/UDP/WebSocket | Q6, Q7 |
| C2 / Lateral | T1090 — Proxy (SOCKS) | Built-in SOCKS proxy command | Q6 |
Native Audit-Log Hunts
| Hunt | Source | Logic | Response |
|---|---|---|---|
| N1 · Spooler child / print processor | Sysmon 1 / Security 4688 | spoolsv.exe spawning unusual children or writing a print-processor DLL; injection into svchost.exe | Isolate; capture memory |
| N2 · Sched task → side-load | Security 4698 / Task Scheduler Op | New scheduled task launching a signed binary from a path that side-loads an attacker DLL | Triage; pull task XML + DLL |
| N3 · Kernel driver / service install | System 7045 / Sysmon 6 | New kernel-mode service or driver load; unsigned / never-before-seen .sys at boot or runtime | Block; image the host |
| N4 · Initial access | Security 4624/4672 | Anomalous logons / privileged access preceding the load chain | Scope; reset creds |
| N5 · Covert listener | Netflow / firewall | Unexpected inbound to a host on odd ports; small "knock" packets preceding a session shift | Block; identify host |
CrowdStrike LogScale CQL Hunt Queries
SyntheticProcessRollup2. Because WIN_DRV's rootkit hides post-install artifacts, the highest-yield hunts fire at load time: Q1 (driver written to disk) and Q2 (kernel-mode service install / BYOVD). Driver-load and kernel-service telemetry can be uneven across sensor versions and configs — see the coverage map (§15) for honest gaps. Pair the network hunts (Q5-Q7) with netflow; the port-knock diversion blunts pure host-side network signal.Looks for: a PE / driver file written to a user/temp/ProgramData path (rather than the normal driver store) — the WIN_DRV encrypted driver / DriverLoader drop, caught before the rootkit hides it. FP: some installers/AV stage drivers in non-standard paths — exclude known software-distribution writers and signed vendor processes.
// HUNT: kernel driver / encrypted .sys|.dat written to non-standard path (pre-rootkit) // MITRE: T1014, T1543.003 | CONF: high FP: med COST: low // REQUIRES: PeFileWritten / file-write telemetry // FALSE POSITIVES: legit driver installers (exclude signed vendor writers, SCCM/Intune staging) #event_simpleName=/PeFileWritten|NewExecutableWritten/ | TargetFileName=/\.(sys|dat)$/i | TargetFileName=/\\(Temp|AppData|ProgramData|Users\\Public|Windows\\Tasks)\\/i | TargetFileName!=/\\Windows\\System32\\DriverStore\\/i | table([@timestamp, ComputerName, UserName, ImageFileName, TargetFileName, SHA256HashData], limit=200)
Looks for: installation of a kernel-mode service or a driver load referencing a .sys outside the trusted driver store — the WIN_DRV rootkit install (and the BYOVD pattern of loading an unsigned/vulnerable driver to reach kernel). FP: legitimate driver/EDR/virtualization installs — baseline known service names + image paths and alert on first-seen.
// HUNT: kernel-mode service install / driver load from untrusted path (BYOVD / rootkit) // MITRE: T1543.003, T1068, T1014 | CONF: high FP: med COST: low // REQUIRES: ServiceInstalled / driver-load telemetry (uneven across sensor versions) // FALSE POSITIVES: vendor driver installs -- baseline service names + signer; alert first-seen #event_simpleName=/CreateService|ModifyServiceBinary|DriverLoad/ | ServiceImagePath=/\.sys$/i | ServiceImagePath!=/\\Windows\\System32\\(drivers|DriverStore)\\/i | table([@timestamp, ComputerName, ServiceDisplayName, ServiceImagePath, ImageFileName, SHA256HashData], limit=200)
Looks for: a scheduled-task registration or a task-launched signed binary executing from a non-standard path (side-load staging directory) — the WIN_DRV trigger. FP: legit apps use scheduled tasks + side directories — flag user/temp/ProgramData paths and correlate to Q1 driver writes on the same host.
// HUNT: scheduled-task-triggered DLL side-load staging (WIN_DRV) // MITRE: T1053.005, T1574.002 | CONF: medium FP: med COST: low // REQUIRES: ScheduledTaskRegistered + ProcessRollup2 // FALSE POSITIVES: legit task-launched apps -- restrict to user/temp paths; correlate Q1 #event_simpleName=/ScheduledTaskRegistered|ProcessRollup2|SyntheticProcessRollup2/ | (ScheduledTaskName=/.+/ or ParentBaseFileName=/^(svchost|taskeng|taskhostw)\.exe$/i) | ImageFileName=/\\(Temp|AppData|ProgramData|Users\\Public)\\/i | ImageFileName=/\.exe$/i | table([@timestamp, ComputerName, UserName, ScheduledTaskName, ParentBaseFileName, ImageFileName, CommandLine], limit=200)
Looks for: spoolsv.exe spawning unexpected children or writing a print-processor DLL, and anomalous svchost.exe children consistent with injection — the WIN_PLUS load path. FP: printer drivers legitimately extend the Spooler — exclude signed printer-vendor processes and known print-processor paths.
// HUNT: Print Spooler print-processor loader / svchost injection (WIN_PLUS) // MITRE: T1547.012, T1055 | CONF: medium FP: med COST: low // REQUIRES: ProcessRollup2 (+ module load if available) // FALSE POSITIVES: legit printer drivers extend Spooler -- exclude signed vendor procs #event_simpleName=/ProcessRollup2|SyntheticProcessRollup2/ | ParentBaseFileName=/^spoolsv\.exe$/i | FileName!=/^(spoolsv|splwow64|rundll32)\.exe$/i | ImageFileName!=/\\Windows\\System32\\spool\\/i | table([@timestamp, ComputerName, UserName, ParentBaseFileName, FileName, ImageFileName, CommandLine], limit=200)
Looks for: a non-system / user-path binary opening a TCP listener — a pre-rootkit window onto the backdoor's hidden port before the driver diverts/hides it. FP: high — many apps listen; restrict to user/temp-path images and unexpected ports, and correlate to Q1-Q4 on the same host. Note: WIN_DRV's port-knock diversion means the listener may never appear in host telemetry post-install — treat absence as inconclusive, not clean.
// HUNT: anomalous TCP listener from user-path binary (hidden-port covert channel) // MITRE: T1205.001, T1014 | CONF: medium FP: high COST: med // REQUIRES: NetworkListenIP4 // FALSE POSITIVES: many apps listen -- restrict to user/temp images; correlate Q1-Q4 #event_simpleName=NetworkListenIP4 | ImageFileName=/\\(Temp|AppData|ProgramData|Users\\Public)\\/i | ImageFileName!=/\\Windows\\System32\\/i | table([@timestamp, ComputerName, ImageFileName, LocalAddressIP4, LocalPort, Protocol_decimal], limit=200)
Looks for: outbound connections from an injected svchost.exe or a user-path binary to non-RFC1918 addresses (WebSocket / TCP C2 to the hardcoded server). FP: high — svchost talks to many endpoints; baseline normal svchost egress and correlate to Q4 injection / Q1-Q2 install. Replace the C2 placeholder once atomic infra is published.
// HUNT: WebSocket / hardcoded-C2 beacon from injected svchost or user-path binary // MITRE: T1071, T1090 | CONF: medium FP: high COST: med // REQUIRES: NetworkConnectIP4 // FALSE POSITIVES: svchost has broad egress -- baseline + correlate Q4 injection #event_simpleName=NetworkConnectIP4 | (ImageFileName=/\\svchost\.exe$/i or ImageFileName=/\\(Temp|AppData|ProgramData|Users\\Public)\\/i) | RemoteAddressIP4!=/^(10\.|192\.168\.|172\.(1[6-9]|2\d|3[01])\.|127\.|169\.254\.)/ | table([@timestamp, ComputerName, ImageFileName, RemoteAddressIP4, RemotePort, Protocol_decimal], limit=200)
Looks for: UDP egress (Protocol_decimal=17) to a fixed external endpoint on a non-standard port from a non-browser, non-DNS process — the SprySOCKS UDP C2 channel. FP: high — VoIP/QUIC/game traffic — exclude 53/123/443 and known media apps; aggregate to spot a stable beacon to one host.
// HUNT: UDP C2 beacon to fixed external endpoint (non-DNS) // MITRE: T1095 | CONF: medium FP: high COST: med // REQUIRES: NetworkConnectIP4 with Protocol_decimal // FALSE POSITIVES: VoIP/QUIC/games -- exclude 53/123/443 + media apps; look for stable beacon #event_simpleName=NetworkConnectIP4 | Protocol_decimal=17 | RemoteAddressIP4!=/^(10\.|192\.168\.|172\.(1[6-9]|2\d|3[01])\.|127\.|169\.254\.|224\.|239\.)/ | RemotePort!=53 | RemotePort!=123 | RemotePort!=443 | groupBy([ComputerName, ImageFileName, RemoteAddressIP4, RemotePort], function=count(as=beacons)) | beacons >= 5 | table([ComputerName, ImageFileName, RemoteAddressIP4, RemotePort, beacons], limit=200)
Looks for: an injected svchost.exe or user-path binary spawning a burst of recon/management LOLBins (the 30+ command set: sysinfo, process/service enum, file ops) — hands-on-keyboard operation. FP: medium — admin/monitoring tooling does this — require an unusual parent (injected svchost / user-path) and a tight time burst; correlate to Q4.
// HUNT: SprySOCKS recon/command burst under injected svchost or user-path parent // MITRE: T1059, T1057, T1007 | CONF: medium FP: med COST: med // REQUIRES: ProcessRollup2 // FALSE POSITIVES: admin/monitoring tooling -- require injected/user-path parent + burst #event_simpleName=/ProcessRollup2|SyntheticProcessRollup2/ | ParentBaseFileName=/^(svchost|spoolsv)\.exe$/i | FileName=/^(whoami|net|net1|ipconfig|systeminfo|tasklist|sc|reg|netstat|query)\.exe$/i | groupBy([ComputerName, ParentBaseFileName], function=count(as=cmds)) | cmds >= 4 | table([ComputerName, ParentBaseFileName, cmds], limit=200)
CrowdStrike Custom IOA Recommendations
| IOA Name | Field Patterns | Benign Exclusions | Deployment Path |
|---|---|---|---|
| SprySOCKS — driver dropped to non-standard path | File write of .sys/.dat to Temp/AppData/ProgramData/Public | Signed vendor installers; SCCM/Intune staging (allow-list) | Endpoint Security → Custom IOA → File Creation, Detect+Block |
| SprySOCKS — kernel-mode service install | ServiceImagePath ends .sys outside DriverStore | Vetted driver/EDR/virtualization services | Custom IOA → (Service/Process Creation), Detect |
| SprySOCKS — spoolsv anomalous child | Parent spoolsv.exe → unexpected child / non-spool path | Signed printer-vendor processes | Custom IOA → Process Creation, Detect |
Machine-Readable IOC Appendix
Grouped IOC Quick-Copy
One-click blocks for detection. The rootkit hides post-install artifacts and C2 infra rotates — load-chain behavior is the durable surface. Add per-incident atoms during triage.
type,value,action,severity,expiration,description,tags sha256,68aec5085599e8a272767f50da66c83a6582e4e16ed97c209f65f81538b0c028,prevent,critical,2026-12-17,SprySOCKS WIN_DRV sample,campaign:SprySOCKS-FishMonger domain,REPLACE_WITH_C2_DOMAIN,detect,high,2026-09-17,SprySOCKS hardcoded C2,campaign:SprySOCKS-FishMonger ipv4,REPLACE_WITH_C2_IP,detect,high,2026-09-17,SprySOCKS C2 (TCP/UDP/WebSocket),campaign:SprySOCKS-FishMonger
Kernel driver / encrypted .sys|.dat written to Temp/AppData/ProgramData/Public (pre-rootkit) New kernel-mode service install or driver load with ServiceImagePath outside System32\drivers|DriverStore (BYOVD) spoolsv.exe spawning unexpected children / writing a print-processor DLL -> svchost.exe injection (WIN_PLUS) Scheduled task launching a signed binary from a user/temp path that side-loads an attacker DLL (WIN_DRV) Non-system user-path binary opening a TCP listener; covert hidden port reached via packet-marker port knock Hardcoded C2 over TCP/UDP/WebSocket; stable UDP beacon to a fixed external endpoint on a non-standard port Recon/command burst (whoami/net/sc/reg/netstat/systeminfo) under injected svchost/spoolsv parent
SprySOCKS WIN_DRV # stealthier; kernel-driver rootkit + port-knock traffic diversion SprySOCKS WIN_PLUS # Print Spooler print-processor loader -> svchost injection Actor: FishMonger (China-nexus; linked to I-Soon contractor) SHA256 (WIN_DRV): 68aec5085599e8a272767f50da66c83a6582e4e16ed97c209f65f81538b0c028 Driver (RawWNPF): KW1B5206BDC1743FP.dat # filename likely per-build; treat as pattern DriverLoader: KX1B5206BDC1743DD.dat # encrypted kernel driver loader C2 channels: TCP / UDP / WebSocket (hardcoded config per sample); built-in SOCKS proxy; 30+ commands
Enable Microsoft Vulnerable Driver Blocklist (HVCI / WDAC) -- blocks BYOVD driver loads WDAC / Smart App Control: default-deny unsigned kernel drivers fleet-wide Audit System 7045 (service install) + Sysmon Event ID 6 (driver load) -- collect at install time Disable Print Spooler on servers that do not print (CVE-class + WIN_PLUS print-processor abuse) GPO: restrict print-processor and printer-driver install to admins (PointAndPrint hardening) Promote Q1/Q2 to Detect+Block; enable Falcon suspicious/vulnerable-driver prevention Egress: baseline svchost; flag UDP/WebSocket beacons to fixed external endpoints
Detection Validation Gates
| Gate | Check | Pass Criteria |
|---|---|---|
| Telemetry ready | Driver-load + ServiceInstalled + PeFileWritten + System 7045 / Sysmon 6 flowing | Events visible in last 24h on a sample of servers |
| Benign baseline | Catalogue sanctioned driver installers, printer-vendor Spooler extensions, task-launched apps | Allow-list captured; Q1/Q2/Q4 FP volume acceptable |
| Positive tests | Lab: write a benign .sys to ProgramData (Q1); install a benign test driver service (Q2); benign spoolsv child (Q4) | Each query returns the seeded event |
| Promotion | Promote Q1/Q2 to Detect+Block IOAs; enable vulnerable-driver blocklist; keep Q5-Q7 as hunts | IOAs enabled; HVCI/blocklist on; netflow correlation in place |
Hardening — Tiered & Deployable
Block the path to kernel, shrink the Spooler surface, and capture install-time telemetry before the rootkit hides.
- Enable the Microsoft Vulnerable Driver Blocklist + HVCI/Memory Integrity — M1050 / M1038. Breaks BYOVD-style loads WIN_DRV relies on to reach kernel.
- Promote Q1/Q2 (driver drop + kernel-mode service install) to Detect+Block — M1040. Catch WIN_DRV before the rootkit maps.
- Disable Print Spooler on servers that don't print — M1042. Removes the WIN_PLUS print-processor entry point.
- Enable Falcon suspicious/vulnerable-driver prevention — M1040.
- WDAC / Smart App Control: default-deny unsigned kernel drivers — M1038. Pilot in audit mode first.
- Restrict print-processor / printer-driver install to admins (PointAndPrint GPO) — M1018 / M1026.
- Audit and constrain scheduled-task creation; alert on tasks launching from user/temp paths — M1028 / M1047.
- Egress control: baseline
svchost; flag UDP/WebSocket beacons to fixed external endpoints — M1037.
- Application allowlisting; default-deny user-path execution on servers — M1038. Cuts DLL side-load staging.
- Network segmentation + east-west monitoring to limit covert C2 reach — M1030.
- Fleet-wide driver-load + service-install + scheduled-task telemetry into the SIEM, retained for retro-hunt — M1047. The only reliable view of a host once the rootkit is live.
Deployable Playbooks
1 · Enable Microsoft Vulnerable Driver Blocklist (Windows 11 / Server 2022+)
REM Verify / enable HVCI + Vulnerable Driver Blocklist (run as admin; reboot to apply) reg add "HKLM\SYSTEM\CurrentControlSet\Control\CI\Config" /v VulnerableDriverBlocklistEnable /t REG_DWORD /d 1 /f REM HVCI needs VBS enabled as well -- the scenario key alone is inert and the REM control silently never activates. All three values are required. reg add "HKLM\SYSTEM\CurrentControlSet\Control\DeviceGuard" /v EnableVirtualizationBasedSecurity /t REG_DWORD /d 1 /f reg add "HKLM\SYSTEM\CurrentControlSet\Control\DeviceGuard" /v RequirePlatformSecurityFeatures /t REG_DWORD /d 1 /f reg add "HKLM\SYSTEM\CurrentControlSet\Control\DeviceGuard\Scenarios\HypervisorEnforcedCodeIntegrity" /v Enabled /t REG_DWORD /d 1 /f REM Prereqs: UEFI + Secure Boot + virtualization extensions. Reboot required. REM PILOT FIRST -- incompatible legacy drivers can block boot under HVCI. REM Verify AFTER reboot (SecurityServicesRunning must contain 2): REM (Get-CimInstance Win32_DeviceGuard -Namespace root\Microsoft\Windows\DeviceGuard).SecurityServicesRunning REM Rollback: set both DeviceGuard values and the scenario Enabled back to 0, then reboot. REM If the host will not boot, revert from Safe Mode or WinRE. REM Confirm after reboot: powershell -c "(Get-CimInstance -ClassName Win32_DeviceGuard -Namespace root\Microsoft\Windows\DeviceGuard).SecurityServicesRunning"
2 · Disable Print Spooler on non-print servers (removes WIN_PLUS entry)
Stop-Service -Name Spooler -Force Set-Service -Name Spooler -StartupType Disabled # Hardening for hosts that MUST print: restrict driver/print-processor install to admins reg add "HKLM\SOFTWARE\Policies\Microsoft\Windows NT\Printers\PointAndPrint" /v RestrictDriverInstallationToAdministrators /t REG_DWORD /d 1 /f
3 · Hunt: kernel drivers loaded from non-standard paths (local sweep)
# List loaded drivers whose path is outside the trusted driver store
Get-CimInstance Win32_SystemDriver |
Where-Object { $_.PathName -and $_.PathName -notmatch 'System32\\(drivers|DriverStore)' } |
Select-Object Name, State, PathName, StartMode | Format-Table -Auto
# Recently written .sys/.dat outside System32 (catch the drop before the rootkit hides it)
Get-ChildItem C:\Users,C:\ProgramData,C:\Windows\Temp -Recurse -Include *.sys,*.dat -EA SilentlyContinue |
Where-Object { $_.LastWriteTime -gt (Get-Date).AddDays(-14) } | Select FullName, LastWriteTime
Containment Runbook
| Phase | Actions | Owner | Evidence |
|---|---|---|---|
| Isolate | Network-contain the host; capture memory and a disk image before reboot (rootkit hides live artifacts; offline analysis sees the driver); preserve EDR install-time events | SOC L2 | Containment timestamp; Q1/Q2 events; memory + disk image |
| Triage | Identify variant (WIN_DRV driver/sched-task side-load vs WIN_PLUS Spooler); locate dropped .sys/.dat and service; map any covert listener and C2; assess scope of FishMonger access | IR | Driver path + service; process tree; C2 list |
| Eradicate | Remove the kernel driver + service and scheduled task / print-processor; block C2; rotate credentials exposed on the host; hunt laterally for the same load chain | IR | Removal log; cred reset; lateral sweep |
| Recover | Reimage — kernel rootkit + nation-state hands-on access warrants a clean rebuild; restore from verified-clean backup; re-baseline | IR + IT | Rebuild ticket |
| Harden | Vulnerable-driver blocklist + HVCI; disable Spooler where unused; promote Q1/Q2; enable driver/service/task auditing fleet-wide | Detection Eng | IOA enabled; blocklist + auditing on |
Detection Coverage Map
| Technique | Behavior | CQL | IOA | Coverage |
|---|---|---|---|---|
| T1014 / T1543.003 | Driver dropped to non-standard path | Q1 | IOA-1 | Good pre-rootkit |
| T1543.003 / T1068 | Kernel-mode service install (BYOVD) | Q2 | IOA-2 | Partial driver-load telemetry uneven |
| T1053.005 / T1574.002 | Sched task → DLL side-load (WIN_DRV) | Q3 | — | Partial correlate to Q1 |
| T1547.012 / T1055 | Spooler print-processor → svchost (WIN_PLUS) | Q4 | IOA-3 | Partial + N1 |
| T1205.001 / T1014 | Port-knock hidden-port covert channel | Q5 | — | GAP rootkit hides listener + diverts traffic |
| T1071 / T1095 / T1090 | WebSocket / UDP / SOCKS C2 | Q6, Q7 | — | GAP diversion + conn-hiding; needs netflow |
| T1059 / T1057 / T1007 | 30+ command recon burst | Q8 | — | Partial hands-on-keyboard only |
| T1014 (post-install) | Live host inspection once rootkit active | — | — | GAP offline image / install-time events only |
Honest gaps: WIN_DRV's kernel rootkit hides files, processes, registry keys, and network connections, and the port-knock traffic diversion reroutes C2 from any open port to a hidden one — so the network hunts (Q5-Q7) and any post-install host inspection are structurally weakened and should be treated as corroboration, not primary detection. Driver-load / kernel-service telemetry (Q2) is uneven across sensor versions and config. The reliable detection window is install time (Q1 driver write, Q2 service install) and offline forensic imaging. Validation gates: see §11 — confirm driver/service/file telemetry is flowing, baseline benign driver/printer/task activity, lab-test Q1/Q2/Q4 with seeded benign events, then promote Q1/Q2 and enable the vulnerable-driver blocklist before relying on the network hunts.
Hunt Summary Ticket
TITLE: Hunt — SprySOCKS Windows (WIN_DRV / WIN_PLUS, FishMonger kernel-rootkit backdoor)
SEVERITY: High (China-nexus espionage; kernel rootkit + covert port-knock C2)
SCOPE: Windows servers/endpoints; driver + service + scheduled-task + Spooler telemetry; egress
HYPOTHESIS: FishMonger deploys SprySOCKS via Print Spooler (WIN_PLUS: print-processor -> svchost inject)
or sched-task DLL side-load (WIN_DRV) that drops + loads an encrypted kernel driver acting
as a rootkit, opening a port-knock covert channel for TCP/UDP/WebSocket C2 (30+ commands).
QUERIES RUN: Q1 driver .sys|.dat drop (IOA) | Q2 kernel-mode service install / BYOVD (IOA) |
Q3 sched-task DLL side-load | Q4 Spooler print-processor -> svchost (IOA) |
Q5 anomalous TCP listener | Q6 WebSocket/C2 beacon | Q7 UDP beacon | Q8 recon command burst
+ Native N1-N5 (Spooler child, sched task, driver/service install, logons, covert listener)
DO FIRST: Q1/Q2 + vulnerable-driver blocklist -- catch WIN_DRV BEFORE the rootkit hides itself
FINDINGS: <pending analyst execution>
GAPS: Rootkit hides files/procs/registry/network; port-knock diverts C2 -- network hunts (Q5-Q7)
are corroboration only; reliable window is install-time events + offline forensic imaging
ACTIONS: Promote Q1/Q2; HVCI + vulnerable-driver blocklist; disable Spooler where unused;
WDAC default-deny unsigned drivers; audit driver/service/task installs fleet-wide
OWNER: HuntPack
VERSION: v0.1 - 2026-06-17
Changelog
table() calls now carry an explicit row limit: the default is 200 and truncation is silent, so a capped result was indistinguishable from a complete one. Atomic-IOC sweeps (filters over 5+ hashes or C2 IPs) use limit=max so a wide infection is never silently under-scoped; behavioural hunts use limit=200, where exceeding the cap indicates the query needs tuning. Where present, event names that do not exist in the Falcon data model were corrected (e.g. ServiceInstalled is a Sysmon concept, not a Falcon event; ElfFileWritten is ELFFileWritten) — such queries could never return a row. No detection logic, fields, or IOCs changed.References
| Tier | Source | Used For | Access |
|---|---|---|---|
| 1 | The Hacker News — China-linked SprySOCKS expands to Windows | Variant names, driver filenames/hash, Spooler + sched-task load, TCP/UDP/WebSocket C2, 30+ commands | 2026-06-17 |
| 2 | Infosecurity Magazine — SprySOCKS backdoor (Windows) | Kernel-driver rootkit, covert channel, targeting | 2026-06-17 |
| 2 | Dark Reading — SprySOCKS Windows variant kernel drivers | Kernel driver / rootkit behavior, traffic diversion | 2026-06-17 |
| 2 | SC World — SprySOCKS expands to Windows | Corroboration of variants + FishMonger / I-Soon attribution | 2026-06-17 |
| 2 | MITRE ATT&CK T1205.001 — Traffic Signaling: Port Knocking | Covert-channel technique mapping | 2026-06-17 |
| 2 | MITRE ATT&CK T1547.012 — Print Processors | WIN_PLUS Spooler load mapping | 2026-06-17 |
HuntPack v0.1 · SprySOCKS Windows (WIN_DRV / WIN_PLUS · FishMonger) · Generated 2026-06-17 · Defensive use only — no offensive code. WIN_DRV's kernel rootkit hides files/processes/registry/network and uses a port-knock covert channel — the reliable detection window is install-time (driver drop Q1, kernel-mode service install Q2) and offline forensic imaging; network hunts are corroboration. Validate field names in your tenant before promoting any query.