Feed
CriticalPublished 23 Aug 2026Updated 24 Aug 202623 packages · 37 versions

GitHub Advisory malware sweep - 2026-08-23 batch (npm `@syncraft-labs/{core,react,vue}` EtherHiding blockchain-C2 dropper + 5-package `N-*-sight-web` bitbucket dropper + 4-package `*-testing-utils`/`*-testkit` jsonstorage.net pino-impersonator + 5-package `stillm4ddpocs-*` oast.fun DNS dep-confusion + `totp-utils` Minecraft JAR + Discord stealer + `create-coin` esbuild typosquat + `@usaa-grp` USAA dep-confusion + PyPI `scrambleeeer` 5th variant + PyPI `libasync` miner)

Summary

20 new GHSA CWE-506 advisories in the 24h ending 2026-08-23. Highlights: @syncraft-labs/{core,react,vue} uses Ethereum-blockchain dead-drop C2 (EtherHiding); five N-*-sight-web packages fetch mutable Bitbucket payloads; four pino-impersonators pull from jsonstorage.net; totp-utils drops a Minecraft mod JAR + steals Discord tokens.

dependency-confusioninfostealercredential-thefttyposquatobfuscationdns-exfiltrationci-cd-compromisecdn-supply-chain
Detected by
GitHub Advisory Database · OpenSSF malicious-packages · OpenSSF Package Analysis · Amazon Inspector · bad-packages.kam193.eu
Also known as
2026-08-23 GHSA sweep · @syncraft-labs EtherHiding cluster · N-sight-web bitbucket dropper family · pino impersonator testing-utils/testkit cluster · stillm4ddpocs oast.fun DNS dep-confusion cluster · totp-utils Minecraft Fabric JAR dropper · create-coin esbuild netbsd-x64 typosquat · @usaa-grp USAA dep-confusion · scrambleeeer 2026-08-scrambleeer sixth variant · libasync 2026-08-libasync miner
Ecosystems
npmPyPI
Packages tracked
23

What happened

The 24-hour window ending 2026-08-23 06:00 UTC published 18 new GHSA CWE-506 advisories on npm and 2 on PyPI. Two things about this batch matter beyond the usual sweep noise: (1) the @syncraft-labs/* trio uses Ethereum-blockchain dead-drop C2 (the EtherHiding pattern that ChainDrop debuted three weeks ago at scale) as a standalone dropper — the technique is now becoming a template for smaller-catchment operators; (2) five N-*-sight-web siblings run an XSS-by-design payload from an unpinned Bitbucket branch, so any frontend that shipped them ran attacker JavaScript in the host page origin for the entire deploy window.

Cluster A - npm @syncraft-labs/{core,react,vue} EtherHiding blockchain-C2 dropper (3 packages)

| Package | Versions | GHSA | Hash | |---|---|---|---| | @syncraft-labs/core | <=0.4.1 | GHSA-54xx-8x72-3539 | 0efe2190…d4ac | | @syncraft-labs/react | <=0.4.1 | GHSA-83j7-x5xf-qxwq | c3986bd0…5cb9 | | @syncraft-labs/vue | <=0.4.1 | GHSA-9cqm-9mxm-f9gh | d78f2856…065f |

All three share the operator address 0xa322E5f3… on Ethereum mainnet and the same RPC candidate list (eth.drpc.org, ethereum-rpc.publicnode.com, eth-mainnet.public.blockscout.com, 1rpc.io/eth, Blockscout, Etherscan-shape txlist endpoints). Only the ESM dist/index.js is tampered — TypeScript sources and the CommonJS build are clean, which means a routine git diff on the published artefacts misses the payload entirely. The injected code hides behind a fake isDevMode() helper: it captures require/module/__filename onto globalThis, pulls transaction call-data from the attacker address, zlib-decompresses it, and child_process.spawns the resulting JavaScript. Because the payload lives in a mutable smart-contract dead-drop, the operator can rotate payloads without republishing a single package, and the C2 endpoint set can be widened to any public Ethereum RPC. This is the standalone-dropper flavour of the same technique the ChainDrop worm (2026-08-04) used inside a worming keyv/cacheable payload — EtherHiding is now graduating from a headline research pattern into a reusable template.

Cluster B - npm N-*-sight-web mutable-Bitbucket dropper (5 packages)

| Package | Versions | GHSA | Hash | |---|---|---|---| | 2-loadsight-web | 1.0.0, 1.0.1 | GHSA-4f5v-fg99-x9xc | cae23fe6…c08b5 | | 3-buildsight-web | 1.0.0, 1.0.1 | GHSA-p6pp-6xxg-295v | ed2d8b62…5545 | | 6-viewsight-web | 1.0.0, 1.0.1 | GHSA-g8jq-29p5-5qrp | 96501ebb…6e68 | | 8-fetchsight-web | 1.0.0, 1.0.1 | GHSA-6wj3-8mh4-prqm | d0e6a4c6…f549 | | 10-shardsight-web | 1.0.0, 1.0.1 | GHSA-6fq4-5r9g-9gfh | 4c7da642…4555 |

All five are the same package under different numeric prefixes (2-, 3-, 6-, 8-, 10-), pointing at the same C2: https://bitbucket.org/p2p-alt-public/p2p-emis/raw/main/GameWebSight. The operator did not bother varying the URL — five siblings hit one endpoint. On module load, a top-level async IIFE fetches the HTML, splats it into document.head/document.body, then re-creates every <script> element as a live script tag so the browser executes it in the host page origin. The Bitbucket workspace p2p-alt-public is unaffiliated with any legitimate publisher and the main branch is unpinned — the operator can push new JavaScript at any time and every deployed frontend that shipped these packages will run it on the next page load with no republish. This is runtime browser-side XSS by design, not install-time backdoor: --ignore-scripts does not help, and a git audit of the bundle only shows a small fetch() call.

Cluster C - npm pino-impersonator *-testing-utils/*-testkit jsonstorage.net dropper (4 packages)

| Package | Versions | GHSA | Hash | Shape | |---|---|---|---|---| | rust-testing-utils | 2.3.0 | GHSA-mgfq-rgcw-ff87 | ee33bded…ffa65 | detached child + Function() | | solidity-testing-utils | 1.2.0 | GHSA-g5g4-w6x5-58j4 | 7a7ffd7d…f3bd8 | detached child + Function() | | hatdhat-testkit | <=3.2.14 | GHSA-3ghm-p4g2-9r6p | 83b6e58e…46d9 | detached child + Function() | | chai-as-testkit | <=2.3.5 | GHSA-4wfj-hpq9-58mw | 0bf8ab4a…cec31 | 4MB CFF bundle, no lazy path |

All four impersonate the legitimate pino logging library — README copied verbatim, source tree cloned, fraudulent author Robert King, hello@jsonspack.com. The first three share one C2: index.js spawns lib/caller.js as a detached child process; caller.js base64-decodes an embedded URL to https://api.jsonstorage.net/v1/json/2ef8c758-a96f-459e-b036-b3b90379a165/f89e8264-86c2-4684-94da-c3f82d59370f, POSTs with an x-secret-key header, and executes the returned JSON cookie field via Function.constructor — full require() access to the parent process. chai-as-testkit swaps that architecture for a single 4MB+ control-flow-flattened bundle at lib/config.js that runs immediately on import, no lazy paths, no network round trip needed to compromise. The jsonstorage.net endpoint is a mutable public keyed store — the operator can rewrite the payload without republishing any package.

Cluster D - npm stillm4ddpocs-* oast.fun DNS-tunnel dep-confusion beacon (5 packages)

| Package | Versions | GHSA | Hash | Published | |---|---|---|---|---| | stillm4ddpocs-demo-sprocket | 999.9.12 | GHSA-6cpg-8367-hp87 | f71ba0f8…4e2b | 2026-08-23 | | stillm4ddpocs-rtest-alpha | 999.9.9, 999.9.10 | GHSA-mrj6-mc6j-fpcm | 47545f80…3839 | 2026-08-23 | | stillm4ddpocs-rtest-bravo | 999.9.9, 999.9.10 | GHSA-j8vq-ph59-27pv | 15e4272b…f5f2 | 2026-08-23 | | stillm4ddpocs-demo-widget | 999.9.9 | GHSA-ghqx-mmmj-m486 | f71ba0f8…4e2b | 2026-08-22 | | stillm4ddpocs-demo-gadget | 999.9.10, 999.9.12, 999.9.20 | GHSA-452p-xh57-7mqp | 3ade0d32…85c6 | 2026-08-22 |

All five share the callback domain da51rv0hb2uc72tg4gvgdepinjcallbk1.oast.fun (interact.sh / Nuclei OAST public endpoint) and the fingerprint 999.9.x dep-confusion sentinel version. preinstall runs a reconnaissance beacon that collects hostname, username, home directory, local IPv4, egress IP (via api.ipify.org, icanhazip.com, ifconfig.me), DNS resolver config, and consuming-project package.json. Exfil goes out three channels in parallel: HTTP POST/80, HTTPS POST/443, and DNS TXT lookups formatted as <idx>-<chunk>.u-<uuid>.<callback> with the payload hex-encoded and split into 60-char chunks. The DNS channel is deliberate — it defeats HTTP-only egress filtering by leaking through the recursive resolver. The -widget/-gadget variants use the same domain but publish minimal GHSA IOC data. The still m4dd pocs (as in "still mad" + PoC) framing plus README claims of "authorised security research" are not an out — the beacon fires on install without consent, and the same package can (and does) get pulled into unrelated builds via dep-confusion.

Cluster E - npm totp-utils Minecraft JAR dropper + Discord/browser stealer (1 package)

| Package | Versions | GHSA | Hash | |---|---|---|---| | totp-utils | 1.4.2, 1.4.3, 1.4.4, 1.4.5, 1.4.6, 1.4.7, 1.4.8, 1.4.9 | GHSA-93j4-gp34-3h5m | 8cebaa0a…deeb5 |

Two separate infection paths that defeat --ignore-scripts alone: (1) a postinstall hook, (2) the advertised public API function validateSecret() also runs the payload — so any CI job or developer that called the API after installing with --ignore-scripts still tripped the payload. On execution the malware walks the Discord, Chrome, Edge, Brave, and Opera credential stores; it validates harvested Discord tokens against the real Discord API before exfil; and it exfils to a Discord webhook at discord.com/api/webhooks/1532429233769419004/…. Separately, it drops optimized-renderer-1.0.0.jar from cdn.discordapp.com/attachments/1507484731535785994/1540335670831222894/optimized-renderer-1.0.0.jar into the Minecraft mods directory; the JAR runs the next time the user launches Minecraft with Fabric loader, extending the compromise from a one-shot install to a lifestyle backdoor on gaming laptops. This is the cross-audience shape (dev laptop → gamer install of same laptop) that infostealer operators have been iterating toward for months.

Cluster F - npm create-coin esbuild netbsd-x64 typosquat + trycloudflare env exfil (1 package)

| Package | Versions | GHSA | Hash | |---|---|---|---| | create-coin | <=20.1.1 | GHSA-468x-vgxv-xv9w | d92da1d8…c380 |

package.json describes itself as a "netbsd-x64 build for esbuild", squatting on the esbuild platform-binary family (packages like @esbuild/netbsd-x64 are official). postinstall runs build/payload.node.js which fingerprints the environment (CI/GitHub Actions/Docker/limited-env checks) and skips if it looks like a sandbox — a research-evasion tell. If it decides to run, it reads ~/.npmrc, package.json, package-lock.json, .env, and src/config.*, enumerates hostname/user/open localhost ports, and POSTs the full process.env to https://<random-name>.trycloudflare.com/ with TLS verification disabled. Idempotency marker .ran prevents re-firing. Randomised 10-30s delays defeat naïve timing correlation. Forces exit 0 to mask any error a developer might notice.

Cluster G - npm @usaa-grp-personal-profile/personal-profile-common USAA-targeted dep-confusion (1 package)

| Package | Versions | GHSA | Hash | |---|---|---|---| | @usaa-grp-personal-profile/personal-profile-common | 999.0.0 | GHSA-rh37-fc24-hw7w | de7570e7…630a |

Highly targeted: the scope @usaa-grp-personal-profile reads as USAA (the US bank/insurer) internal group name. The 999.0.0 version is the dep-confusion sentinel. beacon.js collects hostname/username/CWD, hex-encodes it into DNS labels, and exfils via DNS TXT queries to attacker-controlled oastify.com subdomains (Burp Collaborator public OAST). If USAA (or any org squatting a @usaa-grp-* scope) has a private package under this scope, the operator now has a confirmed catchment for a targeted follow-up payload.

Cluster H - npm internallib_v902 no-IOC dep-confusion pull (1 package)

| Package | Versions | GHSA | Note | |---|---|---|---| | internallib_v902 | >=0 | GHSA-3p65-4jqj-5j69 | No IOCs published; internallib_* naming continues the campaign in /incident/multi-2026-08-19-ghsa-malware-sweep |

The internallib_ prefix + numeric-suffix pattern matches the internallib_* guessing campaign already flagged in prior sweeps. Treat as full RCE against any private-registry proxy that ever fell through to public.

Cluster I - PyPI scrambleeeer (four e's) fifth scrambleeer/reqcrypt sibling (1 package)

| Package | Versions | GHSA | Campaign | Hash | |---|---|---|---|---| | scrambleeeer | 0.1.0 | GHSA-xw2j-24j3-3282 | 2026-08-scrambleeer | 52bcde49…d414 |

Same hardcoded reverse-shell payload as scrambleeer three e's (see 2026-08-22 sweep Cluster C). The six-variant operator register now spans: reqcrypt (Aug 19), reqcrypt-dev (Aug 20), reqcrypts (Aug 21), requests-crypt (Aug 22), scrambleeer (Aug 22), scrambleeeer (Aug 22). The operator started with suffix rotation (-dev, s), then went to prefix rotation (requests-), and is now on letter-count mutation (scrambleeerscrambleeeer → next likely scrambleeeeer). Any scanner that tracked five names will miss the sixth; watch for scrambleeeeer, screambler, reqcrypto, and adjacent letter-shuffles.

Cluster J - PyPI libasync cryptominer + registry-key persistence (1 package)

| Package | Versions | GHSA | Campaign | Hashes | |---|---|---|---|---| | libasync | 1.0.0 | GHSA-7vpc-7xx6-5v47 | 2026-08-libasync (related 2026-07-pyqt6darktheme) | a46929f4…eb9c, 11d7c6bd…a278, b7e770b7…c0d0 |

Installs a native (C-extension) bootstrapper that downloads a remote executable, establishes persistence via Windows registry keys under Run, and runs a cryptominer. Ships obfuscated code + sandbox-detection so the sample fights dynamic analysis. The upstream link to 2026-07-pyqt6darktheme (already-known miner campaign) suggests the same operator running the same monetisation stack against a new package brand.

Registry state

All 20 packages yanked from their respective registries during the 2026-08-23 takedown window. Private mirrors that cached tarballs before takedown will keep serving them.

Related tracked activity

  • EtherHiding blockchain-C2 pattern (Cluster A): first shipped at scale by the ChainDrop worm on 2026-08-04; now a standalone-dropper template.
  • 2026-08-reqcrypt/2026-08-scrambleeer PyPI register (Cluster I): now six variants across reqcrypt, reqcrypt-dev, reqcrypts, requests-crypt, scrambleeer, scrambleeeer. See the 2026-08-19, 2026-08-20, 2026-08-21, and 2026-08-22 sweeps for prior variants.
  • *`internallib_` dep-confusion register** (Cluster H): continuation of the campaign flagged in /incident/multi-2026-08-19-ghsa-malware-sweep.
  • trycloudflare.com short-lived-tunnel C2 (Cluster F): also seen in clx DGA dropper (2026-07-01).
  • Discovery credits: GitHub Advisory Database, OpenSSF malicious-packages, OpenSSF Package Analysis, Amazon Inspector, bad-packages.kam193.eu. No named threat actor.

Affected packages (23)

These are usually pulled in as transitive dependencies rather than installed directly. Check your whole tree at once - it runs in your browser and nothing is uploaded.

Impact

  • Cluster A - npm @syncraft-labs/{core,react,vue} EtherHiding blockchain-C2 dropper (2026-08-23): @syncraft-labs/core@<=0.4.1 (GHSA-54xx-8x72-3539, hash 0efe2190…d4ac), @syncraft-labs/react@<=0.4.1 (GHSA-83j7-x5xf-qxwq, hash c3986bd0…5cb9), @syncraft-labs/vue@<=0.4.1 (GHSA-9cqm-9mxm-f9gh, hash d78f2856…065f). All three share the same operator infrastructure. The ESM build was tampered post-compile (CJS build is clean, TypeScript source is clean — so the malware is invisible to a git diff of the source tree). The obfuscated payload hides inside a fake isDevMode() helper: on import it stashes require/module/__filename onto globalThis, then queries Ethereum JSON-RPC (eth.drpc.org, ethereum-rpc.publicnode.com, eth-mainnet.public.blockscout.com, 1rpc.io/eth) for transactions from the attacker address 0xa322E5f3…. Transaction call-data contains zlib-compressed JavaScript; the loader decompresses it and executes via child_process.spawn. Because the smart-contract data is mutable and off-chain-blocklist, blocking one C2 endpoint is useless — the operator posts a new transaction and every install worldwide gets a new payload with no republish. Same technique class as the ChainDrop worm documented three weeks ago, but here run as a standalone dead-drop rather than as part of a self-propagating worm
  • *Cluster B - npm `N--sight-web mutable-Bitbucket dropper (2026-08-23, 5 packages)**: 2-loadsight-web@1.0.0-1.0.1 (GHSA-4f5v-fg99-x9xc, hash cae23fe6…c08b5), 3-buildsight-web@1.0.0-1.0.1 (GHSA-p6pp-6xxg-295v, hash ed2d8b62…5545), 6-viewsight-web@1.0.0-1.0.1 (GHSA-g8jq-29p5-5qrp, hash 96501ebb…6e68), 8-fetchsight-web@1.0.0-1.0.1 (GHSA-6wj3-8mh4-prqm, hash d0e6a4c6…f549), 10-shardsight-web@1.0.0-1.0.1 (GHSA-6fq4-5r9g-9gfh, hash 4c7da642…4555). Numeric-prefixed sibling family (2-, 3-, 6-, 8-, 10-) all identical in shape: on import a top-level async IIFE fetches HTML from https://bitbucket.org/p2p-alt-public/p2p-emis/raw/main/GameWebSight (**an unpinned main branch**), replaces document.head/document.body with the fetched markup, then re-creates every <script> element as a live script tag so the browser executes it in the host page origin. The Bitbucket workspace p2p-alt-public` is not affiliated with any legitimate publisher, and every install downstream runs whatever the branch owner pushes right now — pure browser-side XSS by design
  • *Cluster C - npm pino-impersonator `-testing-utils/-testkit` jsonstorage.net dropper (2026-08-23, 4 packages): rust-testing-utils@2.3.0 (GHSA-mgfq-rgcw-ff87, hash ee33bded…ffa65), solidity-testing-utils@1.2.0 (GHSA-g5g4-w6x5-58j4, hash 7a7ffd7d…f3bd8), hatdhat-testkit@<=3.2.14 (GHSA-3ghm-p4g2-9r6p, hash 83b6e58e…46d9), chai-as-testkit@<=2.3.5 (GHSA-4wfj-hpq9-58mw, hash 0bf8ab4a…cec31). All four impersonate the legitimate pino logging library (copied README and source tree, fraudulent author Robert King, hello@jsonspack.com). First three share the same C2: index.js spawns lib/caller.js as a detached child process; caller.js base64-decodes an embedded URL to https://api.jsonstorage.net/v1/json/2ef8c758-a96f-459e-b036-b3b90379a165/f89e8264-86c2-4684-94da-c3f82d59370f, POSTs with an x-secret-key header, and executes the returned cookie field via Function(...). chai-as-testkit is the same operator but ships a 4MB+ control-flow-flattened bundle* at lib/config.js that runs immediately on import — no lazy path. The jsonstorage.net collector is a public keyed JSON store, so blocking api.jsonstorage.net at the perimeter is the correlation lever
  • *Cluster D - npm `stillm4ddpocs- oast.fun DNS-tunnel dep-confusion beacon (2026-08-22 → 2026-08-23, 5 packages)**: stillm4ddpocs-demo-sprocket@999.9.12 (GHSA-6cpg-8367-hp87, hash f71ba0f8…4e2b), stillm4ddpocs-rtest-alpha@999.9.9, 999.9.10 (GHSA-mrj6-mc6j-fpcm, hash 47545f80…3839), stillm4ddpocs-rtest-bravo@999.9.9, 999.9.10 (GHSA-j8vq-ph59-27pv, hash 15e4272b…f5f2), stillm4ddpocs-demo-widget@999.9.9 (GHSA-ghqx-mmmj-m486, hash f71ba0f8…4e2b), stillm4ddpocs-demo-gadget@999.9.10, 999.9.12, 999.9.20 (GHSA-452p-xh57-7mqp, hash 3ade0d32…85c6). All five use the **999.9.x dep-confusion sentinel version** so any resolver misconfigured to prefer the highest version across all registries picks the public tarball over the private internal one. preinstall collects hostname, username, home dir, local IPv4, egress IP (via api.ipify.org/icanhazip.com/ifconfig.me), DNS resolver config, and consuming-project package.json, then exfiltrates through **three** channels: HTTP POST/443, HTTPS POST/80, and DNS TXT lookups with hex-encoded chunks against da51rv0hb2uc72tg4gvgdepinjcallbk1.oast.fun`. The DNS channel is deliberate: any org that egress-filters HTTP still leaks via recursive DNS. Package names ("still mad ppl", "PoC") plus README claims of "authorised security research" do not neutralise this — the beacon fires on every install, without consent, at any org the resolver happens to fall through to
  • Cluster E - npm totp-utils Minecraft JAR dropper + Discord/browser stealer (2026-08-23): totp-utils@1.4.2-1.4.9 (GHSA-93j4-gp34-3h5m, hash 8cebaa0a…deeb5). Masquerades as a TOTP helper. Two infection paths: (1) postinstall runs immediately, (2) the public API validateSecret() also runs the payload — so a consumer that ran with --ignore-scripts still triggers it on the first API call. Payload scans Discord, Chrome, Edge, Brave, Opera for auth tokens, extracts Minecraft launcher credentials (vanilla + Lunar + Modrinth stores), validates harvested Discord tokens against the real Discord API, and exfils to a Discord webhook (discord.com/api/webhooks/1532429233769419004/…). Separately, drops optimized-renderer-1.0.0.jar from cdn.discordapp.com/attachments/1507484731535785994/1540335670831222894/optimized-renderer-1.0.0.jar into the Minecraft mods directory — the JAR executes the next time the user launches Minecraft with Fabric loader, extending the compromise from install-time to a persistent lifestyle backdoor
  • Cluster F - npm create-coin esbuild netbsd-x64 typosquat + trycloudflare env exfil (2026-08-23): create-coin@<=20.1.1 (GHSA-468x-vgxv-xv9w, hash d92da1d8…c380). package.json falsely describes this as "netbsd-x64 build for esbuild" — a targeted typosquat of the esbuild platform-binary family. postinstall runs build/payload.node.js which: (1) checks for CI/GitHub Actions/Docker/limited-env fingerprints and skips if sandboxed (anti-analysis), (2) reads ~/.npmrc, package.json, package-lock.json, .env, and src/config.*, (3) enumerates hostname, user, and open localhost ports, (4) POSTs the full process.env to https://<random-name>.trycloudflare.com with cert-validation disabled, (5) drops a .ran idempotency marker to avoid re-firing, (6) forces exit code 0 to mask any errors, (7) sleeps 10-30s randomly to defeat naïve timing correlation. Any developer who ran npm install create-coin has leaked their entire shell environment plus all .env/.npmrc secrets
  • Cluster G - npm @usaa-grp-personal-profile/personal-profile-common USAA-targeted dep-confusion with DNS exfil (2026-08-23): @usaa-grp-personal-profile/personal-profile-common@999.0.0 (GHSA-rh37-fc24-hw7w, hash de7570e7…630a). Highly targeted: scope @usaa-grp-personal-profile reads as USAA (the US bank/insurer) internal group. 999.0.0 is the dep-confusion sentinel. beacon.js collects hostname/username/CWD, hex-encodes it into DNS labels, and exfils via DNS TXT queries to attacker-controlled oastify.com subdomains (Burp Collaborator public OAST). If USAA has a private @usaa-grp-personal-profile scope, the operator now has a confirmed catchment for a targeted follow-up
  • Cluster H - npm internallib_v902 no-IOC dep-confusion pull (2026-08-22): internallib_v902@>=0 (GHSA-3p65-4jqj-5j69). GHSA published no per-package IOCs — the boilerplate "any computer with this package installed should be considered fully compromised". The internallib_ prefix + numeric suffix pattern (_v902) matches the fingerprint of the internal-lib-guessing dep-confusion campaign already tracked at /incident/multi-2026-08-19-ghsa-malware-sweep and prior sweeps; treat as full RCE against any org running a private internallib_* scope
  • Cluster I - PyPI scrambleeeer (four e's) fifth 2026-08-scrambleeer/reqcrypt sibling variant (2026-08-22): scrambleeeer@0.1.0 (GHSA-xw2j-24j3-3282, hash 52bcde49…d414, campaign 2026-08-scrambleeer). Hardcoded reverse shell — same payload shape as scrambleeer (three e's, 2026-08-22 sweep Cluster C). This is the fifth republish across the combined reqcrypt/scrambleeer operator space (reqcrypt, reqcrypt-dev, reqcrypts, requests-crypt, scrambleeer, scrambleeeer), confirming the operator is running a letter-shuffle takedown-evasion register: any host that ran pip install scrambleeeer gave the operator an interactive shell
  • Cluster J - PyPI libasync cryptominer + registry-key persistence (2026-08-20): libasync@1.0.0 (GHSA-7vpc-7xx6-5v47, hashes a46929f4…eb9c, 11d7c6bd…a278, b7e770b7…c0d0, campaign 2026-08-libasync, tracked upstream as related to 2026-07-pyqt6darktheme). Installs a native (C-extension) bootstrapper that downloads a remote executable, establishes persistence via Windows registry keys, and runs a cryptominer. Ships obfuscated code + sandbox-detection so dynamic analysis has to fight the sample. Any Windows host that ran pip install libasync needs to be re-imaged and its wallet + browser + VPN credentials rotated

What to do

  1. 1Grep every lockfile (package-lock.json, yarn.lock, pnpm-lock.yaml, requirements.txt, Pipfile.lock, poetry.lock, uv.lock) for: @syncraft-labs/core, @syncraft-labs/react, @syncraft-labs/vue, 2-loadsight-web, 3-buildsight-web, 6-viewsight-web, 8-fetchsight-web, 10-shardsight-web, rust-testing-utils, solidity-testing-utils, hatdhat-testkit, chai-as-testkit, stillm4ddpocs-demo-sprocket, stillm4ddpocs-rtest-alpha, stillm4ddpocs-rtest-bravo, stillm4ddpocs-demo-widget, stillm4ddpocs-demo-gadget, totp-utils, create-coin, @usaa-grp-personal-profile/personal-profile-common, internallib_v902, scrambleeeer, libasync
  2. 2*For Cluster A (`@syncraft-labs/ EtherHiding)**: uninstall and treat any host that resolved a build as compromised. --ignore-scripts does NOT help — the payload runs on import/require from the ESM bundle, so every downstream app that shipped it to a browser or Node runtime already fetched a blockchain payload. Rotate credentials the process could reach: npm auth tokens, cloud tokens, SSH keys, git tokens, .env values. **Do not rely on blocking the RPC endpoints** — the operator can add more (any public Ethereum RPC works). The correlation lever is unexpected outbound HTTP to any Ethereum JSON-RPC (.drpc.org, .publicnode.com, blockscout.com, 1rpc.io, etherscan.io`) from a build runner. Same class of technique as ChainDrop — if you already have EtherHiding-aware detections for ChainDrop, this sample should light them up
  3. 3*For Cluster B (`N--sight-web)**: uninstall from every frontend bundle. Any HTML that shipped these packages ran arbitrary Bitbucket-hosted JavaScript **in the host page origin** — treat as a live XSS window on every user of the affected app for the entire time the package was deployed. Add bitbucket.org/p2p-alt-public/*` to your outbound-block list for browsers and CI. Consider a Content-Security-Policy tightening pass so runtime script injection cannot happen against a page origin without an explicit allow-list
  4. 4*For Cluster C (`-testing-utils/-testkit`)*: uninstall from every project and CI pipeline. Because the payload is fetched at runtime from a mutable JSON store (api.jsonstorage.net), any host that ran require("chai-as-testkit") or the middleware from any of the four packages already loaded operator-controlled JavaScript with full require() access. Rotate credentials. Add api.jsonstorage.net to egress deny for build runners and dev hosts (no legitimate CI/build use). Watch for republishes under adjacent slugs (vitest-testing-utils, mocha-testkit, jest-testkit) — the impersonator template is trivially reusable
  5. 5*For Cluster D (`stillm4ddpocs-)**: uninstall from every private-registry cache. **Lock private-registry resolution to explicit-scope-only** so a 999.9.x public tarball cannot beat your internal semver. Because Cluster D exfils via DNS to .oast.fun`, HTTP-only egress blocks do not* cover it — add oast.fun, oastify.com, webhook.site, and interact.sh to your DNS RPZ / resolver deny list. Treat any host that installed one as leaked (hostname, egress IP, project name, resolver config are now known to the operator)
  6. 6For Cluster E (totp-utils): uninstall from every project. Because the payload fires both on postinstall and on the first validateSecret() call, --ignore-scripts alone is insufficient — any developer or CI job that called the advertised API also triggered the stealer. Assume Discord, Chrome, Edge, Brave, and Opera token stores are exfiltrated; log out of Discord everywhere, rotate Discord passwords + 2FA, force-clear browser saved passwords + auth cookies. If the host runs Minecraft with Fabric, remove optimized-renderer-1.0.0.jar from the mods directory and rebuild the modpack from a known-good source. Add discord.com/api/webhooks/* and cdn.discordapp.com/attachments/* to egress deny for build runners and non-Discord-user machines
  7. 7For Cluster F (create-coin): uninstall. Because postinstall exfils full process.env to a trycloudflare.com tunnel, rotate every credential in the shell that ran npm install: npm auth tokens (~/.npmrc), CI/CD secrets, cloud tokens, database URLs, API keys, plus every .env value sourced into the shell. Add *.trycloudflare.com to egress deny for build runners — Cloudflare Tunnel has no legitimate build-time use, and it is a common short-lived-tunnel C2 pattern (also seen in clx DGA dropper)
  8. 8*For Cluster G (`@usaa-grp-)**: if you operate anywhere near USAA infrastructure or use a @usaa-grp-*` scope, lock your private-registry proxy to explicit-scope-only resolution and audit whether the private scope was ever queried from outside the corporate egress. Treat as an active dependency-confusion probe against a specific target
  9. 9For Cluster H (internallib_v902): block at your registry proxy. Because the naming pattern matches the earlier internallib_* guessing campaign, review your private-registry logs for other internallib_v<NNN> resolutions in the last 90 days
  10. 10For Cluster I (scrambleeeer 4-e): uninstall from every virtualenv. Correlate scanner state across the six-variant register (reqcrypt, reqcrypt-dev, reqcrypts, requests-crypt, scrambleeer, scrambleeeer) — a scanner that tracked five will miss the sixth. Expect a seventh variant (scrambleeeeer, screambler, reqcrypto) within days
  11. 11For Cluster J (libasync): uninstall from every virtualenv. Any Windows host that installed it: re-image, then rotate wallet, browser, VPN, and SSH credentials before restoring. Grep HKCU\Software\Microsoft\Windows\CurrentVersion\Run and HKLM\...\Run for entries added on or after 2026-08-20 that reference an executable in %APPDATA% / %LOCALAPPDATA% / %TEMP%
  12. 12For all npm installs in CI, run with --ignore-scripts — this blocks Cluster D preinstall beacons and Cluster F postinstall env exfil, but does not block Clusters A/B/C/E (all fire on import or first API call, not on script hooks). For all pip install runs, prefer --only-binary=:all: and pin transitive dependencies from a curated allow-list
  13. 13Verify none of these packages still resolves via your private mirror — internal caches routinely keep serving yanked tarballs after the public takedown

References

multi-2026-08-23-ghsa-malware-sweep