A coordinated PyPI supply chain attack that deployed 37 malicious wheel artifacts across 19 packages, part of the sprawling Mini Shai-Hulud/Miasma malware lineage, is now tracked across 448 artifacts on npm and PyPI combined.
Dubbed “Hades” after its distinctive Underworld-themed GitHub exfiltration markers, this campaign targets developer credentials, CI/CD pipeline secrets, and cloud infrastructure access keys, making it one of the most technically sophisticated open-source supply chain threats documented this year.
How the Attack Works
The attack’s delivery mechanism is elegant and deeply dangerous. Each malicious wheel ships two key files: _index.js (a heavily obfuscated JavaScript payload) and a *-setup.pth file that serves as the bootstrap trigger.
Python’s site module processes .pth files at every interpreter startup not just on import. Any line beginning with import followed by a space is executed automatically, meaning the attacker achieves code execution the next time a developer runs python, pip, a test suite, a notebook kernel, or any CI job that invokes Python. The victim doesn’t even need to call the compromised package explicitly.
Once triggered, the loader:
- Checks for a sentinel file at
tempfile.gettempdir()/.bun_ranto avoid re-execution - Locates
_index.jswithin the package directory - Downloads Bun v1.3.13 from GitHub (
oven-sh/bun/releases/download) if no cached binary exists - Executes
bun run _index.jsas a subprocess - Writes the sentinel to suppress repeat runs
This cross-runtime execution model, delivering a JavaScript stealer via Python but running it under the Bun JavaScript runtime rather than Node.js, is a defining fingerprint of the Shai-Hulud family. The attackers deliberately avoid assuming any existing runtime is present, instead bootstrapping their own execution environment from scratch.
Payload Deobfuscation: Four Layers Deep
Static analysis of _index.js reveals a multi-stage obfuscation chain consistent with previous Miasma and Mini Shai-Hulud samples:
- Outer wrapper: A
try { eval(...) }block decodes a character-code array with ROT-style alphabet substitution - AES-GCM loader: The decoded stage imports
node:crypto, decrypts two AES-128-GCM blobs, writes the main payload to/tmp/p*.js, and executes it - Bun bootstrapper: A decrypted sub-stage handles the Bun download if the Python-side loader hasn’t already done so
- Main stealer payload: Uses a rotated string table, PBKDF2/SHA256-based string decoding, and AES-256-GCM plus gzip compression for the credential harvesting logic
Credential Theft Scope: Developer and Cloud Secrets
The recovered payload targets an exceptionally broad credential surface:
- Source control: GitHub tokens (
ghs_*), GitHub Actions runner secrets, runner memory, deploy keys - Package registries: npm, PyPI, RubyGems, JFrog, CircleCI tokens
- Cloud platforms: AWS credentials, STS identity, SSM Parameter Store, Secrets Manager; GCP identity and Secret Manager; Azure identity and Key Vault; Kubernetes service-account tokens and cluster secrets; HashiCorp Vault tokens
- Developer environment files:
.env,.npmrc,.pypirc,.gitconfig, shell histories, SSH keys, Docker configs, cloud CLI caches - AI toolchain: Anthropic API keys, Claude/MCP configuration files, and wallet/app data
The payload routes stolen data through multiple paths. GitHub repository exfiltration is the confirmed active channel the malware creates public repositories via POST /user/repos and commits encrypted result envelopes under results/results-<timestamp>-<counter>.json.
The Hades marker distinguishes this wave from prior campaigns: repositories carry the description “Hades – The End for the Damned”, and commits include the marker IfYouYankThisTokenItWillNukeTheComputerOfTheOwnerFully, and workflow artifacts are named format-results under a workflow called “Run Copilot”.
A secondary HTTPS exfiltration path targets api.anthropic.com/v1/api a real Anthropic host, but /v1/api is not a live route. Socket assesses this as deliberate network-log camouflage: traffic to a widely trusted AI vendor host blends in with normal developer traffic and is difficult to block at the network layer without causing broad disruption.
The payload also checks for Russian locale signals and StepSecurity/harden-runner indicators, actively attempting to identify and avoid instrumented analysis environments, a behavioral continuity point tying Hades firmly to the broader Shai-Hulud family.
Affected Packages
The 37 malicious artifacts span 19 PyPI packages originating from what appears to be a single maintainer account takeover, with consecutive patch releases mass-published across the author’s entire portfolio simultaneously. High-risk packages include:
dynamo-release— Aristoteleo single-cell RNA-velocity framework (hundreds of thousands of cumulative downloads)spateo-release— spatial transcriptomics sibling to dynamocoolbox— GangCaoLab’s Jupyter-based multi-omics genomic visualization toolkitufish/napari-ufish— deep-learning FISH spot-detection tools
These bioinformatics tools represent the bulk of the install base exposure. The remaining affected packages are the lower-traffic agent and lab utilities, both caught in the same account-level blast.
Recovered persistence artifacts indicate the attacker intends to survive environment rebuilds:
~/.local/bin/gh-token-monitor.shwith a correspondingsystemduser service~/Library/LaunchAgents/com.github.token-monitor.plist(macOS).claude/setup.mjsand.github/setup.js— targeting AI developer toolchain persistence.github/workflows/codeql.yml— disguising malicious workflow injection as a legitimate security scan
Detection and Recommended Response
Organizations should immediately audit for these filesystem and behavioral indicators:
/tmp/.bun_ranor%TEMP%\.bun_ransentinel files_index.jsor*-setup.pthinsidesite-packages- Python spawning
bunor making outbound connections togithub.com/oven-sh/bun/releases/download/ - GitHub repositories matching the Hades description or
format-resultsartifacts
Any organization that installed an affected version should remove the malicious releases, rebuild affected environments, and immediately rotate GitHub tokens, PyPI/npm publishing tokens, AWS/GCP/Azure/Kubernetes credentials, SSH keys, and Anthropic API keys accessible from affected machines or CI runners.
Socket is tracking the full campaign 448 artifacts across npm and PyPI at socket.dev/supply-chain-attacks/miasma-mini-shai-hulud-supply-chain-attack.
Frequently Asked Questions
Q1: What is the Hades PyPI supply chain attack? It is a coordinated malware campaign where 37 malicious Python wheel packages ship a .pth startup hook that silently downloads the Bun JavaScript runtime and executes an obfuscated credential stealer targeting developer, cloud, and CI/CD secrets.
Q2: How does the malicious .pth file execute without user interaction? Python’s site module automatically executes any .pth line beginning with import at every interpreter startup, meaning simply having the compromised package installed is sufficient to trigger the payload.
Q3: Which credentials are stolen by the Hades payload? The stealer targets GitHub tokens, AWS/GCP/Azure/Kubernetes credentials, npm/PyPI/RubyGems publishing tokens, SSH keys, Docker configs, .env files, shell histories, Vault tokens, and Anthropic/Claude API keys.
Q4: How can developers and organizations detect and remediate this compromise? Check for /tmp/.bun_ran, _index.js in site-packages Unexpected Bun processes spawned by Python and GitHub repositories matching the Hades markers, then rotate all credentials accessible from affected machines and rebuild compromised environments.
Site: thecybrdef.com
For more insights and updates, follow us on Google News, Twitter, and LinkedIn.