The Incident
On June 8, 2026, an attacker cluster operating under the Shai-Hulud / Miasma lineage published trojanized releases of six bioinformatics and graph-ML Python packages to PyPI within a roughly sixty-second window. Endor Labs quarantined the initial six within thirty minutes of publication, but by the time PyPI completed takedown, the campaign — Orca Security named it Hades — had expanded to 37 malicious wheel artifacts spanning 19 packages, with a follow-on wave reported across 23 additional PyPI package versions targeting MCP and AI tooling typosquats (langchain-core-mcp, openai-mcp, instructor-mcp, tiktoken-mcp, ray-mcp-server). The confirmed compromised legitimate packages include embiggen 0.11.97, ensmallen 0.8.101, and gpsea 0.9.14, alongside phenopacket-store-toolkit, ppkt2synergy, and pyphetools.
Each release shipped a *-setup.pth file. Python’s site module processes .pth files at interpreter startup — a feature, not a vulnerability, and the same primitive the March 2026 LiteLLM compromise abused. The hook downloaded the Bun JavaScript runtime (v1.3.14) from GitHub and executed an obfuscated _index.js containing sixteen independent functional components, each gzip-compressed and AES-256-GCM encrypted with a unique hardcoded key. The components harvested cloud credentials (AWS, GCP, Azure), CI/CD tokens (Kubernetes, Vault, CircleCI), source-control tokens (GitHub, GitLab, SSH keys), package-manager configuration (.npmrc, .pypirc, .env), and Claude/MCP configuration files. Exfiltration used an AES-256-GCM payload wrapped in an RSA-2048 hybrid envelope, dropped into attacker-controlled public GitHub repositories. Stolen GitHub, PyPI, and npm tokens were then re-used to publish trojanized versions of other packages the credentials could reach, completing the worm cycle.
Two payload behaviors are new to this lineage. First, a gh-token-monitor daemon installs itself at ~/Library/LaunchAgents/com.user.gh-token-monitor.plist on macOS and ~/.config/systemd/user/gh-token-monitor.service on Linux, polls GitHub every sixty seconds to check the validity of the stolen token, and executes rm -rf ~/ if the token is revoked. The daemon auto-exits after twenty-four hours. Second, the _index.js payload embeds prompt-injection text framed as a biological/nuclear weapon disclosure, designed to trigger safety refusals in any LLM-powered analysis tool that ingests the script — Tom’s Hardware and Security Boulevard independently confirmed the mechanism stops AI scanners mid-analysis. The upstream Miasma worm toolkit itself was briefly open-sourced on GitHub between June 8 and June 10, 2026 via a repository named “Miasma-Open-Source-Release,” accelerating copycat waves and complicating attribution — neither Orca nor StepSecurity attribute the Hades wave specifically to any named actor.
MITRE ATT&CK coverage: T1195.002 (Compromise Software Supply Chain), T1546.018 (Event Triggered Execution: Python Startup Hooks), T1543.001 (Launch Agent), T1543.003 (Systemd Service), T1552.001 (Credentials In Files), and T1485 (Data Destruction).
The Authority Path That Failed
The identity that carried execution authority was a PyPI maintainer credential — and, in the worm-propagation loop, every GitHub PAT, npm token, and PyPI API key that the harvested cloud and source-control configurations contained. Each token held publish authority over a specific package and write access to the maintainer’s other repositories. What each token exercised was the publication of a new release that shipped a .pth auto-execute hook on the consumer’s interpreter — a use case the maintainer never sanctioned and the token’s scope language never described. PyPI’s permission model treats publish-a-release and publish-a-release-with-an-interpreter-startup-hook as the same action; consumers’ Python toolchains treat .pth execution as routine. That is the gap the worm walks through.
The novel authority twist is what the payload does to the canonical remediation. When a defender detects the compromise and rotates the stolen token — the standard NHI-compromise playbook — the gh-token-monitor daemon on every endpoint that ran the .pth hook detects the revocation and destroys the developer’s home directory. Rotation, the path back to a known-good state, becomes the destructive path. The attacker has not just compromised a non-human identity; the attacker has built a tripwire that raises the operational cost of de-authorizing it.
SecurityV0 Perspective
This is a nhi_compromise story with a structural twist on the standard pattern. The evidence pack SecurityV0 would produce around the affected PyPI tokens names every stolen credential by issuer, scope, and last-rotation timestamp; maps each token to the packages and repositories it can publish to (the worm’s reachability graph); records the sha256 of every wheel artifact published from each token in the seventy-two hours surrounding the incident; and inventories the .pth-bearing wheels and their consumers. For each consumer organization that pulled an affected version, the pack also lists the developer machines that started a Python interpreter against the affected site-packages/ — every interpreter that processed the .pth hook is a host where credentials may already be exfiltrated and where a gh-token-monitor Launch Agent or systemd user unit may already be installed.
Pre-exfiltration, the pack answers: which of our maintainer tokens could publish a wheel containing arbitrary interpreter-startup code, and which of those tokens were used in the last seventy-two hours? Post-exfiltration, with the revocation tripwire in play, the question becomes: which compromised tokens can we safely revoke, and which machines need to be isolated before revocation so a wipe does not land on a live developer workstation? The second question is the one that makes this incident different. Standard NHI remediation assumes rotation is non-destructive. Hades makes it operationally destructive on every host where the daemon landed.
What To Do
- Treat any wheel that ships a
.pthfile as a code-execution artifact. Inventory.pthfiles in your build images, base CI containers, and developer environments. Block them at the package-proxy layer or fail the install. PyPI wheel metadata exposes this — scan each wheel’sRECORDfor entries matching*.pthand require explicit human approval to admit one. - Quarantine before you rotate when revocation-retaliation is plausible. For any GitHub PAT, PyPI token, or npm token suspected stolen in a
.pth-class orpreinstall-class compromise, isolate every host the token reached (snapshot, then disconnect) before revoking the credential. Hunt forgh-token-monitorLaunch Agents and systemd user units —launchctl list | grep gh-token-monitorandsystemctl --user list-units 'gh-token-monitor*'— before letting a developer back on the box. - Audit maintainer-token reach against the package graph. A PyPI maintainer credential that can publish to every package its owner touches is a worm reachability graph. Move every project you publish to per-package PyPI Trusted Publishing with an OIDC workflow constraint that fails on
.pthartifacts in the built wheel, and revoke long-lived legacy API tokens once Trusted Publishing is live. - Treat AI-assisted triage outputs as potentially adversary-shaped. The Hades
_index.jsembeds prompt injection designed to make LLM scanners abort analysis under a safety-refusal pretext. If your SOC uses Claude, Copilot, or a security-analyst agent to summarize unknown wheels, log the raw artifact for human review and compare the agent’s output against a deterministic signature scan; do not let agent silence be interpreted as evidence of safety. - Watch for two deterministic egress signals. A Python interpreter on a developer workstation reaching
github.com/oven-sh/bun/releases/download/bun-v1.3.14/is anomalous; a Python interpreter pushing AES+RSA blobs to a freshly-created public GitHub repository is the exfil signal. Both are stable detections against this campaign and any copycat that forks the open-sourced Miasma toolkit.
Sources
- Orca Security — Hades PyPI Supply Chain Attack
- StepSecurity — The Hades Campaign: Graph ML PyPI Packages
- Endor Labs — Shai-Hulud “Hades” wave hits six PyPI bioinformatics packages
- Socket — Mini Shai-Hulud, Miasma, and Hades worms target bioinformatics and MCP developers
- The Hacker News — Hades PyPI Attack: 19 Packages Poisoned to Auto-Run Bun Credential Stealer
- SecurityWeek — Over 100 npm and PyPI packages hit in new Shai-Hulud supply-chain attacks
- SOCRadar — Shai-Hulud Hades PyPI campaign
- Tom’s Hardware — Hades malware now tricks AI bots with biological/nuclear weapons text to halt scans
- Security Boulevard — Shai-Hulud campaign evolution: Miasma, Hades, and AI scanner evasion
- The Register — Miasma worms its way onto GitHub as attack kit goes open source
- MITRE ATT&CK: T1195.002, T1546.018, T1543.001, T1543.003, T1552.001, T1485