Feed
HighAdvisory sweepPublished 28 Sept 202623 packages · 34 versions

GitHub Advisory malware sweep - 2026-09-27 (late) + 2026-09-28 (donutautosellsrc campaign extends to pip `aseity`, `coinscan`, `donutpromotion`, `claudedashbord`; pip `scrapetools2` novel IPFS-gateway auto-updater; pip `caracas4check` targeted setup.py remote-EXE; pip `metrio`/`metrics-sdk` sentinel-version pentest recon; 15-package npm CWE-506 boilerplate batch with no published analysis)

Summary

GHSA 2026-09-27 (late) + 2026-09-28: 23 new advisories - 8 pip + 15 npm. Cluster A extends yesterdays donutautosellsrc Polygon-blockchain-C2 campaign to 4 more pip packages sharing the same payload hash and attacker wallet. Cluster B scrapetools2` uses IPFS gateways for auto-update payload distribution. Cluster E is a 15-package npm CWE-506 boilerplate batch with no published analysis - likely a mix of typosquats, dep-confusion probes, and unknown-classification takedowns.

infostealercredential-theftobfuscationtyposquatdependency-confusionci-cd-compromise
Incident type
Advisory sweep. A dated batch of GitHub Advisory Database malware entries collected together. A sweep mixes kinds - typosquats, dependency-confusion probes, boilerplate takedowns with no published analysis, and occasionally real payloads - and its severity reflects the worst confirmed item, not the batch as a whole.
Detected by
GitHub Advisory Database · OpenSSF malicious-packages · OpenSSF Package Analysis · Amazon Inspector · kam193/bad-packages
Also known as
2026-09-28 GHSA npm+pip sweep · donutautosellsrc Polygon-blockchain C2 campaign wave 2 · aseity coinscan donutpromotion claudedashbord pip campaign extension · scrapetools2 pip IPFS-gateway auto-updater · caracas4check pip targeted setup.py remote EXE · metrio metrics-sdk pip sentinel-version dep-confusion · npm CWE-506 boilerplate batch 2026-09-28
Ecosystems
npmPyPI
Packages tracked
23

What happened

Between roughly 2026-09-27 12:00 UTC and 2026-09-28 12:00 UTC, the GitHub Advisory Database (with the OpenSSF malicious-packages bulk export, Amazon Inspectors IN-MAL feed, and kam193/bad-packages) published 23 new malware advisories: 8 pip and 15 npm. The most defensively interesting content in this window is that yesterdays donutautosellsrc operator (Polygon-blockchain C2 + steganography + native-extension infostealer) is now confirmed to span at least 5 pip packages under the same wallet, and a separate pip package (scrapetools2) introduces IPFS-gateway distribution as a payload-rotation primitive that defeats DNS-based egress lists.

Cluster A - pip donutautosellsrc campaign extends to 4 more pip packages

aseity@0.1.0 (GHSA-pvh9-pfxq-jq5q), coinscan@0.1.0 (GHSA-78pg-cc9h-7rf3), donutpromotion@<=0.1.0 (GHSA-c2rx-rjgw-p83h), and claudedashbord@0.1.0/0.1.1/0.1.2/0.1.3 (GHSA-28f3-pmhh-qxcm) all share the primitive stack from yesterdays [donutautosellsrc`](/incident/multi-2026-09-27-ghsa-malware-sweep) record:

  1. Steganography - retrieves an image with the real executable bytes hidden inside the image data.
  2. Native Python C-extension infostealer - drops compiled .so/.pyd modules that carry the obfuscated stealer.
  3. Polygon-blockchain-resolved C2 - queries a public Polygon RPC endpoint for the transaction history of attacker-controlled wallet 0x9c0a507300fd902787bb193d80fca5ce6e1bff9a and parses the C2 endpoint from transaction metadata.

All four ship the same payload hash d03c42c275f0dbc617428441508c49ae1adcbbc95af4eeb094bca4e4f8943f3e, which confirms this is one operator publishing under multiple names, not independent copycats. aseity and coinscan additionally include explicit sandbox-detection checks. claudedashbord is a plausible misspelling of "Claude dashboard" - a lure aimed at the Claude Code / AI-assistant tooling ecosystem.

Classify each as malicious-package (fresh name, real payload). Severity critical-equivalent per the calibration rules, but rolled into the sweep as part of a high overall because none of the affected names had legitimate publish history.

The campaign is now known to span at least 5 pip packages (donutautosellsrc plus todays 4). Expect further packages under this wallet. Yesterdays record already contains the domain and hash IOCs; today`s addition is that the operator is scaling their name catalogue.

Cluster B - pip scrapetools2 IPFS-gateway auto-updater

scrapetools2@0.2.0/0.2.1/1.2.0/1.2.1 (GHSA-frv4-982x-mv7m). Novel-for-this-corpus primitive: payload distribution over public IPFS gateways.

Mechanics:

  1. Package advertises a RuntimeSite/browser-pool runtime flow, which under the hood spawns a 60-second auto-update loop.
  2. Every 60 seconds it fetches a tar.gz from one of eu.orbitor.dev, dget.top, or ipfs.filebase.io, resolved via IPNS name k51qzi5uqu5dmh5178x8jzdkz8u3k3qona4zrwlvdr6865it3901l1oe8emjwc.
  3. Decrypts the fetched blob with a bundled Fernet symmetric key.
  4. Writes decrypted payload to scrapetools2/modules/ and imports it at runtime.

Defensive impact:

  • DNS-based egress denylists fail - IPFS content is addressed by hash/IPNS name, not domain. The operator republishes the same content-address across any public gateway (there are dozens of large-scale free ones).
  • Payload rotation is free and untraceable - a fresh IPNS publication is anonymous.
  • Persistence - any scrapetools2 process left running is still fetching new payloads every 60 seconds today. pip uninstall alone does not stop an already-running process.

IOC: source hash 44124d389269a5e4dc8801d3af1afeb08aee57313fcc7082570c5890e7d89233. Classify as malicious-package.

Cluster C - pip caracas4check targeted setup.py remote EXE

caracas4check@1.1.1/1.1.2 (GHSA-8p46-j5h8-w78j, campaign 2026-09-caracas4check). Overrides setup.py install to run at install time, downloads a malicious executable from a remote location. OSSF flags this as a targeted attack: the payload gates on specific victim characteristics before firing.

Why targeting matters defensively: casual sandbox execution of caracas4check will not observe the download - the check gates on host attributes the sandbox does not present. So absence-of-evidence on a defenders side does not prove the remote EXE did not fire on a real victim. Treat any host that ran pip install caracas4check as compromised. Hashes: source fe298eb267ef99191242315438fe8b7a619bece89e39d3e607cc34af455c647a, secondary 296b5205b6a5c48ab5dcdbf4abf34818991f1202e560137ee480c075135f63ec`.

Name reads as a Caracas-region compliance-check lure - a Venezuelan or Spanish-language regulatory context. Classify as malicious-package.

Cluster D - pip metrio + metrics-sdk dep-confusion pentest recon

metrio@999.0.0/1000.0.0/1001.0.0 (GHSA-ww2h-pjh2-r85q), metrics-sdk@999.0.0/1000.0.0/1001.0.0 (GHSA-vcmr-hgqh-xrh3). Both use classic dep-confusion sentinel-versioning to resolve preferentially over any legitimate internal-registry version.

OSSF classifies these as GENERIC-standard-pypi-install-pentest - probably bug-bounty/pentest probes, not opportunistic operators. Payload exfiltrates only IP + username at install time (no secret material). Hashes: metrio f7b0289ef68f815e0fd296282739990dfc918c0070fb5acdae2787ca8eba23f3, metrics-sdk 1378dcfc94bda0e9beb3e3d66c0588967a164741686ab473826fbab077e7afb9.

Classify both as dependency-confusion. Severity medium per calibration rules (no confirmed payload beyond a recon beacon).

Cluster E - 15-package npm CWE-506 boilerplate batch

15 npm packages quarantined on 2026-09-28 with GitHub`s CWE-506 boilerplate advisory body and no published analysis:

  • api-typings (GHSA-gjx9-hrcc-f6qj)
  • seek-pass (GHSA-q39g-5xh5-89h3)
  • riot-private (GHSA-qgpm-ggcf-4fqm)
  • capacitor-plugin-service-worker (GHSA-qg5c-9jmq-fpmf)
  • swiper_angular (GHSA-r6m9-x8fm-wq5c)
  • discord-mfa-solver (GHSA-vf4w-775x-ccfh)
  • ultra-ws (GHSA-rwhp-v7w5-c6cc)
  • vinzzsync-wacli (GHSA-rmcq-f7vh-v86v)
  • open-item-validator (GHSA-55qh-42r8-hcgq)
  • tanksync (GHSA-47j4-w95p-wjp7)
  • @consts/links (GHSA-5rp9-7r4x-3fqp)
  • spotify-url-resolvers (GHSA-w77g-6g5j-wr2r)
  • discord-resolvers (GHSA-whmq-ffxc-4jpc)
  • discord-players (GHSA-mvg6-qj9g-3j3j)
  • @digi-kernel/digi-kernel-constrains (GHSA-h37m-2c3q-82j8)

By name-shape inspection:

  • Likely typosquats: swiper_angular (for swiper), ultra-ws (for ws), capacitor-plugin-service-worker (Ionic Capacitor plugin family), api-typings (for @types/*).
  • Discord-ecosystem lures: discord-mfa-solver, discord-resolvers, discord-players, spotify-url-resolvers - all target discord-bot-tooling developers.
  • Dep-confusion at internal-scope names: riot-private (-private suffix), @consts/links, @digi-kernel/digi-kernel-constrains (note the typo "constrains" for "constraints"), vinzzsync-wacli.
  • Generic malicious-package lures: seek-pass, open-item-validator, tanksync.

Without a published payload analysis these all stay medium for the sweep purposes. If Socket, Amazon Inspector, or a vendor blog lands a payload write-up on any of them later they may re-split into their own record.

Operator continuity check

All six multi-day operators tracked in prior sweeps are quiet in this window:

  • ltidi.storage.googleapis.com (2026-09-26 Cluster D GCS-tarball loader) - no fresh @airbnb-extended/*, ltidisafe*, or GCS-tarball-loader manifests
  • oob.algamil7x.xyz - no new day-10+ additions
  • eo8f3m3ho26a0nm.m.pipedream.net (2026-09-26 Cluster E shoplist-app Pipedream beacon) - no new Pipedream-beaconing packages
  • simple-date-formatter-new-<N> family (124.221.154.135 SSH beacon) - no -new-12/-16/higher today
  • *`n8n-nodes- mkicom.com`** - no new packages
  • .oastify.com/.oast.fun Burp Collaborator OOB (2026-09-27 Cluster D cma-self-hosted-sandbox-cf) - no new packages beaconing OOB

The egress blocks (ltidi.storage.googleapis.com, oob.algamil7x.xyz, eo8f3m3ho26a0nm.m.pipedream.net, mkicom.com, 104.221.154.135, Polygon RPC endpoints, Burp Collaborator zones) remain durable and should not be relaxed on a two-to-three-day quiet.

Registry state

All 23 packages in this sweep are pip/npm-quarantined at time of writing. Active operator-side infrastructure unique to today`s batch:

  • Polygon wallet 0x9c0a507300fd902787bb193d80fca5ce6e1bff9a (Cluster A - same as yesterday; the campaign scaled its name catalogue overnight)
  • IPNS name k51qzi5uqu5dmh5178x8jzdkz8u3k3qona4zrwlvdr6865it3901l1oe8emjwc (Cluster B)
  • IPFS gateway rotation set eu.orbitor.dev, dget.top, ipfs.filebase.io (Cluster B)

Discovery credits

GitHub Advisory Database, OpenSSF malicious-packages, OpenSSF Package Analysis, Amazon Inspector, kam193/bad-packages. Per-package IOC details drawn from GHSA and OSSF advisory bodies published between 2026-09-27 12:00 UTC and 2026-09-28 12:00 UTC.

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 - pip donutautosellsrc campaign extends to 4 more packages (real payload, malicious-package): aseity@0.1.0 (GHSA-pvh9-pfxq-jq5q), coinscan@0.1.0 (GHSA-78pg-cc9h-7rf3), donutpromotion@<=0.1.0 (GHSA-c2rx-rjgw-p83h), claudedashbord@0.1.0/0.1.1/0.1.2/0.1.3 (GHSA-28f3-pmhh-qxcm). All four share the same primitive stack as yesterdays donutautosellsrc (Cluster A on [2026-09-27 sweep](/incident/multi-2026-09-27-ghsa-malware-sweep)): steganographic image loader, native Python C-extension infostealer, and command-and-control server addresses read from Polygon blockchain transaction history for attacker wallet 0x9c0a507300fd902787bb193d80fca5ce6e1bff9a. All four ship the same payload hash d03c42c275f0dbc617428441508c49ae1adcbbc95af4eeb094bca4e4f8943f3e - this is the same campaign, not four independent operators. aseity and coinscan additionally include explicit sandbox-detection checks. claudedashbord is a lure aimed at the Claude Code / AI-assistant ecosystem (misspelling of "dashboard"). The Polygon-blockchain C2 remains the same: polygonscan.com/address/0x9c0a507300fd902787bb193d80fca5ce6e1bff9a`
  • Cluster B - pip scrapetools2 novel IPFS-gateway auto-updater + Fernet-encrypted payload rotation (real payload, malicious-package): scrapetools2@0.2.0/0.2.1/1.2.0/1.2.1 (GHSA-frv4-982x-mv7m). Novel-for-this-corpus primitive: package fetches tar.gz payloads from public IPFS gateways (eu.orbitor.dev, dget.top, ipfs.filebase.io) resolved via IPNS name k51qzi5uqu5dmh5178x8jzdkz8u3k3qona4zrwlvdr6865it3901l1oe8emjwc, decrypts them with a bundled Fernet symmetric key, writes to scrapetools2/modules/, and executes at runtime. Auto-updater fires on a 60-second interval via the advertised RuntimeSite/browser-pool flow. IPFS-content-addressed distribution means that (a) the operator can rotate payloads without touching DNS, (b) traditional domain-based egress blocks fail because content moves across public IPFS gateways, and (c) any host that ran scrapetools2 and left the process alive is still checking for new payloads every 60 seconds. Source hash 44124d389269a5e4dc8801d3af1afeb08aee57313fcc7082570c5890e7d89233
  • Cluster C - pip caracas4check targeted setup.py remote-EXE downloader (real payload, malicious-package): caracas4check@1.1.1/1.1.2 (GHSA-8p46-j5h8-w78j, campaign 2026-09-caracas4check). Overrides setup.py install to run at install time and downloads a malicious executable from a remote location; the OSSF analysis flags this as a targeted attack (the payload only fires under specific conditions on the victim host, not on any install). Hashes: source fe298eb267ef99191242315438fe8b7a619bece89e39d3e607cc34af455c647a, secondary 296b5205b6a5c48ab5dcdbf4abf34818991f1202e560137ee480c075135f63ec. Because the payload gates on victim characteristics, casual sandbox execution may report a null observation - a real target still gets popped. The name reads as a Caracas-region compliance-check lure
  • Cluster D - pip metrio + metrics-sdk sentinel-version pentest recon (dependency-confusion probe): metrio@999.0.0/1000.0.0/1001.0.0 (GHSA-ww2h-pjh2-r85q), metrics-sdk@999.0.0/1000.0.0/1001.0.0 (GHSA-vcmr-hgqh-xrh3). Both use the classic dep-confusion sentinel-version pattern (999.x/1000.x/1001.x, well above any real release) to guarantee they resolve preferentially over any legitimate internal-registry version. Payload is a setup.py-hook that exfiltrates host IP and username at install time - the standard GENERIC-standard-pypi-install-pentest recon flavour. No secret-material exfil, no persistence. The metrio and metrics-sdk names read as generic analytics/metrics SDK stubs used by internal-registry consumers - the operator is fishing for orgs that pull a metrio or metrics-sdk package from a private index without pinning against the public PyPI resolver. Hashes: metrio f7b0289ef68f815e0fd296282739990dfc918c0070fb5acdae2787ca8eba23f3, metrics-sdk 1378dcfc94bda0e9beb3e3d66c0588967a164741686ab473826fbab077e7afb9
  • Cluster E - 15-package npm CWE-506 boilerplate batch, no published analysis (mixed kinds, unclassified): api-typings, seek-pass, riot-private, capacitor-plugin-service-worker, swiper_angular, discord-mfa-solver, ultra-ws, vinzzsync-wacli, open-item-validator, tanksync, @consts/links, spotify-url-resolvers, discord-resolvers, discord-players, @digi-kernel/digi-kernel-constrains - all versions, all quarantined. GitHubs advisory bodies are CWE-506 boilerplate ("any computer that has this package installed or running should be considered fully compromised") with no IOCs, no source-code link, and no vendor write-up. Names read as: typosquats (swiper_angular for the real swiper, ultra-ws for ws, capacitor-plugin-service-worker for the Ionic Capacitor plugin family, api-typings for @types/*); Discord-ecosystem lures (discord-mfa-solver, discord-resolvers, discord-players, spotify-url-resolvers - all reach the same discord-bot-tooling audience); dependency-confusion probes at internal-scope names (riot-private, @consts/links, @digi-kernel/digi-kernel-constrains, vinzzsync-wacli); and generic malicious-package lures (seek-pass, open-item-validator, tanksync). Treat each as medium` for the purposes of the sweep because no analysis has been published; if kam193/Amazon Inspector/Socket lands a payload write-up on any of these later, they may re-split into their own record
  • Operator continuity check - Cluster A donutautosellsrc campaign is now a multi-day, multi-package operator: with aseity, coinscan, donutpromotion, claudedashbord today the campaign now spans at least 5 pip packages (plus yesterdays donutautosellsrc@0.3.7/0.3.8/0.3.9) sharing wallet 0x9c0a507300fd902787bb193d80fca5ce6e1bff9a. The Polygon-RPC egress block from yesterday remains the durable mitigation for the whole family. No fresh ltidi.storage.googleapis.com, oob.algamil7x.xyz, eo8f3m3ho26a0nm.m.pipedream.net, mkicom.com, 104.221.154.135, or Burp-Collaborator .oastify.com/.oast.fun` beacons appeared in this window either - all six multi-day operators tracked over the last week remain quiet. Do NOT relax those blocks on a two-to-three-day quiet

What to do

  1. 1Grep every package-lock.json, yarn.lock, pnpm-lock.yaml, package.json, requirements.txt, Pipfile.lock, poetry.lock, and pyproject.toml for every package name in Clusters A through E. Uninstall on hit, wipe node_modules/.venv, delete the lockfile, rebuild against a clean cache. Clusters A, B, and C carry confirmed real payloads (blockchain-C2 infostealer, IPFS-fetched auto-updater, targeted setup.py remote EXE); a hit on any of those is a compromise, not a warning
  2. 2For Cluster A (pip aseity+coinscan+donutpromotion+claudedashbord donutautosellsrc campaign extension): uninstall on hit and image the host - the native-extension infostealer landed compiled C code on the host, so what a defender sees on disk today may not be the full payload. Rotate every credential the installer user account had access to (browser-saved passwords, wallet extensions, SSH keys, cloud CLI credentials, hardcoded env vars). Because the C2 addresses are fetched from a public Polygon RPC lookup against wallet 0x9c0a507300fd902787bb193d80fca5ce6e1bff9a, a domain-only egress denylist is not enough - either block the specific IOC domains (from yesterdays record: thisisafalsepositive.st, sltnnt.ru) OR block outbound Polygon RPC endpoints (polygon-rpc.com, rpc-mainnet.matic.network, polygon-mainnet.g.alchemy.com, polygon-mainnet.infura.io, common public RPCs) from build/CI networks. Add a lockfile-lint rule that rejects all four of todays names outright. The campaign is now known to span at least 5 pip packages - expect further packages under this wallet
  3. 3For Cluster B (pip scrapetools2 IPFS-gateway auto-updater): uninstall on hit AND kill any Python process still running scrapetools2 code (the auto-updater fires every 60 seconds while a scrapetools2 process is alive). Because the payload distribution uses IPFS gateways rotating across eu.orbitor.dev, dget.top, and ipfs.filebase.io, a domain-only block against those three catches this operator but the IPNS name k51qzi5uqu5dmh5178x8jzdkz8u3k3qona4zrwlvdr6865it3901l1oe8emjwc can be republished behind any public IPFS gateway. Block outbound HTTPS to public IPFS gateway hostnames (*.ipfs.io, *.filebase.io, dget.top, orbitor.dev, cloudflare-ipfs.com, gateway.pinata.cloud) from build/CI networks unless you have a specific IPFS use case. Rotate any credential the scrapetools2 process had in memory or on disk
  4. 4For Cluster C (pip caracas4check targeted setup.py remote EXE): uninstall on hit. Because the payload gates on victim characteristics, absence-of-log-evidence on your side does not prove the remote EXE did not fire - assume compromise on any host that ran pip install caracas4check. Rotate every credential the installer user account had access to. Watch for outbound connections in build/CI networks to non-standard high ports (the campaign class covers non-443 HTTP fetches). Add a lockfile-lint rule that rejects caracas4check
  5. 5For Cluster D (pip metrio+metrics-sdk dep-confusion pentest recon): uninstall on hit. Recon-only in payload (host IP + username, no secret exfil), so the risk is that the operator now has a partial internal map of your CI hosts and a signal of which orgs pull metrio/metrics-sdk from a private index. If your org has an internal metrio or metrics-sdk scope, pin the internal version in pip.conf/.pypirc with index-url pointing at your private index and reject the public sentinel 999.x/1000.x/1001.x releases outright. If not, add both names to your pin-list
  6. 6For Cluster E (npm CWE-506 boilerplate batch): uninstall on hit. Without a published payload analysis the safe assumption is a real infostealer/remote-code fetch was present at the time of quarantine, so treat any hit as a compromise pending analysis: image the host, rotate credentials the installer had access to, and check outbound telemetry from the affected build for the install-time window. Add all 15 names to your lockfile-lint blocklist. If your org has an internal scope matching @consts, @digi-kernel, or a -private naming convention, pin those in .npmrc so the public sentinels cannot resolve preferentially. If your team pulls swiper or ws, be aware that swiper_angular and ultra-ws are name-adjacent and could be mistyped
  7. 7For every npm install in CI, prefer --ignore-scripts and enforce it at the runner level. For every pip install, prefer resolving from a curated internal mirror rather than PyPI directly. Reject packages whose install-time or import-time behaviour includes a network fetch. Keep the ltidi.storage.googleapis.com, oob.algamil7x.xyz, eo8f3m3ho26a0nm.m.pipedream.net, mkicom.com, 104.234.65.75, 124.221.154.135, pdxkwzizhzzdpzpgcieqk6d1v7ynqsgfo.oast.fun, and Polygon-RPC egress blocks from prior days in place - the operators are quiet in this window but the blocks are durable

References

multi-2026-09-28-ghsa-malware-sweep