# durabletask PyPI Supply Chain Compromise (v1.4.1–1.4.3) — Microsoft-Published Azure Durable Functions SDK Trojanized w/ Cross-Cloud Credential Stealer + Linux Disk Wiper (TeamPCP / Mini Shai-Hulud)

> TeamPCP trojanized the officially Microsoft-published `durabletask` Python SDK (Azure Durable Functions client, ~417K monthly downloads) on PyPI on 2026-05-19, publishing three malicious versions (1.4.1, 1.4.2, 1.4.3) inside a ~35-minute window before yank. The dropper is injected directly into the package's Python source files, so a bare `import durabletask` triggers execution. The second-stage payload is a cross-cloud credential stealer and worm targeting AWS, Azure, GCP, HashiCorp Vault, 1Password, and Bitwarden, propagating via AWS SSM (EC2) and `kubectl exec` (Kubernetes), and carrying a Linux disk wiper.

- **Published:** 2026-05-25T00:00:00Z
- **Last reviewed:** 2026-05-25T00:00:00Z
- **Canonical:** https://intel.threadlinqs.com/threat/TL-2026-0580
- **ID:** TL-2026-0580
- **Severity:** CRITICAL
- **Category:** SUPPLY_CHAIN
- **Status:** MONITORING
- **Actor:** TeamPCP
- **Detections:** 9 · **IOCs:** 25 (full data via the Threadlinqs MCP server — Purple tier)
- **CVEs:** CVE-2026-45321

## Description

On 2026-05-19, threat actor TeamPCP (the operator behind the Mini Shai-Hulud npm wave and the GitHub-internal breach via Nx Console v18.95.0) published three trojanized versions (1.4.1, 1.4.2, 1.4.3) of the official Microsoft-published `durabletask` Python SDK to PyPI. The package is Microsoft's Azure Durable Functions Python client with approximately 417,000 monthly downloads at the time of compromise. PyPI maintainers and Microsoft yanked the versions within approximately 35 minutes of the first publish, but during that window any `pip install durabletask` (including transitive resolutions in CI/CD pipelines, ephemeral runners, and developer workstations) would have pulled the malicious build. This is the first officially-Microsoft-published package surface trojanized in the TeamPCP campaign.

## Initial Access & Trigger

Unlike typical supply-chain droppers that piggyback on `setup.py` / `pyproject.toml` install hooks, TeamPCP injected the dropper directly into the package's Python source files. This means execution occurs not at install time, but at **import time** — a single `import durabletask` (or any transitive import via Azure Functions Python tooling) is sufficient to execute the dropper. This bypasses install-time scanners that focus on package metadata and `setup.py` post-install hooks, and it ensures execution on any host that ever loaded the SDK during the compromise window, including hosts where the affected version was later upgraded out.

## Exploit Chain

1. **Initial Access (T1195.002 — Compromise Software Supply Chain).** Maintainer credentials for the official Microsoft `durabletask` PyPI project were used to publish v1.4.1, then v1.4.2, then v1.4.3 within ~35 minutes on 2026-05-19. The exact credential-theft vector against Microsoft's PyPI publishing identity has not been disclosed in public reporting, but the broader TeamPCP campaign has consistently abused OIDC tokens and harvested CI/CD secrets (cf. CVE-2026-45321, the TanStack OIDC abuse chain that fed the Nx Console publish).
2. **Execution (T1059.006 — Python).** The Python source files of the package are mutated to include a small bootstrapping stub that runs on module import. Because Python evaluates top-level statements when a module is first loaded, no install-time hook is required.
3. **Defense Evasion (T1027 — Obfuscated Files or Information).** The dropper stub is obfuscated and minified to avoid casual review of the package's source on PyPI, and the second-stage payload is fetched dynamically — the package on PyPI does not itself carry the credential-stealer bytes.
4. **Credential Access (T1552 — Unsecured Credentials, T1555 — Credentials from Password Stores, T1528 — Steal Application Access Token).** The second stage enumerates AWS, Azure, GCP, HashiCorp Vault, 1Password, and Bitwarden credential stores and harvests environment-resident tokens, including GitHub PATs and npm granular access tokens.
5. **Discovery (T1057, T1082, T1018).** Cloud-provider metadata services are queried (IMDS/IMDSv2 on AWS, Azure IMDS, GCE metadata) to discover instance identity, role bindings, and reachable peers.
6. **Lateral Movement (T1021.007 — Cloud Services, T1609 — Container Administration Command).** When running inside an EC2 instance with an attached IAM role that permits SSM, the worm uses AWS Systems Manager (`ssm:SendCommand`, `ssm:StartSession`) to execute commands on peer EC2 instances. When running inside a Kubernetes pod with a service-account that permits `pods/exec`, the worm uses `kubectl exec` to execute commands inside other pods. Both pivots deliver and re-execute the same payload, producing a worm that propagates inside cloud accounts and clusters rather than across the public internet.
7. **Exfiltration (T1567 — Exfiltration Over Web Service, T1573 — Encrypted Channel).** Harvested credentials and secrets are encrypted (PBKDF2-derived key, AES) and exfiltrated to Session messenger infrastructure: `filev2.getsession.org` (file delivery) and `seed1.getsession.org` (seed/control). The Session-messenger dead-drop pattern is shared with the @antv npm wave and the broader Mini Shai-Hulud lineage.
8. **Impact (T1485 — Data Destruction, T1561 — Disk Wipe).** iTnews reporting characterizes the durabletask second stage as carrying a Linux disk wiper. Unlike the W20 @ctrl/tinycolor wave, which gated wipe behavior on a 1-in-6 locale-conditional roll, the durabletask wiper materially extends destructive capability and removes the locale gating documented in prior waves. Any host that imported the trojanized SDK and matched the wiper's targeting criteria is at risk of irreversible data loss.

## C2 Infrastructure

The exfiltration channel uses the open-source Session messenger network (`getsession.org`), a Signal-fork that runs over a decentralized onion-routed Service Node network. The campaign uses two named hosts:

- `filev2.getsession.org` — File-server dead-drop. Encrypted credential bundles are uploaded here.
- `seed1.getsession.org` — Seed/coordination node. Used for bootstrap and configuration.

Session traffic is HTTPS-tunneled and difficult to distinguish from legitimate messaging traffic without explicit allow-listing. Egress-control environments that do not allow outbound to `*.getsession.org` will block exfiltration; environments that allow it (developer endpoints, dev/test cloud accounts, ephemeral CI runners) are exposed.

## Persistence on Developer Endpoints

Where the dropper detects a developer endpoint (presence of VS Code workspace files, presence of `.claude/` directories), the second-stage writes persistence into the AI coding agent surface — the same vector first documented in the TanStack May 11 wave:

- `~/.claude/settings.json` — Anthropic Claude Code agent settings; the worm injects a malicious agent task that re-fires on next agent launch.
- `.vscode/tasks.json` — VS Code workspace task definitions; the worm injects a task that re-fires when the workspace is opened.

These persistence vectors survive credential rotation and survive package removal, because they live in the user's home directory and the project workspace rather than in the package itself.

## Attribution

Attribution to TeamPCP rests on toolchain reuse across the Mini Shai-Hulud lineage (PBKDF2 salt strings, encrypted-bundle format, Session dead-drop addresses, persistence vectors), the operator's `"Love - TeamPCP"` README signature in the leaked framework source, and the temporal/coordinated nature of the W21 escalation (the durabletask publish on 2026-05-19 coincided with the @antv npm wave and was 24 hours after the Nx Console v18.95.0 publish that breached GitHub-internal). Mandiant / Google Threat Intelligence Group has not (as of 2026-05-25) issued a named-actor product on UNC6780 covering this incident. Microsoft publicly entered the response coalition; CISA has not added CVE-2026-45321 (the TanStack OIDC abuse chain that bridges Nx Console to TeamPCP) to the Known Exploited Vulnerabilities catalog in either of the two W21 update tranches.

## Affected Surface

Any environment that executed `pip install durabletask` resolving to 1.4.1, 1.4.2, or 1.4.3 on 2026-05-19 — or whose lockfile pinned one of those versions — is exposed. This includes ephemeral CI runners that ran a single `pip install` step. The import-time trigger means hosts that resolved to one of those versions and then never imported the package are at lower risk, but Azure Functions Python runtimes import the SDK at function-app startup, so any Functions deployment that pulled an affected version is at maximum exposure.

## Detection Surface

Durable behavioral indicators (preferred over framework artifacts, which now also fire on copycat forks of the leaked Shai-Hulud source):

- Writes to `~/.claude/settings.json` and `.vscode/tasks.json` from non-interactive processes.
- Outbound DNS or HTTPS to `*.getsession.org` from server, CI, or container workloads.
- Python processes invoking `aws ssm send-command` or `kubectl exec` against peer instances within the same cloud account or cluster.
- IMDSv2 / Azure IMDS / GCE metadata enumeration from a Python process that just installed or imported `durabletask`.
- 2FA-bypassing token-harvest patterns (large-scale enumeration of `~/.aws/credentials`, `~/.azure`, `~/.config/gcloud`, Vault token files, 1Password / Bitwarden CLI session tokens within a short time window from a single process).


## MITRE ATT&CK

- T1195 Supply Chain Compromise
- T1195.002 Compromise Software Supply Chain
- T1078.004 Valid Accounts: Cloud Accounts
- T1059.006 Command and Scripting Interpreter: Python
- T1204.002 User Execution: Malicious File
- T1546 Event Triggered Execution
- T1574 Hijack Execution Flow
- T1027 Obfuscated Files or Information
- T1036.005 Match Legitimate Resource Name or Location
- T1070.004 Indicator Removal: File Deletion
- T1552.001 Unsecured Credentials: Credentials In Files
- T1552.005 Unsecured Credentials: Cloud Instance Metadata API
- T1555 Credentials from Password Stores
- T1528 Steal Application Access Token
- T1539 Steal Web Session Cookie
- T1580 Cloud Infrastructure Discovery
- T1082 System Information Discovery
- T1613 Container and Resource Discovery
- T1021.007 Remote Services: Cloud Services
- T1609 Container Administration Command
- T1005 Data from Local System
- T1530 Data from Cloud Storage
- T1071.001 Application Layer Protocol: Web Protocols
- T1573.001 Encrypted Channel: Symmetric Cryptography
- T1105 Ingress Tool Transfer
- T1567 Exfiltration Over Web Service
- T1048 Exfiltration Over Alternative Protocol
- T1485 Data Destruction
- T1561 Disk Wipe
- T1586 Compromise Accounts
- T1587.001 Develop Capabilities: Malware

## Sources

- [SANS ISC — TeamPCP Supply Chain Campaign: Activity Through 2026-05-24 (Kenneth Hartman)](https://isc.sans.edu/diary/33016)
- [Wiz — durabletask TeamPCP supply chain attack analysis](https://www.wiz.io/blog/durabletask-teampcp-supply-chain-attack)
- [Aikido — durabletask package compromised (Mini Shai-Hulud)](https://www.aikido.dev/blog/durabletask-package-compromised-mini-shai-hulud)
- [Endor Labs — Trojanized Microsoft SDK durabletask 1.4.1–1.4.3 delivers credential-stealing malware](https://www.endorlabs.com/learn/trojanized-microsoft-sdk-durabletask-1-4-1-through-1-4-3-deliver-credential-stealing-malware)
- [iTnews — Mini Shai-Hulud worm injects disk wiper into Microsoft Azure PyPI package](https://www.itnews.com.au/news/mini-shai-hulud-worm-injects-disk-wiper-into-microsoft-azure-pypi-package-625988)
- [PyPI — durabletask project page](https://pypi.org/project/durabletask/)
- [BleepingComputer — GitHub links repo breach to TanStack npm supply-chain attack (OIDC chain context)](https://www.bleepingcomputer.com/news/security/github-links-repo-breach-to-tanstack-npm-supply-chain-attack/)
- [Help Net Security — GitHub/Grafana breach root cause: Nx Console (TeamPCP context)](https://www.helpnetsecurity.com/2026/05/21/github-grafana-breach-root-cause-nx-console/)
- [Datadog Security Labs — Shai-Hulud open-source framework static analysis](https://securitylabs.datadoghq.com/articles/shai-hulud-open-source-framework-static-analysis/)
- [ReversingLabs — The Shai-Hulud code drop](https://www.reversinglabs.com/blog/the-shai-hulud-code-drop)
- [OX Security — New actors deploy Shai-Hulud clones (TeamPCP copycats)](https://www.ox.security/blog/new-actors-deploy-shai-hulud-clones-teampcp-copycats-are-here/)
- [Snyk — Mini Shai-Hulud @antv npm supply chain attack (context for @antv wave on same day)](https://snyk.io/blog/mini-shai-hulud-antv-npm-supply-chain-attack/)
- [StepSecurity — Shai-Hulud here we go again: mass npm supply chain attack hits the @antv ecosystem](https://www.stepsecurity.io/blog/shai-hulud-here-we-go-again-mass-npm-supply-chain-attack-hits-the-antv-ecosystem)
- [Socket — @antv packages compromised](https://socket.dev/blog/antv-packages-compromised)
- [The Hacker News — Mini Shai-Hulud pushes malicious @antv packages](https://thehackernews.com/2026/05/mini-shai-hulud-pushes-malicious-antv.html)

## Full data

Detection queries (Splunk SPL / Microsoft KQL / Sigma) and IOC values require the Threadlinqs MCP server (Purple tier): https://intel.threadlinqs.com/mcp

Canonical: https://intel.threadlinqs.com/threat/TL-2026-0580
