一次スクリプトインジェクション攻撃で、どのようにユーザー情報と送金資金を同時に狙うのか?文章作者、出典:慢霧科技
背景
最近、慢霧のセキュリティ担当者は日常的な脅威インテリジェンスの調査中に、Udeskカスタマーサポートシステムに関連するスクリプトが毒化された攻撃を検出しました。チームはその後、udeskApi.2026-10-16.cached.js および deeps.js の2つのJavaScriptサンプルを取得し、分析を実施して、悪意のあるコードがどのようにカスタマーサポートスクリプトを通じてページに侵入し、ユーザーのデータや業務操作にどのような影響を与えたかを追跡しました。
サンプルの検査を段階的に進めるうちに、二つのリスクが明らかになりました。一つは、悪意のあるスクリプトがウェブページ内のセッションデータとユーザーが送信した機密情報を収集しながら、サイトのルールに従って入金アドレスとコピー内容を変更する行為です。前者は攻撃者がログインセッションを不正に使用したりアカウントを乗っ取ったりする可能性があり、後者はユーザーが置き換えられた受取アドレスに入金資金を送金してしまう可能性があります。私たちはカスタマーサポートスクリプトの読み込みエントリから着手し、データの読み取り、ネットワーク送信、ページ変更のロジックに沿って、これらの二つの行動の実装方法とトリガー条件を再構成しました。
MistEye が応答しました
MistEyeは、SlowMistが自社開発したWeb3の脅威インテリジェンスおよび動的セキュリティ監視システムで、セキュリティ監視とインテリジェンス集約機能を統合し、ユーザーにリアルタイムのリスク警告と資産保護を提供します。
MistEyeは、情報プッシュと顧客アラートチャネルを通じて即座にリスクを共有しました。

悪意のあるローダーとリモートペイロードローディングメカニズム
udeskApi.2026-10-16.cached.js を開くと、カスタマーサポートボタン、チャットiframe、訪問者トラッキング、メッセージ通信などのコードが確認できます。ファイルの末尾をさらに確認すると、メイン処理の後にもう1つの独立した関数があり、_ud() によって2つの文字列がデコードされ、要素が作成されて現在のドキュメントのheadに挿入されます。
このセクションではタグ名とリモートURLが直接記載されていません。プレーンテキストのドメインのみを検索すると、ロードエントリが見落とされる可能性があります。_ud()の実装を追跡すると、毎回2つの16進数文字を取得して文字に変換していることがわかります。定数を展開すると、ロードターゲットが明確になります。
736372697074 は script にデコードされ、別の定数は https[:]//udeskqlobal[.]com/deeps.js にデコードされます。ドメイン内の qlobal は q で始まるため、検索時にこの綴りを保持してください。ローダーはスクリプトを非同期に設定してページに挿入し、この位置に到達し、ブラウザのポリシーとネットワークが許可する場合、リモートコードが現在のドキュメントに取り込まれます。
このURLに対応するペイロードはdeeps.jsです。調査の焦点はカスタマーサポートSDKからペイロードそのものに移りました。サードパーティの古典的なスクリプトは、ドキュメントに埋め込まれたコンテキストで実行され、アクセス可能なデータは実際に実行されているページまたはiframeに依存します。カスタマーサポートチャットウィンドウはiframeを使用しており、ホストページに読み込まれたスクリプトを自動的に隔離することはありません。
ウェブページデータ収集メカニズムと影響範囲
deeps.js は最初に window.location.hostname を読み取り、3つのサイトルールに基づいて設定 C を生成します。どのページが収集されるかを判断するには、この設定だけでは不十分です。この設定がスクリプト全体に適用されるのか、それとも特定のモジュールに適用されるのかを確認するには、終了判断の位置をさらに追跡する必要があります。
制御フローを下に確認すると、Cookieおよびウェブストレージの読み取り、スナップショット送信、フォームおよび認証リクエストフックは、if (!C) return; の前に表示されています。以下に、ソースコードの順序でスナップショット送信文と末尾のXHRフックを抽出します。コメントには、フォーマットされたビュー D:L100、D:L151–L166 に対応する省略されたコードが示されています。
退出判断の位置が影響範囲を明確にしました:hostnameが3つのサイトルールに一致しなくても、スクリプトはまずデータ収集パスに入り、フックをインストールした後、アドレスモジュールを終了します。露出ページを調査する際には、この3つのサイト設定のみに焦点を当ててはいけません。
起動時に、ペイロードは現在のウェブページからアクセス可能な Cookie、localStorage、sessionStorage を読み取ります。これらの場所にはログイン状態、ユーザー情報、ビジネスデータが保存される可能性があり、其中有効で再利用可能なログイントークンが含まれている場合、攻撃者がそれを取得してユーザーのセッションを不正に使用する可能性があります。スクリプトは、トップレベルページの URL と現在のドキュメントの origin も付与し、これらのデータを元のページとともに送信します。
収集プロセスは各項目に対してエラー許容です。外部ソースからのトップレベルURLの読み取りに失敗した場合、スクリプトはxで置き換え、他のフィールドの処理を継続します。2種類のウェブページストレージはJSONとしてシリアライズされます。クッキーの範囲はdocument.cookieで読み取れる内容に限定され、HttpOnlyクッキーは含まれません。
スクリプトは、後続で送信されるデータ用のエントリポイントも保持しています。ユーザーがフォームを送信すると、スクリプトはinput、select、textareaを繰り返し処理し、空でない内容をコピーした上で、元の送信プロセスを継続します。アカウント、パスワード、キャプチャコードなど、ページ上で実際に入力されたフィールドが、追加のデータ送信パスに含まれる可能性があり、漏洩した場合、アカウントへのログインやアカウントの乗っ取りに利用される可能性があります。
このパスは、HTMLFormElement.prototype.submit をラップし、キャプチャ段階の submit イベントを監視することで実現されています。インターフェースを通じて直接データを送信するページについては、スクリプトは fetch と XHR もラップします。本文を含み、URL に login|signin|auth|register|signup|password などのキーワードが含まれるリクエストの場合、該当する内容をコピーしつつ元のリクエスト呼び出しを保持します。fetch 分岐では、URL が文字列であり、本文がリクエストオプションから取得されることを要件としています。FormData などのオブジェクトを直接 JSON シリアライズする場合、収集される内容には実際のフィールドが欠ける可能性があります。
データ漏洩メカニズムとバックアップチャネル
上記の収集エントリは最終的に同じ _send() を呼び出します。この関数をさらに追跡すると、固定受信先 https[:]//udeskqlobal[.]com/c.php が確認できます。スナップショットの起動時には、s、o、c、l、ss フィールドがそれぞれページアドレス、現在のソース、読み取り可能な Cookie、および2種類のウェブストレージを格納します。その後のフォームおよび認証リクエストは、それぞれがトリガーされた際に送信されます。
関数はURLのクエリパラメータを抽出し、非同期POST本文に挿入して、Content-Type: application/x-www-form-urlencodedを設定します。以下に送信関数(D:L45–L60)を完全に保持します:

送信パスには、画像リクエストのフォールバックも含まれます:XHRエラーが発生した場合、または送信中に同期エラーが発生した場合、スクリプトはImageオブジェクトを作成し、パラメータを含むURLをsrcに割り当てて、GETでデータを再送信しようとします。URLは8,000文字のJavaScript文字まで切り詰められるため、長い内容は不完全になる可能性があります。
このパスを理解するには、「リクエスト送信」と「レスポンス読み取り」を区別する必要があります。スクリプトはc.phpのレスポンスを読み取りません。単純なリクエスト条件を満たすクロスオリジンPOSTは、ブラウザがレスポンスの読み取りを制限する前に送信されるため、CORSエラーはリクエスト送信と同時に発生します。トラブルシューティングログでは、POST本文と画像GETパラメータの両方を確認する必要があります。出口ポリシーでは、connect-srcとimg-srcをそれぞれ確認してください。通常のフォームがドキュメントナビゲーションを引き起こす場合、非同期リクエストの完了にも影響します。
これで、ウェブページセッションデータとその後の送信内容の行き先は明確になった。しかし、ペイロードはサイト退出判定の後にも、アドレス形式の識別、ページテキストの変更、およびコピーパスの制御という別の一連の操作を保持している。これらのコードは調査を入金業務へとさらに導いている。
入金アドレスの置換とクリップボードハイジャックメカニズム
if (!C) return; の後、スクリプトはアドレスモジュールに入ります。最初の3つのhostnameルールは、ここで明確な目的を持ちます:mgbx[.]com、bikingex[.]、およびbitxex[.]ioに一致させ、異なるページに対してアドレスとコピーボタンの要素セレクターを選択します。
これらの正規表現には先頭および末尾のアンカーがなく、正確なドメイン比較よりも広範囲にマッチします。ページルールは、完全なlocation.hrefやクエリパラメータ、フラグメント内のdeposit、recharge、assetsなどのキーワードもチェックして判断に参加させます。ページ、要素、アドレス形式にヒットした後、スクリプトは200ミリ秒ごとにスキャンし、識別された入金アドレスを設定値に変更します。ユーザーが置き換えられたアドレスを使用して有効な送金を完了した場合、受取先はそのアドレスになります。
三つのサイトブランチが6つの設定値を共有しており、コードはBTC、EVM、TRON、Solana、LTC、DOGEとマークされています。アドレスの識別は文字の形状と一致する順序のみに基づき、ユーザーが選択したネットワークやアドレスチェックサムを確認しません。そのため、通常のビジネス識別子を誤って識別する可能性もあります。
コピー関連のコードを継続して確認すると、サンプルがページ表示とクリップボードの両方を同時に操作していることがわかります。これにより、ユーザーがページのアドレスとコピーした結果を比較しても、一致する改ざんされた値を得てしまう可能性があります。三つのパスは次の通りです:
- 包装クリップボードAPI。navigator.clipboard.writeTextは、まずR()を呼び出してパラメータを置換し、その後元のメソッドに渡す。このパスはhostname設定による制限のみを受け、再び入金ページの条件をチェックせず、DOMスキャンによってヒットした要素にも依存しない。
- コピーボタンを置き換えます。スクリプトは一致するボタンをクローンし、新しいクリックリスナーを設定して元のノードを置き換えます。新しく追加されたリスナーはデフォルトの動作とイベントの伝播を阻止し、共有変数 _cur に保存されたアドレスのコピーを試みます。
- copyイベントをブロックします。_curが空でなく、ページのルールが満たされている場合、documentのリスナーはユーザーが選択したテキストがアドレスかどうかを確認せずに、コピー内容を_curに変更します。
その中で、クリップボードAPIラッパーとcopyリスナーはソースコード内で隣接しています(D:L260–L275)が、トリガー条件は異なります:
_cur は最後に実際に置換されたアドレスを保存します。同一画面に複数のアドレスが表示されている場合、後の置換が前の記録を上書きします。複数のボタンが同じ値をコピーする可能性があります。ページが初期状態で設定アドレスを表示している場合、スキャンによって _cur は初期化されず、追加されたボタンリスナーも内容を書き込みません。複製された保持された HTML インラインイベント属性は、イベント処理に引き続き参加できます。
分析中に、行動判断に影響を与える実装上の欠陥が発見されました:スクリプトは Element.prototype から textContent の独自プロパティディスクリプタを読み取ろうとしていますが、標準的なプロパティ定義は Node.prototype にあります。標準的なプロトタイプ関係下では、その後 .set にアクセスした際に例外がスローされます。この分岐が失敗した後、catch は例外を無視します。前後のコードを確認すると、ポーリングは既に登録されており、後続のコピーフックはそれぞれの条件に従ってインストールされます。この単一の分岐のエラーは、アドレスハイジャックモジュールの実行を停止しません。
要約
カスタマーサポートスクリプトのローダーを追跡した結果、サンプルの攻撃目標は、セッションやアカウントログインに使用可能なデータを収集し、チャージページおよびコピー操作における受取アドレスを設定値に変更することであることが明確になりました。前者は3つのサイトの設定制限を受けませんが、後者はサイトおよび具体的なコピー経路に応じて有効化されます。調査時には、異なる露出シナリオを網羅する必要があります。
関連スクリプトの読み込みを継続している業務は配布を停止し、漏洩した認証情報を処理し、信頼できるバックエンドと取引記録を通じて入金先を確認してください。
提案
- 汚染リソースの保存と配信を停止してください。生産環境が関連スクリプトを引き続き読み込んでいる場合、実際のレスポンス、リクエストの発信チェーン、キャッシュ情報、収集時間を保存した後、速やかにブロックしてください。独立して検証された信頼できるバージョンに復元し、サイトホスティング、CDN、ビルド、タグ管理の設定を確認してください。
- 検索の読み込みと外部記録を確認します。悪意のあるドメイン、2つのパス、ファイルハッシュを結合して照会します。外部記録ではPOST本文とGETパラメータを同時にチェックします。圧縮スクリプトを調査する際には、ローダー内の16進数URLも検索し、平文のみの確認による見落としを回避します。
- 汚染されたドキュメントを終了し、漏洩した認証情報を処分してください。関連するページまたはWebViewドキュメントを完全に閉じ、古いリソースの再読み込みを防いでください。漏洩の範囲に応じて、清浄な環境からセッションを無効化し、トークンとパスワードをローテートしてください。scriptタグを削除しても、既にインストールされたフックやタイマーは無効化されません。
- 入金アドレスと取引を独立して確認してください。ペイロードを実行したページについては、信頼できるチャネルを通じて元の入金アドレス、関連する取引、および実際の送金先を確認し、取引記録に基づいて影響を評価してください。
- スクリプトの検証とデータエクスポート制限。ビジネス設定に基づき、スクリプトのソースと整合性制御を組み合わせ、connect-src、img-srcなどのポリシーをそれぞれ検証し、udeskqlobal[.]comに対するスクリプトの読み込みとデータ外部送信を制限します。
IOC
ドメイン
udeskqlobal[.]com
URL
https[:]//udeskqlobal[.]com/deeps[.]js
https[:]//udeskqlobal[.]com/c[.]php
ウォレットアドレス
BTC:bc1qhzppfj69ywp22swj50jwcfxdamg3ym245srng9
EVM: 0x9B6EcD0023a28E1391c5124eCe578A9751A337b2
TRON: TH4L5YAhhxtC8qALbZKbPZZgausbGi25nF
Solana: AFmCUe3nNbjTaC585CcdA3vvC9iWVR8YunooFKpaQx2Z
LTC: ltc1qwz0zp39ywl34kahvn9lyk7j5x63wsy9tcxhm3w
DOGE: DAoy2w8uvFtZ92q87s9qKEoHbWgV7mVThj
悪意のあるファイル
filename: udeskApi.2026-10-16.cached.js
SHA256: 45b4e8f160d8d5177819f6c1dc67acc7abbdc65eeaffc909e668799dc778bcf6
filename: deeps.js
SHA256: 57c1441c4f5bb3260981a2df64f9ff35f117abde0d8667c8c66a047880074c59
MistEyeについて
MistEyeは、SlowMistが自社開発したWeb3の脅威インテリジェンスおよび動的セキュリティ監視プラットフォームで、APIを通じてオープンソースパッケージエコシステムの悪意のある活動検出とサプライチェーンリスク警告機能を提供します。
本アクションに関連するすべての悪意のあるパッケージおよびIOCは、MistEye脅威検出エンジンに統合されています。開発者はAPIを通じてプロジェクトの依存関係を自動検出でき、既知の悪意のあるパッケージに一致したかどうかを迅速に判定し、対応案を取得できます。


