ブログ/記事一覧/「Pythonを起動するだけで感染」月間9500万DLのLiteLLMが乗っ取られた
litellm-pypi-supply-chain-attack-cover

「Pythonを起動するだけで感染」月間9500万DLのLiteLLMが乗っ取られた

PyPIで月間9500万回ダウンロードされるLiteLLMが攻撃者に乗っ取られた。.pthファイルによりPython起動時に自動実行されるcredential stealerが仕込まれ、SSH鍵やクラウド認証情報を窃取。攻撃の起点はセキュリティスキャナーTrivyだった。

ニュース
kkm-horikawa

kkm

Backend Engineer / AWS / Django

2026.03.256 min6 views

何が起きたのか

2026年3月24日、PythonのAI開発で広く使われるライブラリ「LiteLLM」のPyPIパッケージが攻撃者に乗っ取られた。LiteLLMは100種類以上のLLM APIを統一的に呼び出せるプロキシツールで、月間9500万回以上ダウンロードされている。クラウド環境の36%で使われているというWizの調査もある。

攻撃者「TeamPCP」は、LiteLLMのメンテナーのPyPIアカウントを乗っ取り、正規のアカウントからマルウェアを仕込んだバージョン1.82.7と1.82.8を公開した。パッケージはPyPIに約3時間公開された後、隔離措置が取られた。

何が盗まれるのか

仕込まれたマルウェアはcredential stealer(認証情報窃取ツール)で、インストールされたマシンから以下を根こそぎ収集する。

対象具体例
SSH鍵~/.ssh/ 配下の秘密鍵・公開鍵
クラウド認証情報AWS、GCP、AzureのIMDS経由の認証情報・設定ファイル
Kubernetesシークレットサービスアカウントトークン、クラスタ全ネームスペースのSecret
環境変数・.envファイルAPIキー、データベースパスワード、CI/CDトークン
暗号ウォレットウォレットディレクトリの秘密鍵
シェル履歴.bash_history.zsh_history
SSL秘密鍵サーバー証明書の秘密鍵

収集したデータはAES-256-CBCで暗号化し、ハードコードされた4096ビットRSA公開鍵でセッション鍵を保護した上で、攻撃者が管理するドメイン models.litellm.cloud にPOST送信される。このドメインは攻撃当日の3月24日にNamecheapで取得されたものだ。

「importしなくても動く」という衝撃

今回の攻撃で最も危険なのは、バージョン1.82.8で採用された .pth ファイルという手法だ。

通常のPyPIマルウェアは、パッケージをimportしたとき、あるいは setup.py のインストールフック経由で実行される。しかし .pth ファイルはPythonの起動メカニズムそのものに組み込まれている。Pythonインタープリタが起動するたびに site.pysite-packages 内の .pth ファイルを走査し、import で始まる行をPython文として実行する。

つまり、import litellm を書いていなくても、pytest を実行しても、django の開発サーバーを起動しても、flask アプリを動かしても、同じvenv内であればPythonプロセスが起動するたびにマルウェアが発火する。

攻撃者が仕込んだ litellm_init.pth の中身は、二重base64エンコードされたペイロードを subprocess.Popen で子プロセスとして起動する1行だった。

バージョン1.82.7は proxy_server.py にペイロードを埋め込む手法で、litellm --proxy コマンドの実行やモジュールのimport時に発動する。1.82.8は.pthファイルでの自動実行に「進化」しており、13分の間隔で両バージョンが公開された。

攻撃チェーン、セキュリティツールが入口になった

攻撃の起点は、LiteLLM自体ではなくセキュリティスキャナー「Trivy」だった。

3月19日、攻撃者はTrivy GitHub Actionsリポジトリの trivy-action のGitタグを書き換え、悪意あるリリースv0.69.4を指すようにした。LiteLLMはCI/CDパイプラインでTrivyをバージョンピンなしで使用していたため、ビルド時に改ざんされたTrivyが実行され、PyPIの公開用トークン(PYPI_PUBLISH)が攻撃者に流出した。

攻撃者はこのトークンを使い、GitHubにタグもリリースも作らずPyPIに直接パッケージをアップロードした。正規のメンテナーアカウントからの公開であるため、PyPIの通常のセキュリティチェックでは検出できない。

日時出来事
3月1日Aqua Security(Trivyメンテナー)が初期侵害を受ける
3月19日trivy-actionのGitタグが悪意あるリリースに書き換えられる
3月23日攻撃者がexfilドメイン litellm.cloud を登録
3月24日 08:30 UTC悪意あるv1.82.7、続いてv1.82.8がPyPIに公開
3月24日 11:25 UTCPyPIがlitellmパッケージ全体を隔離
3月24日 20:15 UTC侵害バージョンがyanked、隔離解除

Kubernetesクラスタへの横展開

マルウェアの被害はローカルマシンにとどまらない。Kubernetesのサービスアカウントトークンを検出すると、クラスタ内の全ネームスペースのSecretを読み取り、さらに全ノードに node-setup-{ノード名} という名前の特権Podをデプロイする。

このPodは alpine:latest イメージで起動し、ホストのファイルシステムをマウントした上で chroot でホストに入り込む。そこに ~/.config/sysmon/sysmon.py というバックドアをsystemdユーザーサービスとしてインストールする。このサービスは checkmarx.zone/raw に50分ごとにアクセスし、次段階のペイロードを取得する。

開発者のローカルマシンが感染しただけで、本番のKubernetesクラスタ全体が乗っ取られる可能性がある。

現在の状況と対処法

PyPIは侵害バージョンをyanked(削除)し、LiteLLMチームはGoogleのMandiantセキュリティチームと協力して調査を進めている。新しいメンテナーアカウントへの移行も完了した。Dockerイメージ経由でLiteLLMを使用しているユーザーは、依存関係がピン留めされているため影響を受けていない。

3月24日以降にlitellmをインストールまたはアップグレードしたシステムは、以下の確認が必要だ。

確認項目コマンド
バージョン確認pip show litellm | grep Version
.pthファイルの存在確認find $(python3 -c "import site; print(site.getsitepackages()[0])") -name "litellm_init.pth"
バックドアの存在確認ls -la ~/.config/sysmon/sysmon.py
systemdサービスの確認systemctl --user status sysmon.service
K8s不正Podの確認kubectl get pods -n kube-system | grep node-setup

該当バージョンがインストールされていた場合は、パッケージの削除に加え、SSH鍵、クラウド認証情報、APIキー、Kubernetesトークンなど、マシン上に存在したすべての認証情報のローテーションが必要になる。

参照元