TeamPCPがLiteLLM PyPIパッケージを汚染、50種以上の認証情報を窃取するマルウェアを埋め込む
2026年3月24日、LiteLLMのPyPIパッケージ1.82.7と1.82.8に悪意コードが埋め込まれ、約46分間公開された。発見のきっかけは、マルウェアの実装バグによるフォークボムだった。
この攻撃はTrivyのサプライチェーン攻撃を起点とするTeamPCPの多段階キャンペーン(一連の攻撃活動)の一部だ。Trivy経由のキャンペーン(trivy-canisterworm-npm-supply-chain-icp-c2)とOpenVSX拡張機能への侵害(glassworm-open-vsx-extension-dependencies-supply-chain)に続くフェーズ9にあたる。
攻撃の流れ
graph TD
A[Trivy CI/CDワークフロー脆弱性<br/>2026-02-27] -->|aqua-bot PAT窃取| B[汚染Trivyバイナリ<br/>v0.69.4 - 2026-03-19]
B -->|LiteLLMのCircleCIがaptで最新版取得| C[PYPI_PUBLISH_PASSWORD窃取<br/>2026-03-23]
C -->|krrishdholakiaアカウントでアップロード| D[litellm 1.82.7 - 2026-03-24T10:39 UTC]
D --> E[litellm 1.82.8 - 2026-03-24T10:52 UTC]
E -->|フォークボムで発覚| F[PyPI隔離 - 2026-03-24T11:25 UTC]
F --> G[PyPA アドバイザリ PYSEC-2026-2]
LiteLLMのCircleCIはTrivyをapt経由でバージョン固定なしにインストールしていた。汚染されたTrivy(v0.69.4以降)がCI実行時にすべてのシークレットを窃取し、TeamPCPはPyPIトークンを使ってパッケージを直接アップロードした。GitHubにはv1.82.7/v1.82.8に対応するタグが存在しない。
2バージョンの違い
| バージョン | トリガー | マルウェア配置先 | 送信先ドメイン |
|---|---|---|---|
| 1.82.7 | import litellm.proxy 時 | proxy_server.py埋め込み | checkmarx.zone/raw |
| 1.82.8 | Python起動時(import不要) | litellm_init.pth + proxy_server.py | models.litellm.cloud |
1.82.8が危険なのは.pthファイルを使っている点だ。Pythonはsite-packages/に置かれた.pthファイルをインタープリタ起動時に自動実行する。importはおろかパッケージを直接使わなくても、Python環境を起動するだけでマルウェアが走る。
litellm_init.pth(34,628バイト、SHA256: ceNa7wMJnNHy1kRnNCcwJaFjWX3pORLfMh7xGL8TUjg)の内容は以下のとおり。
import os, subprocess, sys; subprocess.Popen([sys.executable, "-c", "import base64; exec(base64.b64decode('...'))"])
ペイロード(悪意コード本体)はダブルbase64エンコードされている。
マルウェアの動作
情報収集
50種以上のパスから認証情報を収集する。
| カテゴリ | 収集対象 |
|---|---|
| システム | hostname、whoami、uname -a、ip addr |
| 環境変数 | printenv(全APIキー・シークレット・トークン) |
| SSH | ~/.ssh/id_rsa、id_ed25519、id_ecdsa、authorized_keys、known_hosts、config |
| Git | ~/.gitconfig、~/.git-credentials |
| AWS | ~/.aws/credentials、~/.aws/config、IMDS(インスタンスメタデータ)トークン+セキュリティクレデンシャル |
| Kubernetes | ~/.kube/config、/etc/kubernetes/admin.conf、サービスアカウントトークン |
| GCP | ~/.config/gcloud/application_default_credentials.json |
| Azure | ~/.azure/ |
| Docker | ~/.docker/config.json、/kaniko/.docker/config.json |
| シェル履歴 | ~/.bash_history、~/.zsh_history、.mysql_history |
| 暗号ウォレット | Bitcoin、Ethereum、Solanaなど9種 |
| CI/CD | terraform.tfvars、.gitlab-ci.yml、Jenkinsfile |
暗号化と窃取
- 収集データを一時ファイルに書き込み
openssl randで32バイトのAES-256セッションキーを生成openssl enc -aes-256-cbc -pbkdf2でデータを暗号化- ハードコードされた4096ビットRSA公開鍵(攻撃者所有)でセッションキーをRSA-OAEP暗号化
tpcp.tar.gzに梱包してcurl POSTで窃取
フォークボムで発覚
.pthファイルはPythonの子プロセスにも引き継がれる。subprocess.PopenでPythonを起動するマルウェアが子プロセスでも再び実行され、連鎖的にプロセスが増殖するフォークボムになった。
FutureSearch(AI研究会社)のCallum McMahonが、自分のMCPサーバーをuvxで自動更新した際にlitellm 1.82.8が取り込まれ、マシンがCPU 100%・約11,000プロセスで応答不能になった。Claude AIと協力して原因を特定し、PyPIセキュリティとLiteLLMメンテナに報告した。
1.82.7/1.82.8が公開されてから隔離されるまで約46分。
対応と緩和策
site-packages/にlitellm_init.pthが存在する場合は侵害確定。即座に確認が必要。
Dockerイメージ利用者はバージョンがピン固定されているため影響を受けない。
LiteLLM(BerriAI)は次のように対応した。
- 汚染バージョンをPyPIから削除
- 全メンテナアカウントを削除し新アカウントを作成
- GitHub・Docker・PyPIの全シークレットをローテーション
- TrivyのCIバージョンを安全な
v0.35.0にピン固定 - Google Mandiantと連携して調査中
侵害指標(IOC)
| 種別 | 値 |
|---|---|
| ファイル | litellm_init.pth(site-packagesに存在で侵害確定) |
| SHA256 | ceNa7wMJnNHy1kRnNCcwJaFjWX3pORLfMh7xGL8TUjg |
| 窃取先(1.82.8) | models.litellm.cloud(2026-03-23登録) |
| 窃取先(1.82.7) | checkmarx.zone/raw(IP: 83.142.209.11) |
| C2(指令サーバー)ドメイン | scan.aquasecurtiy.org(正規ドメインに似せた偽名)、IP: 45.148.10.212 |
| Telegram | @Persy_PCP、@teampcp |
PyPAが公式アドバイザリPYSEC-2026-2を出している。攻撃者TeamPCPはvxundergroundへのDMで54GBのデータ窃取を主張している。
CI/CDの教訓
この攻撃はLiteLLMのCIがTrivyをバージョン固定なしにインストールしていたことで成立した。
PyPI公開にはOIDCを使う。 静的PyPIトークンは長命で広スコープのため、一度窃取されると長期間悪用される。OIDC(OpenID Connect)ベースの一時トークンはCI実行ごとに発行・失効するため影響を局所化できる。
ツールチェーンをバージョン固定する。 外部ツール(Trivy、Docker Buildxなど)のバージョンをCIで固定し、予期しないアップグレードでシークレットが漏洩するリスクを排除する。