Skip to content

Back to the catalog

Microsoft's durabletask PyPI Package Compromised in Supply Chain Attack
stepsecurity.iowriteup

Microsoft's durabletask PyPI Package Compromised in Supply Chain Attack

StepSecurity documents the compromise of Microsoft's durabletask PyPI package (versions 1.4.1-1.4.3, 400k+ monthly downloads), where an attacker bypassed the GitHub CI/CD pipeline entirely using stolen publishing credentials to inject a dropper for rope.pyz, a modular cloud-intrusion framework with dedicated collectors for AWS, Azure, GCP, Kubernetes, HashiCorp Vault, password managers, and the filesystem. The framework encrypts stolen data with AES-256-GCM/RSA-4096, exfiltrates via HTTPS, GitHub commit beacons, and attacker-created public repos using the victim's own stolen GitHub tokens, propagates via AWS SSM and kubectl exec, and drops a geo-targeted rm -rf wiper for systems matching Israeli locale/timezone markers. The post ties the attack to TeamPCP's Mini Shai-Hulud campaign (same infrastructure as TanStack, Mistral AI, LiteLLM, @antv) and later updates describe a second compromise of the Azure/durabletask GitHub repo that plants payloads triggering in Claude Code, Gemini CLI, Cursor, and VS Code.

TL;DR Microsoft's durabletask PyPI SDK was compromised to drop rope.pyz, a modular AWS/Azure/GCP/K8s/Vault credential stealer with a geo-targeted wiper, attributed to TeamPCP's Mini Shai-Hulud/Miasma campaign, which later also re-infected the GitHub repo to target AI coding agents like Claude Code and Cursor.
Document

What it is

StepSecurity's analysis of the compromise of Microsoft's durabletask PyPI package — the official SDK for Azure Durable Functions, downloaded 400,000+ times/month. Three malicious versions (1.4.1, 1.4.2, 1.4.3) were uploaded directly to PyPI on May 19, 2026 within a 35-minute window using stolen publishing credentials, bypassing CI/CD. A second attack on June 5, 2026 used the same contributor account to push commit 5f456b8 to the Azure/durabletask GitHub repo. Tied to TeamPCP's Mini Shai-Hulud campaign (same group behind TanStack, Mistral AI, LiteLLM, @antv).

How it works

The PyPI payload activates on import, not install — pip install durabletask shows only legitimate PyPI traffic. On import durabletask, a 14-line dropper pulls rope.pyz from C2 check.git-service.com, then spawns multiple /tmp/managed.pyz processes that install cryptography at runtime, decrypt secrets via gpg, steal GitHub tokens (gh auth token, gh auth status --show-token), recon Kubernetes, and install systemd persistence.

The June 5 GitHub commit carries a decoy message ("Switched DataConverter to OrchestrationContext [skip ci]") and plants five files (the existing summary lists four). The fifth, .github/setup.js, is the actual 4.6 MB malware with triple-layered obfuscation (ROT cipher, AES-128-GCM, JS string-table mangling); the others are triggers for Claude Code, Gemini CLI, Cursor, and VS Code.

Preconditions / Affected

  • PyPI: any system running 1.4.1, 1.4.2, or 1.4.3.
  • GitHub: anyone who cloned or opened Azure/durabletask in VS Code, Claude Code, Cursor, or Gemini CLI after commit 5f456b8.
  • The destructive rm -rf /* wiper only fires for specific geographies.

What to do

pip show durabletask

If the version is 1.4.1/1.4.2/1.4.3, treat the system as compromised, pin to 1.4.0, and start incident response. If you opened the repo in an affected AI/IDE tool after June 5, treat the system as compromised and rotate all credentials.

Indicators of compromise:

  • C2: check.git-service.com (rope.pyz download)
  • Secondary C2: t.m-kosche[.]com (campaign attribution)
  • www.youtube.com used as connectivity check/decoy
  • /tmp/managed.pyz child processes off python3

Caveats

  • StepSecurity disabled the Harden-Runner Global block list to capture the full chain; in a default deployment the outbound call to check.git-service.com is blocked automatically, terminating the run before download/exfiltration.
  • The reused contributor account across both incidents suggests credentials were never fully rotated after May 19, or the account was re-compromised via the worm's self-propagation. GitHub blocked the repo for TOS violations; Microsoft yanked the PyPI versions.

Organisations named here

  • MAL-2026-4174
  • t.m-kosche.com

CVEs named here

  • CVE-2026-45321

Technologies named here

  • durabletask
  • Harden-Runner
  • StepSecurity OSS Package Security
  • Azure/durabletask GitHub repository
  • rope.pyz
  • Azure Functions runtime and language worker projects
  • ThreadPoolExecutor
  • Claude Code
  • Gemini CLI
  • kubectl
  • gh
  • Cursor
  • VS Code
  • gpg
  • systemctl/systemd
  • tanstack
  • Mistral AI packages
  • pip
  • guardrails-ai
  • LiteLLM
  • OpenSearch
  • telnyx
  • AntV
  • Checkmarx
  • Python
  • PyPI
  • AWS
  • Azure
  • Kubernetes

Techniques named here

  • Malicious code injection at import time
  • Process detachment and log evasion
  • Anti-analysis / sandbox evasion
  • Credential harvesting from cloud metadata and config files
  • Password manager brute-forcing
  • Data encryption for exfiltration
  • Redundant exfiltration channels
  • Lateral movement via AWS SSM
  • Lateral movement via Kubernetes pod exec
  • In-memory certificate handling
  • Persistence via fake systemd service
  • Geofenced destructive wiper
  • AI coding agent targeting
  • Triple-layered obfuscation

Threat actors named here

  • TeamPCP
  • Mini Shai-Hulud
  • Miasma worm
  • rope.pyz / managed.pyz payload