Skip to main content

汚染されたセキュリティスキャナーがLiteLLMへのバックドア設置の鍵となった経緯

illustration hero ai

2026年3月24日

0 分で読めます

2026年3月24日、PyPI上のlitellm Pythonパッケージの2つのバージョンに、悪意のあるコードが含まれていることが判明しました。これらのパッケージ(バージョン1.82.7および1.82.8)は、LiteLLMのCI/CDパイプラインで使用されているオープンソースのセキュリティスキャナーTrivyが以前に侵害されたことを利用し、メンテナーのPyPI認証情報を入手したTeamPCPという脅威アクターによって公開されました。

悪意のあるバージョンは、PyPIがパッケージを隔離するまで約3時間公開されていました。LiteLLMは1日に約340万回ダウンロードされています。

Snykはこのインシデントを追跡しています。Snykをご利用のお客様には、アプリ内バナーによるアラートがすでに表示され、メール通知も届いている可能性があります。脆弱性レコードはSNYK-PYTHON-LITELLM-15762713、ステータスの更新情報はSnyk Trust Centerでご確認いただけます。

要約

影響を受けるパッケージ

litellm(PyPI)

影響を受けるバージョン

1.82.7、1.82.8

安全なバージョン

≤ 1.82.6

Snyk ID

初回検出

2026年3月24日 10:39 UTC(1.82.7のアップロード)

PyPIでの隔離

\~2026年3月24日 13:38 UTC

攻撃者

TeamPCP(別名:PCPcat、Persy_PCP、ShellForce、DeadCatx3)

攻撃経路

サプライチェーン:LiteLLMのCI/CDにおける、汚染されたTrivy GitHub Actionを介したPyPI公開者認証情報の侵害

ペイロードの種類

3段階:認証情報窃取+暗号化された情報流出+永続的なバックドア+Kubernetesワーム

情報流出先ドメイン

models.litellm.cloud(2026年3月23日登録)

MITRE ATT\&CK

T1546.018(Python起動フック)、T1003(認証情報のダンプ)、T1610(コンテナのデプロイ)

主な出来事

時刻(UTC)

証拠

出来事

2026年2月下旬

MegaGame10418によるTrivy CIへのPwn Request攻撃。pull_request_targetワークフローを悪用し、aqua-botの認証情報を窃取

3月19日 17:43 UTC

Trivy v0.69.4 GitHub Actionのタグが書き換えられ、悪意のあるリリースを指すように変更

3月23日 12:58 UTC

Endor Labs(削除前のPyPIメタデータを取得)

Checkmarx KICS GitHub Actionが侵害される。C2ドメインcheckmarx.zoneとmodels.litellm.cloudが登録される

3月24日 10:39 UTC

Endor Labs(削除前のPyPIメタデータを取得)

悪意のあるlitellm 1.82.7がPyPIに公開される

3月24日 10:52 UTC

悪意のあるlitellm 1.82.8がPyPIに公開される(1.82.7の13分後。強化された.pth配信方式を採用)

3月24日 11:48 UTC

FutureSearch(Callum McMahon)が開示に関するissueを作成

3月24日 12:36 UTC

HNにスレッドが投稿され、324ポイントを獲得

3月24日 \~12:44 UTC

GitHub issue #24512(コメントのタイムスタンプで確認)

ボットによるコメントがissue #24512に殺到。侵害されたメンテナーアカウントを使ってissueがクローズされる

3月24日 13:03 UTC

FutureSearch(タイムスタンプ付きの更新)

FutureSearchがissueのクローズとボットによるスパムを確認

3月24日 13:48 UTC

新たにクリーンな追跡用issueが作成される

3月24日 15:09 UTC

LiteLLMのメンテナーが、GitHub、Docker、PyPIのすべてのキーをローテーションし、メンテナーアカウントを新しいIDに移行したと確認

3月24日 15:27 UTC

侵害されたバージョンが削除され、PyPIでのパッケージの隔離が解除される

発見の経緯

FutureSearchのCallum McMahonは、litellmを推移的依存関係として取り込むCursor MCPプラグインをテストしていました。Pythonの起動直後、RAMが枯渇してマシンが応答しなくなりました。原因を新たにインストールしたlitellmパッケージと特定し、litellm_init.pthを発見しました。これはsite-packages/内にある34,628バイトのファイルで、base64で二重にエンコードされていました。

RAMの枯渇はペイロードによる副作用であり、意図された機能ではありませんでした。.pthの仕組みはPythonインタープリターが起動するたびに実行されます。ペイロードは新しいPythonサブプロセスを生成し、そのプロセスでも.pthが実行されるため、意図しないフォーク爆弾が発生しました。McMahonが調査結果をfuturesearch.aiで公開すると、1時間以内にr/LocalLLaMA、r/Python、Hacker Newsへと情報が広まりました。

攻撃の流れ

LiteLLMへの攻撃は、その5日前にTrivyから始まりました。

3月19日:攻撃者はtrivy-action GitHub ActionリポジトリのGitタグを書き換え、後続の攻撃でも使用されたものと同じ認証情報窃取ペイロードと情報流出インフラを含む悪意のあるリリース(v0.69.4)を指すようにしました。(Trivy侵害の詳細は、SnykによるTrivy GitHub Actionsサプライチェーン侵害の解説をご覧ください。)

3月23日:同じインフラが、Checkmarx KICS(Keep Infrastructure as Code Secure)への別の攻撃にも使われました。この攻撃で、Checkmarxのセキュリティ企業を装ったC2ドメインcheckmarx.zoneが登録され、運用を開始しました。

3月24日:LiteLLMのCI/CDパイプラインはビルドプロセスの一環としてTrivyを実行し、バージョンを固定せずにaptから取得していました。侵害されたActionは、GitHub Actionsランナー環境からPYPI_PUBLISHトークンを流出させました。この認証情報を使い、攻撃者は10:39 UTCに1.82.7、10:52 UTCに1.82.8のlitellmを公開しました。どちらにも悪意のあるペイロードが含まれていました。

サプライチェーン侵害についてのLiteLLMメンテナーによるHacker Newsのコメント。CI/CDの脆弱性、Proxy Dockerへの影響が限定的であること、PyPIでの隔離状況について説明しています。

Hacker Newsに投稿されたLiteLLMメンテナーの初回対応。

2つの配信方式

2つの悪意のあるバージョンでは、それぞれ異なるコード注入手法が使われていました。

1.82.7(ソースコードへの注入):ペイロードはBase64でエンコードされ、litellm/proxy/proxy_server.pyに直接埋め込まれていました。LiteLLMのプロキシサーバーモードで標準的なインポートパスである何かがlitellm.proxyをインポートすると実行されます。

1.82.8(.pthファイル):このバージョンでは、litellm_init.pthがsite-packages/に追加されました。.pthの仕組みはインポートなしでPythonインタープリターの起動時に毎回実行されます。pip、python -c、IDEの言語サーバーがPythonを起動する場合も同様です。

.pthファイルはwheelのRECORDファイルに正しく記載されているため、pipのハッシュ検証を通過します。悪意のあるコンテンツは事後に注入されたのではなく、正規の認証情報を使って公開されているため、パッケージは標準的な完全性チェックをすべて通過します。この種の攻撃の仕組みについて詳しくは、Snyk Learnの正規パッケージの侵害をご覧ください。

CPythonのメンテナーは、issue #113659で.pth起動フックのセキュリティリスクを認めていますが、修正パッチは適用されていません。この手法はMITRE ATT\&CKのT1546.018(Python起動フック)に該当します。

3段階のペイロード

ステージ1:情報収集

スクリプトは以下の情報を収集します。

  • システムデータ:ホスト名、環境変数、実行中のプロセス、ネットワークルーティング、/var/log/auth.logにある最近の認証ログ

  • 認証情報:SSH秘密鍵、.envファイル、Git認証情報、シェル履歴にあるAPIキー、SlackとDiscordのWebhookトークン、CI/CD設定(Jenkins、Travis CI、Terraform)、/etc/shadowにあるパスワードハッシュ

  • クラウド認証情報:AWS認証情報と設定、GCPおよびAzureのサービスアカウントファイル、IMDSへの直接クエリを介したクラウドメタデータ、AWS Secrets Manager、SSM Parameter Store(スクリプトにはIMDSv2の署名処理が完全に実装されています)

  • コンテナとオーケストレーション:Dockerのconfig.json(レジストリ認証情報)、Kubernetesのkubeconfigファイル、サービスアカウントトークン、シークレット、証明書

  • 暗号資産:Bitcoin、Ethereum、Solana、Cardano、Moneroのウォレットファイルとシードフレーズ、Ledgerハードウェアウォレットの設定

画像 image2

復号した悪意のあるコードの一部。複数のディレクトリを順に調べ、シークレットを収集する様子

ステージ2:暗号化と情報流出

収集したデータは送信前に暗号化されます。

  1. openssl randを使って32バイトのAES-256セッションキーを生成

  2. データをAES-256-CBC(PBKDF2鍵導出)で暗号化

  3. ハードコードされた4096ビットRSA公開鍵でセッションキーを暗号化(OAEPパディング)

  4. すべてをtpcp.tar.gzにまとめる

  5. curlを使ってバンドルをhttps://models.litellm.cloud/にPOST送信

models.litellm.cloudは正規のlitellm.aiドメインとは別のもので、悪意のあるパッケージが公開される1日前の3月23日に登録されました。

このペイロード内のRSA公開鍵は、TrivyとKICSのペイロードで見つかったものと同一です。Wizの研究者が3つの攻撃すべてで一致を確認しており、技術面での帰属を示す最も強力な単一の証拠となっています。

情報流出時に作成される一時ファイル:システムの一時ディレクトリ内のsession.key、payload.enc、session.key.enc、tpcp.tar.gz。

画像 3

悪意のあるコードを無害化して表示。tpcp.tar.gzというアーカイブ名は、Trivy、KICS、LiteLLMの各攻撃に共通する識別指標です。

ステージ3:永続化とラテラルムーブメント

ローカルでの永続化:

  • バックドアとなるPythonスクリプトを~/.config/sysmon/sysmon.py(または/root/.config/sysmon/sysmon.py)に書き込む

  • 説明に「System Telemetry Service」と記載したsystemdユーザーサービスを~/.config/systemd/user/sysmon.serviceに作成

  • 登録して有効化:systemctl --user daemon-reload && systemctl --user enable --now sysmon.service

永続化スクリプトは5分ごとにhttps://checkmarx.zone/rawをポーリングしてURLを取得し、ファイルを/tmp/pglogにダウンロードして実行可能にし、バックグラウンドプロセスとして実行します。状態は/tmp/.pg_stateで追跡されます。分析時点ではエンドポイントはYouTubeのURLを返していましたが、攻撃者はいつでも実際のペイロード配信に切り替えられます。

Kubernetesでのラテラルムーブメント:標準のマウントパスにKubernetesサービスアカウントトークンが見つかると、スクリプトはすべての名前空間にあるすべてのシークレットを読み取ります。次に、kube-system内のすべてのノードにalpine:latestを使った特権ポッドのデプロイを試みます。これらのポッドはホストのファイルシステムをマウントし、基盤となるノードにsysmonバックドアをインストールします。

悪意のあるポッドの名前はnode-setup-{node_name}(ノード名は35文字に切り詰め)で、コンテナ名はsetupです。

TeamPCPについて

Wiz Threat Centerによると、TeamPCP(PCPcat、Persy_PCP、ShellForce、DeadCatx3とも確認されています)は、少なくとも2025年12月から活動しています。攻撃者はTelegramチャンネル@Persy_PCPと@teampcpを運営し、ペイロードに「TeamPCP Cloud stealer」という文字列を埋め込んでいます。Wizはキャンペーン全体を追跡しています(Wiz Threat Center、Wizのブログ、ramimac.me)。

LiteLLMへの侵害は、進行中のキャンペーンのフェーズ09にあたります。すべての攻撃で共通するインフラは、同じRSA鍵ペア、同じtpcp.tar.gzというバンドル名、デッドドロップ型C2のステージングに使われたtpcp-docsで始まるGitHubリポジトリです。この攻撃で使われた3つのドメインはいずれも、同じレジストラ(Spaceship, Inc.)とホスティングプロバイダー(DEMENIN B.V.)を利用しています。

攻撃者は、Internet Computer Protocol(ICP)をC2チャネルとして使うCanisterWormも展開しています。ICPキャニスターは、ドメインレジストラやホスティングプロバイダーによって停止されることがありません。Aikidoのセキュリティ研究者は、サプライチェーンキャンペーンでICPがC2の仕組みとして使われた初の確認事例として報告しています。

hackerbot-clawというコンポーネントは、AIエージェント(openclaw)を使って攻撃対象の選定を自動化します。Aikidoの研究者は、サプライチェーン攻撃でAIエージェントが実運用された初期の事例の一つとして報告しています。

issueの投稿抑制

コミュニティメンバーがGitHub issue #24512で侵害を報告し始めると、攻撃者は102秒間(12:44〜12:46 UTC)に73個のアカウントから88件のボットコメントを投稿しました。使用されたのは、攻撃用に新たに作成されたプロフィールではなく、以前に侵害された開発者アカウントでした。Rami McCarthyの分析によると、アカウントの76%がTrivyの情報公開時に使われたボットネットと重複していました。

侵害したメンテナーアカウントkrrishdholakiaを使い、攻撃者はissue #24512を「not planned」としてクローズし、無関係なリポジトリに「teampcp update」というメッセージでコミットしました。

コミュニティは並行して追跡用のissue(#24518)を立ち上げ、Hacker Newsでも議論を続けました。このスレッドは324ポイントを獲得しました。

確認された影響

影響を受けるバージョンは、約3時間PyPIで公開されていました。以下のプロジェクトは3月24日、1.82.7と1.82.8を除外するためのセキュリティPRまたはissueを提出しました。

プロジェクト

証拠

DSPy

PR #9498がマージ済み、CI失敗レポート

MLflow

PR #21971がマージ済み

OpenHands

CrewAI

PR #5040(litellmとの依存関係を分離)、PR #5039

langwatch

strands-agents/sdk-python

Arize Phoenix

nanobot

dreadnode/rigging

CoPaw

Aider

安全を確認済み(litellm==1.82.3に固定)

.pthの仕組みはpip自体を含む、Pythonプロセスの起動時に実行されます。CI/CD環境では、アプリケーションの実行時だけでなく、ビルド工程中にもペイロードが実行される可能性があります。

検出:影響を受けているか確認する

ステップ1:インストール済みバージョンを確認する

pip show litellm | grep Version

出力に1.82.7または1.82.8が表示された場合、システムが侵害されたものとして扱い、以下の修復手順に従ってください。単にアップグレードするだけでは不十分です。ペイロードがすでに実行されている可能性があります。

ステップ2:永続化の痕跡を確認する

# Check for the sysmon backdoor
ls -la ~/.config/sysmon/sysmon.py 2>/dev/null && echo "BACKDOOR FOUND"
ls -la /root/.config/sysmon/sysmon.py 2>/dev/null && echo "ROOT BACKDOOR FOUND"

# Check for the systemd persistence service
systemctl --user status sysmon.service 2>/dev/null
ls -la ~/.config/systemd/user/sysmon.service 2>/dev/null && echo "PERSISTENCE SERVICE FOUND"

# Check for exfiltration archive remnants
ls /tmp/tpcp.tar.gz /tmp/session.key /tmp/payload.enc /tmp/session.key.enc 2>/dev/null && echo "EXFIL ARTIFACTS FOUND"

ステップ3:悪意のある.pthファイルを確認する

# Find .pth files in site-packages with suspicious patterns
find $(python3 -c "import site; print(' '.join(site.getsitepackages()))") \
  -name "*.pth" -exec grep -l "base64\|subprocess\|exec" {} \;

ステップ4:ファイルのハッシュを検証する

# Check proxy_server.py (1.82.7)
find / -path "*/litellm/proxy/proxy_server.py" 2>/dev/null -exec shasum -a 256 {} \;
# Malicious: a0d229be8efcb2f9135e2ad55ba275b76ddcfeb55fa4370e0a522a5bdee0120b

# Check litellm_init.pth (1.82.8)
find / -name "litellm_init.pth" 2>/dev/null -exec shasum -a 256 {} \;
# Malicious: 71e35aef03099cd1f2d6446734273025a163597de93912df321ef118bf135238

ステップ5:ネットワーク上の痕跡を確認する

grep "litellm.cloud\|checkmarx.zone" /etc/hosts
grep "models.litellm.cloud\|checkmarx.zone" /var/log/syslog 2>/dev/null

ステップ6:Kubernetesを確認する

kubectl get pods -A | grep "node-setup-"

Snykでスキャンする

snyk test --package-manager=pip
リポジトリのテスト率61%、休眠中のリポジトリ、重大な脆弱性を含む高リスクのClass Aリポジトリ一覧などの指標を表示するSnykのセキュリティダッシュボード。

影響を受けるリポジトリがアセットインベントリに表示された、Snykアプリ内のバナーアラート。Trust Centerへのリンクから、リアルタイムのインシデント状況を確認できます。

Snykをご利用のお客様は、litellmパッケージアドバイザーと、脆弱性の詳細レコードSNYK-PYTHON-LITELLM-15762713もご確認ください。

修復方法

1.82.7または1.82.8をインストールしていない場合:

安全なリリースが提供されるまで、<=1.82.6に固定してください。

pip install "litellm<=1.82.6"
# requirements.txt:
litellm<=1.82.6

1.82.7または1.82.8をインストールした場合:

ペイロードはpip install自体を含め、Pythonの起動時に実行されます。アプリケーションコードを実行したかどうかにかかわらず、システムが侵害された可能性があるものとして扱ってください。

  1. 永続化の痕跡を削除する:

rm -f ~/.config/sysmon/sysmon.py
rm -f ~/.config/systemd/user/sysmon.service
systemctl --user disable sysmon.service 2>/dev/null
systemctl --user daemon-reload
rm -f /tmp/tpcp.tar.gz /tmp/session.key /tmp/payload.enc /tmp/session.key.enc /tmp/.pg_state /tmp/pglog
  1. 影響を受けたシステムの認証情報をローテーションする:

  • SSH秘密鍵:新しい鍵を生成し、authorized_keys、GitHub、GitLabから古い鍵を無効化する

  • クラウド認証情報:AWSアクセスキー、GCPサービスアカウントキー、Azureサービスプリンシパル

  • APIキー:.envファイル、シェル環境変数、CI/CDシークレット

  • Dockerレジストリ認証情報:~/.docker/config.json

  • Kubernetes:~/.kube/config、クラスター内のサービスアカウントトークン

  • システム上の設定ファイルに記載されたデータベースパスワード

  • ~/.gitconfigまたはシステムの認証情報ストアに保存されたGit認証情報

  • 暗号資産ウォレットのシードフレーズ

  1. AWS Secrets ManagerとSSM Parameter Storeを監査する。インスタンスメタデータにアクセスできる場合、ペイロードはこれらに直接クエリを実行します。

  1. Kubernetesクラスターのシークレットを監査する。サービスアカウントトークンが存在していた場合、すべての名前空間にあるシークレットが読み取られた可能性があります。kube-system内にnode-setup-*ポッドがないか確認してください。

  1. インプレースでアップグレードするのではなく、新しい環境にクリーンなバージョンをインストールする:

pip install "litellm<=1.82.6"

pipのハッシュ検証で検出できなかった理由

ハッシュ検証では、ファイルがPyPIで公開された内容と一致することを確認できますが、その内容が悪意のあるものかどうかは判断できません。

1.82.8のlitellm_init.pthファイルは、wheelのRECORDファイルに正しいハッシュとともに記載されています。pip install --require-hashesも通過します。悪意のあるコンテンツが正規の認証情報を使って公開されたため、このパッケージは標準的な完全性チェックをすべて通過します。ハッシュの不一致も、不審なドメインも、スペルミスのあるパッケージ名もありません。

インストール時に検出する唯一の方法は、パッケージが.pthファイルをインストールするかどうかと、そのファイルにsubprocess、base64、execなどのパターンが含まれているかを調べることです。現在、これを自動的に行う広く導入されたpipプラグインはありません。

より広範な傾向

このキャンペーンで標的となったのは、自動化されたパイプラインへの高いアクセス権限を持つツールです。コンテナスキャナー(Trivy)、インフラストラクチャスキャンツール(KICS)、AIモデルのルーティングライブラリ(LiteLLM)が該当します。これらのツールはいずれも、その設計上、動作対象のシステムにある認証情報、設定、環境変数などへの広範な読み取りアクセスを必要とします。

LiteLLMは、複数のモデルプロバイダーのAPI認証情報を保存する、集中型LLMゲートウェイとして導入されるケースが増えています。この構成では、1台の侵害されたホストからアクセスできる認証情報は、一般的なアプリケーションよりも広範囲に及びます。

最初の情報公開は、r/netsecやCVEフィードといった従来のセキュリティチャネルではなく、AI開発者コミュニティ(r/LocalLLaMA、r/Python、Hacker News)を通じて広まりました。

LLMツールに特有のサプライチェーンリスクについて詳しく知りたい方は、Snyk LearnのLLMにおけるサプライチェーンの脆弱性をご覧ください。2024年のUltralytics AI Pwn Requestサプライチェーン攻撃も参考になる比較事例です。CI/CDの悪用によって広く使われていた別のAI向けPythonライブラリが侵害され、類似した攻撃チェーンが用いられました。

侵害の痕跡

ファイルハッシュ:

ファイル

SHA-256

litellm_init.pth(1.82.8)

71e35aef03099cd1f2d6446734273025a163597de93912df321ef118bf135238

proxy_server.py(1.82.7)

a0d229be8efcb2f9135e2ad55ba275b76ddcfeb55fa4370e0a522a5bdee0120b

sysmon.py

6cf223aea68b0e8031ff68251e30b6017a0513fe152e235c26f248ba1e15c92a

ネットワーク:

  • 情報窃取:https://models.litellm.cloud/(POST)

  • C2ポーリング:https://checkmarx.zone/raw(GET)

ファイルシステム:

  • ~/.config/sysmon/sysmon.pyまたは/root/.config/sysmon/sysmon.py

  • ~/.config/systemd/user/sysmon.service(説明:「System Telemetry Service」)

  • /tmp/tpcp.tar.gz、/tmp/session.key、/tmp/payload.enc、/tmp/session.key.enc

  • /tmp/.pg_state、/tmp/pglog

Kubernetes:

  • ポッド:node-setup-{node_name}(kube-system内)

  • コンテナ名:setup、イメージ:alpine:latest

RSA公開鍵のプレフィックス(3つの操作すべてのペイロードにハードコード):

MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAvahaZDo8mucujrT15ry+...

今すぐ行うこと

  1. litellmのバージョンを確認する:pip show litellm | grep Version

  2. すべての環境で<=1.82.6に固定する

  3. snyk test --package-manager=pipを実行する

  4. 1.82.7または1.82.8をインストールしていた場合:認証情報をローテーションし、永続化の痕跡を確認する

  5. GitHub Actionsを含め、CI/CDパイプラインでツールのバージョンが固定されていないものがないか監査する

  6. Kubernetesを確認する:kubectl get pods -A | grep node-setup-

ホワイトペーパー

Python環境に潜むAIセキュリティの危機

開発スピードが急上昇する中、AI環境が何にアクセスできるか、本当に把握できていますか?

続きを読む

Blog

フロンティアモデルは脆弱性を発見した。攻撃者だけがエクスプロイトチェーンを見つけた。

静的解析で欠陥は見つかりましたが、ライブ攻撃テストで侵害につながる連鎖を実証できたのは唯一でした。Evo COS、Claude Security、Claude Code Securityを比較します。

feature insights context
Blog

自律型攻撃はすでに始まっている。防御もそのスピードに追いつかなければならない。

自律型攻撃者によって、防御に使える時間は短くなっています。継続的な検出、修復、検証、予防で、セキュリティチームが攻撃に歩調を合わせる方法をご紹介します。

Blog

AIコーディングエージェントが不適切なアクセス制御を繰り返し実装する理由

AIコーディングエージェントは、コンパイルが通りレビューも通過する一方で、あるテナントのデータを別のテナントに公開してしまう認可ロジックを生成することがあります。不適切なアクセス制御が検出しにくい理由と、その防止策をご紹介します。