The Python Ecosystem Just Got Poisoned Again
Here's the thing about supply chain attacks: they work because we trust each other too much. You install a package called ensmallen — it's a graph machine learning library, right? Sounds legit. It has real maintainers, real documentation, real downloads. So when version 0.8.101 drops and you pip install it without a second thought, you're not just pulling in code. You're letting someone execute arbitrary JavaScript on your machine.
That's exactly what happened with the Hades Campaign, disclosed June 8, 2026. Nineteen PyPI packages — thirty-seven malicious wheel files across them — were compromised with a credential-stealing payload that's honestly one of the most technically ambitious supply chain attacks I've seen. And it's not even trying to hide from traditional security tools anymore. It's actively lying to AI-powered scanners.
The threat lineage traces back through Shai-Hulud (first spotted September 2025), through Mini Shai-Hulud (April 2026), and lands here. Socket's research team called the tradecraft "unmistakably Shai-hulud/Miasma." Some vendors, including those tracking TeamPCP — a financially motivated group that emerged in late 2025 — see the fingerprints. Rescana confirmed active exploitation on June 9, meaning someone's already pulling credentials from compromised environments as we speak.
This isn't a theoretical exercise. If you've installed any of these packages, your cloud tokens might already be gone.
What Got Compromised
The affected packages cluster into two groups, and the targeting is deliberate. The first cluster hits bioinformatics and graph ML — packages researchers actually depend on for real work:
- ensmallen (0.8.101) — graph machine learning, the flagship target
- mflux-streamlit (0.0.3, 0.0.4) — Streamlit integration
- nhmpy (2.4.7), ppkt2synergy (0.1.1) — phenotype analysis
- embiggen (0.11.97), gpsea (0.9.14) — bioinformatics tooling
- pyphetools (0.9.120), rlask, rsquests, tlask — research utilities
The second cluster is broader developer tooling. These are the packages you reach for when setting up a new project:
- bramin, cmd2func, coolbox, dynamo-release
- executor-engine, executor-http, funcdesc
- magique, magique-ai, mrbios
- napari-ufish, nucbox, okite
- pantheon-agents, pantheon-toolsets, spateo-release
- synago, ufish, uprobe
The bioinformatics cluster is the clever part. Researchers install these packages, run them in Jupyter notebooks or CI pipelines, and never think about it again. That's exactly the trust pattern attackers exploit.
How the Malware Actually Runs
The execution chain is elegant in its simplicity, which is what makes it dangerous. Here's the sequence:
Step 1: The Python import hook. Compromised packages ship a *-setup.pth file or inject obfuscated code into __init__.py. This isn't a normal import hook — it executes automatically when the Python interpreter starts, even if you never explicitly import the package. You open a terminal, type python, and boom: payload is running before you've typed a single line of code.
Step 2: Bun runtime download. The hook checks for a flag file at /tmp/.bun_ran. If it doesn't exist, the script crawls Python module search paths to find a companion _index.js file, then downloads Bun JavaScript runtime v1.3.14 from GitHub — the architecture-specific binary for your OS (Linux, macOS ARM64/x64, or Windows). It extracts to a temp directory and runs bun run _index.js. The flag file gets written so it only fires once per boot cycle.
This Bun choice is significant. By bundling its own JavaScript runtime, the malware doesn't need Node.js installed on the target system. It bypasses package manager controls and network proxy logs that might flag a Node.js download.
Step 3: Modular payload decryption. The _index.js bundle acts as a bootstrapper, loading and decrypting sixteen independent functional payloads at startup. Each blob is gzip-compressed and encrypted with AES-256-GCM using a unique hardcoded key. The bootstrapper uses native Bun APIs for rapid decryption and decompression.
Step 4: Cross-platform memory scraping. This is where it gets nasty. The malware reads process memory on all three major operating systems:
- Linux: walks
/proc/{pid}/mapsand reads/proc/{pid}/memdirectly - macOS: invokes Mach kernel VM APIs via ctypes — no root needed since the runner worker and execution process share a UID
- Windows: dynamically compiles C# via PowerShell's
Add-Type, usingVirtualQueryExandReadProcessMemoryto crawl the target process
The primary target is the GitHub Actions Runner.Worker process. That's where your CI/CD secrets live in plaintext.
What They're Stealing
The credential harvesting scope is staggering. We're talking about a comprehensive sweep across every authentication vector a developer or DevOps engineer touches:
Cloud infrastructure: AWS, GCP, and Azure authentication tokens. Kubernetes secrets and configurations.
Source control: GitHub personal access tokens, GitHub Actions tokens, GitLab tokens.
Package registries: PyPI, npm, and RubyGems publishing credentials — which is how the malware propagates further.
Local secrets: SSH keys, Docker registry configs, .env files, shell histories.
AI tooling: Claude, OpenAI Codex, Gemini, and Copilot configurations. Yeah, they're stealing your AI assistant credentials too.
CI/CD platforms: JFrog, CircleCI, Anthropic tokens.
That's fourteen distinct credential categories. And the memory scraping catches everything — unmasked variables, session tokens, anything sitting in RAM that hasn't been encrypted yet.
The data gets compressed with gzip, encrypted with AES-256-GCM plus RSA-2048 hybrid encryption, and pushed to attacker-controlled GitHub repositories. The repos are named with Hades underworld theming — stygian-cerberus-42817, tartarean-charon-18401 — and carry the description "Hades - The End for the Damned." It's theatrical, sure, but it also gives defenders a clear signature to hunt for.
The AI Scanner Evasion
This is the part that made me actually sit up straight.
The Hades Campaign includes a prompt injection at the start of its _index.js bundle. Plain-text text, sitting right there in the source code, instructing any LLM-based security scanner that parses it to classify the package as benign. It's a direct adversarial prompt injection targeting the cognitive logic of automated AI triage systems.
Security companies increasingly rely on LLM pipelines to inspect and summarize suspicious package code. The attacker figured out that if they can hijack the analyzer's system instructions, they can coerce it into generating false-negative verdicts. The package passes through organization analysis with a clean bill of health.
This represents a genuine conceptual shift. Attackers are now writing payloads that target the cognitive logic of automated security tools, not just the detection signatures. It's adversarial AI against defensive AI, and right now the attackers have the upper hand because most scanners don't isolate their system prompts from untrusted input.
There's also a decoy traffic component: the malware sends network requests to Anthropic AI servers to confuse network-level analysis. And a Russian locale check — the malware skips execution on systems with Russian locale settings, presumably to avoid detection by researchers in that region.
The wiper deterrent is equally creative. The gh-token-monitor persistence daemon threatens destructive actions if stolen tokens are revoked. It's extortion baked into the malware itself — "don't rotate your credentials or we'll nuke your repos." It's a novel mechanism designed specifically to discourage immediate incident response.
Command and Control Through GitHub
The C2 infrastructure is brilliant in its banality. All three channels use public GitHub — the same platform victims are trying to secure.
Channel 1: Token Dead-Drop. Harvested GitHub tokens are encrypted and pushed as commits to attacker-controlled public repos. The commit messages use the keyword "DontRevokeOrItGoesBoom." The attacker queries GitHub's search API to locate and recover these commits.
Channel 2: Signed JS Eval. The malware queries GitHub for commits containing "TheBeautifulSnadsOfTime." Commit messages carry base64-encoded JavaScript payloads with RSA-PSS signatures. The malware verifies against a hardcoded public key and executes valid payloads via eval().
Channel 3: Python Dropper. A new channel for this campaign. The malware writes updater.py to disk as a background service that polls GitHub for commits matching "firedalazer." These commits encode a URL and RSA-PSS signature. When detected, the daemon downloads and executes the script.
All three channels blend seamlessly with normal GitHub traffic. There's nothing unusual about commits to public repos. That's what makes detection so hard.
The Worm Spreads Itself
Here's where Hades stops being a simple credential stealer and becomes a self-replicating threat. The malware has three lateral movement vectors:
SSH/SCP propagation. It parses ~/.ssh/known_hosts and ~/.ssh/config to build a target list, then iterates through hostnames attempting connections in batch mode with pre-configured key pairs. If both ssh and scp binaries are present, it spreads.
OIDC trust abuse. Using compromised OIDC tokens from CI/CD environments, the malware uploads trojanized packages back to PyPI. This is the propagation loop: steal credentials → publish malicious package → more developers install it → repeat.
Repository infection. The malware can also infect GitHub repositories directly, executing code when folders are opened in IDEs and AI assistants — a technique first documented in the Miasma campaign but now refined.
This self-spreading behavior means a single compromised developer workstation can become the seed for an ecosystem-wide infection. The blast radius isn't limited to who installed the malicious package — it extends to everyone that package depends on.
What You Need to Do Right Now
If you work with Python packages, the clock is ticking. Here's the priority order:
1. Remove or pin away from affected versions immediately. Every package listed above needs to be uninstalled or pinned to a clean version. This isn't optional.
2. Rotate ALL credentials from affected environments. Prioritize GitHub tokens and package registry publishing credentials first — those enable further propagation. Then cloud provider tokens (AWS, GCP, Azure), Kubernetes secrets, SSH keys, and Docker registry credentials.
3. Hunt for persistence artifacts. Check these locations on all potentially affected systems:
- Linux:
~/.config/systemd/user/update-monitor.serviceandgh-token-monitor.service - macOS:
~/Library/LaunchAgents/com.user.gh-token-monitor.plist - Lock files:
/tmp/.bun_ranand/tmp/tmp.0144018410.lock
4. Rebuild affected environments where possible. Developer workstations and CI runners that were exposed should be rebuilt from scratch. The persistence mechanisms are deep enough that cleanup alone may not suffice.
5. Audit GitHub repositories. Look for unauthorized commits, workflow modifications, or new repos matching the attacker's naming patterns (stygian-cerberus-*, tartarean-charon-*).
6. Monitor for anomalous credential access. Set up alerts for unusual GitHub API activity, unexpected package publishing events, and credential access from unfamiliar IPs.
The wiper deterrent is designed to make you hesitate before rotating credentials. Don't fall for it. Isolate the affected system first, then rotate. The threat of destructive action is real but secondary to the damage already done by stolen tokens.
The Bigger Picture
The Hades Campaign doesn't exist in a vacuum. It's the latest chapter in an escalating arms race between supply chain attackers and the ecosystems they target.
Shai-Hulud first appeared in September 2025, focused on basic credential theft. Mini Shai-Hulud (April 2026) added advanced memory scraping and self-replication. Miasma brought the worm-like propagation through npm packages and Red Hat Cloud Services. And now Hades adds AI scanner evasion, cross-platform memory access, and a wiper deterrent that actively fights incident response.
Each iteration gets more sophisticated. Each iteration pushes the boundary of what we thought was possible in a supply chain attack.
The prompt injection technique is the most concerning development. It signals that attackers are now thinking about how their malware will be analyzed by AI systems and building countermeasures into the payload itself. This isn't just about evading signature-based detection anymore — it's about adversarial manipulation of the tools we're increasingly relying on for security analysis.
The Python ecosystem needs to wake up. Trust-based package distribution is broken at scale. We need stricter review processes, better runtime monitoring, and a cultural shift that treats every package installation as a potential security event. The researchers at Socket, Orca, StepSecurity, and Rescana have done extraordinary work documenting this campaign. The question is whether the ecosystem will actually change its behavior based on what they've found.
Because the next iteration of Shai-Hulud isn't coming. It's already here.