マルウェア
Discordから個人情報漏洩の危険性あり:Codespaceを悪用する情報窃取型マルウェアについて解説
この記事では、Discordから個人情報が漏洩してしまう危険性について紹介します。Codespaceを不正利用し標的端末内で永続化する情報窃取型マルウェアの手口について、調査結果をもとに詳しく解説します。
主要なコミュニケーションツールの1つである「Discord」の普及は、利便性とリスクの双方をもたらしました。パンデミック期に大勢のユーザが新規参入したことに伴い、サイバー犯罪者も本プラットフォームに高い関心を寄せるようになり、結果としてセキュリティ面やプライバシー面での懸念が浮上しました。攻撃者側の視点から見ると、世界の月間アクティブユーザ数が1億5千万にも及ぶDiscordは、活動の拠点に利用できそうなサーバの集積地としても、被害に遭いやすいユーザが多数存在する猟場としても、魅力的に映るものです。
前回の記事では、Rust言語で作られた情報窃取ツールについて解説しました。このツールはWindowsプラットフォーム上で動作し、解析やデバッグを妨害する機能を備え、ファイル共有・ストレージサービス「Gofile」や、クラウド開発環境「Codespace」の「Webhook」を用いて情報窃取を行います。窃取対象の情報として、Chromiumブラウザをベースとする認証情報や、クレジッドカード情報、暗号資産ウォレット、SteamおよびDiscordのトークン情報などが挙げられます。本稿では、この情報窃取ツールに関する新たな発見事項として、被害端末内のDiscordクライアントを改ざんして永続化を実現した手法について解説します。なお、以降に挙げるスクリーンショットや詳細情報は、以下のi検体に対する解析結果となります。
SHA256:c92a7425959121ff49970c53b78e714b9e450e4b214ac85deb878d0bedf82a70
「GitHub Codespace」をはじめとするクラウド開発環境により、開発者は場所を問わずにどこからでも業務を行えるようになりました。しかし、こうした自由度や柔軟性が攻撃者側に不正利用される場合もあります。2022年7月、Rust言語で作成された情報窃取型マルウェアのソースコードが、アンダーグラウンドのフォーラム上に流出しました。攻撃者は、流出したコードを各種経路から入手し、無料で使用可能なクラウド開発環境の利点を活かすことで、さらに手際よくマルウェア開発を進めていくと考えられます。こうした状況を踏まえると、クラウド開発環境のユーザにとって、クラウドセキュリティの確保は重要な課題の1つと言えるでしょう。
マルウェア解析
今回の情報窃取ツールは、被害端末にインストールされたアプリケーション「Discord」を改ざんすることで、認証情報を継続的に窃取します。本ツールでは、起動時に指定されたコマンドライン引数が2つ以上の場合に感染処理(図1の関数「malware::discord::inject」)をスキップする仕組みが備わっています。これは、被害端末内のDiscordが2度以上に渡って感染することを防ぐためです。引数が2つ以上指定された場合、その個数や内容自体が動作に影響を与えることはありません。
コマンドライン引数が2つ未満の場合、感染処理の初期段階として、下記に示すノードモジュール「discord_desktop_core」のASAR(Atom Shell Archive Format)ファイルを改ざんします。
%localappdata%\\Discord\app-<version>\modules\discord_desktop_core-1\discord_desktop_core\core.asar
ASARは、フレームワーク「Electron」が用いるアーカイブ形式の1つであり、アプリケーションを構成するJavaScriptやHTML、CSSなどの各種リソースを1つのファイルに圧縮して配布する目的で使用されます。DiscordのWindows版、Linux版、MacOS版は、Electronによって開発されています。今回の情報窃取ツールは、図2と図3の通り、感染処理の過程で「index.js」の中身を改ざんし、パッケージ「discord_desktop_core」の內部に不正なバックドア機能を埋め込みます。
図3の24行目が示すように、関数「startup」の內部で、JavaScriptモジュール「cdn」が呼び出されます。これが、改ざん前のDiscordとの明確な相違点です。「cdn.js」の内容を解析したところ、本情報窃取ツールが監視対象とするURLのリストが2種類発見されました(図4の「filter1」と「filter2」)。
上記URLリストに続く形で、2つの定数「json_file」と「executable」が定義されます(図5)。このうち、「json_file」にはJSONファイルへのパスが、「executable」にはコマンドライン引数付きで情報窃取ツール自身のパスが設定されます。前述の通り、コマンドライン引数を2つ以上添えて情報窃取ツールを起動した場合、アプリケーション「Discord」に対する感染処理自体はスキップされます。
初回起動時、情報窃取ツールは自身のコピーを以下のパスに作成します。
%AppData%\defender.exe
図6の「BrowserWindow」は、フレームワーク「Electron」が提供するJavaScriptのクラスであり、Webブラウザ用ウィンドウの作成や調整を行います。メソッド「getAllWindows()」は、開かれている全ブラウザ用ウィンドウを配列で返却します。今回の場合、返却された第一番目のウィンドウが処理対象となります。そのウィンドウに属するクラス「webContents」は、Webページのレンダリングや調整を行います。最後にメソッド「executeJavaScript」は、対象Webページのコンテキスト下で、第一引数として指定されたコードを実行します。第二引数については、ユーザによるアクションなしで当該コードを実行させるオプションであり、今回は「true」に設定されています。
上述した第一引数のコードは、全体として、ユーザを強制的にログアウトさせ、再ログインのためにメールアドレスとパスワードの入力を促すように動作します。メソッド「setInterval」內部のコードは、iframe(インラインフレーム)を作成し、「localStorage.token」に空文字を設定することで、Discordのトークン情報を消去します。「localStorage」は、ブラウザエンジン「Chromium」が提供する永続的なWebストレージです。Electronベースのアプリでは通常、Discord用トークン情報を含むユーザ情報の保存先として、このストレージを使用します。続いて、メソッド「setTimeOut」により、ログインページが2.5秒後にリロードされるようになります。この結果、ユーザは強制的に再ログインの手順を踏まされることとなります。今回の攻撃者は、一連の手口に関する着想を、図7に示す「Gist」から得たものと推測されます。
以下のイベントを定義することで、Electronアプリケーションの「defaultSession」によってネットワークリクエストが送信される前に割り込みをかけ、リクエストの内容や動作を改変することが可能です。
session.defaultSession.webRequest.onBeforeRequest
今回の場合、以下のURL宛てのリクエストがキャンセルされるように改変されています。
wss://remote-auth-gateway.discord.gg/
この結果、被害者はログイン時にQRコードを使用できなくなり、代わりにメールアドレスとパスワードの使用を余儀なくされます(図9)。そこで入力したパスワードなどは、後に情報窃取ツールによって収集され、攻撃者側に送信されます。
以下のイベントを定義すると、先と似たような仕組みにより、ネットワークリクエストがElectronアプリケーションの「defaultSession」によって処理された後に割り込みをかけ、特殊な処理を追加することが可能です。
session.defaultSession.webRequest.onCompleted
図12の通り、情報窃取ツールは、先述の「filter1」または「filter2」で設定したURLへのリクエストを監視します。リクエストに対する応答コードが「200(OK)」または「202(Accepted)」の場合、JSONデータを解析し、その内容を別の変数「data」に格納します。さらに、Discordのクライアント用関数「getToken」を呼び出します(図13、図14)。
上図の関数「discordFunction」を引数「getToken」を添えて呼び出すと、第一番目のBrowserWindowによるコンテキスト下で、下記のコードが実行されます。
上記コードでは、Discordのトークン情報を取得済みで、かつ定数「json_file」で示される以下のファイルが存在しない場合、当該ファイルを新規に作成し、トークン情報を書き込みます。
%AppData%\call.json
次に、下記コマンドラインを実行します。
defender.exe deltastealer666 40929288_CLIENT_ID 309393883ndnjdje 3747dnjdj 28187dhjjsjs 298sjsj
本コマンドラインによって情報窃取ツールが再度呼び出されますが、引数が2個以上指定されているため、感染処理はスキップされます。
2. Discordのログイン認証情報(メールアドレスとパスワード)
ユーザがDiscordアカウントにログインすると、動作上、図16のように認証情報がPOSTリクエストで送信されます。
上図のURLは、以下のとおり、図4の12行目で示した監視対象のパターンと合致します。
https://discord.com/api/v9/auth/login
結果、図17の通り、情報窃取ツール側ではリクエスト内のJSONデータを傍受し、そこから抽出したパスワードを以下のファイルに保存します。
%AppData%\call.json
さらに、関数「exec」を呼び出してパスワードを攻撃者宛てに流出させます。
図18の「gofile_link」は、ファイル共有サービス「GoFile」のURLであり、窃取された情報の格納先ファイル「diagnostics.zip」を指します。この内容もまた、情報窃取ツールのコピー「defender.exe」によって攻撃者側に流出します。
3. ユーザによって更新されたログイン認証情報(メールアドレスとパスワード)
上記と類似した動作として、ユーザがログイン用のメールアドレスやパスワードを更新した際にも、その内容がCodespaceのWebhook側に流出します(図20)。
実際にユーザがメールアドレスを更新した際の通信履歴を確認したところ、更新を示唆するデータが確かにGitHub CodespaceのWebhookに送信されることが分かりました。しかし、図19の109行目に指定された更新後のメールアドレス「data.login」は誤りであり、正しくは「data.email」であるべきと考えられます。「data.login」のデータは存在しないため、図21の通り、更新後のメールアドレスがWebhook側に送信されることはありません。
4. クレジットカード情報とPayPalのステータス
情報窃取ツール「PirateStealer」との類似点
GitHub上で今回の情報窃取ツールと類似するJavaScriptコードを探したところ、機能強化を図ったと考えられる新規バージョン「PirateStealer」が新たに発見されました(図23)。
PirateStealerのAPIは、クレジットカードの支払いに関連する処理を呼び出します。この処理においても、クレジットカード情報の窃取が行われます。また、PayPalの情報が登録済みかどうかのチェックも行います。これは、対象ユーザが課金サービス「Discord Nitro」に加入済みであることを確かめるためと推測されます。ユーザが課金サービスの利用を開始する場合、クレジットカードやPayPal、Venmoなどの支払い方法を設定する必要があります。
監視対象のURLリスト中、末尾が「paypal_accounts」で終わるものとして、下記が確認されました。
https://api.braintreegateway.com/merchants/49pp2rp4phym7387/client_api/v*/payment_methods/paypal_accounts
上記URLの「Braintree」は、支払い関連業務を扱うPayPalの子会社です。以下については、PayPalの文書によると、Discordがユーザからの支払いを受ける際に用いる一意な販売者ID(Merchant ID)に相当します。
49pp2rp4phym7387
実際に感染したDiscord上でクレジットカード情報を登録したところ、初期のリクエスト(図24)が下記URL宛てに送信されました。
https://client-analytics.braintreegateway.com/49pp2rp4phym7387
被害者が正規のクレジットカード情報を登録すると、PayPal情報の存在を示すステータスが情報窃取ツールを通してCodespace側に送信されます。これにより、攻撃者側では、クレジットカード情報がDiscordのプロフィール内に入力済みであることを判断できるようになります。なお、PirateStealerのコード中には未定義の関数や誤った箇所も見られるため、本マルウェアは依然として開発途上にあると推測されます。
上で挙げた各種情報は、Webhook同様に機能する「GitHub Codespaceの公開ポート」に送信されます。また、先述の処理は、Discordが被害端末上にインストールされている場合にのみ動作するものであり、ユーザ側からの操作を必要とします(情報窃取ツールに感染後、ユーザがメールアドレスとパスワードを用いてDiscordにログインしない限り本稼働しない)。
図25に、本情報窃取ツールによる全体的な処理の流れを示します。
結論と推奨事項
Covid-19の影響を受けて多くの人々がオンラインによる交流の場を求めたことにともない、Discordは当初のゲーマー層からなるユーザベースを大きく超えて成長しました。多種多様な目的を持つ大勢のユーザを獲得した結果、Discordは、リスク(米国国防総省の機密文書が流出した件)および被害者(今年はじめのデータ流出に関する報告)という双方の面で、セキュリティ事象をおびき寄せる傾向にあります。今回の調査より、サイバー犯罪者はDiscordのユーザを標的とする高度なツールを開発し続けていると考えられ、将来的には、Discordへの攻撃が増加していくと推測されます。
GitHubをはじめとする開発者向けプラットフォームは、従来のセキュリティソリューションから一定の信頼を置かれているため、それを逆手に取る形で攻撃者に不正使用される場合があります。トレンドマイクロでは、これらのプラットフォームが不正使用されたインシデントを多数確認してきました。その1つが、最近発生した3CXのサプライチェーン攻撃であり、攻撃者が管理するGitHubのリポジトリ内に、暗号化されたコマンドコントロール(C&C:Command and Control)サーバの情報が格納されていました。
Codespaceを使うことで、ポートを外部に公開することが可能です。このことは、インターネット上のあらゆるユーザが、認証の手続きなどを行うことなく、当該ポートを経由する形でCodespaceの仮想マシンにアクセスできることを意味します。Codespaceが生成するURLのドメイン部はランダムであり、脅威インテリジェンス・プラットフォームでも不正な活動が記録されていません。そのため、保護された環境からデータを流出させるなどの目的で、当該URLが攻撃者によって利用される可能性があります。
「dev-containers」や「Codespace」のように開発者を支援する機能やサービスは、環境構築やリソース配備といったソフトウェア開発上の苦労を軽減するものです。しかし、これは攻撃者にとっても同様であり、不正なソフトウェアのビルド、テスト、配布などの目的に利用される場合があります。攻撃者はクラウド開発環境を活用し、さらに既存の情報窃取ツールから各機能を抜き出して再利用することで、マルウェアのビルドやテストを迅速に実行できるようになると考えられます。
数多くのツールやプラットフォーム、サービスが一般公開されるのに伴い、それを利用したサイバー攻撃のリスクも高まると予想されます。企業や組織では、攻撃者に先手を取られないようにするため、システム内で発生している各種事象を明確に把握することが求められます。そのための推奨事項を、下記に挙げます。
- 企業や組織、およびサイバーセキュリティチームでは、Codespaceなどの開発環境を不正使用する手口が数多く存在する点に注意してください。こうした開発環境の恩恵は、攻撃者側にも当てはまるためです。例として、配備したプロキシから発信される外向けのDNS通信ログについては、不正な活動やマルウェアの兆候として監視、検査することを推奨します。
- クラウドサービス・プロバイダ側では、クラウド開発環境へのアクセスを制限する機能を提供する他、サービスが不正使用されるリスクや攻撃シナリオ、およびそれに基づく脅威モデルを検討してください。具体例として、前回の記事でも解説したように、Codespaceをオープンディレクトリとして不正使用する手口が挙げられます。
侵入の痕跡(Indicators of Compromise、IoC)
侵入の痕跡(IoC)はこちらで確認してください。
参考記事:
Info Stealer Abusing Codespaces Puts Discord Users at Risk
By: Nitesh Surana, Jaromir Horejsi
翻訳:清水 浩平(Core Technology Marketing, Trend Micro™ Research)