Threat reportSupply ChainTL-2026-5566
Malicious @ethersphere/bee-js 13.3.0 npm Release and Swarm Desktop 0.56.2 Deliver SleepyDuck Ethereum C2 Backdoor
On 2026-11-09 the Ethersphere release pipeline was abused to publish a malicious @ethersphere/bee-js 13.3.0 npm package (live about 75 minutes, valid SLSA provenance) and a signed, notarized Swarm Desktop 0.56.2 (public about 8.5 hours). Both ran a loader that fetched JavaScript from api.frameworkmetrics.xyz, exfiltrated Bee node config.yaml and swarm.key, and installed a stage 3 backdoor (Go implant on macOS/Linux, ScreenConnect on Windows) linked by Socket to the SleepyDuck/EtherDuck campaign.
Key facts
| Identifiers | TL-2026-5566 |
|---|---|
| Also known as | bee-js compromise, Swarm Desktop 0.56.2 compromise, evjawbreaker |
| Severity | CRITICAL |
| First disclosed | |
| Affected products | Ethersphere @ethersphere/bee-js (npm); Ethersphere / Swarm Association Swarm Desktop; Ethersphere ecosystem Dependents: @ethersphere/swarm-cli, @ethersphere/bee-dashboard, @snaha/swarm-id, @solarpunkltd/file-manager-lib, bee-wasm-js, create-swarm-app |
| Weaknesses (CWE) | CWE-506 |
| Attribution | SleepyDuck, EtherDuck operator (medium confidence) |
| Malware | Bee, UACMe, evjawbreaker, systemd |
| Tools | ScreenConnect, ScreenConnect 25.4.3 |
| MITRE ATT&CK techniques | T1036 Masquerading, T1059.001 PowerShell, T1059.004 Unix Shell, T1059.007 JavaScript, T1071.001 Web Protocols, T1078 Valid Accounts, T1102.001 Dead Drop Resolver, T1195.002 Compromise Software Supply Chain, T1219 Remote Access Tools, T1497.001 System Checks, T1543.001 Launch Agent, T1543.002 Systemd Service and 7 more in the attack flow |
| Motivation | FINANCIAL |
| Target sectors | technology, finance, cryptocurrency, software-development |
| Target regions | Global |
| Detection rules | 9 (1 shown free) |
| Sources | 6 cited sources |
Detection coverage
As of 2026-11-09, Threadlinqs Intelligence publishes 9 detection rule(s) for TL-2026-5566 across Splunk SPL, Microsoft KQL and Sigma, covering 26 indicator(s) of compromise. The whole corpus is readable without an account. Every threat comes with one complete detection in Splunk SPL, Microsoft KQL and Sigma, free for everyone; a free account adds daily TL Creds to unlock the rest. Paid plans add a larger daily allowance, correlation and the MCP server. Threadlinqs MCP server · View plans.
Free detection: SleepyDuck Loader: frameworkmetrics.xyz Contact or generate-version.cjs Postinstall Execution
Behaviour-first hunt for the first stage of the Ethersphere release-pipeline compromise: a Sysmon DNS lookup or connection to api.frameworkmetrics.xyz (the loader/stage 2/stage 3 delivery host gated by an X-Ethersphere: 1 header), or node.exe executing the trojanized scripts/generate-version.cjs postinstall loader shipped in @ethersphere/bee-js 13.3.0. A hit on a developer workstation or CI runner during or after 2026-11-09 means the host ran the loader, which exfiltrates Bee config.yaml and swarm.key and installs a SleepyDuck stage 3 backdoor.
- Languages: Splunk SPL, Microsoft KQL, Sigma
- ATT&CK: T1195.002, T1071.001, T1583.001, T1105
- Data sources: sysmon:EventID 1 (process creation), sysmon:EventID 3 (network connection), sysmon:EventID 22 (DNS query)
- Severity: critical
- Confidence: high
Splunk SPL
((index=sysmon sourcetype="XmlWinEventLog:Microsoft-Windows-Sysmon/Operational") OR (index=wineventlog sourcetype="XmlWinEventLog:Microsoft-Windows-Sysmon/Operational"))
((EventCode=22 (QueryName="frameworkmetrics.xyz" OR QueryName="*.frameworkmetrics.xyz"))
OR (EventCode=3 Initiated=true DestinationHostname="*frameworkmetrics.xyz")
OR (EventCode=1 Image="*\\node.exe" CommandLine="*generate-version.cjs*"))
| eval signal=case(EventCode=22,"dns_lookup_loader_host",EventCode=3,"connect_loader_host",EventCode=1,"npm_postinstall_loader_exec")
| stats earliest(_time) as first_seen latest(_time) as last_seen values(signal) as signals values(Image) as processes values(CommandLine) as command_lines values(QueryName) as dns_queries values(DestinationHostname) as dest_hosts count by host, User
| eval first_seen=strftime(first_seen,"%Y-%m-%d %H:%M:%S"), last_seen=strftime(last_seen,"%Y-%m-%d %H:%M:%S"), threat="TL-2026-5566 bee-js 13.3.0 / Swarm Desktop 0.56.2 SleepyDuck loader"
| table first_seen last_seen host User signals processes command_lines dns_queries dest_hosts count threatMicrosoft KQL
let LoaderDomains = dynamic(["api.frameworkmetrics.xyz", "frameworkmetrics.xyz"]);
union
(
DeviceNetworkEvents
| where Timestamp > ago(24h)
| where RemoteUrl has_any (LoaderDomains)
| extend Signal = "network_to_loader_host"
| project Timestamp, DeviceName, AccountName = InitiatingProcessAccountName, Process = InitiatingProcessFileName, CommandLine = InitiatingProcessCommandLine, RemoteUrl, RemoteIP, RemotePort = tostring(RemotePort), Signal
),
(
DeviceProcessEvents
| where Timestamp > ago(24h)
| where FileName in~ ("node.exe", "node") and ProcessCommandLine has "generate-version.cjs"
| extend Signal = "npm_postinstall_loader_exec"
| project Timestamp, DeviceName, AccountName, Process = FileName, CommandLine = ProcessCommandLine, RemoteUrl = "", RemoteIP = "", RemotePort = "", Signal
)
| order by Timestamp descSigma
title: SleepyDuck Loader Host frameworkmetrics.xyz DNS Lookup
id: 7c1f4a52-3b9e-4d68-a1c7-5e2b90d4f6a1
status: experimental
description: Detects DNS resolution of frameworkmetrics.xyz and api.frameworkmetrics.xyz, the host used by the malicious @ethersphere/bee-js 13.3.0 and Swarm Desktop 0.56.2 loaders (TL-2026-5566) to deliver stage 2 and stage 3 payloads and to receive stolen Bee node keys.
references:
- https://socket.dev/blog/bee-js-compromise
- https://github.com/advisories/GHSA-hh7j-5m3j-23pf
- https://pluto.security/blog/sleepyduck-malware-open-vsx-extensions/
author: Threadlinqs Team
date: 2026/11/09
tags:
- attack.initial-access
- attack.t1195.002
- attack.command-and-control
- attack.t1071.001
- attack.t1105
- attack.resource-development
- attack.t1583.001
logsource:
category: dns_query
product: windows
detection:
selection:
QueryName|endswith: '.frameworkmetrics.xyz'
selection_apex:
QueryName: 'frameworkmetrics.xyz'
condition: 1 of selection*
falsepositives:
- Security researchers or analysts deliberately resolving the IOC domain from a sandbox
level: high
Known false positives:
- Security researchers or threat-intel sandboxes deliberately resolving the IOC domain
- Legitimate project with its own scripts/generate-version.cjs that runs under npm (name collision on the script file only)
Tuning notes: Search is Windows/Sysmon based; for macOS and Linux developer hosts and CI runners run the same domain logic against DNS resolver, proxy (Web datamodel) or EDR network telemetry. Point the index at your Sysmon index (index=sysmon or index=wineventlog). If a project legitimately ships generate-version.cjs, require the dns/connect signals or add its repo path as an exclusion. Alert at critical severity with no threshold: any hit should trigger credential rotation.
- Malicious bee-js 13.3.0 Postinstall: npm Lifecycle Script Running generate-version.cjs · unlock with TL Creds
- SleepyDuck Windows Stage 3: UACME 39 COR_PROFILER UAC Bypass and Microsoft Defender Exclusion · unlock with TL Creds
- SleepyDuck EtherHiding Dead Drop: eth_call to Config Contract 0xf8a900Db... / Backdoor Querying Ethereum RPC · unlock with TL Creds
- SleepyDuck Stage 2: Bee Node swarm.key and config.yaml Exfiltration via [indicator] · unlock with TL Creds
- SleepyDuck Windows Stage 3: Silent ScreenConnect 25.4.3 Install with Attacker Relay [indicator]:8041 · unlock with TL Creds
- SleepyDuck evjawbreaker Go Backdoor Execution from ~/.solidity (Linux/macOS) · unlock with TL Creds
- SleepyDuck Stage 3 Persistence: solidity-langsupport-runner systemd Unit and com.solidity.langsupport.runner LaunchAgent · unlock with TL Creds
- SleepyDuck C2: evjawbreaker Hub (TCP 4912), Payload Host (TCP 3000) and ScreenConnect Relay ([indicator]:8041) Connections · unlock with TL Creds
Indicators of compromise
As of 2026-11-09, Threadlinqs Intelligence tracks 26 indicators of compromise for TL-2026-5566.
Sample indicators (3 of 26)
- IP address:
193.57.9[.]155 - Domain:
frameworkmetrics[.]xyz - File hash:
d01fdf241aa9e0a1ba6ebc19f8f667af1bf652745021c5050126cb7036f7ce58
Defanged, TLP:CLEAR. Full set of 26 indicators: unlock with TL Creds.
Technical analysis
Socket Threat Research reports that two GitHub accounts, the maintainer account nugaon and the release automation identity bee-worker, were used to abuse the Ethersphere release pipeline. The origin of both compromises is unexplained and predates 2026-11-06. On 2026-11-06 the actor pushed workflows that dumped secrets and vars to webhook.site collectors plus a pastebin second stage; Socket assesses with moderate confidence nothing was exfiltrated. On 2026-11-08 at 23:59:54 UTC an unsigned commit (de2f74e, authored as bee-worker) turned scripts/generate-version.cjs into a remote loader and renamed the prepare script to postinstall. An unsigned annotated tag v13.3.0 and GitHub release at 00:06:01 UTC on 2026-11-09 triggered the Publish on npm workflow, which accepts release events without branch checks or required reviewers. bee-js 13.3.0 was latest on npm from 00:09:50 to 01:24:58 UTC and carried valid SLSA provenance. The loader also ran three times inside the publish job itself (npm ci postinstall, build, prepublishOnly).
About 30 minutes after the npm publish, branch emergency/0.56.2 added the same loader to src/index.ts of Swarm Desktop. A manually dispatched pre-release workflow with a free-form branch input and no environment protection was given Apple and Windows signing certificates and the notarization Apple ID, and produced signed and notarized assets for Linux (deb/rpm), macOS arm64 (dmg/zip) and Windows x64 (Setup.exe, nupkg, zip). update-electron-app served 0.56.2 to Windows x64 from 00:43:17 UTC and to Apple Silicon Macs from 00:44:49 UTC. The desktop loader runs at the top of main() on every launch in the unsandboxed Electron main process.
The loader sends an HTTPS GET to api.frameworkmetrics.xyz (/v1/analytics for npm, /v1/electron for desktop) with the User-Agent set to the OS platform and a gate header X-Ethersphere: 1; without the header the server returns a decoy. The response is compiled with new Function and run with the real require, console and process. Stage 2 JavaScript locates the Swarm Desktop data directory, POSTs config.yaml and data-dir/keys/swarm.key to /v1/swarm/report (config.yaml stores the keystore password in plaintext, exposing the node wallet), and downloads the OS-specific stage 3 implant from /v1/assets/. On macOS and Linux the stage 3 is a Go backdoor (module evjawbreaker) written to ~/.solidity/, persisted via systemd user unit solidity-langsupport-runner.service or LaunchAgent com.solidity.langsupport.runner, which exits on debugger or VM detection, resolves its hub address from an Ethereum contract via public RPC gateways, and connects over TLS without certificate validation to run operator commands in a persistent sh pseudo-terminal. On Windows an obfuscated PowerShell loader (invoke.ps1) uses UACME method 39 (COR_PROFILER against mmc.exe) for local admins or a repeated UAC prompt otherwise, adds a Defender exclusion, and silently installs a genuine ConnectWise-signed ScreenConnect 25.4.3 client configured for relay 185.232.84.169:8041 as SYSTEM service ScreenConnect Client (5cbe79c9c25524df).
Attribution to the SleepyDuck/EtherDuck campaign (documented by Pluto Security on 2026-10-01) rests on a shared Ethereum config contract (0xf8a900Db50b3331be6B768bA460BB59f3E40C344) whose write history matches Pluto's report, six of seven matching payload hashes, identical persistence names, ScreenConnect instance ID and relay. The contract hub was updated to 193.57.9.155:4912 at 23:30:47 UTC on 2026-11-08, 29 minutes before the malicious commit. The campaign targets Ethereum tooling and wallet developers and has moved from fake Open VSX extensions to compromising a real project's release pipeline. No CVE has been assigned; GitHub advisory GHSA-hh7j-5m3j-23pf (CWE-506) covers bee-js 13.3.0 with no patched version. A BeaconBeagle lookup for 193.57.9.155 returned HTTP 502 and could not be used. Pluto's report was fetched and its details (contract, hashes, persistence) are consistent with Socket's account.
MITRE ATT&CK techniques by tactic:
Defense Evasion
T1036 Masquerading; T1497.001 System Checks; T1622 Debugger Evasion
Execution
T1059.001 PowerShell; T1059.004 Unix Shell; T1059.007 JavaScript
Command and Control
T1071.001 Web Protocols; T1102.001 Dead Drop Resolver; T1219 Remote Access Tools
Initial Access
T1078 Valid Accounts; T1195.002 Compromise Software Supply Chain
Persistence
T1543.001 Launch Agent; T1543.002 Systemd Service; T1543.003 Windows Service
Privilege Escalation
T1548.002 Bypass User Account Control
Credential Access
defense-impairment
T1553.002 Code Signing; T1685 Disable or Modify Tools
Resource Development
Remediation
Patches
- Swarm Desktop 0.56.3 or later per Socket (not yet published as of 10:30 UTC 2026-11-09); bee-js: no patched 13.3.0, use 13.2.0
Immediate actions
- Search lockfiles, caches, internal registries and mirrors for @ethersphere/bee-js@13.3.0 (integrity sha512-ltkrphoNy7TBIjCICDW7y3qa+j8yljt3+ohPRSM+id1rK2NaOgm5H5V/FioTQ0rEJ5IJ+Zj1micbAdQCqqc8iw==) and pin to 13.2.0
- Treat any machine or CI job that installed 13.3.0 with scripts enabled between 00:09:50 and 01:24:58 UTC on 2026-11-09 as compromised and rotate reachable credentials from a clean machine
- Uninstall Swarm Desktop 0.56.2 and assume the Bee node password and wallet key were stolen; move wallet funds, chequebook and stake to a new key from a clean machine
- Remove ~/.solidity/, the com.solidity.langsupport.runner LaunchAgent, the solidity-langsupport-runner.service unit and the ScreenConnect Client (5cbe79c9c25524df) service
- Block and hunt DNS/proxy logs for api.frameworkmetrics.xyz, hubs on port 4912 and ScreenConnect relay 185.232.84.169:8041
Workarounds
- Use npm 12, pnpm 10+, Yarn Berry 4.14.0+, Bun or Deno, which skip dependency postinstall scripts unless allowlisted
- Linux Swarm Desktop packages do not auto-update; replace them manually
- Hunt for eth_call to 0xf8a900Db50b3331be6B768bA460BB59f3E40C344 with data 0x02d91518 where RPC traffic is visible
Longer-term hardening
- Enforce proof that a release commit is on a protected branch or from a merged release PR inside the publishing workflow
- Require reviewers on the publish environment, restrict deployable tags and use repository rulesets for tag and release creation
- Keep signing and notarization credentials away from manually dispatched workflows that accept arbitrary branches
- Scope and rotate release-bot tokens and alert on releases that bypass release-please
- Disable dependency lifecycle scripts by default in package managers and CI
Affected and fixed versions
- Ethersphere — @ethersphere/bee-js (npm)
Vulnerable versions: 13.3.0
Fixed in: 13.2.0 (last known good) - Ethersphere / Swarm Association — Swarm Desktop
Vulnerable versions: 0.56.2
Fixed in: 0.56.3 or later (per Socket, not published as of 10:30 UTC 2026-11-09) - Ethersphere ecosystem — Dependents: @ethersphere/swarm-cli, @ethersphere/bee-dashboard, @snaha/swarm-id, @solarpunkltd/file-manager-lib, bee-wasm-js, create-swarm-app
Vulnerable versions: swarm-cli 3.6.0, 3.7.0; bee-dashboard 0.37.0, 0.37.1 (0.33.0-0.36.2 indirectly); swarm-id 0.5.0-0.8.0; file-manager-lib 1.1.0, 1.1.1; bee-wasm-js 0.1.0, 0.1.1
Timeline
- Operator deploys Ethereum config contract locked-ioc-10 used as a C2 address book; hub value changes through Sep 2026.
- Pluto Security publishes its report on the SleepyDuck/EtherDuck Open VSX campaign, documenting hub locked-ioc-23:4912 and the same payload set.
- locked-ioc-14 registered at 15:08 UTC; actor pushes workflows dumping secrets and vars to webhook.site collectors (no exfiltrated data observed).
- Contract hub updated to locked-ioc-21:4912 at 23:30:47 UTC; unsigned commit de2f74e turns scripts/generate-version.cjs into a remote loader at 23:59:54 UTC.
- Swarm Desktop v0.56.2 tag deleted at 09:04 UTC and release no longer public by about 09:14 UTC; Socket publishes analysis, noting no 0.56.3 yet as of 10:30 UTC.
- npm removes bee-js 13.3.0 at 01:24:58 UTC; GitHub advisory GHSA-hh7j-5m3j-23pf issued at 01:25:27 UTC.
- Swarm Desktop 0.56.2 built, signed and notarized (assets uploaded 00:41-00:44 UTC); auto-update offered to Windows x64 from 00:43:17 UTC and Apple Silicon from 00:44:49 UTC.
- Tag v13.3.0 and release created at 00:06:01 UTC; @ethersphere/bee-js 13.3.0 live as latest on npm from 00:09:50 UTC with valid SLSA provenance.
Sources cited
- GHSA-hh7j-5m3j-23pf: Malware in @ethersphere/bee-js GitHub · Advisory · 2026-11-09
- Malicious bee-js npm Release and Swarm Desktop Releases Deliver SleepyDuck Ethereum C2 Backdoor socket.dev · Vendor report · 2026-11-09
- SafeDep: Ethersphere bee-js npm compromise safedep.io · Research · 2026-11-09
- Pluto Security: SleepyDuck malware in Open VSX extensions (EtherDuck) pluto.security · Research · 2026-10-01
- Hive Pro: SleepyDuck Trojan Nesting in the Open VSX Marketplace hivepro.com · Research
- SC World: SleepyDuck RAT deployed via bogus Solidity VSCode extension scworld.com · News
Further reading
Drafted by the Threadlinqs research pipeline from 6 sources; published ; last updated —.