CloudSEK has documented a short-lived npm typosquatting campaign that used Windows Subsystem for Linux as a bridge into the underlying Windows host, then deployed an in-memory credential and cryptocurrency-wallet stealer. The malicious npm packages are gone, and the GitHub release that hosted the payload was removed on August 17, but CloudSEK reported that the collection server at 193.70.34.101:20099 was still responding on August 18.

The Windows consequence is more serious than a typical bad JavaScript dependency. According to CloudSEK, installing one of 40 look-alike packages from inside WSL could cause the package’s install hook to identify the environment, invoke Windows-side execution, place main.exe in the user’s temporary directory, and start it invisibly. The malware then targets desktop wallets, Chromium-family browser credentials and cookies, and Telegram Desktop session data.

CloudSEK is currently the only detailed public technical analysis of this specific activity. But the central mechanism is independently consistent with Microsoft’s WSL documentation: WSL supports running Windows executables directly from a Linux shell, including powershell.exe, and Windows drives and user data are accessible across the Windows–Linux boundary. That interoperability is a development convenience. In this campaign, it became the route from an npm install running in Linux to a Windows-native payload running under the same user.

Cybersecurity illustration showing a malicious WSL package exploiting Windows to steal credentials and crypto wallets.The npm removal did not end the exposure​

The packages impersonated six heavily used JavaScript libraries: chalk, axios, commander, lodash, react, and typescript. The roster included names such as chalk-core, axious-core, comand, ladash-cli, raectjs, and multiple misspellings of TypeScript. All were published at version 1.0.0 on August 16 and removed roughly 84 minutes later.

That brief window is enough for a typosquatting operation. A developer, an automated dependency update, a flawed install command, or a copied package name can turn a package’s lifecycle hook into immediate code execution. The official npm documentation makes clear that preinstall, install, and postinstall scripts are executable dependency behavior, not passive package metadata.

CloudSEK’s reporting adds the important operational detail: npm was only the courier. The packages contacted a hard-coded server and decoded a second-stage URL pointing to a GitHub release asset. The payload was reportedly uploaded before the npm packages appeared and remained available after the registry takedown.

That sequencing changes how incident response should be measured. A registry removal prevents fresh installs from the public package page; it does not retract copies already placed in CI caches, developer package caches, lockfile-driven builds, internal artifact repositories, or malware payloads already downloaded to endpoints. CloudSEK observed the GitHub asset’s download count rise from 119 to 173 on August 17, after the npm packages had been removed. That is not an infection count, but it is evidence that downloads continued after the visible npm component was gone.

WSL was the selection gate​

The campaign did not treat every Linux system as equally useful. CloudSEK found that the JavaScript dropper checked for WSL using environment variables and Linux kernel-identification files such as /proc/version and /proc/sys/kernel/osrelease.

A native Linux developer could be fingerprinted without receiving the Windows payload. A WSL user, by contrast, was treated as a route to the Windows environment beneath the Linux shell. The malware’s WSL branch assembled a hidden PowerShell command that downloaded and launched a Windows executable from %TEMP%.

Microsoft documents precisely the capability the malware abused: Windows executables can run directly from WSL, inherit the active Windows user’s rights, and appear in Windows Task Manager as Windows-side processes. This is why viewing WSL as an isolated Linux VM is a security mistake. It is a tightly integrated developer environment whose convenience features cross process, filesystem, and identity boundaries.

The native-Windows branch reportedly did not need PowerShell. CloudSEK found that it used Node’s HTTPS capability to fetch the executable and spawned it directly, hidden and detached. For defenders, that creates a practical detection gap: a rule that watches only for npm or Node launching powershell.exe will identify the WSL delivery path but miss Windows machines that take the direct Node-to-executable route.

The payload was built to leave little behind​

CloudSEK identified the downloaded file as a 22 MB Rust PE executable with only about 266 KB of code. Most of the file was a continuous hexadecimal text block that decoded into an encrypted payload. The wrapper decrypted and executed that payload inside its existing process rather than writing a conventional second-stage executable to disk or creating an obvious child process.

That behavior should change hunting priorities. A clean %TEMP% directory, no discovered dropped payload, and no suspicious child process do not rule out execution. CloudSEK’s dynamic analysis found one process whose memory footprint expanded sharply as it unpacked the embedded data, then performed its collection work and exited.

The report says the in-memory stage loaded Windows cryptographic and DPAPI-related libraries, connected first to api.ipify.org to learn the system’s public IP address, then attempted to contact upload.gofile.io. The latter is a public file-sharing service rather than attacker-owned infrastructure. CloudSEK could not capture the outbound content because the malware rejected the analysis environment’s TLS certificate, but a memory capture taken while the process was active recovered the collection lists and a multipart upload header.

The collection scope described by CloudSEK is clear:

  • The stealer contains paths for 26 desktop cryptocurrency wallet locations, including products such as Electrum variants, Exodus, OneKey, SafePal, Specter, Coinbase Wallet, and WalletWasabi.
  • It targets Chromium profile material associated with Microsoft Edge and Brave, including browser credential keys, cookies, history, autofill-related databases, and Local State.
  • It includes Telegram Desktop tdata locations, which can contain authenticated session material rather than merely chat history.

A stolen browser session can matter as much as a saved password. For developers, Chromium profiles often hold active sessions for source-code hosting, package registries, cloud consoles, identity providers, and administrative portals. The campaign’s direct wallet focus should not obscure the more general endpoint compromise risk.

Detection needs to follow the install-to-network chain​

CloudSEK says the malware’s only clearly attacker-controlled endpoint was 193.70.34.101 on TCP port 20099, using the /vote path. That is the most straightforward block indicator in the report. The GitHub repository and payload asset were already unavailable when CloudSEK rechecked them, while api.ipify.org, GitHub, and GoFile are shared legitimate services with substantial benign use.

Broad blocking of api.ipify.org or GitHub is not an appropriate response. Blocking upload.gofile.io may be justified in tightly controlled enterprise environments, but it has collateral impact and does not address the root of the compromise. The stronger analytic is process-aware sequence detection: an install-time Node process, followed by Windows execution, followed by the rapid pairing of public-IP lookup and an upload attempt.

For endpoints and EDR platforms, high-value signals include:

  • A Node or npm lifecycle process launching hidden PowerShell with -WindowStyle Hidden, -NoProfile, or -ExecutionPolicy Bypass.
  • A Node or npm-associated process writing an executable into %TEMP% and launching it without an intervening shell.
  • WSL-side Node activity reading WSL-identification files or variables and then invoking a Windows .exe or powershell.exe.
  • A process contacting api.ipify.org and then upload.gofile.io within seconds.
  • The string expad 232-byte k in suspicious Windows executables, which CloudSEK identified as a deliberately modified ChaCha20-related constant.
  • PE files whose .rdata section comprises most of the binary and contains a very large uninterrupted run of hexadecimal characters.

The last two are more durable than a file hash. CloudSEK reported 36 distinct hashes among the 40 npm droppers because of trivial variation such as trailing whitespace. Hash-only controls would have caught samples, not the campaign pattern.

Package-script approval is now a practical control​

Teams using current npm tooling should review the npm CLI’s install-script controls. npm documents an allowScripts mechanism that blocks dependency lifecycle scripts by default unless a package is specifically approved. That will not be painless for every project; native-module dependencies and build tools frequently rely on install-time execution. But a controlled exception list is a far better position than silently granting every transitive dependency execution rights on developer workstations and CI runners.

The immediate response for any organization that installed one of the listed package names is to identify affected Windows users and build agents, then treat browser-held credentials and sessions as exposed. Rotate active browser sessions for registry, source-control, cloud, and administrative accounts. Move assets from any desktop cryptocurrency wallet present on an affected user profile. Review proxy, DNS, EDR, and firewall logs for the C2 address and for the IP-lookup-to-file-upload sequence.

WSL deployments deserve a separate policy decision. Microsoft supports per-distribution controls in /etc/wsl.conf that can disable Windows interoperability and prevent Windows path injection:

Code:
[interop]
enabled=false
appendWindowsPath=false

That setting will disrupt workflows that deliberately call Windows tools from WSL, so it belongs on build-only distributions, hardened CI images, and other WSL environments where the cross-boundary convenience is not required. On mixed-use developer systems, visibility and package-script restrictions are more realistic than treating WSL as if it were an isolated Linux guest.

CloudSEK’s report is a reminder that a malicious dependency does not have to stay in the runtime where it was installed. In this case, the disposable npm package was a delivery mechanism for Windows-native theft, and the most important containment work begins after the package registry has already removed the obvious evidence.