Hades / Shai-Hulud PyPI wave: bioinformatics, MCP typosquats, and the .pth + Bun startup payload
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.
- 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
nanguagepackages are PyPI-quarantined; installation is blocked. - No CVE / GHSA / OSV entries for the bioinformatics cluster at disclosure; GitLab GLAD
GMS-2026-572..576are 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>/memon Linux (specifically targeting the GitHub ActionsRunner.Workerprocess 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 onecho/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)
- PyPI
bramin0.0.20.0.30.0.4 - PyPI
cmd2func0.2.20.2.3 - PyPI
coolbox0.4.10.4.2 - PyPI
dynamo-release1.5.4 - PyPI
embiggen0.11.97 - PyPI
ensmallen0.8.101 - PyPI
executor-engine0.3.40.3.5 - PyPI
executor-http0.1.30.1.4 - PyPI
funcdesc0.2.20.2.3 - PyPI
gpsea0.9.14 - PyPI
langchain-core-mcp1.4.21.4.3 - PyPI
magique0.6.80.6.9 - PyPI
magique-ai0.4.40.4.5 - PyPI
mflux-streamlit0.0.30.0.4 - PyPI
mrbios0.1.10.1.2 - PyPI
napari-ufish0.0.20.0.3 - PyPI
nhmpy0.0.1 - PyPI
nucbox0.1.20.1.3 - PyPI
okite0.0.70.0.8 - PyPI
openai-mcp2.41.12.41.2 - PyPI
pantheon-agents0.6.10.6.2 - PyPI
pantheon-toolsets0.5.50.5.6 - PyPI
phenopacket-store-toolkit0.1.7 - PyPI
ppkt2synergy0.1.1 - PyPI
pyphetools0.9.120 - PyPI
ray-mcp-server0.2.1 - PyPI
rlask0.0.1 - PyPI
rsquests0.0.1 - PyPI
spateo-release1.1.2 - PyPI
synago0.1.10.1.2 - PyPI
tiktoken-mcp0.13.10.13.2 - PyPI
tlask0.0.1 - PyPI
ufish0.1.20.1.3 - PyPI
uprobe0.1.30.1.4
Impact
.pthstartup hook executes on every Python interpreter launch — noimportrequired and nosetup.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,
.envfiles, 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-ufishare 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,ppkt2synergyare monarch-initiative tooling used in clinical phenotype work - AI / MCP exposure: typosquats and trojans in the
langchain-*,openai-*,instructor,tiktoken,ray-mcp-servernamespace target developers building MCP servers - Cross-platform process-memory scraping (Linux
/proc/<pid>/mem, macOS Mach kernel APIs, WindowsReadProcessMemory) lifts GitHub OIDC + Kubernetes service-account + AWS temporary creds straight out of the GitHub ActionsRunner.Workerprocess, 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
- 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
- 2Treat any Python environment that ran a malicious version under any interpreter (including
python -csmoke-tests) as fully compromised; rotate every credential reachable from that host AND from any GitHub account whose tokens were resident - 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)
- 4Audit PyPI publish history under your team accounts for unexpected
X.Y.(Z+1)or0.0.xpatch bumps published in the window - 5Block outbound HTTPS to
bun.sh/github.com/oven-sh/bun/releasesegress from CI runners that do not legitimately need Bun, and from research workstations - 6Hunt for
*-setup.pthfiles insidesite-packagesand for_index.js/__init__.pyone-lineimporthooks that exec base64/eval payloads - 7For the typosquat cluster (
rlask,tlask,rsquests,nhmpy), grep your requirements files / pip caches for the malicious names directly
References
- PyPIphenopacket-store-toolkit on PyPI (quarantined, 0.1.7 = malicious)pypi.org
- PyPIcoolbox on PyPI (quarantined, 0.4.1/0.4.2 = malicious)pypi.org
- PyPIufish on PyPI (quarantined, 0.1.2/0.1.3 = malicious)pypi.org
- PyPInapari-ufish on PyPI (quarantined, 0.0.2/0.0.3 = malicious)pypi.org
- PyPIdynamo-release on PyPI (quarantined, 1.5.4 = malicious)pypi.org
- PyPIspateo-release on PyPI (quarantined, 1.1.2 = malicious)pypi.org
- PyPImflux-streamlit on PyPI (0.0.3/0.0.4 yanked "Seems Token Leak")pypi.org
- SocketSocket announces 37 malicious PyPI artefacts across 19 packages (Hades wave 1)x.com
- SocketSocket announces 23 new MCP / LangChain / Flask typosquats (Hades wave 2)x.com
- PyPIopenai-mcp on PyPI (quarantined, 2.41.1/2.41.2 published 2026-06-07)pypi.org
- PyPItiktoken-mcp on PyPI (quarantined, 0.13.1/0.13.2 published 2026-06-07)pypi.org
- PyPIray-mcp-server on PyPI (quarantined, 0.2.1 published 2026-06-07)pypi.org
- PyPIlangchain-core-mcp on PyPI (quarantined, 1.4.2/1.4.3 published 2026-06-07)pypi.org
- StepSecurityStepSecurity: The Hades Campaign — Graph ML PyPI packages deploy cross-platform memory scrapers, AI analyst misdirection, and a wiper deterrentstepsecurity.io
- The Hacker NewsHades PyPI Attack: 19 Packages Poisoned to Auto-Run Bun Credential Stealerthehackernews.com
- PyPImagique on PyPI (quarantined, 0.6.8/0.6.9 = malicious)pypi.org
- PyPIuprobe on PyPI (quarantined, 0.1.3/0.1.4 = malicious)pypi.org