💀

Python .pthファイルを利用したサプライチェーン攻撃 — LiteLLM事例分析

pip installだけで全システムが乗っ取られる攻撃チェーンの構造

LiteLLMはOpenAI、Anthropic、Google等を統合するPythonライブラリだ。月間9500万ダウンロード。2026年3月にサプライチェーン攻撃を受けた。

サプライチェーン攻撃とは

ソフトウェアを直接攻撃するのではなく、そのソフトウェアが依存するライブラリやビルドツールを攻撃する手法だ。npm、PyPI、RubyGemsのようなパッケージリポジトリに悪意あるコードを仕込めば、それをインストールする全ユーザーが感染する。

直接攻撃はファイアウォール・認証で防げる。サプライチェーン攻撃は「通常のパッケージ更新」に偽装するため、既存のセキュリティ体制を迂回する。開発者が毎日行うpip installが攻撃ベクターになる。

今回の攻撃経路

  1. まずTrivy(脆弱性スキャナー)v0.69.4〜v0.69.6が攻撃された
  2. CI/CDからPyPIクレデンシャルが流出
  3. 流出クレデンシャルでLiteLLMメンテナーアカウントを乗っ取り
  4. 悪意あるv1.82.7/v1.82.8をPyPIに直接アップロード

importなしでインストールだけでコードが実行される。

.pthファイルとは

Pythonのsite-packages/ディレクトリの.pthファイルはインタプリタ起動時に自動読み込みされる。本来はパッケージパス追加用だが、importで始まる行はそのまま実行される

pip install → wheel展開 → site-packagesに.pth設置 → Python起動時に自動実行。

4段階ペイロード

Stage 0 — .pthがsubprocess生成
Stage 1 — RSA-4096公開鍵 + AES-256-CBC暗号化ルーチンロード
Stage 2 — 25箇所以上からクレデンシャル収集:SSHキー、AWS/GCP/Azureトークン、K8sサービスアカウントトークン、11種以上暗号通貨ウォレット、シェルヒストリー
Stage 3 — C2サーバーに50分間隔ポーリング、任意バイナリ実行可能

Kubernetesクラスター掌握

tolerations operator: Exists + privileged: trueで全ノードに特権Pod生成。ホストFSを/hostにマウントして永続バックドア設置。

影響範囲

19,262依存リポジトリ — OpenHands、DSPy(Stanford NLP)、Databricks AI含む。

実際の対応 — Trivyユーザーとして

筆者はCI/CDでtrivy-actionを使っていた。乗っ取りが発生した3/19〜3/20に実際にワークフローが実行されていた。

幸い、trivy-actionをバージョンタグではなくfull-length commit SHAで固定していた。v0.28.0時点のSHAを直接指定していたため、乗っ取られたv0.69.4〜v0.69.6に自動更新されなかった。

確認手順として3/19〜3/20期間のGitHub Actionsログを全てダウンロードし、乗っ取られたバージョンが実行されていないことを検証した。仮に乗っ取られていたとしても、該当ワークフローのenv/secretsに危険なキー(AWSクレデンシャル、PyPIトークン等)が設定されていなかったため被害はなかったはずだ。

GitHub Actionsを使っているなら必ずやっておくこと

Repository Settings → Actions → General → Actions permissions → "Require actions to be pinned to a full-length commit SHA"をチェックしておくと、SHAで固定されていないactionを使用した時にワークフローがエラーで実行拒否される。

# ❌ タグ指定 — タグは誰でも上書き可能
uses: aquasecurity/trivy-action@v0.28.0

# ✅ SHA固定 — この特定コミットのコードのみ実行
uses: aquasecurity/trivy-action@a23fa65c5ff3e8d0c5f578c4b2a2b69e3b03be3b

タグは上書きできる。SHAは変えられない。この差が今回の事件で明暗を分けた。

既存ワークフローのactionを一括SHA固定するにはpinactというOSSが便利だ。pinact run.github/workflows/内の全タグをSHAに自動変換してくれる。

動作フロー

1

Trivy攻撃 → CI/CDからPyPIクレデンシャル流出

2

流出クレデンシャルでLiteLLMメンテナーアカウント乗っ取り

3

.pthファイル含む悪意あるバージョンをPyPIにアップロード

4

pip installで.pthがsite-packagesに設置 → Python起動時自動実行

5

4段階ペイロード:subprocess→暗号化→クレデンシャル収集(25箇所+)→C2ポーリング

ユースケース

AI/ML開発環境 — LLM統合ライブラリの依存性チェーン CI/CDパイプライン — ビルド環境でのクレデンシャル保護 Kubernetesクラスター — Pod Security Standardsで特権Pod遮断