Threat reportSupply ChainTL-2026-3557
BRIDGEHEAD: npm typosquatting campaign crosses from WSL into Windows to deploy Rust crypto-wallet stealer
BRIDGEHEAD: npm typosquatting campaign crosses from WSL into (TL-2026-3557), also tracked as BRIDGEHEAD, is a high-severity supply-chain compromise, first published 2026-10-14. It has no confirmed attribution, affects npm registry users 40 typosquatted npm packages (chalk, axios, maps to 14 MITRE ATT&CK techniques (T1005, T1027, T1027.002), and is covered by 9 detection rules and 27 indicators of compromise.
- Severity
- HIGHAssessed severity
- CVEs
- 0None referenced
- Techniques
- 14MITRE ATT&CK
- Actors
- 0Not attributed
- Detection rules
- 9SPL · KQL · Sigma
- IOCs
- 27Indicators of compromise
Key facts for TL-2026-3557
- Threat ID
- TL-2026-3557
- Also known as
- BRIDGEHEAD
- Severity
- HIGH
- Status
- ACTIVE
- Category
- SUPPLY_CHAIN
- First published
- Last reviewed
- Attribution confidence
- LOW
- Motivation
- FINANCIAL
- Target sectors
- technology, software-development, cryptocurrency, finance
- Target regions
- Global
- Detection rules
- 9
- Indicators of compromise
- 27
How BRIDGEHEAD: npm typosquatting campaign crosses from WSL into works
CloudSEK reports 40 typosquatted npm packages (v1.0.0) imitating chalk, axios, commander, lodash, react and typescript, published and unpublished on 2026-08-16. Install hooks detect Windows/WSL, bridge into the Windows host via hidden PowerShell, and run an in-memory Rust stealer (main.exe) that targets cryptocurrency wallets, Chromium browser data and Telegram sessions, uploading to gofile.io. The operator C2 at 193.70.34.101:20099 was still answering at time of analysis.
In August 2026 an operator published 40 disposable npm packages, each a misspelling of a heavily installed library: chalk (4 packages), axios (2), commander (9), lodash (7), react (1) and typescript (16), plus one test package (testingsmthb1g). All were version 1.0.0 and carried a scripts/postinstall.js install hook. Per CloudSEK the packages were published 2026-08-16 between 02:28 and 02:56 UTC and unpublished between 04:07 and 04:12 UTC, about 84 minutes of exposure. They were spread across five throwaway npm accounts with generated names.
The install hook holds XOR-encoded arrays (key 'stf2026'; array names ADDON_ENC, BRIDGE_LAUNCHER_ENC, BRIDGE_SCRIPT_PRE_ENC, BRIDGE_SCRIPT_POST_ENC) that decode to the payload URL, the PowerShell bridge commands and the download logic. It first sends an install beacon to the C2 (POST http://193.70.34.101:20099/vote) carrying only a coarse OS label (Windows, MacOS or Linux). It then runs a WSL gate: the WSL_DISTRO_NAME and WSLENV environment variables, and /proc/version and /proc/sys/kernel/osrelease checked for 'microsoft' or 'WSL' (function isVirtualizedLinux). Only Windows and WSL hosts get the payload. From WSL it calls powershell.exe -WindowStyle Hidden -NoProfile -NonInteractive -ExecutionPolicy Bypass to run Invoke-WebRequest into $env:TEMP\main.exe followed by a hidden Start-Process. On native Windows, Node's HTTPS client downloads main.exe to %TEMP% and spawns it detached with no shell.
The payload is a release asset on GitHub, not in npm: https://github.com/bebraz1/qPzM50V1AKG0rVlH/releases/download/null/main.exe. The bebraz1 account was created 2026-06-20 and its name and bio were literally 'null'. The release was published 2026-08-15 and downloads rose from 119 to 173 between 2026-08-17 01:50 and 18:49 UTC. GitHub removed the account by 2026-08-17 23:12 UTC. The payload therefore survived the npm takedown by roughly 39 hours.
main.exe is a 22,969,344-byte Rust-compiled PE32+ GUI executable with a zeroed PE timestamp. About 98.7% of it is .rdata, which holds a single run of about 22.6 million hex characters. That run decodes to an 11,319,296-byte (0xACB800) encrypted blob. The wrapper decrypts it with a ChaCha20 variant whose constant is deliberately mutated ('expad 232-byte k' instead of 'expand 32-byte k'), then runs it in-process with no disk write and no child process. It has a timing-based anti-analysis loop of 552,054 iterations that sleeps 500 ms if it finishes in 9 ms or less. Embedded strings include 'ez_run_', '.exe', '.exe.config' and the log string '[LOG] Payload unpacking and decryption completed in'.
The decrypted stealer imports DPAPI and crypto libraries (crypt32, dpapi, cryptbase, bcryptprimitives) and uses raw Winsock sockets. It resolves api.ipify.org to fingerprint the victim's public IP, then about 0.18 s later contacts upload.gofile.io, an anonymous public file host, to upload stolen data. CloudSEK's sandbox saw TLS certificate validation reject both connections, so no exfiltration was observed. It also collects CPU, GPU and RAM telemetry. Targets are 26 desktop wallet paths (Electrum-DASH, Electron Cash, ElectrumSV, Exodus, Copay/BitPay, Specter, OneKey, KeepKey, SafePal, Trezor Suite, Wasabi, Jaxx Liberty, Coinbase Wallet, Infinity Wallet, Daedalus, Blockstream Green, Bybit and others), Microsoft Edge and Brave profile data (Local State, Web Data, History, Cookies), and Telegram Desktop tdata directories. The run lasts about 33 seconds and the process then exits with no persistence.
The source gives no attribution; the cryptocurrency focus suggests a financial motive. Severity HIGH is an analyst assessment: no CVE or CVSS exists, the payload steals wallet and credential material from developer hosts, and the C2 was live.
MITRE ATT&CK techniques used in TL-2026-3557
Collection
Defense Evasion
T1027 Obfuscated Files or Information; T1027.002 Software Packing; T1497.001 System Checks; T1620 Reflective Code Loading
Execution
T1059.001 PowerShell; T1059.007 JavaScript
Command and Control
Discovery
T1082 System Information Discovery
Initial Access
T1195 Supply Chain Compromise; T1195.002 Compromise Software Supply Chain
Credential Access
T1539 Steal Web Session Cookie; T1555.003 Credentials from Web Browsers
Exfiltration
Affected products and versions in BRIDGEHEAD: npm typosquatting campaign crosses from WSL into
- npm registry users — 40 typosquatted npm packages (chalk, axios, commander, lodash, react, typescript lookalikes)
Vulnerable versions: 1.0.0 of each listed package - Microsoft — Windows and Windows Subsystem for Linux developer hosts
Vulnerable versions: Hosts where a listed package was installed with lifecycle scripts enabled
Remediation for BRIDGEHEAD: npm typosquatting campaign crosses from WSL into
Immediate actions
- Search developer hosts and WSL environments for %TEMP%\main.exe and hidden PowerShell spawned from node/npm
- Purge all 40 BRIDGEHEAD package names from package-lock.json, yarn.lock and pnpm-lock.yaml, private npm mirrors and CI/CD caches
- Block 193.70.34.101:20099 at the perimeter
- Rotate browser-stored credentials and sessions for affected Windows users and move funds out of desktop wallets on affected hosts
Workarounds
- Disable WSL interoperability (appendWindowsPath/interop) on hosts that do not need it
- Install dependencies with --ignore-scripts in untrusted contexts and verify package names before install
Longer-term hardening
- Alert on package-manager install hooks spawning powershell.exe with -WindowStyle Hidden / -ExecutionPolicy Bypass
- Alert on install hooks writing executables to %TEMP% and launching them without a shell
- Add a behavioral rule for a process contacting api.ipify.org followed within about 0.2 s by upload.gofile.io
- Scan executables for the mutated ChaCha20 constant 'expad 232-byte k' and for PEs with .rdata above 90% of file size holding a hex run over 1,000,000 characters
- Track npm accounts publishing multiple typosquats and watch GitHub for repositories with null-style names and hex release names
Weaknesses (CWE) in BRIDGEHEAD: npm typosquatting campaign crosses from WSL into
Timeline of BRIDGEHEAD: npm typosquatting campaign crosses from WSL into
- GitHub account bebraz1, later used to host the payload, is created; its name and bio are literally 'null'
- A repository named '123' is created under the bebraz1 account
- Payload repository qPzM50V1AKG0rVlH is created and main.exe is released as a GitHub release asset at about 03:19 UTC
- All 40 packages are unpublished between 04:07 and 04:12 UTC, about 84 minutes after publication
- All 40 typosquatted npm packages (v1.0.0) are published between 02:28 and 02:56 UTC from five throwaway npm accounts
- CloudSEK analyzes the payload; GitHub release downloads rise from 119 to 173 during the day; the bebraz1 account is removed by 23:12 UTC
- C2 193.70.34.101:20099 (/vote) is still answering at the time of CloudSEK's writing
- CloudSEK publishes the BRIDGEHEAD analysis with IOCs and detection guidance
- Secondary coverage (OffSeq Threat Radar) summarizes the campaign and the roughly 39-hour gap between npm takedown and GitHub payload removal
Sources cited for BRIDGEHEAD: npm typosquatting campaign crosses from WSL into
- BRIDGEHEAD: An npm typosquatting campaign that crosses from WSL into Windows to plant a crypto-wallet stealer (CloudSEK, Vikas Kundu)
- 40 fake npm packages: WSL was the real target (OffSeq Threat Radar)
- BRIDGEHEAD: npm Typosquatting Campaign Targeting WSL and Windows (detections.ai)
- BRIDGEHEAD summary (Hendry Adrian)
- MITRE ATT&CK T1195.002 Compromise Software Supply Chain
- MITRE ATT&CK T1620 Reflective Code Loading
- MITRE ATT&CK T1497.001 Virtualization/Sandbox Evasion: System Checks
Detection coverage for TL-2026-3557
As of 2026-10-14, Threadlinqs Intelligence publishes 9 detection rule(s) for TL-2026-3557 across Splunk SPL, Microsoft KQL and Sigma, covering 27 indicator(s) of compromise. The whole corpus is readable without an account; a free account unlocks full detection query text in Splunk SPL, Microsoft KQL and Sigma; paid tiers add raw indicator values, correlation and the MCP server. Threadlinqs MCP server · View plans.