Needle: マルウェアにキーを残したモジュール式暗号盗難C2の内部

研究ノート: このインフラストラクチャを列挙するために使用されたAPIキーは、MalwareBazaarで公開配布されたマルウェアから抽出されました。これは脅威アクターが感染したマシンから電話をかけるために独自のエージェントに埋め込んだのと同じ認証情報です。ここで報告されている統計以外の被害者データは保持されていません。設定は変更されていません。


要点

  • 分析はCaronteによって自律的に実行されました。私たちのエージェント型脅威インテリジェンスプラットフォーム: 単一のMalwareBazaarサンプルから完全なC2属性化、被害者列挙、オンチェーン資金追跡まで、数分で実施され、手動リバースエンジニアリングは不要でした
  • Needleは、アクティブなMaaS暗号盗難プラットフォームで、2つのライブモジュールがあります: MetaMask、Phantom、Trust Walletを対象とするブラウザ拡張機能スプーファーおよびExodus、Trezor、LedgerになりすましているmkRustデスクトップエージェント
  • Rustエージェントは保護されていない状態でC2 APIキーを埋め込んでいます。それを使用して、6つのブロックチェーン全体で1,932人の被害者と攻撃者の完全な引き出し設定を列挙しました
  • パネルのReact SPAは認証を完全にクライアント側で実行していました: 構造的に有効なトークンをlocalStorageに書き込むだけで、サーバー検証なしで完全な管理ダッシュボードがレンダリングされました
  • フロントエンドバンドルは、エージェントキー認証スキームを使用して引き出し設定の書き込みエンドポイントを定義しており、感染したマシンから電話をかけてくるのと同じ認証情報が将来のすべての自動引き出しをリダイレクトできる可能性があります

主要な調査結果の概要

カテゴリ 詳細
サンプル Rust PE (Windows)、v1.3、SHA256: d6ca3760...a490
C2スタック React 19 SPA · Express.js API · nginx 1.29.8
アクティブモジュール デスクトップウォレットスプーファー · ブラウザウォレットスプーファー
被害者 1,932人(ブラウザ拡張機能111人、デスクトップセッション1,821人)
対象ウォレット MetaMask · Trust · Phantom · OKX · Exodus · Trezor · Ledger · Atomic · Guarda · Zelcore
キャンペーンウィンドウ 2026年4月18日からアクティブ; 執筆時点で進行中
認証の失敗 保護されていないエージェントキー · クライアント側のみの認証 · 認証されていないビルダー
C2インフラストラクチャ 130.12.180.135 (ポート 3000、8080、8181)
確認された資金移動 EVM ホットウォレット: 約$148 ETHがコールドストレージに転送

発見: MalwareBazaarから完全なC2可視化まで

Windows暗号盗難プログラムとしてフラグが付けられたサンプルがMalwareBazaarで浮上しました。これをCaronte、私たちのエージェント型脅威インテリジェンスプラットフォームに送信しました。その単一のアップロードから、Caronteは完全な分析パイプラインを自律的に実行し、手動リバースエンジニアリングは不要でした。

Caronteはバイナリ分類から始まりました: ストリップされたRust PE、8.9MB、未署名、エントロピー6.71、MalwareBazaarでRustyStealerとタグ付けされ、Phorpiexスパムボットネットを介して配布されました。特性的なストリング パターンからeguiデスクトップGUIフレームワークを識別し、Rustパニックハンドラーパスをトレースしてウォレット偽装ターゲット(zelcoretrezorledger)を復元し、バイナリのデータセグメントから埋め込み設定スキーマを再構築しました。

静的リバースエンジニアリングも、ウォレットスプーファーを超える機能を明らかにしました: GetAsyncKeyState経由のキーロギング(入力時のシードフレーズキャプチャと一致、送信時のみではなく)、Windowsレジストリ実行キー経由のpersistence、SetUnhandledExceptionFilterおよびソフトウェアブレークポイントトラップを含むアンチデバッグ技術。C2 IPはASN 202412(Omegatech LTD、アムステルダム)に解決され、分析時点でOTXで27の悪意あるパルスを記録した既知の無差別ホスティングプロバイダーです。

完全な分析により、94ノードと135エッジの脅威グラフが生成され、ローカルおよびMalwareBazaar規則セット全体で40のYARA規則と一致しており、キーロギング、アンチVM回避、Rustベースのスティーラーパターンの高重大度ヒットを含みます。提出から数分以内に、Caronteは完全なオペレータープロファイルを生成しました: プラットフォームID、C2アドレス、APIキー、およびほぼ2,000人の被害者を管理するライブパネル。

Caronteが自律的に生成したもの

成果物 出力
バイナリ分類 ストリップされたRust PE、8.9MB、RustyStealer族
フレームワーク識別 egui GUI、Phorpiex配布
機能抽出 キーロギング、persistence、アンチデバッグ
埋め込み設定復元 バイナリデータセグメントからのC2 URLおよびAPIキー
インフラストラクチャ属性化 ASN 202412 Omegatech、27のOTXパルス
脅威グラフ 94ノード、135エッジ
検出カバレッジ 40のYARA規則一致
インテリジェンスまでの時間 手動REの日数対分数

このセクション以下のすべてのコンテンツは、Caronteの自律出力の上に構築された検証と探索です: ヒューマンインザループステップ。


Needleとは何か

Needleはモジュール式MaaS(Malware-as-a-Service)プラットフォームです。パネルは購入可能なモジュールの周りに構築されています: オペレーターが必要なものをアクティブにし、インフラストラクチャは共有のままです。分析中、2つのモジュールがアクティブでした:

モジュール ステータス 説明
Needle Core 非アクティブ フォームグラバー、クリッパー、システムコア
Extension Base 非アクティブ サイト代用、バックアップドメイン管理
デスクトップウォレットスプーファー アクティブ Rustエージェント、偽のウォレットUI、シードフレーズキャプチャ
ブラウザウォレットスプーファー アクティブ 拡張機能置換、パスワードおよびシード傍受
Farm 非アクティブ 残高しきい値によってトリガーされる遅延引き出し
Launch Panel 非アクティブ トラフィック管理およびランチャー作成
Captcha (Win+R) 非アクティブ ソーシャルエンジニアリング配信メカニズム

モジュール構造は複数のオペレーターに販売またはレンタルされるプラットフォームと一致しており、非アクティブモジュールは現在のオペレーターがサブスクライブしていない機能を表しています。これは独立した研究によって裏付けられています: 同じ月に、Malwarebytesは別のNeedleキャンペーンを文書化しました完全に異なるインフラストラクチャ(異なるハッシュ、異なるC2 IP)を使用し、偽のトレーディングサイトおよびDLLハイジャック経由の配信に焦点を当てています。彼らのサンプルはこのC2と重複していません。その分析が被害者の感染方法を文書化したところ、本レポートはそれを処理するインフラストラクチャの内部に入ります。


バイナリはデバッグシンボルのないストリップされたRust PEです。Rustのパニックハンドラーメカニズムはリリースビルドでもソースファイルパスを保持し、これらの文字列はバイナリのデータセクションに存在し、ウォレット偽装ターゲットを識別します:

src/views/zelcore/app.rs
src/views/trezor/seed_panel.rs
src/views/ledger/screens/seed_recovery.rs

バイナリは完全なeguiデスクトップGUIフレームワークも備えており、バイナリ内の特性的なストリングパターンから識別可能で、被害者が相互作用する偽のウォレットダイアログをレンダリングするために使用されます。

バイナリのデータセグメントと設定構造の分析を通じて、Caronteはエージェントの埋め込み設定ブロックを再構築しました:

{
  "version": "1.3",
  "api_url": "http://130.12.180.135:3000/api/v2",
  "api_key": "alk_776...fc1",
  "open_original_wallet_on_valid_seed": true
}

open_original_wallet_on_valid_seedフィールドは注目に値します: trueに設定されると、エージェントはシードフレーズを正常にキャプチャした後に正当なウォレットアプリケーションを開くので、被害者は本物のウォレットが正常にロードされるのを見て、何も悪いことが起こったと疑う理由がありません。これは設定に焼き付けられた意図的なアンチ検出対策です。

設定は難読化も暗号化もなく保存されていました。さらに重要なことに、api_keyフィールドは感染したマシンがC2に認証するために使用する同じ認証情報です。エージェント認証とAPI読み取りアクセスの間に分離はありません: 新しい被害者を登録するキーは被害者全体リストも読み取ります。


APIサーフェスのマッピング: フロントエンドバンドル分析

サーバーへリクエストを送信する前に、Caronteはポート3000で提供されるReact SPAのwebpackバンドルを分析しました。すべてのAPIルート文字列はバンドルされたJavaScriptに存在していました:

/api/v2/wallets
/api/v2/antiledger/settings
/api/v2/antiledger-v2/seed-phrases
/api/v2/panel-access/evaluate
/api/v2/backup-domains/active
/api/v2/browser-spoofer/build/{buildId}/status
/api/v2/builds/{buildId}/{filename}

これにより、サーバーの積極的な列挙の前に、単一のバンドルフェッチから導出された完全なエンドポイントマップが提供されました。


パネル内部への侵入: 2つの独立したアクセスレイヤー

C2分析には、異なる種類の可視性を提供する2つの別個の技術が必要でした。それらは明確に区別する価値があります。

フロントエンドUI: クライアント側のみの認証

React SPAの認証ロジックはlocalStorageから読み取り、ダッシュボードをレンダリングするか、ログインにリダイレクトするかを決定します。サーバーはこのルーティング決定に役割を果たしていません。

ブラウザのlocalStorageに直接2つの値を書き込むだけで十分でした:

localStorage.setItem("auth_token", "<structurally valid JWT, exp:9999999999>");
localStorage.setItem("auth_user", JSON.stringify({ username: "admin", role: "admin" }));

/loginへのリクエストが傍受され、アプリケーションが認証状態をリフレッシュするのを防ぐと、完全な管理ダッシュボードがレンダリングされました。これはJWTライブラリ回避ではありません; UIルーティングレイヤーのサーバー側認証ゲートの欠落です。SPAはlocalStorageをレンダリング決定で無条件に信頼しています。

これが私たちに与えたもの: パネルの構造、モジュールレイアウト、設定ページ、全体的なUI。C2スタックはHTTPレスポンスヘッダー(Server: nginx/1.29.8)とバンドルメタデータ(webpackの出力のReact 19バージョン文字列)から確認されました。このレポートのスクリーンショットはレンダリングされたフロントエンドを示しています。

それが与えなかったもの: 実際のデータ。バックエンドAPIエンドポイントは特権操作に対して有効な署名済みJWT (HS256)が必要です。偽のトークンのみで、SPAからのAPI呼び出しは401を返しました。

データアクセス: 埋め込まれたエージェントキー

すべての被害者レコード、引き出し設定、およびセッション統計は、Caronteがバイナリから抽出したエージェントキーを使用した直接的なAPI呼び出しから得られました。このキーは管理JWT スキームとは独立してエージェント対向エンドポイントを認証し、感染したマシンが自分自身を登録するために使用するのと同じ認証情報は被害者全体リストとオペレータ設定を読み取るのに十分でした。

2つの技術は相互に補完的ですが、完全に独立しています。フロントエンドバイパスはパネルの構造を明らかにし、それがライブオペレータプラットフォームであることを確認しました。エージェントキーはすべてのデータを提供しました。


2つの攻撃戦略

ブラウザウォレットスプーファー

ブラウザモジュールは正当な暗号ウォレット拡張機能を置換または傍受します。被害者は通常のMetaMaskまたはPhantom拡張機能のように見えるものと相互作用します; 偽版は入力されたパスワードまたはシードフレーズを傍受し、それをC2に流出させます。

ポート8080で実行されるビルダーは意味のある認証がなく、オペレーターが対象にするウォレット、インストーラーの自己破壊動作、待機モード、スマートPINオプションを構成できます。

ターゲットには、MetaMask、Trust Wallet、Phantom、OKX、TonKeeper、Coinbase、Atomic、Bybit、およびBinance Walletが含まれます。APIから111のブラウザ被害者が記録されました:

ウォレット 被害者
MetaMask 48
Trust Wallet 30
Phantom 20
OKX 6
TON 3
Binance 2
Bybit 2
合計 111

/api/v2/walletsエンドポイントを監視ウィンドウ中に繰り返しポーリングすると、カウントが数時間おきに3〜5人の新しいエントリずつ増加していることが観察されました。キャンペーンは観察期間全体を通じてアクティブに被害者を獲得していました。

デスクトップウォレットスプーファー

Rustエージェントはデスクトップウォレットアプリケーションになりすまします。被害者が自分のExodus、Trezor、またはLedgerアプリケーションと信じるものを開くと、偽の「ウォレットを復元」ダイアログが表示され、シードフレーズを要求します。入力されたシードはC2に投稿されます; 有効で、自動転送モジュールが有効な場合、資金はオペレーターの引き出しアドレスに移動します。

データ収集時点で1,821のデスクトップセッションが記録されており、すべてawaitingSeed: trueで、C2が感染したマシンを登録していたが、シードフレーズはまだ送信されていないことを示していました。継続監視中にサーバーが報告した合計は1,825に達し、新しいセッションが蓄積していることを確認しました。提出されたシードの欠落が初期段階の配布または被害者が偽のダイアログを放棄していることを反映しているかどうかは、データだけからは判断できません。

引き出しモジュールは3つのオートメーションモードをサポートしています: 接続時の自動残高確認、パスワード入力後の自動引き出し、シードフレーズ送信によってトリガーされた引き出しで、すべてオペレーターごとに独立して切り替え可能です。


C2内部: エージェントキーがロックを解除したもの

攻撃者の構成および資金移動

GET /api/v2/antiledger/settingsは完全なオペレーション構成を返しました: BTC(1PVq...qfZ)、LTC(LKmc...DBL)、DOGE(D5xE...FFq)、SOL(BpxG...YU)、TRON(TDij...UNp)、およびEVM(0xD5...F1b)の引き出しアドレス、およびTronGrid APIキー

TronGridはTRONのInfuraに相当し、プロフェッショナルグレードのブロックチェーンRPCサービスです。その存在はここで、オペレーターが手動監視に頼るのではなく、引き出しをトリガーする前に自動化されたTRON/USDT残高チェックを設定していることを示しています。

オンチェーン分析は操作がアクティブに資金を移動していることを確認しています。EVMアドレスの引き出しは分析時点で3つの異なるコールドウォレットに転送された約$148 ETHが空になっていました。TRONアドレスは約$60のUSDTとTRXを保有していました。BTC、LTC、DOGE、およびSOLアドレスは記録されたトランザクション履歴を示していませんでした。これらのチェーンではまだ初期段階の回収キャンペーンと一致しています。

引き出し設定への書き込みアクセス

フロントエンドバンドルはPUT /api/v2/antiledger/settingsをGETエンドポイントと同じエージェントキー認証スキームを使用して定義しています。キーが書き込みパスで受け入れられている場合、同一の認証実装が示唆するもの、6つの引き出しアドレスは任意のアドレスに置き換えられ、将来のすべての自動転送をオペレーターから離れてリダイレクトできます。

書き込みリクエストを送信しませんでした。含意はここで報告されています。なぜなら、スコープ制限のないエージェントキーの配布の完全な結果を表しているため: 研究者、競合他社、またはサンプルバイナリへのアクセスを持つ敵の団体は、このC2の被害者を列挙し、潜在的にその収益をリダイレクトできます。


2つのインスタンス、1つのデータベース

列挙中に、同じホスト上のポート8181の2番目のパネルインスタンスを識別し、同じエージェントキーを受け入れました。シードフレーズセッションIDを相互参照すると、ポート3000から照会された1,817件のうち1,814件が共通の記録を確認し、ほぼ完全な重複がバックエンドデータベースを共有していることを確認しました。デルタはクエリ間の時間ギャップを反映し、個別の展開ではありません。

共有データベース設定は、複数のオペレーターまたはアフィリエイトに個別のパネルアクセスを提供するMaaSプラットフォームと一致しており、個別のインフラストラクチャはありません。ポート8181はブラウザウォレットエンドポイントのために空の結果セットを返しました; これが異なるモジュールサブスクリプションを反映しているか、単に異なるAPIサーフェスをそのインスタンスのためにするかどうかは、利用可能なデータから確実に決定することは不可能です。


侵害の兆候

Sample:
  SHA256: d6ca3760...a490
  MD5:    8b3433...36ca534b
  Name:   needle_agent_v1.3 (internal)
Network:
  C2 Panel:  130.12.180.135:3000
  Builder:   130.12.180.135:8080
  Secondary: 130.12.180.135:8181
  Stack:     nginx/1.29.8 (Server header), React 19, Express.js
  Hosting:   ASN 202412 Omegatech LTD, Amsterdam (bulletproof hoster)
Persistence:
  Registry:  HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Run
rule Needle_Crypto_Stealer_v1 {
    meta:
        description  = "Needle MaaS crypto-stealer, Rust desktop agent v1.x, distributed as agent.exe"
        author       = "Beelzebub Research"
        date         = "2026-04-28"
        reference    = "https://beelzebub.ai/blog/needle-c2-crypto-stealer-analysis"
    strings:
        // Needle固有のC2 APIパスと設定フィールド
        $api1 = "antiledger-v2/seed-phrases" ascii
        $api2 = "open_original_wallet_on_valid_seed" ascii
        // Rustパニックハンドラーソースパス、リリースビルドに存在
        $src1 = "src/views/zelcore/app.rs" ascii
        $src2 = "src/views/trezor/seed_panel.rs" ascii
        $src3 = "src/views/ledger/screens/seed_recovery.rs" ascii
        // Needleの偽ウォレットダイアログロジックのUIストリングキー
        // needle_desktop_wallet_debug.txtはエージェントに埋め込まれたデバッグログパス
        // needle.wallet.はウォレット固有のUIキーの名前空間プリフィックス
        $ui1  = "checkseed.invalid_message" ascii
        $ui2  = "needle_desktop_wallet_debug.txt" ascii
        $ui3  = "needle.wallet." ascii
    condition:
        // 有効なWindows PE (MZヘッダー + PEシグネチャ)
        uint16(0) == 0x5A4D and
        uint32(uint32(0x3c)) == 0x4550 and
        // Rust + eguiバイナリサイズ範囲
        filesize > 5MB and filesize < 50MB and
        // Needle固有のAPIストリングの両方が存在する必要があります
        all of ($api*) and
        // 少なくとも1つのコンパイルされたRustソースパス
        1 of ($src*) and
        // 少なくとも2つのNeedleのUIストリング
        2 of ($ui*)
}

結論

2週間未満で、このNeedle展開は2つの攻撃サーフェス全体で1,932ターゲットを登録しました。EVMホットウォレットは分析完了前にコールドストレージに資金を移動していました。操作は仮説的ではありませんでした。

完全な全体像が利用可能になったのは、オペレーターがエージェントをどのように構築したかのためでした。独自のマルウェア内で配布した認証情報を使用して、被害者リストを読み取り、引き出し設定を抽出し、オンチェーン活動をトレースしました。別のNeedleキャンペーンに関するMalwarebytesレポートは、これが分離された展開ではないことを確認しています: 複数のオペレーターが同じプラットフォーム上で同時キャンペーンを実行しています。


Caronteはこれをどのように可能にしたか

この調査全体は単一のサンプルアップロードから始まりました。Caronteは埋め込み設定を自律的に復元し、インフラストラクチャを属性化し、YARAルールを生成し、脅威グラフを構築しました。シニアリバースエンジニアが日数かかる作業でした。アナリストの役割は検証とオンチェーン相関であり、抽出ではありませんでした。

あなたのSOCが依然として手動でサンプルをリバースエンジニアリングしている場合、あなたは攻撃者の最初のウェーブではなく、最後のウェーブの速度で操作しています。

Caronteがどのように機能するかを学ぶ

翻訳元: https://beelzebub.ai/blog/needle-c2-crypto-stealer-analysis/

ソース: beelzebub.ai