# Microsoft `durabletask` PyPI compromised - TeamPCP Mini Shai-Hulud stage-2 dropper

> Three malicious versions of `durabletask` - Microsoft's Python SDK for Azure Durable Functions (~417K monthly downloads) - were uploaded directly to PyPI inside a 35-minute window on 2026-05-19. None correspond to any git tag or CI run; the attacker bypassed Microsoft's pipeline with a stolen PyPI API token. Stage-2 is the full Mini Shai-Hulud credential-stealer with dedicated cloud-secret collectors. Attributed to TeamPCP. Last clean release: `1.4.0`.

- Published: 2026-05-19
- Last updated: 2026-05-29
- Severity: critical
- Kind: Compromise - A legitimate, already-used package, maintainer account, CI pipeline, or release tag was hijacked and a malicious version was published under a name people already depend on.
- Ecosystems: PyPI
- Scope: 1 package, 3 compromised versions
- Tags: credential-theft, worm, ci-cd-compromise, maintainer-takeover, obfuscation
- Threat actor: TeamPCP
- Also known as: Mini Shai-Hulud
- Detected by: Wiz, StepSecurity, Endor Labs, Aikido, SafeDep
- Incident ID: pypi-2026-05-19-durabletask-teampcp

## Affected packages (1)

Only the exact versions listed were named by the source advisories. Other versions are not implicated.

| Package | Ecosystem | Compromised versions |
|---|---|---|
| [durabletask](https://dependencywatch.io/package/pypi/durabletask) | PyPI | 1.4.1, 1.4.2, 1.4.3 |

## What happened

On 2026-05-19, hours after the `@antv` npm burst, **TeamPCP** pushed three malicious versions of Microsoft's official `durabletask` Python SDK (~417K monthly downloads) directly to PyPI inside a 35-minute window: `1.4.1` at 16:19 UTC, `1.4.2` at 16:49 UTC, `1.4.3` at 16:54 UTC. None of the three have corresponding tags, releases, or CI runs in `microsoft/durabletask-python`. The attacker bypassed Microsoft's build pipeline entirely and uploaded with a stolen or compromised PyPI API token - almost certainly one of the long-lived tokens cycled out of the broader Mini Shai-Hulud credential cache.

Execution does not require an install hook. The malicious wheels carry a Python dropper injected into the package's source files that fires on `import durabletask`. The dropper silently fetches a 28,703-byte zipapp `rope.pyz` (SHA-256 `069ac1dc7f7649b76bc72a11ac700f373804bfd81dab7e561157b703999f44ce`) from a three-day-old C2 domain `check.git-service[.]com` (registered 2026-05-16 via Namecheap), with `t.m-kosche[.]com/rope.pyz` as a documented fallback.

Stage-2 is the full Mini Shai-Hulud credential-harvesting framework with dedicated collectors for **AWS Secrets Manager + SSM Parameter Store, Azure Key Vault, GCP Secret Manager, Kubernetes secrets, HashiCorp Vault, password managers, and 90+ developer-tool configurations**. Results are encrypted with an attacker RSA public key and POSTed to `/api/public/version`; `/v1/models` is the secondary retrieval endpoint. The payload skips hosts with a Russian locale.

- **In-cloud worm propagation**: when stage-2 detects an AWS IAM profile, it runs `aws ssm send-command` with `AWS-RunShellScript` against up to 5 enumerated EC2 instances per profile, dropping itself on each.
- **In-cluster worm propagation**: when a Kubernetes service-account token is reachable, it uses `kubectl exec` into up to 5 running pods.
- Encrypted HTTPS exfil defeats most outbound TLS inspection.
- Dropper executes on `import durabletask` - `pip install --no-deps` does NOT mitigate; only pinning away from `1.4.1`/`1.4.2`/`1.4.3` does.

Disclosed publicly within hours by Wiz, StepSecurity, Endor Labs, Aikido, SafeDep, and The Hacker News. C2 fingerprints (`t.m-kosche.com`) are shared with the same-day `@antv` burst and the `actions-cool` tag hijack later the same day, plus the earlier TanStack, Mistral AI, `@uipath`, LiteLLM, and Telnyx compromises - TeamPCP's consistent infrastructure tells. Microsoft has yanked all three versions on PyPI; the last clean release is `durabletask` `1.4.0` (2026-04-08).

## Impact

- Cloud credential and secret theft: AWS Secrets Manager + SSM Parameter Store, Azure Key Vault, GCP Secret Manager, Kubernetes secrets, HashiCorp Vault
- Developer-tool credentials harvested from 90+ config locations: env files, GitHub CLI, npm/pip/poetry tokens, SSH private keys, Terraform state, DB passwords, password managers
- In-cloud worm propagation: AWS SSM SendCommand with AWS-RunShellScript launches the stage-2 on up to 5 other EC2 instances per accessible IAM profile
- In-cluster worm propagation: `kubectl exec` into up to 5 running pods when stage-2 detects a service-account token
- Encrypted exfiltration to attacker-controlled C2 over HTTPS, defeating most outbound TLS inspection
- Dropper executes on `import durabletask` - `pip install --no-deps` does NOT mitigate; only pinning away from 1.4.1/1.4.2/1.4.3 does

## What to do

1. Pin `durabletask` to `<= 1.4.0` everywhere. Refuse 1.4.1, 1.4.2, and 1.4.3 in lockfiles and constraints
2. Purge any cached wheels of `durabletask-1.4.{1,2,3}` from CI image layers, pip caches, and internal mirrors
3. Treat every host or runner that ran `import durabletask` with 1.4.1/1.4.2/1.4.3 installed as fully compromised. Rotate: AWS/Azure/GCP keys, every Secrets-Manager / Key-Vault / Secret-Manager entry reachable from that IAM scope, K8s service-account tokens, Vault tokens, npm/PyPI/GitHub/GitLab/CircleCI tokens, SSH keys, DB passwords, password-manager vaults
4. Audit CloudTrail / Azure Activity / GCP Audit for unexpected `ssm:SendCommand`, `secretsmanager:GetSecretValue`, `kv:GetSecret`, `secretmanager.versions.access` calls during the exposure window starting 2026-05-19T16:19Z
5. Audit Kubernetes audit logs for unexpected `pods/exec` calls - the worm uses kubectl-exec into other pods to spread
6. Block egress to `check.git-service.com`, `t.m-kosche.com`, and any *.git-service.com subdomain; alert on outbound HTTP POST containing `/api/public/version` or `/v1/models` paths to non-allow-listed hosts
7. Hunt for the rope.pyz file by SHA-256 069ac1dc7f7649b76bc72a11ac700f373804bfd81dab7e561157b703999f44ce on every Python host that ran the bad versions
8. PyPI publishing for production projects: enforce Trusted Publishers (OIDC) and disable long-lived API tokens; the attacker only succeeded because a long-lived token was reachable

## Check your own dependencies

- Check a requirements.txt against this incident: https://dependencywatch.io/check/requirements-txt

The scan runs entirely in the browser; lockfile contents are never uploaded.

## References

- [Microsoft's durabletask PyPI package compromised in supply-chain attack](https://www.stepsecurity.io/blog/microsofts-durabletask-pypi-package-compromised-in-supply-chain-attack) - StepSecurity
- [durabletask: TeamPCP's latest PyPI compromise](https://www.wiz.io/blog/durabletask-teampcp-supply-chain-attack) - Wiz
- [Trojanized Microsoft SDK: durabletask 1.4.1 through 1.4.3 deliver credential-stealing malware](https://www.endorlabs.com/learn/trojanized-microsoft-sdk-durabletask-1-4-1-through-1-4-3-deliver-credential-stealing-malware) - Endor Labs
- [Potential malicious code execution in durabletask versions 1.4.1, 1.4.2, and 1.4.3 (microsoft/durabletask-python#137)](https://github.com/microsoft/durabletask-python/issues/137) - Microsoft
- [durabletask on PyPI - versions 1.4.1 / 1.4.2 / 1.4.3 yanked as "Compromised"](https://pypi.org/project/durabletask/) - PyPI

---

Canonical page: https://dependencywatch.io/incident/pypi-2026-05-19-durabletask-teampcp
Markdown version: https://dependencywatch.io/incident/pypi-2026-05-19-durabletask-teampcp.md
Site index for agents: https://dependencywatch.io/llms.txt
DependencyWatch.io is operated by Precursor Security (https://precursorsecurity.com).
