Durabletask Supply-Chain Attacks Hit PyPI Package and Azure GitHub Repository

Summary
Microsoft confirmed malicious durabletask PyPI versions 1.4.1–1.4.3 were uploaded and yanked; analysis traced a credential-stealing cloud framework. The article also reports a June 5 Azure/durabletask commit that added malware triggered by AI coding tools and VS Code.
Key points
- Microsoft confirmed that durabletask versions 1.4.1, 1.4.2, and 1.4.3 were uploaded directly to PyPI without matching Git tags or CI runs, then yanked.
- The compromised package’s import-time Linux dropper downloaded rope.pyz from check.git-service[.]com; Step Security observed the payload execute during runtime analysis.
- The framework collected credentials and secrets from cloud providers, Kubernetes, developer tools, filesystems, password managers, and HashiCorp Vault.
- The payload encrypted collected data for exfiltration, including through attacker-controlled infrastructure and public repositories created with stolen GitHub tokens; it could also propagate through AWS SSM and Kubernetes.
- The analysis describes a geography-dependent destructive wiper and, otherwise, persistence through a fake systemd service.
- The article reports that a June 5 commit to Azure/durabletask added triggers for Claude Code, Gemini CLI, Cursor, and VS Code; GitHub blocked the repository.
- The article links the activity to TeamPCP/Mini Shai-Hulud based on shared infrastructure and other indicators. It advises affected users to isolate systems, rotate credentials, investigate for payload artifacts, and review cloud resources.
Article Details
- Attack Vectors
- An attacker used compromised publishing credentials to upload durabletask versions 1.4.1, 1.4.2, and 1.4.3 directly to PyPI, bypassing the GitHub release workflow.
- Importing the affected package on Linux downloads and launches rope.pyz as a detached process; the payload collects credentials and cloud secrets, establishes persistence, and supports lateral movement.
- A June 5 malicious commit to Azure/durabletask added files that trigger a credential-harvesting payload when the repository is opened in VS Code or specified AI coding tools.
- The payload can propagate through AWS SSM and Kubernetes pod execution, and can exfiltrate stolen data to C2 infrastructure or public GitHub repositories created with stolen tokens.
- Defensive Notes
- Treat systems that installed durabletask 1.4.1, 1.4.2, or 1.4.3 as compromised; isolate them, investigate persistence and payload artifacts, rotate accessible credentials, and audit cloud resources and other pods or instances.
- For systems that opened the compromised repository after the June 5 commit, treat the system as compromised and rotate credentials.
- Pin durabletask to 1.4.0 and verify package hashes; use PyPI Trusted Publishing (OIDC) instead of long-lived publishing tokens.
- Restrict outbound network access from CI/CD runners and production workloads, and monitor for releases that lack matching GitHub tags.
- The article reports that Harden-Runner's default global block list would block the outbound call to check.git-service.com.
Indicators of compromise
| Type | Indicator | Context |
|---|---|---|
| DOMAIN | check[.]git-service[.]com | Primary attacker-controlled C2 domain and payload host. |
| DOMAIN | t[.]m-kosche[.]com | Secondary C2 domain identified in the article as TeamPCP infrastructure. |
| IPV4 | 160[.]119[.]64[.]3 | IP address identified as the C2 server for the attack. |
| SHA256 | 069ac1dc7f7649b76bc72a11ac700f373804bfd81dab7e561157b703999f44ce | SHA-256 hash of rope.pyz, the credential-theft and lateral-movement payload. |
| SHA256 | 3de04fe2a76262743ed089efa7115f4508619838e77d60b9a1aab8b20d2cc8bf | SHA-256 hash of the compromised durabletask 1.4.1 source distribution. |
| SHA256 | 7d80b3ef74ad7992b93c31966962612e4e2ceb93e7727cdbd1d2a9af47d44ba8 | SHA-256 hash of the compromised durabletask 1.4.1 wheel. |
| SHA256 | 85f54c089d78ebfb101454ec934c767065a342a43c9ee1beac8430cdd3b2086f | SHA-256 hash of the compromised durabletask 1.4.2 source distribution. |
| SHA256 | 877ff2531a63393c4cb9c3c86908b62d9c4fc3db971bc231c48537faae6cb3ec | SHA-256 hash of the compromised durabletask 1.4.3 wheel. |
| SHA256 | aeaf583e20347bf850e2fabdcd6f4982996ba023f8c2cd56bbd299cfd56516f5 | SHA-256 hash of the compromised durabletask 1.4.2 wheel. |
| SHA256 | c0b094e46842260936d4b97ce63e4539b99a3eae48b736798c700217c52569dc | SHA-256 hash of the compromised durabletask 1.4.3 source distribution. |
| URL | hxxps[:]//check[.]git-service[.]com/api/public/version | Primary C2 exfiltration endpoint identified by the article. |
| URL | hxxps[:]//check[.]git-service[.]com/rope.pyz | Payload-download URL used by the malicious package dropper. |
MITRE ATT&CK
T1041 · Exfiltration Over C2 ChannelThe payload sends encrypted stolen data to the primary C2 endpoint using HTTPS POST.T1059.006 · PythonThe malicious package launches rope.pyz using python3, and the payload runs as a Python zipapp.T1059.007 · JavaScriptThe June 5 repository injection includes a JavaScript malware file, .github/setup.js, described as the actual malware.T1105 · Ingress Tool TransferThe package dropper downloads rope.pyz from the C2 server; propagation scripts also download the payload to other instances and pods.T1195.002 · Compromise Software Supply ChainCompromised durabletask releases were uploaded to PyPI, and a later malicious commit injected payload files into the Azure/durabletask repository.T1485 · Data DestructionOn systems matching the described geography checks and a specified random roll, roulette.py executes rm -rf /*.T1497.001 · System ChecksThe payload exits on systems with a Russian locale or two or fewer CPUs, checks described as avoiding analysis environments and sandboxes.T1528 · Steal Application Access TokenThe payload runs gh auth token and gh auth status --show-token to obtain GitHub tokens.T1543.002 · Systemd ServiceThe payload installs a fake pgsql-monitor.service through systemd for persistence across reboots.T1552.001 · Credentials In FilesThe filesystem collector reads credential files, shell histories, .env files, and configuration files containing secrets.T1552.005 · Cloud Instance Metadata APIThe cloud collectors retrieve credentials through EC2 and Azure instance metadata services.T1555.005 · Password ManagersThe password collector attempts to unlock 1Password, Bitwarden, pass, and gopass using harvested candidate passwords.T1567.001 · Exfiltration to Code RepositoryUsing stolen GitHub tokens, the payload creates public repositories and uploads encrypted stolen data bundles.T1609 · Container Administration CommandThe Kubernetes collector uses kubectl exec to run a script and propagate the payload into other pods.T1651 · Cloud Administration CommandThe propagation module uses AWS SSM SendCommand with AWS-RunShellScript to execute the payload on other managed instances.
Threat Actors
Malware
Miasma wormFor a detailed technical analysis, see our blog post: Miasma Worm Hits Microsoft Again: Azure Functions Action and 72 Other Repositories Disabled After Supply Chain Attack Targeting AI Coding Agents.rope.pyzThe 14 lines of injected Python code are just the tip of the iceberg. They serve as a dropper for rope.pyz, a modular cloud intrusion framework with 17 source files and dedicated collectors for every major cloud
Vendors
Amazon Web Servicesstolen tokens), installs persistence via fake systemd services, and propagates to other machines through AWS SSM and Kubernetes kubectl exec. For systems in specific geographies, it rolls the dice on a destructiveGCPGCP (collectors/gcp.py): Reads service account JSON key files, generates JWTs manually for authentication, and falls back to the metadata server. It then dumps all secrets from Secret Manager for the discovered project.GitHubUpdate - June 5, 2026: Azure/durabletask GitHub Repository Compromised AgainMicrosoftFor a detailed technical analysis, see our blog post: Miasma Worm Hits Microsoft Again: Azure Functions Action and 72 Other Repositories Disabled After Supply Chain Attack Targeting AI Coding Agents.Microsoft AzureUpdate - June 5, 2026: Azure/durabletask GitHub Repository Compromised Again
Products
Azure Durable FunctionsPython SDK was compromised on PyPI. The package, which serves as the official SDK for Azure Durable Functions and is downloaded over 400,000 times per month, had three malicious versions (1.4.1, 1.4.2, andClaude Code.claude/settings.json - triggers on Claude Code session startCursor.cursor/rules/setup.mdc - auto-applied Cursor AI rule that tricks the agent into running the payloadDurableTaskUpdate - June 5, 2026: Azure/durabletask GitHub Repository Compromised AgainGemini CLI.gemini/settings.json - triggers on Gemini CLI session startGitHubUpdate - June 5, 2026: Azure/durabletask GitHub Repository Compromised AgainGitHub ActionsWe installed the compromised durabletask package in a GitHub Actions workflow protected by Harden-Runner to observe the attack in real time. For this analysis, we disabled the StepSecurity Global block list so theKubernetesinstalls persistence via fake systemd services, and propagates to other machines through AWS SSM and Kubernetes kubectl exec. For systems in specific geographies, it rolls the dice on a destructive wiper thatPyPIwas pushed to the repository by the same contributor account whose credentials were used in the May 19 PyPI attack. The commit message ("Switched DataConverter to OrchestrationContext [skip ci]") is a decoy and noVS Code.vscode/tasks.json - triggers on VS Code folder open
Tools
gh│ ├─ gh auth token # GitHub token theftharden-runnerRuntime Analysis with Harden-Runnerkubectlpersistence via fake systemd services, and propagates to other machines through AWS SSM and Kubernetes kubectl exec. For systems in specific geographies, it rolls the dice on a destructive wiper that executes rm -rf
