2026年3月31日、攻撃者がAxiosの主要メンテナーのnpmアカウントを侵害し、パッケージレジストリに2つの不正なバージョンを公開しました。これらの改ざんされたバージョンには新しい依存関係が含まれており、クロスプラットフォームで動作するドロッパーが組み込まれていました。このドロッパーは、npmを通じてパッケージをインストールした端末に対して、各プラットフォームに対応したリモートアクセス型トロイの木馬(RAT)を取得して展開する仕組みになっていました。ドロッパーはハードコードされたコマンド&コントロール(C2)サーバーに接続し、macOS・Windows・Linux向けに用意された不正なペイロードをダウンロードした後、自身の痕跡やパッケージ内の悪意あるコードをすべて削除し、展開されたRATのみを残すよう設計されていました。
Axiosとは?
Axiosは、JavaScriptを使った開発の領域で最も広く利用されているHTTPクライアントライブラリです。フロントエンドフレームワーク、バックエンドサービス、CI/CDツール、企業内の業務アプリケーションなど、Node.jsまたはブラウザでHTTP通信を行うさまざまな仕組みで使用されています。package.jsonに^1.14.0のようなキャレット指定を記載している場合、次回のインストール時に不正版へと自動的に解決される可能性がありました。Axiosのソースコードには目立った変更がなく、パッケージ名、公開者、バージョン番号から不正を判別することは困難でした。
Axiosは週間1億件以上のダウンロード数があり、HTTP通信を行う多くのNode.jsアプリケーションの依存関係に含まれています。このため、本件は非常に広範な影響を及ぼす可能性がありました。
どのように発見されたのか?
Socket Securityの自動スキャナーが、不正な依存パッケージ「plain-crypto-js@4.2.1」を公開から6分以内に検知しました。StepSecurityも独自にAxiosの改ざん版を特定し、詳細な技術分析を公開しました。この分析では、npm installが開始されてから1.1秒後にマルウェアが初めてC2サーバーへ通信を行っていたことが、実行時の挙動から確認されています。
Socketの共同創業者であるFeross Aboukhadijeh氏は、次の内容を公表しました。
Axiosを標的としたサプライチェーン攻撃が進行中。npmで最も多く依存されているパッケージのひとつであり、典型的なサプライチェーン型インストーラーマルウェアである。」
セキュリティチームは、不正な2つのバージョンを削除し、セキュリティ対策用のダミーパッケージに置き換えました。axios@1.14.1は約3時間、axios@0.30.4は約2時間15分公開されていました。この期間、正規メンテナーであるJason Saayman氏はアカウントへのアクセスを封じられていました。また、Axiosの協力者の一人は、攻撃者の権限が自分たちより強かったため、攻撃者のアクセス権を取り消すことができなかったとGitHub上で報告しています。
技術的な詳細
影響を受けたバージョン
改ざんされていたのはaxios@1.14.1とaxios@0.30.4で、最新版系統の1.xと旧版系統の0.xが39分以内に連続して侵害されていました。安全と確認されているバージョンはaxios@1.14.0とaxios@0.30.3です。Socketは、同じ不正ペイロードを含む依存関係が組み込まれた別のパッケージも特定しており、@shadanai/openclaw と @qqbrowser/openclaw-qbot@0.0.130 に同様の仕組みが見られました。
攻撃の経緯
攻撃者はAxiosの主要メンテナーが使用するnpmアカウント「jasonsaayman」を侵害し、登録メールアドレスを匿名のProtonMailに変更したうえで、npm CLIを使って直接不正バージョンを公開しました。この方法により、通常使用されているGitHub Actionsの公開フローを完全に迂回できたため、AxiosのGitHubリポジトリには該当バージョンのコミット、タグ、リリースなどは一切存在しません。
Axiosが侵害される18時間前、攻撃者が利用した捨てアカウント(nrwise、こちらもProtonMail使用)が plain-crypto-js@4.2.0 を公開していました。これは正規ライブラリcrypto‑jsのコピーで、npmの公開履歴を作り、履歴ゼロのパッケージに対する検知を避けるための準備として利用されたものでした。
3月30日23:59(UTC)、攻撃者は plain-crypto-js@4.2.1 を公開しました。このバージョンには難読化されたドロッパーが仕込まれており、実行後に証拠を消すためのクリーンな package.json があらかじめ用意されていました。
その22分後に axios@1.14.1 が公開されました。追加された依存関係は「plain-crypto-js": "^4.2.1」の1件だけであり、このパッケージはAxiosのコード内で使用されることはなく、その役割はnpmのpostinstallフックを実行させるためだけのものでした。
攻撃の流れ
ドロッパー(setup.js)は二重の難読化を用いており、文字列の反転とbase64化を行い、その後XOR復号によって重要な文字列を保存状態では読めないようにし、実行時のみ解読される仕組みになっていました。child_process、os、fs を動的に読み込むことで静的解析による検知を避け、そのうえで対象OSに応じた処理に分岐します。
- npmは、改ざんされたAxiosの依存関係として plain-crypto-js@4.2.1 を自動的に解決し、インストールします。
- postinstallフックが動作し、npm installが完了する前に node setup.js が実行されます。
- ドロッパーは os.platform() を使用してOSを判別し、プラットフォーム識別情報をPOST本文に含め、npmレジストリURLを装った形式で C2 サーバー(sfrclak[.]com:8000)に送信します。
- プラットフォーム別のRAT展開:
- macOS: AppleScriptが /Library/Caches/com.apple.act.mond にバイナリをダウンロードし、実行権限を付与して /bin/zsh から起動します。
- Windows: 正規の powershell.exe を %PROGRAMDATA%\wt.exe にコピーし(Windows Terminal を装った名称)、不可視のVBScript/PowerShell実行チェーンによってRATを取得し、-ExecutionPolicy Bypass で実行します。
- Linux: curl によりPythonベースのRATを /tmp/ld.py に取得し、nohup python3 により親プロセス終了後も動作し続ける状態で実行します。
- 自己削除処理: ドロッパーは setup.js を削除し、postinstallフックを含む package.json を消去し、事前に準備されていたクリーンなスタブを差し替えとして配置します。そのため、感染後に node_modules/plain-crypto-js/ を確認しても不審な痕跡は残りません。
StepSecurityによる静的・動的解析(復号済み文字列や Harden-Runner のプロセス構造を含む)は https://www.stepsecurity.io/blog/axios-compromised-on-npm-malicious-versions-drop-remote-access-trojan に公開されています。
Socketの調査結果は https://socket.dev/blog/axios-npm-package-compromised で確認できます。
このRATには永続化機能がありません。端末を再起動するとバイナリはディスクに残るものの、自動起動は行われません。これは、永続化処理を行うことでEDRに検知されやすくなるため、意図的に省かれた可能性があります。あるいは、RATがC2サーバーに接続した後に追加のペイロードや永続化指令を受ける設計だった可能性もあります。特定の標的に対してのみ永続化を行う意図があった可能性も否定できません。
攻撃者の特定と目的
現時点では、この攻撃を特定の攻撃者に結びつけることも、攻撃の意図や目的を断定することもできません。ただし、今回の攻撃は技術的に成熟しており、ペイロード全体が秘匿性を優先した構造になっていました。
RATの機能は初期段階のRATとして典型的で汎用性があり、以下の動作がハードコードされていました:
- 自身の削除
- バイナリのダウンロードと実行
- スクリプトやコマンドの実行
- ディレクトリの列挙(/home/user/.ssh と /etc/passwd が指定)
RATの機能は汎用的であり、特定の攻撃者に限定されるものではありません。暗号資産のマイニングや認証情報の窃取といった明確な悪意ある機能を組み込んでいないため、EDRに検知されにくい構造になっています。パッケージの侵害は非常に短時間で行われ、攻撃全体が目立たないように実行されていましたが、それでも攻撃者が国家主体か金銭目的かといった分類を狭める決定的な材料にはなりません。メンテナーアカウントへのアクセスさえ得られれば、同様の攻撃は複数の攻撃者が実行可能です。
DPRK(北朝鮮)系の攻撃者は、暗号資産関連の開発者を狙ったソフトウェアサプライチェーン攻撃を繰り返してきました。Axios自体は暗号資産向けの専用ライブラリではありませんが、利用範囲が非常に広いため、暗号資産開発の一部とも重なることが考えられます。ただし、現時点で北朝鮮と結びつけるその他の根拠はありません。
今回使用されたXORキーには「7」が複数含まれており、中国系攻撃者を示唆することもあります。しかし同時に、スター・ウォーズに登場する「Order 66」を連想させる部分も含まれており、中国では広く知られた作品ではないため、決定的な要素とは言えません。
攻撃者の特定には、C2サーバーのフォレンジック調査や、npmおよびGitHub上で侵害されたメンテナーアカウントの操作履歴、アカウント侵害の手口などの調査が役立つ可能性があります。ただし、攻撃者を特定したとしても全体像の理解が大きく進むとは限りません。
影響を受けているか確認する方法
- lockfileに axios@1.14.1、axios@0.30.4、plain-crypto-js の記述がないか確認してください。
- node_modules/plain-crypto-js/ が存在する場合、その端末でドロッパーが実行されています。自己削除処理により、フォルダの内容は無害なスタブに置き換えられています。
- macOSは /Library/Caches/com.apple.act.mond、Windowsは %PROGRAMDATA%\wt.exe、Linuxは /tmp/ld.py にRATの痕跡が残る場合があります。ただし、自己削除により消えている可能性があります。
- ネットワークログで、sfrclak[.]com または 142.11.206.73(ポート8000)への外向き通信がないか確認してください。ネットワークログは消えにくいため、最も信頼性の高い指標です。
- CI/CDで3月31日の00:21~03:15(UTC)の間に npm install が実行されていないか確認してください。この時間帯に実行されていた場合、秘匿情報やデプロイキーが漏えいしている可能性があります。
影響が疑われる場合の対応
axiosを axios@1.14.0 または axios@0.30.3 に戻し、node_modules/plain-crypto-js を削除したうえで、npm install --ignore-scripts を実行してください。
RATの痕跡を確認した場合は、端末全体が侵害されたものとして扱い、信頼できる初期状態のイメージから再構築してください。
侵害された端末で使用可能だったすべての認証情報(保存されたパスワード、npmやその他サービスのトークン、SSH鍵、クラウドアクセスキー、.env、CI/CDシークレット)を更新してください。
sfrclak[.]com と 142.11.206.73 をファイアウォールやDNSで遮断してください。
ソフトウェアサプライチェーンの強化策
- 依存関係のバージョンを固定し、lockfileを必ずコミットすることが重要です。キャレット(^)によるバージョン指定が、不正なバージョンへの自動更新を許してしまいました。CI/CDでは npm ci を使用することで、lockfileに記載されているバージョンだけを確実に利用するようにできます。
- 自動ビルドでは npm ci --ignore-scripts を使用して postinstall スクリプトを実行しないようにしてください。今回の攻撃はnpmの postinstall ライフサイクルフックに全面的に依存しており、多くのパッケージはこのフックを必要としていません。
- 新しく公開されたパッケージについては、一定期間が経過するまで利用できないよう制限を設けることが効果的です。たとえば、.npmrc に min-release-age=7 を設定すると、公開から7日以上経っていないパッケージを利用しないようにできます。AikidoのSafe Chainのようなツールを使えば、任意の待機期間を設定し、その期間内に公開されたパッケージをブロックすることも可能です。今回の不正な plain-crypto-js@4.2.1 は公開から24時間も経っていなかったため、もし48時間の待機期間を設定していれば、この攻撃は防ぐことができました。
- CI/CDランナーからの外向き通信を制御することも重要です。今回のドロッパーは、インストール開始後わずか1.1秒で外部のC2サーバーに接続していました。もしCI/CDランナーが任意の宛先への外向き通信を許可している場合、postinstall スクリプトが自由にC2に接続してしまう可能性があります。
繰り返される攻撃の構図
今回のAxiosの侵害は、過去1年間に発生した大規模なnpmサプライチェーン攻撃と同じ流れに沿っています。メンテナーの資格情報が侵害され、依存関係のマニフェストに小さな変更が加えられ、postinstallフックによって自己削除型の不正コードが実行されるという一連の構図です。2025年9月には、フィッシングによってChalkとDebugが侵害され、これらは合わせて週間20億件以上のダウンロードがあるパッケージでした。同じ月には、Shai‑Huludワームがnpm史上初の自己増殖型マルウェアとして確認され、12月にはその第二世代が約40万件の開発者秘密情報を収集していました。
最近、npmはFIDOによる二要素認証の義務化、自動生成トークンのデフォルト無効化、信頼された公開プロセスの導入などのセキュリティ改善を計画していると発表しました。しかし、現時点ではこれらの改善はまだ開発段階にあります。それまでは、npmが検知しきれない部分を外部ツールや開発者自身の注意で補う必要があります。
LRQAの支援が必要ですか?
今回の事案による影響が疑われ、緊急の対応が必要な場合、または次の攻撃に備えてサプライチェーン全体のリスク状況を把握したい場合は、LRQAが支援できます。
Indicators of Compromise (IOCs)
|
Network |
|
|
C2 domain - hxxp |
//sfrclak[.]com:8000 |
|
C2 IP |
142.11.206.73:8000 |
|
C2 URL |
hxxp:////sfrclak[.]com:8000/6202033 |
|
User-Agent string |
mozilla/4.0 (compatible; msie 8.0; windows nt 5.1; trident/4.0) |
|
Mac C2 payload retrieval POST body |
packages.npm.org/product0 |
|
Windows C2 payload retrieval POST body |
packages.npm.org/product1 |
|
Linux C2 payload retrieval POST body |
packages.npm.org/product2 |
|
Mac Host |
|
|
MacOS temporary file (deleted after use) |
/tmp/6202033 |
|
MacOS RAT binary file |
/Library/Caches/com.apple.act.mond |
|
Injected binaries from RAT activity |
/private/tmp/.[XXXXXX] |
|
Mac RAT SHA256 |
92ff08773995ebc8d55ec4b8e1a225d0d1e51efa4ef88b8849d0071230c9645a |
|
Mac RAT SHA1 |
13ab317c5dcab9af2d1bdb22118b9f09f8a4038e |
|
Mac RAT MD5 |
7a9ddef00f69477b96252ca234fcbeeb |
|
Windows Host |
|
|
Copies powershell.exe to |
%PROGRAMDATA%\wt.exe |
|
VBS wrapper, deleted after use |
%TEMP%\6202033.vbs |
|
Powershell payload, deleted after use |
%TEMP%\6202033.ps1 |
|
Linux Host |
|
|
Linux temporary file |
/tmp/ld.py |
|
NPM Packages |
|
|
axios@1.14.1 shasum |
2553649f232204966871cea80a5d0d6adc700ca |
|
axios@0.30.4 shasum |
d6f3f62fd3b9f5432f5782b62d8cfd5247d5ee71 |
|
plain-crypto-js@4.2.1 shasum |
07d889e2dadce6f3910dcbc253317d28ca61c766 |
|
Post compromise activity |
After payload execution, the dropper removes any indication of the malicious code from the package directory by deleting setup.js and package.json, replacing package.json with a legitimate/clean file. |
|
Notable strings |
|
|
XOR key - OrDeR_7077 |
|
|
XOR constant - 333 |
|
|
Campaign id |
6202033 |
|
Plain-crypto-js@4.2.0 publisher |
nrwise@proton.me |
|
Attacker controlled email address used in axios maintainer account hijack |
ifstap@proton.me |
|
Attacker controlled email address used to publish plain-crypto-js |
nrwise@proton.me |
|
Npm audit commands |
|
|
Check for existence of plain-crypto-js |
npm ls plain-crypto-js |
|
Check for existence of plain-crypto-js |
cat package-lock.json | grep -A3 "plain-crypto-js" |
|
Check for existence of malicious axios versions |
grep -E '"axios".*"(1\.14\.1|0\.30\.4)"' package-lock.json |
