Hades PyPI Graph ML Memory Scraper Campaign

Suspected
Discovered Jun 8, 2026

StepSecurity reported the Hades campaign across graph ML and bioinformatics PyPI packages, using Python import hooks to download Bun v1.3.14, run _index.js, scrape secrets across Linux/macOS/Windows runners, plant developer-tooling persistence, and create GitHub exfiltration repositories.

51
Affected Packages
28
Observables
2
Sources

Analysis

Executive Summary

StepSecurity reported the Hades campaign across graph ML and bioinformatics PyPI packages, using Python import hooks to download Bun v1.3.14, run _index.js, scrape secrets across Linux/macOS/Windows runners, plant developer-tooling persistence, and create GitHub exfiltration repositories.

This folder ports older Astro-era supply-chain coverage into the canonical hp-posts-info authoring shape so the Next.js/Postgres importer can serve it. The current status is needs_review: the source-backed indicators are captured, but the pass intentionally does not claim fresh artifact diffing beyond the cited primary research.

Key Facts

  • Affected assets: bramin, cmd2func, coolbox, dynamo-release, embiggen, ensmallen, executor-engine, executor-http, funcdesc, gpsea, magique, magique-ai ....
  • Execution trigger: Python package import hook embedded in init.py locates _index.js, downloads Bun, and runs the JavaScript payload.
  • Credential risk: GitHub, OIDC, cloud, package-registry, and developer credentials reachable from impacted CI or developer environments.
  • Relationship: migrated from the older Astro blog supply-chain roundup into a standalone Next.js/Postgres-ready incident folder.

Defender Handling

Run the included scope scanner over repository exports, package caches, CI logs, and endpoint telemetry. Treat matches in live dependency manifests, lockfiles, workflow definitions, or runner process/network logs as exposure signals until the owning team confirms whether the malicious artifact actually executed.

Open Questions

This migration captures coverage and source-backed selectors. Before marking publish-ready, perform fresh artifact diffing, validate current package/action cleanup status, and reconcile exact downstream victim counts from direct maintainer or platform sources.

Sources

  1. StepSecurity primary research. Role: PRIMARY_RESEARCH Impact: Primary source for affected assets, execution trigger, payload behavior, and published IOCs.

Timeline

4 of 4 rows

Timeline
DateEventDescriptionSource
Jun 8, 2026DiscoveryDiscovery recorded for Hades PyPI Graph ML Memory Scraper Campaign.StepSecurity
Jun 8, 2026Hades PyPI Graph ML Memory Scraper CampaignUnknownStepSecurity
Jun 8, 2026First seenFirst seen recorded for Hades PyPI Graph ML Memory Scraper Campaign.StepSecurity
Jun 8, 2026DisclosureDisclosure recorded for Hades PyPI Graph ML Memory Scraper Campaign.StepSecurity

Affected Software

51 of 51 rows

Affected Software
PackageEcosystemVersion RangeStatusConfidenceSource
magique-aiunknown0.4.4Malicious65%StepSecurity; haltingproblems.com
magique-aiunknown0.4.5Malicious65%StepSecurity; haltingproblems.com
braminunknown0.0.3Malicious65%StepSecurity; haltingproblems.com
braminunknown0.0.4Malicious65%StepSecurity; haltingproblems.com
cmd2funcunknown0.2.2Malicious65%StepSecurity; haltingproblems.com
cmd2funcunknown0.2.3Malicious65%StepSecurity; haltingproblems.com
coolboxunknown0.4.1Malicious65%StepSecurity; haltingproblems.com
coolboxunknown0.4.2Malicious65%StepSecurity; haltingproblems.com
dynamo-releaseunknown1.5.4Malicious65%StepSecurity; haltingproblems.com
embiggenunknown0.11.97Malicious65%StepSecurity; haltingproblems.com
ensmallenunknown0.8.101Malicious65%StepSecurity; haltingproblems.com
executor-engineunknown0.3.4Malicious65%StepSecurity; haltingproblems.com
executor-engineunknown0.3.5Malicious65%StepSecurity; haltingproblems.com
executor-httpunknown0.1.3Malicious65%StepSecurity; haltingproblems.com
executor-httpunknown0.1.4Malicious65%StepSecurity; haltingproblems.com
funcdescunknown0.2.2Malicious65%StepSecurity; haltingproblems.com
funcdescunknown0.2.3Malicious65%StepSecurity; haltingproblems.com
gpseaunknown0.9.14Malicious65%StepSecurity; haltingproblems.com
magiqueunknown0.6.8Malicious65%StepSecurity; haltingproblems.com
mflux-streamlitunknown0.0.4Malicious65%StepSecurity; haltingproblems.com
mrbiosunknown0.1.1Malicious65%StepSecurity; haltingproblems.com
mrbiosunknown0.1.2Malicious65%StepSecurity; haltingproblems.com
napari-ufishunknown0.0.2Malicious65%StepSecurity; haltingproblems.com
napari-ufishunknown0.0.3Malicious65%StepSecurity; haltingproblems.com
nhmpyunknown2.4.7Malicious65%StepSecurity; haltingproblems.com
nucboxunknown0.1.2Malicious65%StepSecurity; haltingproblems.com
nucboxunknown0.1.3Malicious65%StepSecurity; haltingproblems.com
okiteunknown0.0.7Malicious65%StepSecurity; haltingproblems.com
okiteunknown0.0.8Malicious65%StepSecurity; haltingproblems.com
pantheon-agentsunknown0.6.1Malicious65%StepSecurity; haltingproblems.com
pantheon-agentsunknown0.6.2Malicious65%StepSecurity; haltingproblems.com
pantheon-toolsetsunknown0.5.5Malicious65%StepSecurity; haltingproblems.com
pantheon-toolsetsunknown0.5.6Malicious65%StepSecurity; haltingproblems.com
ppkt2synergyunknown0.1.1Malicious65%StepSecurity; haltingproblems.com
pyphetoolsunknown0.9.120Malicious65%StepSecurity; haltingproblems.com
rlaskunknown3.1.4Malicious65%StepSecurity; haltingproblems.com
rlaskunknown3.1.5Malicious65%StepSecurity; haltingproblems.com
rlaskunknown3.1.6Malicious65%StepSecurity; haltingproblems.com
rlaskunknown3.1.7Malicious65%StepSecurity; haltingproblems.com
rsquestsunknown2.34.3Malicious65%StepSecurity; haltingproblems.com
synagounknown0.1.1Malicious65%StepSecurity; haltingproblems.com
synagounknown0.1.2Malicious65%StepSecurity; haltingproblems.com
tlaskunknown3.1.4Malicious65%StepSecurity; haltingproblems.com
ufishunknown0.1.2Malicious65%StepSecurity; haltingproblems.com
ufishunknown0.1.3Malicious65%StepSecurity; haltingproblems.com
uprobeunknown0.1.3Malicious65%StepSecurity; haltingproblems.com
uprobeunknown0.1.4Malicious65%StepSecurity; haltingproblems.com
braminunknown0.0.2Malicious65%StepSecurity; haltingproblems.com
magiqueunknown0.6.9Malicious65%StepSecurity; haltingproblems.com
mflux-streamlitunknown0.0.3Malicious65%StepSecurity; haltingproblems.com
spateo-releaseunknown1.1.2Malicious65%StepSecurity; haltingproblems.com

IOC Clipboard

28 IOCs
domainapi.github.com
command/proc/{pid}/mem
domaingithub.com
file_path.vscode/tasks.json
file_pathRun Copilot
urlhttps://github.com/oven-sh/bun/releases/download/bun-v1.3.14/
urlhttps://www.stepsecurity.io/blog/the-hades-campaign-pypi-packages
file_path__init__.py
file_path_index.js
file_path/tmp/.bun_ran
file_path/tmp/tmp.0144018410.lock
file_path/var/tmp/.gh_update_state
file_path~/.local/share/updater/update.py
file_path~/.config/systemd/user/update-monitor.service
file_path~/.config/systemd/user/gh-token-monitor.service
file_path~/Library/LaunchAgents/com.user.update-monitor.plist
file_path~/.local/bin/gh-token-monitor.sh
file_path.claude/settings.json
commandtask_for_pid
commandReadProcessMemory
commandbun run _index.js
commandfiredalazer
network_patternHades - The End for the Damned
network_patternDontRevokeOrItGoesBoom
network_patternTheBeautifulSnadsOfTime
network_patternstygian-cerberus-
network_patterntartarean-charon-
commandRunner.Worker

Tested Hunting Scripts

1 of 1 rows

Tested Hunting Scripts
TitleLanguageDescriptionRepositorySource
local repository and exported telemetry scopePythonDoes this scope contain package, workflow, process, filesystem, or network indicators associated with Hades PyPI Graph ML Memory Scraper Campaign?scripts/local_repository_and_exported_telemetry_scope.pyStepSecurity

Hunt Manifest: local repository and exported telemetry scope

Title
local repository and exported telemetry scope
Question
Does this scope contain package, workflow, process, filesystem, or network indicators associated with Hades PyPI Graph ML Memory Scraper Campaign?
Telemetry Family
Python
Repository
scripts/local_repository_and_exported_telemetry_scope.py
scripts/local_repository_and_exported_telemetry_scope.pyPython
#!/usr/bin/env python3
import os
import sys
from pathlib import Path

ROOT = Path(sys.argv[1]).resolve() if len(sys.argv) > 1 else Path('.').resolve()
OUT = Path(os.environ.get('OUT', 'hp-hades-pypi-graph-ml-memory-scraper-scope'))
OUT.mkdir(parents=True, exist_ok=True)

PACKAGES = ["bramin", "cmd2func", "coolbox", "dynamo-release", "embiggen", "ensmallen", "executor-engine", "executor-http", "funcdesc", "gpsea", "magique", "magique-ai", "mflux-streamlit", "mrbios", "napari-ufish", "nhmpy", "nucbox", "okite", "pantheon-agents", "pantheon-toolsets", "ppkt2synergy", "pyphetools", "rlask", "rsquests", "spateo-release", "synago", "tlask", "ufish", "uprobe"]
PACKAGE_VERSIONS = ["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", "embiggen@0.11.97", "ensmallen@0.8.101", "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", "gpsea@0.9.14", "magique@0.6.8", "magique@0.6.9", "magique-ai@0.4.4", "magique-ai@0.4.5", "mflux-streamlit@0.0.3", "mflux-streamlit@0.0.4", "mrbios@0.1.1", "mrbios@0.1.2", "napari-ufish@0.0.2", "napari-ufish@0.0.3", "nhmpy@2.4.7", "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", "ppkt2synergy@0.1.1", "pyphetools@0.9.120", "rlask@3.1.4", "rlask@3.1.5", "rlask@3.1.6", "rlask@3.1.7", "rsquests@2.34.3", "spateo-release@1.1.2", "synago@0.1.1", "synago@0.1.2", "tlask@3.1.4", "ufish@0.1.2", "ufish@0.1.3", "uprobe@0.1.3", "uprobe@0.1.4"]
FILES = ["__init__.py", "_index.js", "/tmp/.bun_ran", "/tmp/tmp.0144018410.lock", "/var/tmp/.gh_update_state", "~/.local/share/updater/update.py", "~/.config/systemd/user/update-monitor.service", "~/.config/systemd/user/gh-token-monitor.service", "~/Library/LaunchAgents/com.user.update-monitor.plist", "~/.local/bin/gh-token-monitor.sh", ".claude/settings.json", ".vscode/tasks.json", "Run Copilot"]
HASHES = []
DOMAINS = ["api.github.com", "github.com"]
URLS = ["https://github.com/oven-sh/bun/releases/download/bun-v1.3.14/", "https://www.stepsecurity.io/blog/the-hades-campaign-pypi-packages"]
IPS = []
PROCESS_PATTERNS = ["Runner.Worker", "/proc/{pid}/mem", "task_for_pid", "ReadProcessMemory", "bun run _index.js", "firedalazer"]
NETWORK_PATTERNS = ["Hades - The End for the Damned", "DontRevokeOrItGoesBoom", "TheBeautifulSnadsOfTime", "stygian-cerberus-", "tartarean-charon-"]

def read_text(path: Path) -> str:
    try:
        return path.read_text(encoding="utf-8", errors="ignore")
    except Exception as exc:
        return f"__READ_ERROR__:{path}:{exc}"

def scan_tree(base: Path, indicators: set[str]) -> list[str]:
    matches = []
    skip = {".git", "node_modules", "vendor", "dist", ".venv", "__pycache__"}
    for current_root, dirs, files in os.walk(base):
        dirs[:] = [d for d in dirs if d not in skip]
        for name in files:
            path = Path(current_root) / name
            text = read_text(path)
            for indicator in indicators:
                if indicator and indicator in text:
                    matches.append(f"{path}: found {indicator!r}")
    return matches

indicators = set()
for group in [PACKAGES, PACKAGE_VERSIONS, FILES, HASHES, DOMAINS, URLS, IPS, PROCESS_PATTERNS, NETWORK_PATTERNS]:
    indicators.update(group)

(OUT / "indicators.txt").write_text("\n".join(sorted(indicators)) + "\n", encoding="utf-8")
matches = scan_tree(ROOT, indicators)
(OUT / "matches.txt").write_text("\n".join(matches) + ("\n" if matches else ""), encoding="utf-8")
print(f"[+] wrote {len(indicators)} selectors and {len(matches)} matches under {OUT}")

Provenance & Sources

2 of 2 rows

Provenance & Sources
SourceTypeReliabilityClaimsEvidence
StepSecuritySecurity Researcher95%1StepSecurity reported the Hades campaign across graph ML and bioinformatics PyPI packages, using Python import hooks to download Bun v1.3.14, run _index.js, scrape secrets across Linux/macOS/Windows runners, plant developer-tooling persistence, and create GitHub exfiltration repositories.
haltingproblems.comBlog80%1StepSecurity reported the Hades campaign across graph ML and bioinformatics PyPI packages, using Python import hooks to download Bun v1.3.14, run _index.js, scrape secrets across Linux/macOS/Windows runners, plant developer-tooling persistence, and create GitHub exfiltration repositories.