サイバー脅威
不正なブラウザ拡張機能を配布し暗号資産を盗む「CopperStealer」の新手口
このサイバー犯罪グループによる最新の活動を調査したところ、暗号資産に関する不正な活動を行うブラウザ拡張機能が発見されました。
情報窃取型マルウェア「CopperStealer」に関する前回のレポートでは、ブラウザ情報窃取ツール、ブラウザ拡張機能で動作するアドウェア、リモートデスクトップなど、さまざまなコンポーネントの不正使用によって当該マルウェアが拡散されるという分析結果を報告しました。今回、当該サイバー犯罪グループによる最新の活動を調査したところ、暗号資産に関する不正な活動を行うブラウザ拡張機能が発見されました。この拡張機能は、ユーザが暗号資産取引所のWebサイトにログインすると、感染しているユーザ端末内からAPIのキー情報を窃取、または新規作成します。さらに、そのキー情報を利用して被害者の暗号資産ウォレットにアクセスし、攻撃者側の暗号資産ウォレットに送金する機能を備えています。
前回の手口と同様、今回発見された不正な拡張機能は偽のクラック版アプリ(別称warez)を配布するWebサイトを起点として拡散します。この拡張機能は通常、他のブラウザ情報窃取ツールや無関係なマルウェアの部品を同梱したドロッパに埋め込まれた形で配布されます。ドロッパはパスワード付きで圧縮され、7月以来野放しな状態で配布されていました。
ドロッパおよび拡張機能のインストーラ
拡張機能のドロップ、インストールを行う本コンポーネントは、前回と同様の手口によって、暗号化、圧縮されています。具体的には、前回の報告で「第一段階」として述べたXOR関数による暗号化と、「第二段階」として述べたUPX「Ultimate Packer for Executables」によるDLL圧縮が施されています。コンポーネントを復号化、展開したところ、「CRX」という名前のリソースディレクトリがあり、その中には7-Zip形式のアーカイブファイルが含まれていました。こうしたパッケージ構成は、他の不正なChromeブラウザの拡張機能においても見られる代表的なものです。
7-Zipアーカイブの中身は、設定情報を記載したJSON形式のファイルと、拡張機能インストーラのバイナリを圧縮した別の7-Zipアーカイブです。
拡張機能インストーラはまず、Chromium系ブラウザの「User Data」ディレクトリ内にある設定ファイル「Preferences」と「Secure Preferences」を書き換えます。1つ目の設定ファイル「Preferences」には、ユーザ個別の設定情報がJSON形式で記述されています。拡張機能インストーラはこれを書き換えてブラウザの通知機能を無効化します。
2つ目の設定ファイル「Secure Preferences」には、インストール済みのブラウザ拡張機能に関する情報が、同じくJSON形式で記述されています。今回の拡張機能インストーラは、この設定ファイルに「crx.json(図2)」の内容を追加することで、当該の不正な拡張機能を新規にインストールします。さらに、インストールした不正な拡張機能を、レジストリの拡張機能許可リストに追加登録します。
上記の設定後、拡張機能インストーラは「crx.7z」アーカイブに含まれるファイルを「User Data\Default\Extension」配下の拡張機能用ディレクトリに移動します。最後に、ブラウザを再起動して不正な拡張機能をアクティブ状態にします。今回標的とされたブラウザは下記を含むChromium系であることが調査によって判明しました。
- Chrome
- Chromium
- Edge
- Brave
- Opera
- Cốc Cốc
- CentBrowser
- Iridium
- Vivaldi
- Epic
- Coowon
- Avast Secure Browser
- Orbitum
- Comodo Dragon
また、不正な拡張機能が標的ブラウザにインストールされる際には、下記の通り2種の異なる拡張機能IDが使用されました。また、そのいずれも公式のChrome用Webストアには存在しないものでした。
- cbnmkphohlaaeiknkhpacmmnlljnaedp
- jikoemlnjnpmecljncdgigogcnhlbfkc
ブラウザ拡張機能の分析
インストール処理の完了後、当該拡張機能の情報が「chrome://extensions/」から確認できる状態になりました。
拡張機能のマニフェストファイルには、2種のJavaScriptが定義されています。1つ目はバックグラウンドスクリプト「background.js」であり、拡張機能のバックグラウンドとしてただ1つのインスタンスで稼働します。2つ目はコンテントスクリプト「content.js」であり、下記のマニフェスト定義に示す通り、coinbase.comへのアクセス時に呼び出されます。
スクリプトの難読化
バックグラウンドスクリプト、コンテントスクリプトのいずれも強力な難読化が施されています。難読化の第一段階として、全ての文字列は短く分割され配列に格納されています。この配列へのアクセスは、5つの16進数の整数パラメータを使用して、16進数文字を組み合わせた名前の関数を呼び出すことで実行されます。
難読化の第二段階として、全ての文字列、論理演算子(+、-、*、/)、関数呼び出しなどは、オブジェクト型の配列に格納されています。個々のオブジェクトには、ランダムな文字列による名前と、それに対応する値として、別の文字列や関数が定義されています。今回分析した例では、_0x1f27e3['PFPYr']は文字列「set」を表し、_0x1f27e3['LYLfc'](0,1)は論理演算「0!=1」として機能します。
いずれの難読化も、専用のスクリプトによる自動解除が可能です。
バックグラウンドスクリプトの解析
以降、スクリプトの解析結果について述べるとともに、サイバー犯罪者が正規の暗号資産ウォレットユーザからアカウント情報を盗み出す手口についても解説します。拡張機能が起動すると、バックグラウンドスクリプトは2つのクエリを作成します。1つ目は「http://<C&Cサーバ>/traffic/chrome」へのGETリクエストであり、これは恐らく統計に使用されるものです。2つ目は「http://<C&Cサーバ>/traffic/domain」へのPOSTリクエストであり、標的端末内で取得したクッキー情報をもとに暗号資産関連Webサイトのドメイン情報を送信します。
- blockchain.com
- coinbase.com
- binance.com
- ftx.com
- okex.com
- huobi.com
- kraken.com
- poloniex.com
- crypto.com
- bithumb.com
- bitfinex.com
- kucoin.com
- gate.io
- tokocrypto.com
- tabtrader.com
- mexc.com
- lbank.info
- hotbit.io
- bit2me.com
- etoro.com
- nicehash.com
- probit.com
続いて、拡張機能は下記の暗号資産やトークンに対応する攻撃者側のアドレス情報を配列で定義します。
- Tether (USDT、特にERC20のEthereum、TRC20のTRON)
- Ethereum(ETH)
- Bitcoin(BTC)
- Litecoin(LTC)
- Binance coin(BNB)
- Ripple(XRP)
- Solana(SOL)
- Bitcoin Cash(BCH)
- Zcash(ZEC)
- Stellar Lumens(XLM)
- Dogecoin(DOGE)
- Tezos(XTZ)
- Algorand(ALGO)
- Dash(DASH)
- Cosmos(ATOM)
ETHに関しては、ERC20系トークンに該当する約170個の追加アドレスがスクリプト内にハードコーディングされています。以上の配列を定義した後、バックグラウンドスクリプトはonMessageのリスナーを用いてコンテントスクリプトや拡張機能プロセスから送られるメッセージの待ち受けを開始します。メッセージはJSON形式による「名前と値」のペアによって記述され、特に「method」の値によって実行内容が指示されます。バックグラウンドスクリプト側で受け取るメッセージのmethod値は下記の通りです。
- Tmethod:homeStart
バックグラウンドスクリプトがこのmethod値のメッセージを受け取ると、APIキー(apiKey)とAPIシークレット(apiSecret)の取得を行います。Chromeのローカルストレージにこれらの値が事前に保存されている場合は、それを使用します。取得したAPIキーとAPIシークレットは、下記の処理に用いられます。
- 「/api/v2/accounts」のAPIにアクセスして暗号資産ウォレット、アドレス、残高情報を取得する。アクセス結果は「http:///traffic/step」に流出させる。
- 成功すると、バックグラウンドスクリプトはコンテントスクリプトに対してmethod値が「okApi」のメッセージを送信した上で、上記で取得したウォレット情報を解析する。もしウォレット残高が0よりも大きい場合は、利用可能残高の85%を攻撃者側のウォレット宛に送金する。また、この送金結果も、「http:///traffic/step」に流出させる。
- 失敗すると、バックグラウンドスクリプトはコンテントスクリプトに対してmethod値が「errorApi」のメッセージを送信する。「errorApi」のメッセージには、「https://www.coinbase.com/settings/api」から得たCSRFトークンの他、APIキー作成結果への参照も含まれる。
- method:createApi
「createApi」のメッセージはコンテントスクリプトから送信され、二要素認証(2FA:Two-Factor Authentication)の入力コードとして「tfa」という名前の値がパラメータの1つとして渡されます。この入力コードはAPIキーの新規作成モーダルを開くために使用されます。通常、CoinbaseのAPI設定メニューで「+New API Key」をクリックすると2FAのコード入力が要求され、入力が正しい場合はAPIキーの新規作成モーダルが表示されます。
次のステップとして、対象の暗号資産ウォレットと権限を選択する必要があります。今回の不正な拡張機能は、全てのアカウントに対して、可能な全ての権限を付与します。
この後、さらに別の認証コードを入力すると、新規に作成されたAPIのキー情報が「API Key details」のフォーム上に表示されます。バックグラウンドスクリプトはこのフォームからAPIキーとAPIシークレットを読み取り、後の使用に備えてChromiumのローカルストレージに保存します。さらに、このペア値を「http://<C&Cサーバ>/traffic/step」にも送信します。API認証に失敗した場合は、「retryApi」のメッセージをコンテントスクリプトに送信します。
コンテントスクリプトの分析
感染した端末から2FAコードを窃取する仕組みを解明するため、コンテントスクリプトの解析を行いました。コンテントスクリプトには、下記の言語に対応した画面表示メッセージがリストで定義されています。
- 英語(en)
- ドイツ語(de)
- スペイン語(es)
- フランス語(fr)
- 日本語(jp)
- インドネシア語(id)
- イタリア語(it)
- ポーランド語(pl)
- ポルトガル語(pt)
- ロシア語(ru)
- タイ語(th)
- トルコ語(tr)
表示用メッセージは「SMSによる認証用」と「承認者による認証用」のそれぞれについて、「タイトル」、「説明」、「エラー情報」の3種が文字列で定義されています。
「SMSによる認証用」で英語の場合、コンテントスクリプトの処理によって下記のメッセージが表示されます。
- タイトル:“Please enter the verification code from your phone.”
- 説明:“Enter the two-step verification code provided by SMS to your phone.”
- エラー情報:“That code was invalid. Please try again.”
「承認者による認証用」で英語の場合、表示されるメッセージは下記の通りです。
- タイトル:“Please enter the verification code from your authenticator.”
- 説明:“Enter the 2-step verification code provided by your authentication app.”
- エラー情報:“That code was invalid. Please try again.”
コンテントスクリプトはまず「/api/v3/brokerage/user_configuration」にアクセスしてユーザがログイン済みであるかを調べます。次に、バックグラウンドスクリプトに対して「homeStart」のメッセージを送ります。この後、バックグラウンドスクリプト側と同様、onMessageリスナーを用いてメッセージの待ち受けを開始します。method値が「okApi」のメッセージを受け取ると、コードローダーを隠し、モーダルウィンドウを削除します。method値が「errorApi」のメッセージを受け取ると、モーダルウィンドウを作成します。
モーダルウィンドウには入力ボックスが用意され、oninputイベントの監視が行われます。各入力ボックスに1桁ずつ数値が入力されると、それらを繋ぎ合わせた値の名前を「tfa(2FA)」として、「createApi」のメッセージのパラメータとしてバックグラウンドスクリプトに送信されます。この際、コードローダーも併せて表示されます。
モーダルウィンドウに表示される入力ボックスの個数は、標的のユーザが使用している認証方式によって変化します。「承認者による認証」を用いている場合は6個の入力ボックスが、「SMSによる認証」の場合は7個の入力ボックスが表示されます。こうした条件分岐のロジックは、モーダルウィンドウ上のコードによって実装されています。最後に、コンテントスクリプトが「retryApi」のメッセージを受け取った場合、下図の通り、モーダル上に入力された値はクリアされ、エラー情報が赤字で表示されます。
結論
CopperStealerの背後にいるサイバー犯罪集団の活動は止む様子がなく、警戒心の薄いユーザを狙ってさまざまな攻撃手段を画策しているように見えます。トレンドマイクロでは引き続き、こうした動向に対する監視を強めていきます。今回の拡張機能と、前回報告したCopperStealerのコンポーネントとの間にはさまざまな類似点が見られました。その1つとして、両者とも同じ感染経路、そして同じドロッパを介して配布される点が挙げられます。
もう1つの特筆すべき類似点は、コマンド&コントロール(C&C)サーバのドメイン文字列が、どちらも同じフォーマットに従っていることです。具体的には、両ドメインとも16進数値の文字列表現で構成されています。さらに、両サーバともPHPフレームワークの「CodeIgniter」によって構築されています。以上の点より、今回発見した不正な拡張機能と、前回報告したマルウェア「CopperStealer」は、開発者または運用者間で何らかの繋がりがあると推測されます。
CopperStealerをはじめとするマルウェアのリスクや脅威を軽減するために、ユーザや組織または企業は、ソフトウェアやアプリケーション、アップデートパッチを公式プラットフォームからダウンロードすることを推奨します。また、セキュリティ対策チームは、システムに対するさまざまな攻撃や感染のリスクを検知、阻止できるように、セキュリティソリューションを常に最新版にアップデートすることを推奨します。
侵入の痕跡(Indicators of Compromise、IoC)
侵入の痕跡(IoC)はこちらで確認してください。
参考記事:
• 「CopperStealer Distributes Malicious Chromium-based Browser Extension to Steal Cryptocurrencies」
By: Jaromir Horejsi, Joseph C Chen
翻訳:清水 浩平(Core Technology Marketing, Trend Micro™ Research)