Skip to main content

Mini Shai-HuludがAntVを襲撃:メンテナーアカウントの侵害により300超の悪意あるnpmパッケージが公開

著者
blog feature supply chain sbom

2026年5月18日

0 分で読めます

@antvのデータ可視化エコシステムと関連するnpmパッケージを狙ったサプライチェーン攻撃が、npmレジストリを通じて現在も拡大しています。TeamPCPと呼ばれる脅威グループによる攻撃で、Mini Shai-Huludキャンペーンの新たな波とされる今回の攻撃では、2026年5月19日、22分間の自動化された公開により323パッケージで300を超える悪意あるバージョンが公開されました。これらのパッケージの週間ダウンロード数は合計で約1,600万件に上ります。

攻撃には、侵害されたnpmメンテナーアカウントが悪用されました。影響を受けたパッケージに埋め込まれたマルウェアは、開発者のシークレットやクラウド認証情報を窃取し、永続的なC2アクセスを確立したうえで、盗んだnpmトークンを使って他のパッケージへ自己拡散を試みます。

要約

攻撃の種類

サプライチェーン攻撃、メンテナーアカウントの侵害

脅威アクター

TeamPCP(別名:DeadCatx3、PCPcat)

キャンペーン

Mini Shai-Hulud(2025年9月から継続中)

インシデント発生日

2026年5月19日、01:39~02:06 UTC

侵害されたパッケージ

323パッケージにわたる637の悪意あるバージョン

推定週間ダウンロード数

約1,600万件

マルウェアの動作

認証情報の窃取、クラウドシークレットの収集、永続化、ワームによる拡散

Snykの対応状況

Snyk Vulnerability Databaseにアドバイザリを掲載。アプリ内でZero Day Reportを提供

直ちに行うべき対応

5月19日より前のバージョンに固定し、npm install --ignore-scriptsを実行して、すべての認証情報をローテーションする

影響を受けたパッケージ

侵害されたnpmアカウントatoolは547のパッケージを管理していました。悪意あるパッケージの公開は、2回の波に分かれて300を超えるパッケージに及びました。

  • 第1波:01:39~01:56 UTC(約317バージョン)

  • 第2波:02:05~02:06 UTC(約314バージョン)

影響を受けたパッケージのうち、ダウンロード数が特に多いものは次のとおりです。

パッケージ

Snyk Advisor

月間ダウンロード数

size-sensor

420万

echarts-for-react

380万

@antv/scale

220万

timeago.js

115万

@antv/g6

100万+

侵害された主要な@antvパッケージには、@antv/g2、@antv/g6、@antv/x6、@antv/l7、@antv/s2、@antv/f2、@antv/g、@antv/g2plot、@antv/graphin、@antv/data-setが含まれます。また、echarts-for-react、timeago.js、size-sensor、canvas-nest.jsなど、スコープのないパッケージも影響を受けました。

AntVはAlibaba発のデータ可視化スイートで、企業向けダッシュボード、財務報告ツール、グラフ分析プラットフォームなどで幅広く使われています。採用範囲の広さから、メンテナーアカウントが管理するパッケージ群は、攻撃者にとって非常に価値の高い標的となりました。

攻撃の仕組み

ステージ1:メンテナーアカウントの侵害

攻撃は、npmアカウントatoolの侵害から始まります。アカウントがどのように侵害されたのかは、現在も調査中です。アカウントを掌握した攻撃者は、管理する547のすべてのパッケージを公開できる状態にありました。

ステージ2:悪意あるパッケージの自動公開

攻撃者は2回に分けて短時間に悪意あるバージョンを公開し、ほとんどのパッケージを2回更新しました(一部の初期テスト用パッケージには3つのバージョンが公開されました)。悪意ある各パッケージのtarballには、次の2つが追加されています。

  • ルート階層のindex.js: 498KBの、高度に難読化されたBun用JavaScriptペイロード

  • package.jsonを変更し、次を追加:"preinstall": "bun run index.js"

preinstallライフサイクルフックは、開発者がnpm installを実行したときに自動的に起動し、他のインストール処理より先に実行されます。

ステージ3:Sigstoreの来歴情報を利用した孤立コミットの注入

今回の攻撃で特に巧妙な手法の1つは、正規のantvis/G2リポジトリにある孤立コミットを参照する、任意依存関係の注入です。

"optionalDependencies": {
  "@antv/setup": "github:antvis/G2#1916faa365f2788b6e193514872d51a242876569"
}

注目すべき点として、GitHubソースの依存関係を利用する手法は、以前のTanStack Shai-Huludサプライチェーン攻撃で使われたものと同じ攻撃手法です。

このコミットは攻撃者が作成したものですが、実在するメンテナーのhuiyu.zjt <huiyu.zjt@ant.com>によるものに偽装されていました。標的のリポジトリへの書き込み権限は必要ありません。攻撃者はantvis/G2をフォークし、ペイロードを含む孤立コミットを作成してからフォークを削除しました。GitHubのオブジェクトストレージには、ガベージコレクションが実行されるまで削除されたフォークのコミットが保持されるため、悪意あるコミットはハッシュ経由で引き続きアクセス可能な状態でした。

このコミットを取得すると、信頼できるリポジトリを参照しているように見せながら、Git経由で取得した認証情報を使ってペイロードを実行する経路が作られます。

盗んだGitHub ActionsのOIDCトークンを使い、マルウェアはFulcio(https://fulcio.sigstore.dev)から署名証明書を要求し、Rekor(https://rekor.sigstore.dev)経由でin-totoの来歴情報を作成できます。その結果、暗号学的に有効なSLSA Build Level 3の証明を持つパッケージが生成されます。

重要なのは、ビルドパイプライン自体が侵害されているため、署名そのものは正規のものだという点です。Sigstoreの来歴情報が示すのは、成果物を生成したパイプラインであり、そのパイプラインが意図どおりに動作したかどうかではありません。そのため、公開パッケージの証明情報だけに頼れば正当性を完全に確認できる、というのはよくある誤解です。

ステージ4:認証情報の収集

開発者のマシンやCIランナーでbun run index.jsが実行されると、ペイロードは80超の環境変数と100超のファイルパスを標的にします。標的となる認証情報の種類は次のとおりです。

  • AWS:アクセスキー(AKIA[0-9A-Z]{16})、セッショントークン、EC2 IMDS(169.254.169.254)、ECSメタデータ(169.254.170.2)、Secrets Manager

  • GCP:サービスアカウントJSON、アプリケーションのデフォルト認証情報

  • Azure:サービスプリンシパルの認証情報

  • GitHub:PATとOIDCトークン(gh[op]_[A-Za-z0-9]{36,})

  • npm:bypass_2faスコープの公開トークン

  • インフラストラクチャ:Kubernetesサービスのトークン、HashiCorp Vaultのトークン

  • データベース:MongoDB、MySQL、PostgreSQL、Redisの接続文字列

  • サービス:Stripeキー、Slackトークン、Docker認証設定

  • SSHキー:~/.ssh/id_*

GitHub Actions環境では、ペイロードは/proc/{pid}/mem経由でRunner.Workerプロセスのメモリからシークレットを直接読み取ろうとし、シークレットのマスキングを完全に回避します。

ステージ5:データの窃取

収集した認証情報はすべてJSONとしてシリアル化され、gzipで圧縮された後、AES-256-GCMで暗号化されます。さらに、その暗号化キーはハードコードされた攻撃者の公開鍵を使い、RSA-OAEPでラップされます。つまり、防御側が流出データを発見しても、何が盗まれたのか特定できません。

データは2つの経路で流出します。

  1. 主要C2:https://t[.]m-kosche[.]com:443/api/public/otel/v1/traces(OpenTelemetryのトレースデータを装う)

  2. GitHubの予備的な隠し場所:GitHubトークンが見つかると、ペイロードは被害者のアカウントにリポジトリを作成します。名前はDuneをモチーフにしたもので、sardaukar、fremen、atreidesなどの単語とsandworm、ornithopter、stillsuitなどの単語を組み合わせ、0~999の数字を付けます。READMEファイルには、過去のShai-Huludキャンペーンで使われた特徴的なフレーズを逆順にしたもの(例:「niagA oG eW ereH :duluH-iahS」)が含まれます。盗んだデータはresults/results-<timestamp>-<counter>.jsonとしてコミットされます。HTTPリクエストのUser-Agentには"python-requests/2.31.0"が使われます。

ステージ6:永続化

ペイロードは、単純なnpm uninstallでは消えない複数の永続化メカニズムをインストールします。

  • AIコーディングエージェントの乗っ取り:.claude/settings.jsonを作成し、SessionStartフックでnode .claude/setup.mjsを実行します。これにより、影響を受けたディレクトリで開発者が新しいClaude Codeセッションを開始するたびに、マルウェアが再実行されます。これは、TanStackなど過去のサプライチェーン攻撃キャンペーンでも見られた手法と似ています。

  • IDEフック:.vscode/tasks.jsonを変更し、"runOn": "folderOpen"を設定して、プロジェクトを開いたときに実行されるようにします。

  • OSレベルのデーモン:~/.local/share/kitty/cat.pyをインストールします。これは、firedalazerというキーワードを含むコマンドを探すため、GitHubのコミット検索APIを1時間ごとにポーリングするバックグラウンドデーモンです。コマンドはハードコードされた4096ビット公開鍵でRSA-PSS署名されているため、攻撃者は最初の感染後も長期間にわたり、侵害されたマシンで任意のPythonコードを実行させることができます。Linuxではsystemdユーザーサービス(~/.config/systemd/user/kitty-monitor.service)として、macOSではLaunchAgent(~/Library/LaunchAgents/com.user.kitty-monitor.plist)として登録されます。

トークン監視:~/.local/bin/gh-token-monitor.shが盗んだGitHubトークンを60秒間隔でポーリングし、トークンの有効期限が切れそうなときに攻撃者がすばやく対応できるようにします。

ステージ7:ワームによる拡散

ペイロードはbypass_2faスコープのnpmトークンを探し、それらを使って侵害されたアカウントから公開できる他のパッケージを再公開します。GitHub Actions環境では、ActionsのOIDCトークンを次の方法でパッケージごとのnpm公開トークンに交換します。

POST https://registry.npmjs.org/-/npm/v1/oidc/token/exchange/package/<package-name>

また、chore/add-codeql-static-analysisというブランチにGitHub Actionsワークフローを注入します。ワークフローファイル名は"Run Copilot"(.github/workflows/codeql.yml)です。このワークフローはtoJSON(secrets)をformat-results.txtというアーティファクトに出力した後、ワークフロー実行を削除して痕跡を自ら消します。

影響の分析

直接的な影響を受けるのは、2026年5月19日の01:39から約02:18 UTCの間に、影響を受けたバージョンのパッケージに対してnpm installを実行した開発者やCI環境です。

CI/CD環境は特にリスクが高い状態です。こうした環境では、ペイロードは環境変数として明示的に渡されたものだけでなく、ランナープロセス内のすべてのシークレットを読み取る可能性があります。影響を受けたバージョンがインストールされていた場合、OIDCトークン、リポジトリシークレット、そのリポジトリにスコープされた組織シークレットなど、GitHub Actionsランナーがアクセスできるすべてのシークレットが侵害されたと考えるべきです。

開発者のマシンも大きなリスクにさらされています。永続化メカニズムがあるため、影響を受けたパッケージを削除するだけでは脅威は取り除けません。.claude/settings.jsonのフック、VS Codeのタスク、システムデーモンは、明示的に削除するまで動作し続けます。

自己拡散機能があるため、開発者のマシンやCIランナーから窃取されたnpmトークンが、侵害されたatoolアカウントの管理範囲外にあるパッケージの汚染にも使われる可能性があります。これにより、AntVや関連パッケージを超えて影響範囲が拡大します。

検知方法

ロックファイルを確認する。package-lock.jsonまたはyarn.lockにatoolアカウントが管理するパッケージが記載されている場合、解決されたバージョンが2026年5月19日の01:39~02:18 UTCに公開されたものか確認してください。

Snykでプロジェクトをスキャンする。Snykは、影響を受けたパッケージのバージョンについてSnyk Vulnerability Databaseにアドバイザリを公開しました。また、お客様が組織全体の侵害状況を調査できるよう、アプリ内通知とZero Day Reportを提供しています。

snyk test

ツリー内の特定のパッケージをすばやくスキャンするには:

snyk test --file=package-lock.json

永続化の痕跡を確認する。影響を受けたパッケージをインストールした場合は、次の項目を確認してください。

# AI agent hook
cat .claude/settings.json 2>/dev/null | grep -A5 SessionStart

# VS Code task hook
cat .vscode/tasks.json 2>/dev/null | grep "folderOpen"

# C2 daemon
ls ~/.local/share/kitty/cat.py 2>/dev/null
ls ~/.local/bin/gh-token-monitor.sh 2>/dev/null
systemctl --user status kitty-monitor 2>/dev/null  # Linux
launchctl list com.user.kitty-monitor 2>/dev/null   # macOS

# Dead-drop repositories on your GitHub account
gh repo list --json name,description | grep -E "sardaukar|mentat|fremen|atreides|harkonnen|gesserit|fedaykin|tleilaxu"

パッケージレベルの指標:

  • node_modules/<package>/package.jsonに、preinstallスクリプトbun run index.jsが存在する

  • ペイロードのSHA256:a68dd1e6a6e35ec3771e1f94fe796f55dfe65a2b94560516ff4ac189390dfa1c

  • github:antvis/G2#1916faa365f2788b6e193514872d51a242876569(またはコミット 7cb42f57561c / dc3d62a2181b)を参照するオプションの依存関係

ネットワーク上の痕跡:

  • クラウド環境以外からの 169.254.169.254 または 169.254.170.2(クラウドメタデータのエンドポイント)へのアウトバウンドリクエスト

  • OpenTelemetryのパスを含む t.m-kosche.com:443 へのHTTPリクエスト

  • 実際のPythonプロセスからではない、User-Agentが python-requests/2.31.0 のGitHub API呼び出し

修復方法

影響を受けたかどうか判断できない場合は、侵害が確認されたものとして対応してください。 RSA暗号化によってデータが持ち出されているため、盗まれた情報を復元することはできません。

ステップ1: トークンを失効させる前に、永続化の仕組みを削除する。

gh-token-monitor.shデーモンは60秒ごとにトークンをポーリングします。デーモンの実行中にGitHubトークンの有効期限が切れるか、失効すると、さらに悪意のあるアクションが引き起こされる可能性があります。まず永続化の仕組みを停止して削除してください:

# Remove systemd service (Linux)
systemctl --user stop kitty-monitor
systemctl --user disable kitty-monitor
rm -f ~/.config/systemd/user/kitty-monitor.service

# Remove LaunchAgent (macOS)
launchctl unload ~/Library/LaunchAgents/com.user.kitty-monitor.plist
rm -f ~/Library/LaunchAgents/com.user.kitty-monitor.plist

# Remove C2 daemon and monitor
rm -f ~/.local/share/kitty/cat.py
rm -f ~/.local/bin/gh-token-monitor.sh

# Remove editor hooks
rm -f .claude/settings.json  # or edit to remove SessionStart hook
# Edit .vscode/tasks.json to remove any "runOn": "folderOpen" tasks

# Check for injected GitHub workflows
git log --oneline --all | grep -i codeql

ステップ2: npmをクリーンアップし、侵害されていないバージョンを再インストールする。

# Remove node_modules
rm -rf node_modules

# Downgrade affected packages to pre-May 19 versions in package.json, then:
npm install --ignore-scripts

--ignore-scriptsを使用すると、インストール中にpreinstall、postinstall、prepareのライフサイクルスクリプトが実行されなくなります。いずれにせよ、これはCI環境で標準的に実施すべき対策です。

ステップ3: すべての認証情報をローテーションする。

影響を受けたパッケージをインストールしたマシンやCIランナーからアクセス可能なものは、すべて侵害されたと想定してください:

  • npm公開トークン

  • GitHubの個人アクセストークンとActionsのシークレット

  • AWSアクセスキー(および影響を受けたランナーからアクセス可能なIAMロール)

  • GCPサービスアカウントキー

  • Azureサービスプリンシパル

  • Kubernetesサービスアカウントトークン

  • HashiCorp Vaultトークン

  • 影響を受けたマシンに存在するSSHキー

  • データベース接続文字列

  • 環境変数や設定ファイルに保存されたAPIキー、サービストークン

ステップ4: GitHub上のワークフローへの不正な挿入とデッドドロップリポジトリを監査する。

# Check for attacker-injected branches
git branch --all | grep "codeql-static-analysis"

# Check for Dune-named repositories created on your account
gh repo list --json name | grep -E "sardaukar|mentat|fremen|atreides|harkonnen"

# Check npm audit log for unexpected publishes
npm access ls-packages

ステップ5: 今後の被害を防ぐ。

  • 組織内のすべてのパッケージで、公開保護を有効にしたnpmの2要素認証を有効化します。

  • CI設定にnpm install --ignore-scriptsをデフォルトとして追加します。

  • 整合性チェック付きのロックファイルを使い、依存関係を正確なバージョンに固定します。

  • レジストリのクールダウンポリシーを検討してください。公開から7日以内のパッケージにフラグを付け、保留します。

  • パッケージが悪意あるものとして報告された時点で検出できるよう、Snykを使って依存関係ツリーを継続的に監視しましょう。

  • 今後のマルウェアインシデントを防ぐためのセキュリティ制御と対策について、npm security best practicesリポジトリを参照し、その推奨事項に従うことを強くお勧めします。

より大規模なキャンペーン: Shai-Huludの波状攻撃

AntVへの攻撃は、TeamPCPが2025年9月から続けているキャンペーンの最新の波です。攻撃の変遷からは、規模、永続性、巧妙さ、信頼されたインフラの悪用が着実に拡大していることが分かります:

波

日付

主な標的

規模

特徴的な手法

第1波(Shai-Hulud)

2025年9月

npm(広範囲)

約4パッケージ

初の自己増殖型npmワーム

第2波(SHA1-Hulud)

2025年11月

Zapier、Posthog、Postman

600以上のパッケージ

コンテナからの脱出、破壊的なワイパー

第3波(Mini、SAP)

2026年4月

SAP CAP-JS、MBT

4パッケージ

Claude CodeのSessionStartフックへの不正な挿入

第4波(TanStack)

2026年5月11日

@tanstack/*

84バージョン/42パッケージ

OIDCハイジャックによる、初の有効なSLSA来歴情報

第5波(AntV)

2026年5月19日

@antv/* + 310以上

637バージョン/323パッケージ

メンテナーアカウントの侵害、C2の拡大

Snykでは、これまでの攻撃の波について詳しく解説しています:

各波では、Bunランタイムベースの難読化されたペイロードが再利用・拡張され、新たな永続化の仕組み(Claude CodeのSessionStartフックは第3波で初めて登場)、新たな情報流出インフラ、信頼された来歴情報を偽造する新たな手法が加えられています。特にSLSA来歴情報の問題には注意が必要です。有効なSigstoreアテステーションで確認できるのは、パッケージを生成したパイプラインであり、そのパイプラインが侵害されていないかどうかではありません。パイプライン設定そのものを監査せず、来歴情報だけを信頼の根拠にすると、今回のキャンペーンが連続する2つの波で悪用したような抜け穴が残ります。

Shai-Huludキャンペーン全体への対応について、Snykを使った修復方法を動画でご覧ください:

Shai-Hulud NPM Attack: Remediation with Snyk

Shai-Hulud NPM攻撃: Snykを使った修復 — Snykのツールを使って侵害されたパッケージを特定し、修復する方法を解説します。

攻撃のタイムライン(2026年5月19日、UTC)

時刻

イベント

01:39

atoolアカウントから、最初の悪意あるパッケージバージョンが公開される

01:56

最初の公開波が終了(約317バージョン)

02:05

第2波が開始

02:06

第2波が終了(さらに約314バージョン)

約02:18

検知。セキュリティ研究者が報告を開始

継続中

調査は継続中。追加のパッケージが特定される可能性あり

Snykによる対応

Snykは、影響を受けたパッケージバージョンについてSnyk Vulnerability Databaseでアドバイザリを公開しています。Snykのお客様は、アプリ内のZero Day Reportを使って、組織内のどのプロジェクトが影響を受けているか調査できます。影響を受けたパッケージに関するSnyk Vulnerability Databaseのエントリーには、最新の状況が反映されています。

この攻撃の種類について詳しく知るには、Snyk Learnのレッスン正規パッケージの侵害をご覧ください。メンテナーアカウントの侵害が、サプライチェーンの脅威全体の中でどのように位置づけられるかを解説しています。

Snykでサプライチェーンを安全に

回答者の87%がサプライチェーンのセキュリティ問題の影響を受けています。Snykでサプライチェーンを安全に保ちましょう。