Feed
CriticalPublished 5 Jun 2026Updated 19 Jun 202634 packages · 56 versions

Hades / Shai-Hulud PyPI wave: bioinformatics, MCP typosquats, and the .pth + Bun startup payload

Summary

Between 2026-06-05 and 2026-06-08 the Shai-Hulud / Miasma operator hopped to PyPI as "Hades", trojanising ~33 packages across the nanguage bioinformatics cluster (StepSecurity: 19 quarantined projects), monarch-initiative phenotype tooling, and MCP/Flask typosquats. Each ships a *-setup.pth startup hook → Bun credential stealer with cross-platform memory scraping.

wormcredential-theftmaintainer-takeovertyposquatobfuscationci-cd-compromise
Threat actor
TeamPCP
Detected by
Socket · Endor Labs · GitLab Vulnerability Research · StepSecurity · JFrog · Sonatype
Also known as
Hades · Mini Shai-Hulud PyPI wave · Miasma PyPI · Shai-Hulud descends to Hades
Ecosystems
PyPI
Packages tracked
34

What happened

The "Hades" PyPI wave is the Python branch of the same Mini Shai-Hulud / Miasma worm that drove the 2026-06-01 @redhat-cloud-services npm compromise and the 2026-06-03 Phantom Gyp binding.gyp wave. Endor Labs named the PyPI variant after the embedded Hades - The End for the Damned marker string in the dropper. Across four days (2026-06-05 → 2026-06-08) the operator burned through three maintainer takeovers and a small typosquat farm, totalling ~25 trojaned packages and >60 quarantined wheels.

Cluster 1 — nanguage takeover (2026-06-05)

The single-cell-RNA / FISH-imaging maintainer nanguage was the first PyPI victim. coolbox (0.4.1, 0.4.2), ufish (0.1.2, 0.1.3), and napari-ufish (0.0.2, 0.0.3) were each republished twice in quick succession — the first wheel as the canonical X.Y.Z drop, the second as a "fix" patch — both carrying the malicious *-setup.pth payload. PyPI quarantined all three projects within ~36 hours.

Cluster 2 — xqiu / YifanLu takeover (2026-06-06)

The spatial-transcriptomics duo dynamo-release (1.5.4) and spateo-release (1.1.2) were trojaned next. Both maintainers (xqiu co-publishes both, YifanLu co-maintains spateo) are tied to the aristoteleo single-cell-omics group and the packages are heavily used in academic genomics. PyPI quarantined both projects on 2026-06-06.

Cluster 3 — Shai-Hulud copycat / MCP typosquats (2026-06-07)

GitLab Vulnerability Research filed five advisories (GMS-2026-572 through GMS-2026-576) for a parallel typosquat cluster: rlask and tlask (Flask typosquats), rsquests (Requests typosquat), nhmpy (NumPy typosquat), and mflux-streamlit (a previously clean package whose maintainer elitexp had their token stolen — versions 0.0.3 and 0.0.4 were yanked as "Seems Token Leak"). A larger Socket disclosure on the same day tracked 23 PyPI packages in an MCP / LangChain / Flask / OpenAI-tooling typosquat farm (langchain-core-mcp, openai-mcp, instructor-mcp, tiktoken-mcp, ray-mcp-server, …) targeting developers building Model Context Protocol servers; the exact wheel set is still being enumerated as Socket reports them to PyPI security.

Cluster 4 — monarch-initiative phenotype tooling (2026-06-08)

Endor Labs disclosed a stolen-token attack against monarch-initiative's rare-disease genomics stack: ensmallen 0.8.101, embiggen 0.11.97, pyphetools 0.9.120, gpsea 0.9.14, phenopacket-store-toolkit 0.1.7, and ppkt2synergy 0.1.1 were all phantom releases — wheels exist on PyPI but no matching tag/commit exists in any upstream GitHub repo. Each ships platform-specific compiled extensions (ensmallen_haswell.abi3.so, ensmallen_core2.abi3.so, ~57 MB each) that execute _index.js on import. PyPI quarantined the projects via Endor's trusted-reporter API.

Cross-cluster payload

Every cluster ships the same *-setup.pth startup-hook pattern: a one-line import directive in a .pth file inside site-packages runs at every Python interpreter launch (this is normal .pth behaviour, just abused), downloads the Bun JavaScript runtime, and runs an obfuscated _index.js credential stealer. The stealer is the same Bun-bundled family used in the npm Phantom Gyp / TanStack / @cap-js SAP / durabletask waves. Exfil is via attacker-controlled GitHub repos created from any stolen gh tokens. Across npm + PyPI, Socket's campaign tracker now lists 471+ artifacts under a single Mini Shai-Hulud / Miasma / Hades roll-up.

  • All six monarch-initiative packages and all three nanguage packages are PyPI-quarantined; installation is blocked.
  • No CVE / GHSA / OSV entries for the bioinformatics cluster at disclosure; GitLab GLAD GMS-2026-572..576 are the only registry-level identifiers so far.
  • The MCP / LangChain typosquat farm is the broadest cluster (Socket: 23 packages) but is still being enumerated; expect this incident's package map to grow.

2026-06-19 update — StepSecurity disclosure expands the bioinformatics cluster

StepSecurity's 2026-06-18 write-up retroactively ties the entire nanguage-aligned bioinformatics cluster together (19 PyPI projects, all quarantined) and confirms 14 additional malicious projects beyond the original 5: bramin, cmd2func, executor-engine, executor-http, funcdesc, magique, magique-ai, mrbios, nucbox, okite, pantheon-agents, pantheon-toolsets, synago, and uprobe. All ship the same *-setup.pth startup hook → Bun → _index.js chain.

The StepSecurity analysis also documents three Hades-specific capabilities absent from earlier Miasma waves:

  • Cross-platform memory scraping — the Bun stealer ReadProcessMemory()s Windows processes, walks /proc/<pid>/mem on Linux (specifically targeting the GitHub Actions Runner.Worker process for masked-in-log secrets), and uses Mach kernel APIs on macOS. The scraper hunts for GitHub OIDC tokens, Kubernetes service-account tokens, and AWS temporary credentials in process memory directly, bypassing GitHub Actions secret-masking on echo/log output.
  • AI-analyst misdirection layer — the dropper embeds fake "analysis results" and misleading code comments (including marker strings such as Hades - The End for the Damned) explicitly engineered to mislead AI-assisted security tools (Claude / Cursor / Gemini agentic scanners) that summarise the package before a human reviews it. This is the first documented supply-chain payload built to defeat AI-powered triage.
  • Token-revocation wiper deterrent — instead of merely exfiltrating discovered credentials, the malware actively revokes them once exfil is complete, so the victim loses access alongside the operator. Combined with the prior Miasma "dead-man's-switch" data-wipe pattern, this makes Hades the first wave to weaponise credential lifecycle itself as a deterrent against incident response.

Dynamic-update hooks in the payload poll attacker GitHub repos for commits whose messages contain marker strings (TheBeautifulSnadsOfTime, firedalazer) to pull additional modules — meaning the campaign remains live for any host still running an unquarantined version.

Affected packages (34)

  • PyPIbramin
    0.0.20.0.30.0.4
  • PyPIcmd2func
    0.2.20.2.3
  • PyPIcoolbox
    0.4.10.4.2
  • PyPIdynamo-release
    1.5.4
  • PyPIembiggen
    0.11.97
  • PyPIensmallen
    0.8.101
  • PyPIexecutor-engine
    0.3.40.3.5
  • PyPIexecutor-http
    0.1.30.1.4
  • PyPIfuncdesc
    0.2.20.2.3
  • PyPIgpsea
    0.9.14
  • PyPIlangchain-core-mcp
    1.4.21.4.3
  • PyPImagique
    0.6.80.6.9
  • PyPImagique-ai
    0.4.40.4.5
  • PyPImflux-streamlit
    0.0.30.0.4
  • PyPImrbios
    0.1.10.1.2
  • PyPInapari-ufish
    0.0.20.0.3
  • PyPInhmpy
    0.0.1
  • PyPInucbox
    0.1.20.1.3
  • PyPIokite
    0.0.70.0.8
  • PyPIopenai-mcp
    2.41.12.41.2
  • PyPIpantheon-agents
    0.6.10.6.2
  • PyPIpantheon-toolsets
    0.5.50.5.6
  • PyPIphenopacket-store-toolkit
    0.1.7
  • PyPIppkt2synergy
    0.1.1
  • PyPIpyphetools
    0.9.120
  • PyPIray-mcp-server
    0.2.1
  • PyPIrlask
    0.0.1
  • PyPIrsquests
    0.0.1
  • PyPIspateo-release
    1.1.2
  • PyPIsynago
    0.1.10.1.2
  • PyPItiktoken-mcp
    0.13.10.13.2
  • PyPItlask
    0.0.1
  • PyPIufish
    0.1.20.1.3
  • PyPIuprobe
    0.1.30.1.4

Impact

  • .pth startup hook executes on every Python interpreter launch — no import required and no setup.py/install-time hook to scan
  • Downloads the Bun JS runtime and runs the same obfuscated credential stealer used by the npm Phantom Gyp wave
  • Harvests GitHub tokens, npm/PyPI/RubyGems publish tokens, JFrog secrets, AWS/Azure/GCP credentials, Kubernetes service-account material, SSH keys, Docker config, .env files, and shell history
  • Self-propagates: stolen GitHub tokens push poisoned commits back to the maintainer's repos and re-publish across PyPI/npm/RubyGems
  • High-trust academic / scientific blast radius: dynamo-release, spateo-release, coolbox, ufish, napari-ufish are widely used in single-cell-RNA, spatial-transcriptomics, Hi-C, and FISH-imaging research pipelines
  • Rare-disease genomics impact: ensmallen, embiggen, pyphetools, gpsea, phenopacket-store-toolkit, ppkt2synergy are monarch-initiative tooling used in clinical phenotype work
  • AI / MCP exposure: typosquats and trojans in the langchain-*, openai-*, instructor, tiktoken, ray-mcp-server namespace target developers building MCP servers
  • Cross-platform process-memory scraping (Linux /proc/<pid>/mem, macOS Mach kernel APIs, Windows ReadProcessMemory) lifts GitHub OIDC + Kubernetes service-account + AWS temporary creds straight out of the GitHub Actions Runner.Worker process, bypassing log-secret masking
  • AI-analyst misdirection: payload embeds fake "analysis result" comments specifically engineered to mislead Claude / Cursor / Gemini agent scanners summarising the package
  • Active credential revocation: discovered tokens are revoked once exfil completes, so the victim loses access at the same moment the operator gains it

What to do

  1. 1Pin BELOW the malicious versions for each affected package — see the package map for exact versions; safe ranges are the immediately-prior clean release in each case
  2. 2Treat any Python environment that ran a malicious version under any interpreter (including python -c smoke-tests) as fully compromised; rotate every credential reachable from that host AND from any GitHub account whose tokens were resident
  3. 3Audit GitHub for new repos created under affected maintainer / developer accounts during 2026-06-05 → 2026-06-09 (the Shai-Hulud exfil pattern is to dump credentials into a freshly-created public repo)
  4. 4Audit PyPI publish history under your team accounts for unexpected X.Y.(Z+1) or 0.0.x patch bumps published in the window
  5. 5Block outbound HTTPS to bun.sh / github.com/oven-sh/bun/releases egress from CI runners that do not legitimately need Bun, and from research workstations
  6. 6Hunt for *-setup.pth files inside site-packages and for _index.js / __init__.py one-line import hooks that exec base64/eval payloads
  7. 7For the typosquat cluster (rlask, tlask, rsquests, nhmpy), grep your requirements files / pip caches for the malicious names directly

References

pypi-2026-06-05-hades-shai-hulud-pypi-wave