Mini Shai-Hulud, Miasma and Hades Worms Spread Through Malicious PyPI Wheels

Summary
Researchers identified 23 new malicious PyPI artifacts using startup hooks, trojanized native extensions, and staged JavaScript payloads to target developer and CI/CD secrets.
Key points
- The new wave adds 23 malicious PyPI package-version artifacts, including bioinformatics, AI/MCP-themed, and typosquatted packages.
- Some packages use executable .pth startup hooks; bioinformatics packages hide import-time execution in trojanized .abi3.so native extensions.
- A langchain-core-mcp variant searches Python’s sys.path for a separate _index.js payload, then attempts to run it with Bun.
- The Hades-family JavaScript stealer targets developer workstations and CI/CD environments for registry tokens, cloud credentials, SSH keys, Kubernetes material, and other secrets.
- A fake prompt-injection header in a JavaScript comment appears intended to disrupt AI-assisted malware analysis; the article says it does not affect execution.
- The campaign tracker lists 471 affected artifacts across npm and PyPI. Defenders are advised to check package versions and execution indicators, preserve evidence, and rotate potentially exposed credentials.
Article Details
- Attack Vectors
- Malicious PyPI wheels use executable *-setup.pth files to launch an obfuscated _index.js payload during Python startup, downloading Bun if needed.
- Trojanized .abi3.so native extensions launch the JavaScript payload when Python imports the package and initializes the extension through dlopen(). The malicious trigger is not visible in the package's Python source files.
- The langchain-core-mcp@1.4.2 wheel installs langchain_core-setup.pth without bundling _index.js. Its loader searches sys.path entries and their immediate subdirectories for the payload, then attempts to execute it with Bun.
- Typosquat-style and AI/MCP-themed packages appear intended to attract developer installations alongside malicious versions of established research-community packages.
- The JavaScript payload includes a fake instruction header intended to disrupt AI-assisted malware analysis, followed by obfuscated executable code.
- The stealer targets developer workstations and CI/CD environments for registry tokens, cloud credentials, Kubernetes service account material, SSH keys, Docker configuration, shell histories, .env files, and AI developer tool configuration.
- Defensive Notes
- Check installed package versions against the affected-artifact list and preserve forensic artifacts before uninstalling where possible.
- Rotate tokens and other credentials that may have been exposed, especially credentials available to build and release environments.
- Inspect Python environments for executable .pth files, unexpected _index.js files, Bun download logic, and newly introduced .abi3.so extensions.
- Review compiled native extensions rather than relying exclusively on Python source, setup scripts, metadata, or dependency declarations.
- Do not assume the loader and JavaScript payload must reside in the same wheel; inspect payload discovery across Python import paths.
- Inspect CI/CD runners for unusual workflow changes, Docker socket abuse, poisoned /etc/hosts entries, unexpected privileged containers, and access to package publishing credentials.
- Treat file content supplied to AI-assisted analysis as untrusted data. The fake comment header does not prevent conventional static or behavioral analysis, including YARA rules, entropy checks, AST parsing, string extraction, and deobfuscation.
- The article identifies agent.stepsecurity.io, api.stepsecurity.io, and app.stepsecurity.io as legitimate defensive-service domains reportedly blocked by the malware, not attacker infrastructure.
Indicators of compromise
| Type | Indicator | Context |
|---|---|---|
| SHA256 | 6506d31707a39949f89534bf9705bcf889f1ecae3dbc6f4ff88d67a8be3d01b2 | SHA256 of langchain_core-setup.pth, the malicious Python startup hook that searches for and launches a separate JavaScript payload. |
| SHA256 | 6d332f814f15f19758d65026bbfd0a8c49671b319ec77b8fa1b27fc48afff7d9 | SHA256 of the malicious langchain_core_mcp-1.4.2-py3-none-any.whl loader artifact. |
MITRE ATT&CK
T1027 · Obfuscated Files or InformationThe Hades JavaScript payload is heavily obfuscated using a character-code array and a ROT-style substitution function.T1059.006 · PythonThe malicious .pth loader executes Python code to search sys.path, download Bun, and launch the discovered payload.T1059.007 · JavaScriptThe loaders execute the _index.js JavaScript stealer using Bun.T1140 · Deobfuscate/Decode Files or InformationThe executable payload uses a try{eval(...)} wrapper with character-code and substitution-based decoding.T1195.001 · Compromise Software Dependencies and Development ToolsMalicious PyPI package versions deliver startup hooks or trojanized native extensions to developers and CI/CD environments; the earlier wave involved a compromised maintainer account.T1546.018 · Python Startup HooksExecutable *-setup.pth files run during Python startup and bootstrap execution of the JavaScript stealer.T1552.001 · Credentials In FilesThe stealer targets credential-bearing files and configuration, including .env files, Docker configuration, shell histories, registry credentials, and AI developer tool configuration.T1552.004 · Private KeysSSH keys are explicitly identified among the secrets targeted by the malware.
Malware
ChainDropSocket Threat Research team identified a newer PyPI wave connected to the broader Mini Shai-Hulud, Miasma, and Hades supply chain attacks. This wave expands beyond the 37 malicious PyPI wheels covered in our weekendHadesThreat Research team identified a newer PyPI wave connected to the broader Mini Shai-Hulud, Miasma, and Hades supply chain attacks. This wave expands beyond the 37 malicious PyPI wheels covered in our weekend reportMiasmaSocket Threat Research team identified a newer PyPI wave connected to the broader Mini Shai-Hulud, Miasma, and Hades supply chain attacks. This wave expands beyond the 37 malicious PyPI wheels covered in our weekendShai-HuludSocket Threat Research team identified a newer PyPI wave connected to the broader Mini Shai-Hulud, Miasma, and Hades supply chain attacks. This wave expands beyond the 37 malicious PyPI wheels covered in our weekend
Vendors
Products
BunInstead, it searches Python’s module search path, sys.path, for _index.js and attempts to run it with Bun.DockerGitHub, npm, PyPI, RubyGems, JFrog, cloud credentials, Kubernetes service account material, SSH keys, Docker configuration, shell histories, .env files, package registry credentials, and AI developer tooldreamgendreamgen@1.8.1embiggenpackages with lookalike and ecosystem-bait packages. The bioinformatics cluster, including embiggen, ensmallen, gpsea, phenopacket-store-toolkit, ppkt2synergy, and pyphetools, affects real packages usedensmallenpackages with lookalike and ecosystem-bait packages. The bioinformatics cluster, including embiggen, ensmallen, gpsea, phenopacket-store-toolkit, ppkt2synergy, and pyphetools, affects real packages used in graphGitHubthe malware targets developer workstations and CI/CD environments for high-value secrets, including GitHub, npm, PyPI, RubyGems, JFrog, cloud credentials, Kubernetes service account material, SSH keys, Dockergpseawith lookalike and ecosystem-bait packages. The bioinformatics cluster, including embiggen, ensmallen, gpsea, phenopacket-store-toolkit, ppkt2synergy, and pyphetools, affects real packages used in graph learning,instructor-mcpinstructor-mcp@1.15.2langchain-core-mcpand MCP-themed packages, typosquat-style packages such as rsquests, tlask, and rlask, and a notable langchain-core-mcp loader variant that does not bundle the expected _index.js payload. Instead, it searches Python’smem8mem8@6.0.1mflux-streamlitmflux-streamlit@0.0.3npmmalware targets developer workstations and CI/CD environments for high-value secrets, including GitHub, npm, PyPI, RubyGems, JFrog, cloud credentials, Kubernetes service account material, SSH keys, Dockeropenai-mcpopenai-mcp@2.41.1orchestr8-platformorchestr8-platform@3.3.2phenopacket-store-toolkitand ecosystem-bait packages. The bioinformatics cluster, including embiggen, ensmallen, gpsea, phenopacket-store-toolkit, ppkt2synergy, and pyphetools, affects real packages used in graph learning, patientppkt2synergypackages. The bioinformatics cluster, including embiggen, ensmallen, gpsea, phenopacket-store-toolkit, ppkt2synergy, and pyphetools, affects real packages used in graph learning, patient phenotyping, phenopacketpyphetoolscluster, including embiggen, ensmallen, gpsea, phenopacket-store-toolkit, ppkt2synergy, and pyphetools, affects real packages used in graph learning, patient phenotyping, phenopacket tooling, and relatedPyPISocket Threat Research team identified a newer PyPI wave connected to the broader Mini Shai-Hulud, Miasma, and Hades supply chain attacks. This wave expands beyond the 37 malicious PyPI wheels covered in our weekendPythonloader variant that does not bundle the expected _index.js payload. Instead, it searches Python’s module search path, sys.path, for _index.js and attempts to run it with Bun.ray-mcp-serverray-mcp-server@0.2.1rlaska separate cluster of AI and MCP-themed packages, typosquat-style packages such as rsquests, tlask, and rlask, and a notable langchain-core-mcp loader variant that does not bundle the expected _index.js payload.rsquestspackages, a separate cluster of AI and MCP-themed packages, typosquat-style packages such as rsquests, tlask, and rlask, and a notable langchain-core-mcp loader variant that does not bundle the expectedtiktoken-mcptiktoken-mcp@0.13.1tlaskpackages, a separate cluster of AI and MCP-themed packages, typosquat-style packages such as rsquests, tlask, and rlask, and a notable langchain-core-mcp loader variant that does not bundle the expected _index.js
Tools
harden-runnerharden-runner — legitimate StepSecurity defensive tooling targeted by the malwareSocket AI ScannerSocket AI Scanner’s analysis of the malicious langchain-core-mcp@1.4.2 wheel highlights a covert Python startup hook in langchain_core-setup.pth.YARAThis is not a magical bypass against static detection. YARA rules, entropy checks, AST parsing, string extraction, deobfuscation, and behavioral rules still work. But it is a practical anti-analysis trick against naive
Industries
bioinformaticsexpanding beyond the 37 malicious PyPI wheels covered in our weekend report. The new set includes six bioinformatics packages, a separate cluster of AI and MCP-themed packages, typosquat-style packages such asgenomicsespecially if the package normally ships compiled performance-sensitive code. In scientific computing, genomics, and machine learning packages, native extensions are common and often expected.scientific computingless scrutiny, especially if the package normally ships compiled performance-sensitive code. In scientific computing, genomics, and machine learning packages, native extensions are common and often expected.