DeceptiveDevelopment Second-Stage Tooling: TsunamiKit, Tropidoor and AkdoorTea

WindowsmacOSLinux

TTP Hunt medium Contagious InterviewDeceptiveDevelopment

The .NET spyware-and-miner kit, the two Windows RATs and the infrastructure ESET documents behind the BeaverTail and InvisibleFerret first stages, including a Tor command channel, coin miners and Defender exclusions.

What this hunt looks for

ESET's September 2025 analysis is the fullest account of what follows the first stage on a Windows machine Contagious Interview has compromised. TsunamiKit is a chain of .NET components that fingerprints the system, adds Microsoft Defender exclusions, drops XMRig and NBMiner and talks to a Tor onion service, using names such as Windows Update Script.pyw and Runtime Broker.exe.

Tropidoor is a C DLL RAT that reimplements Windows commands internally and shares code with Lazarus's PostNapTea, delivered as car.dll and img_layer_generate.dll; AkdoorTea is a TCP RAT launched through run.vbs from a ClickFix-1.bat and nvidiaRelease.zip drop, encoding its traffic with Base64 and XOR 0x49. ESET publishes the controller addresses for each.

These artifacts distinguish a machine that ran a malicious take-home assignment and was then worked on by an operator from one where the first stage failed. The WeaselStore delivery files, nvidia.js, ffmpeg.sh and the VCam updates, are cross-platform, so the hunt also covers macOS and Linux for them.

Technique
Persistence and defence evasion through Defender exclusions (MITRE ATT&CK T1562.001), masquerading as system binaries (T1036.005), resource hijacking with XMRig and NBMiner (T1496), Tor-based command and control (T1090.003) and encoded TCP command and control (T1132.001).
Data sources
EDR process telemetry, EDR file telemetry, EDR network telemetry
Last updated
2026-10-04

Indicators

The atomic values this hunt matches on, listed separately from the queries so they can be lifted into tooling that speaks none of the query languages below. Every value here is reported by one of the sources cited at the foot of this page.

TypeValueNote
File name Windows Update Script.pyw, Runtime Broker.exe, Tsunami Payload.exe, Tsunami Payload.dll TsunamiKit component names. The space in Runtime Broker.exe distinguishes it from the genuine RuntimeBroker.exe (ESET).
Tor address n34kr3z26f3jzp4ckmwuv5ipqyatumdxhgjgsmucc65jac56khdy5zqd[.]onion TsunamiKit command channel (ESET).
String Sometimes you never know the value of a moment until it becomes a memory Distinctive string in TsunamiKit (ESET).
Behaviour Microsoft Defender exclusions added; XMRig and NBMiner dropped TsunamiHardener sets persistence and Defender exclusions; the kit drops both miners (ESET).
File name car.dll, img_layer_generate.dll Tropidoor DLLs (ESET).
IP 45.8.146.93, 86.104.72.247, 103.35.190.170 Tropidoor controllers, all in Stark Industries Solutions space (ESET).
File name drvUpdate.exe, ClickFix-1.bat, nvidiaRelease.zip, run.vbs AkdoorTea drop and launch chain (ESET).
IP 103.231.75.101 AkdoorTea controller; TCP traffic encoded with Base64 and XOR 0x49, version string 01.01 (ESET).
IP 45.159.248.110 BeaverTail controller in the same infrastructure table (ESET).
Domain driverservices[.]store (199.188.200.147), www.royalsevres[.]com (116.125.126.38) Infrastructure ESET lists for the campaign, with registrar and hosting provider in the source.
File name nvidiadrivers.zip, VCam1.update, VCam2.update, nvidia.js, ffmpeg.sh, nvidiaupdate.exe WeaselStore delivery file names; WeaselStore is the Go stealer also tracked as GolangGhost, with a Python port called PylangGhost (ESET).

Logic

Every query below implements these steps, so the same hunt returns the same result in each product.

  1. Collect: process starts, file writes and network connections on Windows, macOS and Linux endpoints
  2. Match: a process image, command line or written file name is a published second-stage name (Runtime Broker.exe with a space)
  3. Match: or a process named xmrig or nbminer
  4. Match: or a command line adds a Defender exclusion (Add-MpPreference or Set-MpPreference with an Exclusion parameter)
  5. Match: or a connection to a TsunamiKit or infrastructure domain, or to a published controller address (addresses rotate)
  6. Report: devices with the signal kinds seen, first and last time, newest first

Queries

Defender / Sentinel KQL

Written for this site, from indicators reported by ESET

One row per device across process, file and network telemetry, where the spaced Runtime Broker.exe and the miners are the strongest hits.

// DeceptiveDevelopment second stage (TsunamiKit, Tropidoor, AkdoorTea, WeaselStore): process, file and network signals, reported per device
union
  (DeviceProcessEvents
   | where Timestamp > ago(30d)
   | where FileName in~ ("Runtime Broker.exe", "Tsunami Payload.exe", "drvUpdate.exe", "nvidiaupdate.exe")
        or ProcessCommandLine has_any ("Windows Update Script.pyw", "Tsunami Payload", "nvidiaRelease.zip", "ClickFix-1.bat")
        or FileName contains "xmrig" or ProcessCommandLine contains "xmrig"
        or FileName contains "nbminer" or ProcessCommandLine contains "nbminer"
        // optional: management tooling and installers also add Defender exclusions
        or (ProcessCommandLine has_any ("Add-MpPreference", "Set-MpPreference") and ProcessCommandLine has_any ("ExclusionPath", "ExclusionProcess", "ExclusionExtension"))
        // optional: these script names are plausible in legitimate projects
        or (FileName in~ ("wscript.exe", "cscript.exe", "node.exe", "bash", "sh", "zsh", "node") and ProcessCommandLine has_any ("run.vbs", "ffmpeg.sh", "nvidia.js"))
   | project Timestamp, DeviceName, Signal = "process", Detail = ProcessCommandLine),
  (DeviceFileEvents
   | where Timestamp > ago(30d)
   | where FileName in~ ("Runtime Broker.exe", "Tsunami Payload.exe", "Tsunami Payload.dll", "Windows Update Script.pyw", "drvUpdate.exe", "ClickFix-1.bat", "nvidiaRelease.zip", "nvidiadrivers.zip", "VCam1.update", "VCam2.update", "nvidiaupdate.exe", "car.dll", "img_layer_generate.dll")
        // optional: these file names are plausible in legitimate projects
        or FileName in~ ("nvidia.js", "ffmpeg.sh")
   | project Timestamp, DeviceName, Signal = "file", Detail = FolderPath),
  (DeviceNetworkEvents
   | where Timestamp > ago(30d)
   | where RemoteUrl has_any ("driverservices.store", "royalsevres.com", "n34kr3z26f3jzp4ckmwuv5ipqyatumdxhgjgsmucc65jac56khdy5zqd")
        // optional: addresses from ESET's collection, shared hosts recycle them
        or RemoteIP in ("45.8.146.93", "86.104.72.247", "103.35.190.170", "103.231.75.101", "45.159.248.110", "199.188.200.147", "116.125.126.38")
   | project Timestamp, DeviceName, Signal = "network", Detail = strcat(RemoteUrl, " ", RemoteIP))
| summarize Signals = make_set(Signal), Events = count(), Examples = make_set(Detail, 5), FirstSeen = min(Timestamp), LastSeen = max(Timestamp) by DeviceName
| sort by LastSeen desc
Lower-fidelity parts (4)
  • the Defender exclusion command (Add-MpPreference or Set-MpPreference with an Exclusion parameter) — management agents, developer-tool installers and some vendors' agents add exclusions as routine. Remove: delete the `// optional: management tooling` line and the `or (ProcessCommandLine has_any ("Add-MpPreference" ...` line below it.
  • the script-name clause (run.vbs, ffmpeg.sh or nvidia.js under a script host, shell or node) — these names are plausible in legitimate projects. Remove: delete the `// optional: these script names` line and the `or (FileName in~ ("wscript.exe" ...` line below it.
  • the nvidia.js and ffmpeg.sh file names — plausible names in legitimate projects. Remove: delete the `// optional: these file names` line in the file branch and the `or FileName in~ ("nvidia.js", "ffmpeg.sh")` line below it.
  • the seven controller addresses — taken from ESET's collection, and shared hosting recycles them. Remove: delete the `// optional: addresses` line and the `or RemoteIP in (...)` line below it.

Splunk SPL

Written for this site, from indicators reported by ESET

Raw EDR events with the Endpoint fields, one row per host, labelled process, file or network.

```index=endpoint is a placeholder for EDR process, file and network events carrying the Endpoint data model fields```
index=endpoint earliest=-30d
| eval proc=lower(process_name), cmd=lower(process), fname=lower(file_name), web=lower(coalesce(url, query))
| eval signal=case(
    in(proc, "runtime broker.exe", "tsunami payload.exe", "drvupdate.exe", "nvidiaupdate.exe") OR match(cmd, "windows update script\\.pyw|tsunami payload|nvidiarelease\\.zip|clickfix-1\\.bat|xmrig|nbminer") OR match(proc, "xmrig|nbminer"), "process",
    ```optional: management tooling and installers also add Defender exclusions```
    match(cmd, "(add|set)-mppreference") AND match(cmd, "exclusionpath|exclusionprocess|exclusionextension"), "process",
    ```optional: these script names are plausible in legitimate projects```
    match(proc, "^(wscript|cscript|node)(\\.exe)?$|^(bash|sh|zsh)$") AND match(cmd, "run\\.vbs|ffmpeg\\.sh|nvidia\\.js"), "process",
    in(fname, "runtime broker.exe", "tsunami payload.exe", "tsunami payload.dll", "windows update script.pyw", "drvupdate.exe", "clickfix-1.bat", "nvidiarelease.zip", "nvidiadrivers.zip", "vcam1.update", "vcam2.update", "nvidiaupdate.exe", "car.dll", "img_layer_generate.dll"), "file",
    ```optional: these file names are plausible in legitimate projects```
    in(fname, "nvidia.js", "ffmpeg.sh"), "file",
    match(web, "driverservices\\.store|royalsevres\\.com|n34kr3z26f3jzp4ckmwuv5ipqyatumdxhgjgsmucc65jac56khdy5zqd"), "network",
    ```optional: addresses from ESET's collection, shared hosts recycle them```
    in(dest_ip, "45.8.146.93", "86.104.72.247", "103.35.190.170", "103.231.75.101", "45.159.248.110", "199.188.200.147", "116.125.126.38"), "network",
    true(), null())
| where isnotnull(signal)
| eval detail=coalesce(file_path, process, web)
| stats count AS events values(signal) AS signals values(detail) AS examples min(_time) AS first_seen max(_time) AS last_seen BY host
| convert ctime(first_seen) ctime(last_seen)
| sort - last_seen
Lower-fidelity parts (4)
  • the Defender exclusion command (Add-MpPreference or Set-MpPreference with an Exclusion parameter) — management agents, developer-tool installers and some vendors' agents add exclusions as routine. Remove: delete the ```optional: management tooling``` comment and the `match(cmd, "(add|set)-mppreference")` line below it.
  • the script-name clause (run.vbs, ffmpeg.sh or nvidia.js under a script host, shell or node) — these names are plausible in legitimate projects. Remove: delete the ```optional: these script names``` comment and the `match(proc, "^(wscript|cscript|node)...` line below it.
  • the nvidia.js and ffmpeg.sh file names — plausible names in legitimate projects. Remove: delete the ```optional: these file names``` comment and the `in(fname, "nvidia.js", "ffmpeg.sh")` line below it.
  • the seven controller addresses — taken from ESET's collection, and shared hosting recycles them. Remove: delete the ```optional: addresses``` comment and the `in(dest_ip, ...)` line below it.

Sigma

Written for this site, from indicators reported by ESET

One rule per telemetry type because a Sigma rule binds to one logsource; the Windows names, miners and macOS and Linux scripts are all matched by image or path suffix.

title: DeceptiveDevelopment Second-Stage Process, Miner or Defender Exclusion
id: c3f2e1d4-6d9a-4e5c-9b83-4fa07d9c3e03
status: experimental
description: >
  Process starts for the TsunamiKit, AkdoorTea and WeaselStore names ESET
  documents (including the spaced Runtime Broker.exe that imitates the genuine
  RuntimeBroker.exe), the XMRig and NBMiner coin miners, and a command line that
  adds a Microsoft Defender exclusion.
references:
  - https://www.welivesecurity.com/en/eset-research/deceptivedevelopment-from-primitive-crypto-theft-to-sophisticated-ai-based-deception/
logsource:
  category: process_creation
detection:
  selection_image:
    Image|endswith:
      - '\Runtime Broker.exe'
      - '\Tsunami Payload.exe'
      - '\drvUpdate.exe'
      - '\nvidiaupdate.exe'
  selection_cmdline:
    CommandLine|contains:
      - 'Windows Update Script.pyw'
      - 'Tsunami Payload'
      - 'nvidiaRelease.zip'
      - 'ClickFix-1.bat'
  selection_miner:
    - Image|contains:
        - 'xmrig'
        - 'nbminer'
    - CommandLine|contains:
        - 'xmrig'
        - 'nbminer'
  # optional: management tooling and installers also add Defender exclusions
  defender_cmdlet:
    CommandLine|contains:
      - 'Add-MpPreference'
      - 'Set-MpPreference'
  defender_param:
    CommandLine|contains:
      - 'ExclusionPath'
      - 'ExclusionProcess'
      - 'ExclusionExtension'
  # optional: these script names are plausible in legitimate projects
  selection_scripts:
    Image|endswith:
      - '\wscript.exe'
      - '\cscript.exe'
      - '\node.exe'
      - '/bash'
      - '/sh'
      - '/zsh'
      - '/node'
    CommandLine|contains:
      - 'run.vbs'
      - 'ffmpeg.sh'
      - 'nvidia.js'
  condition: selection_image or selection_cmdline or selection_miner or (defender_cmdlet and defender_param) or selection_scripts
falsepositives:
  - Management agents and developer-tool installers that add Defender exclusions
  - Legitimate projects that ship a script named ffmpeg.sh or nvidia.js
level: high
---
title: DeceptiveDevelopment Second-Stage File Written
id: 4e8a2c7d-1b36-5f09-9d24-7a5c0e3b8f61
status: experimental
description: >
  Creation of a TsunamiKit, Tropidoor, AkdoorTea or WeaselStore file by the name
  ESET reports, including the two Tropidoor DLLs and the WeaselStore delivery
  files.
references:
  - https://www.welivesecurity.com/en/eset-research/deceptivedevelopment-from-primitive-crypto-theft-to-sophisticated-ai-based-deception/
logsource:
  category: file_event
detection:
  selection_names:
    TargetFilename|re: '(?i)[\\/](Runtime Broker\.exe|Tsunami Payload\.exe|Tsunami Payload\.dll|Windows Update Script\.pyw|drvUpdate\.exe|ClickFix-1\.bat|nvidiaRelease\.zip|nvidiadrivers\.zip|VCam1\.update|VCam2\.update|nvidiaupdate\.exe|car\.dll|img_layer_generate\.dll)$'
  # optional: these file names are plausible in legitimate projects
  selection_scripts:
    TargetFilename|re: '(?i)[\\/](nvidia\.js|ffmpeg\.sh)$'
  condition: 1 of selection_*
falsepositives:
  - Legitimate projects that contain nvidia.js or ffmpeg.sh
level: high
---
title: DeceptiveDevelopment Controller Connection
id: b7d3f5a9-2e41-5c68-8a07-1f9e4d6c2b53
status: experimental
description: >
  A connection to the infrastructure domains or the TsunamiKit onion name ESET
  lists, or to the controller addresses it published.
references:
  - https://www.welivesecurity.com/en/eset-research/deceptivedevelopment-from-primitive-crypto-theft-to-sophisticated-ai-based-deception/
logsource:
  category: network_connection
detection:
  selection_domain:
    DestinationHostname|contains:
      - 'driverservices.store'
      - 'royalsevres.com'
      - 'n34kr3z26f3jzp4ckmwuv5ipqyatumdxhgjgsmucc65jac56khdy5zqd'
  # optional: addresses from ESET's collection, shared hosts recycle them
  selection_ip:
    DestinationIp:
      - '45.8.146.93'
      - '86.104.72.247'
      - '103.35.190.170'
      - '103.231.75.101'
      - '45.159.248.110'
      - '199.188.200.147'
      - '116.125.126.38'
  condition: 1 of selection_*
falsepositives:
  - Another tenant of a recycled hosting address
level: high
Lower-fidelity parts (4)
  • the Defender exclusion command (Add-MpPreference or Set-MpPreference with an Exclusion parameter) — management agents, developer-tool installers and some vendors' agents add exclusions as routine. Remove: delete the `# optional: management tooling` comment, the `defender_cmdlet` and `defender_param` blocks, and `or (defender_cmdlet and defender_param)` from the first rule's condition.
  • the script-name clause (run.vbs, ffmpeg.sh or nvidia.js under a script host, shell or node) — these names are plausible in legitimate projects. Remove: delete the `# optional: these script names` comment, the `selection_scripts` block in the first rule, and `or selection_scripts` from its condition.
  • the nvidia.js and ffmpeg.sh file names — plausible names in legitimate projects. Remove: delete the `# optional: these file names` comment and the `selection_scripts` block in the second rule; `1 of selection_*` needs no change.
  • the seven controller addresses — taken from ESET's collection, and shared hosting recycles them. Remove: delete the `# optional: addresses` comment and the `selection_ip` block in the third rule; `1 of selection_*` needs no change.

CrowdStrike LogScale

Written for this site, from indicators reported by ESET

Falcon writes events only for executable and PE files, so the file line covers the .exe and .dll names and the .pyw, .bat, .zip and .update names are caught only when executed.

// Falcon logs file writes only for executable and PE files, so the file Match line covers the .exe and .dll names here
(
  #event_simpleName=/^(Synthetic)?ProcessRollup2$/
  and (
        ImageFileName=/[\\\/](Runtime Broker|Tsunami Payload|drvUpdate|nvidiaupdate)\.exe$/i
     or CommandLine=/Windows Update Script\.pyw|Tsunami Payload|nvidiaRelease\.zip|ClickFix-1\.bat|xmrig|nbminer/i
     or ImageFileName=/xmrig|nbminer/i
     // optional: management tooling and installers also add Defender exclusions
     or (CommandLine=/(add|set)-mppreference/i and CommandLine=/exclusion(path|process|extension)/i)
     // optional: these script names are plausible in legitimate projects
     or (ImageFileName=/[\\\/](wscript|cscript|node)(\.exe)?$|\/(bash|sh|zsh)$/i and CommandLine=/run\.vbs|ffmpeg\.sh|nvidia\.js/i)
  )
)
or (#event_simpleName=/^(NewExecutableWritten|PeFileWritten)$/ and FileName=/^(Runtime Broker|Tsunami Payload|drvUpdate|nvidiaupdate|img_layer_generate|car)\.(exe|dll)$/i)
or (#event_simpleName=DnsRequest and DomainName=/driverservices\.store|royalsevres\.com|n34kr3z26f3jzp4ckmwuv5ipqyatumdxhgjgsmucc65jac56khdy5zqd/i)
// optional: addresses from ESET's collection, shared hosts recycle them
or (#event_simpleName=NetworkConnectIP4 and in(RemoteAddressIP4, values=["45.8.146.93", "86.104.72.247", "103.35.190.170", "103.231.75.101", "45.159.248.110", "199.188.200.147", "116.125.126.38"]))
| groupBy([ComputerName, aid], function=[count(as=events), collect([ImageFileName, CommandLine, FileName, DomainName, RemoteAddressIP4]), min(@timestamp, as=first_seen), max(@timestamp, as=last_seen)])
| sort(last_seen, order=desc)
Lower-fidelity parts (3)
  • the Defender exclusion command (Add-MpPreference or Set-MpPreference with an Exclusion parameter) — management agents, developer-tool installers and some vendors' agents add exclusions as routine. Remove: delete the `// optional: management tooling` line and the `or (CommandLine=/(add|set)-mppreference/i ...` line below it.
  • the script-name clause (run.vbs, ffmpeg.sh or nvidia.js under a script host, shell or node) — these names are plausible in legitimate projects. Remove: delete the `// optional: these script names` line and the `or (ImageFileName=/[\\\/](wscript|cscript|node)...` line below it.
  • the seven controller addresses — taken from ESET's collection, and shared hosting recycles them. Remove: delete the `// optional: addresses` line and the `or (#event_simpleName=NetworkConnectIP4 ...)` line below it.

Elastic

Written for this site, from indicators reported by ESET

Each signal is a boolean column and the four low-fidelity ones are labelled low fidelity in the result, so they can be dropped without touching the core conditions.

FROM logs-*
| WHERE @timestamp > NOW() - 30 days
| EVAL cmd = TO_LOWER(process.command_line), proc = TO_LOWER(process.name), fname = TO_LOWER(file.name), web = TO_LOWER(COALESCE(url.original, destination.domain, dns.question.name))
| EVAL f_proc = proc IN ("runtime broker.exe", "tsunami payload.exe", "drvupdate.exe", "nvidiaupdate.exe") OR cmd LIKE "*windows update script.pyw*" OR cmd LIKE "*tsunami payload*" OR cmd LIKE "*nvidiarelease.zip*" OR cmd LIKE "*clickfix-1.bat*" OR proc LIKE "*xmrig*" OR cmd LIKE "*xmrig*" OR proc LIKE "*nbminer*" OR cmd LIKE "*nbminer*"
| EVAL f_file = fname IN ("runtime broker.exe", "tsunami payload.exe", "tsunami payload.dll", "windows update script.pyw", "drvupdate.exe", "clickfix-1.bat", "nvidiarelease.zip", "nvidiadrivers.zip", "vcam1.update", "vcam2.update", "nvidiaupdate.exe", "car.dll", "img_layer_generate.dll")
| EVAL f_net = web LIKE "*driverservices.store*" OR web LIKE "*royalsevres.com*" OR web LIKE "*n34kr3z26f3jzp4ckmwuv5ipqyatumdxhgjgsmucc65jac56khdy5zqd*"
| EVAL f_defender = (cmd LIKE "*add-mppreference*" OR cmd LIKE "*set-mppreference*") AND (cmd LIKE "*exclusionpath*" OR cmd LIKE "*exclusionprocess*" OR cmd LIKE "*exclusionextension*")
| EVAL f_script = proc IN ("wscript.exe", "cscript.exe", "node.exe", "bash", "sh", "zsh", "node") AND (cmd LIKE "*run.vbs*" OR cmd LIKE "*ffmpeg.sh*" OR cmd LIKE "*nvidia.js*")
| EVAL f_name = fname IN ("nvidia.js", "ffmpeg.sh")
| EVAL f_ip = TO_STRING(destination.ip) IN ("45.8.146.93", "86.104.72.247", "103.35.190.170", "103.231.75.101", "45.159.248.110", "199.188.200.147", "116.125.126.38")
| WHERE f_proc OR f_file OR f_net OR f_defender OR f_script OR f_name OR f_ip
| EVAL signal = CASE(f_proc, "process", f_file, "file", f_net, "network", "low fidelity")
| STATS events = COUNT(*), signals = VALUES(signal), files = VALUES(file.path), commands = VALUES(cmd), first_seen = MIN(@timestamp), last_seen = MAX(@timestamp) BY host.name
| SORT last_seen DESC
| LIMIT 100
Lower-fidelity parts (4)
  • the Defender exclusion command (Add-MpPreference or Set-MpPreference with an Exclusion parameter) — management agents, developer-tool installers and some vendors' agents add exclusions as routine. Remove: delete the `| EVAL f_defender` line and `OR f_defender` from the `| WHERE` line.
  • the script-name clause (run.vbs, ffmpeg.sh or nvidia.js under a script host, shell or node) — these names are plausible in legitimate projects. Remove: delete the `| EVAL f_script` line and `OR f_script` from the `| WHERE` line.
  • the nvidia.js and ffmpeg.sh file names — plausible names in legitimate projects. Remove: delete the `| EVAL f_name` line and `OR f_name` from the `| WHERE` line.
  • the seven controller addresses — taken from ESET's collection, and shared hosting recycles them. Remove: delete the `| EVAL f_ip` line and `OR f_ip` from the `| WHERE` line.

Cortex XQL

Written for this site, from indicators reported by ESET

Counts matching events per host and telemetry type, with the same name lists as the other languages.

config case_sensitive = false
| dataset = xdr_data
| filter (event_type = ENUM.PROCESS and (
            action_process_image_name in ("Runtime Broker.exe", "Tsunami Payload.exe", "drvUpdate.exe", "nvidiaupdate.exe")
         or action_process_image_command_line contains "Windows Update Script.pyw"
         or action_process_image_command_line contains "Tsunami Payload"
         or action_process_image_command_line contains "nvidiaRelease.zip"
         or action_process_image_command_line contains "ClickFix-1.bat"
         or action_process_image_name contains "xmrig" or action_process_image_command_line contains "xmrig"
         or action_process_image_name contains "nbminer" or action_process_image_command_line contains "nbminer"
         // optional: management tooling and installers also add Defender exclusions
         or (action_process_image_command_line ~= "(add|set)-mppreference" and action_process_image_command_line ~= "exclusion(path|process|extension)")
         // optional: these script names are plausible in legitimate projects
         or (action_process_image_name in ("wscript.exe", "cscript.exe", "node.exe", "bash", "sh", "zsh", "node") and action_process_image_command_line ~= "run[.]vbs|ffmpeg[.]sh|nvidia[.]js")
         ))
    or (event_type = ENUM.FILE and (
            action_file_name in ("Runtime Broker.exe", "Tsunami Payload.exe", "Tsunami Payload.dll", "Windows Update Script.pyw", "drvUpdate.exe", "ClickFix-1.bat", "nvidiaRelease.zip", "nvidiadrivers.zip", "VCam1.update", "VCam2.update", "nvidiaupdate.exe", "car.dll", "img_layer_generate.dll")
         // optional: these file names are plausible in legitimate projects
         or action_file_name in ("nvidia.js", "ffmpeg.sh")
         ))
    or (event_type = ENUM.NETWORK and (
            action_external_hostname ~= "driverservices[.]store|royalsevres[.]com|n34kr3z26f3jzp4ckmwuv5ipqyatumdxhgjgsmucc65jac56khdy5zqd"
         or dns_query_name ~= "driverservices[.]store|royalsevres[.]com|n34kr3z26f3jzp4ckmwuv5ipqyatumdxhgjgsmucc65jac56khdy5zqd"
         // optional: addresses from ESET's collection, shared hosts recycle them
         or action_remote_ip in ("45.8.146.93", "86.104.72.247", "103.35.190.170", "103.231.75.101", "45.159.248.110", "199.188.200.147", "116.125.126.38")
         ))
| alter signal = if(event_type = ENUM.FILE, "file", if(event_type = ENUM.PROCESS, "process", "network"))
| comp count() as events, min(_time) as first_seen, max(_time) as last_seen by agent_hostname, signal
| sort desc last_seen
Lower-fidelity parts (4)
  • the Defender exclusion command (Add-MpPreference or Set-MpPreference with an Exclusion parameter) — management agents, developer-tool installers and some vendors' agents add exclusions as routine. Remove: delete the `// optional: management tooling` line and the `or (action_process_image_command_line ~= "(add|set)-mppreference" ...` line below it.
  • the script-name clause (run.vbs, ffmpeg.sh or nvidia.js under a script host, shell or node) — these names are plausible in legitimate projects. Remove: delete the `// optional: these script names` line and the `or (action_process_image_name in ("wscript.exe" ...` line below it.
  • the nvidia.js and ffmpeg.sh file names — plausible names in legitimate projects. Remove: delete the `// optional: these file names` line and the `or action_file_name in ("nvidia.js", "ffmpeg.sh")` line below it.
  • the seven controller addresses — taken from ESET's collection, and shared hosting recycles them. Remove: delete the `// optional: addresses` line and the `or action_remote_ip in (...)` line below it.

osquery

Written for this site, from indicators reported by ESET

Live check of running processes and their open sockets for hosts without an EDR agent, which cannot see the file writes or the Defender command.

SELECT 'process' AS signal, p.pid, p.name, p.path, p.cmdline AS detail
FROM processes p
WHERE lower(p.name) IN ('runtime broker.exe', 'tsunami payload.exe', 'drvupdate.exe', 'nvidiaupdate.exe')
   OR p.cmdline LIKE '%Windows Update Script.pyw%' OR p.cmdline LIKE '%Tsunami Payload%'
   OR p.cmdline LIKE '%nvidiaRelease.zip%' OR p.cmdline LIKE '%ClickFix-1.bat%'
   OR p.name LIKE '%xmrig%' OR p.cmdline LIKE '%xmrig%' OR p.name LIKE '%nbminer%' OR p.cmdline LIKE '%nbminer%'
   -- optional: these script names are plausible in legitimate projects
   OR (lower(p.name) IN ('wscript.exe', 'cscript.exe', 'node.exe', 'bash', 'sh', 'zsh', 'node') AND (p.cmdline LIKE '%run.vbs%' OR p.cmdline LIKE '%ffmpeg.sh%' OR p.cmdline LIKE '%nvidia.js%'))
-- optional: addresses from ESET's collection, shared hosts recycle them
UNION ALL
SELECT 'network' AS signal, p.pid, p.name, p.path, s.remote_address AS detail
FROM process_open_sockets s
JOIN processes p USING (pid)
WHERE s.remote_address IN ('45.8.146.93', '86.104.72.247', '103.35.190.170', '103.231.75.101', '45.159.248.110', '199.188.200.147', '116.125.126.38')
Lower-fidelity parts (2)
  • the script-name clause (run.vbs, ffmpeg.sh or nvidia.js under a script host, shell or node) — these names are plausible in legitimate projects. Remove: delete the `-- optional: these script names` line and the `OR (lower(p.name) IN ('wscript.exe' ...` line below it.
  • the seven controller addresses — taken from ESET's collection, and shared hosting recycles them. Remove: delete from the `-- optional: addresses` line to the end of the query, which removes the UNION ALL and the second SELECT.

YARA

Written for this site, from indicators reported by ESET

The distinctive TsunamiKit string and onion name as ESET reports them; the rule matches ASCII and wide text, but obfuscation may hide either from a static scan.

rule DeceptiveDevelopment_TsunamiKit_Strings
{
    meta:
        description = "Distinctive string and Tor onion name reported for TsunamiKit"
        reference = "https://www.welivesecurity.com/en/eset-research/deceptivedevelopment-from-primitive-crypto-theft-to-sophisticated-ai-based-deception/"
    strings:
        $motto = "Sometimes you never know the value of a moment until it becomes a memory" ascii wide
        $onion = "n34kr3z26f3jzp4ckmwuv5ipqyatumdxhgjgsmucc65jac56khdy5zqd" ascii wide
    condition:
        any of them
}

False positives and tuning

The file names have no benign use and the miners are unambiguous on a corporate endpoint, so the process and file clauses are high precision.

The Defender-exclusion clause is the noisy one: management tooling, developer-tool installers and some vendors' agents write exclusions, so exclude your management agents as initiating processes or drop the clause.

The controller addresses date from ESET's collection and shared hosts recycle them; treat a hit as a lead to confirm against file-name and exclusion evidence.

ffmpeg.sh and nvidia.js are plausible names in legitimate projects; check the folder and the originating download.

Sources

Tuning required before use This hunt is a starting point. Adapt the queries to your schema, validate them against your baseline and tune them for the false positives noted above. Indicators go stale as operators rotate hosts.