脅威リサーチ

巧妙に細工されたExcel文書を利用して拡散される新種のDridex

投稿者 Xiaopeng Zhang | 2021年9月28日

FortiGuard Labs Threat Research Report

影響を受けるプラットフォーム: Microsoft Windows
脅威を受ける対象:       Windowsユーザー
影響:             被害者のコンピュータから機密情報を収集し、被害者のデバイスに不正なモジュールを配信し、実行します。
深刻度:            クリティカル

Dridexは、BugatやCridexとも呼ばれるトロイの木馬型マルウェアで、感染したマシンから機密情報を盗み出し、不正なモジュール(dll)を配信および実行できます。

FortiGuard Labsは最近、巧妙に細工されたExcel文書の添付ファイルを含む新しいフィッシングEメールキャンペーンが出回っているのを捕捉しました。そのうちの1つを詳しく調べてみたところ、被害者のマシンで不正なExcel文書を開くと、Dridexの新種がダウンロードされることが判明しました。

この解析では、Excel文書がDridexをダウンロードする仕組み、この新種のDridexが被害者のデバイス上で実行される仕組み、どのような機密情報が収集されるのか、さらには不正なモジュール(dll)を配信する仕組みについて詳しく説明します。

Dridexの亜種のフィッシングメール

図1.1は、最近捕捉された、Dridexに感染した不正なExcelの添付ファイルを含む、フィッシングメールの例です。

図1.1:最近捕捉されたフィッシングメールのテキスト

ご覧のように、このメールは輸入関税データを顧客に送信したように装い、添付されたExcelファイル(ここでは「HF7.TRANS 2021.08.09.xlsb」)を開いて詳細を確認するよう求めています。

Excel文書内のマクロの解析

受信者が添付されているExcel文書を開くと、文書の上部に「マクロを有効にしてください」というメッセージが赤色の太字で表示されます。ただし、マクロが現在無効になっていることを示す黄色の「セキュリティ警告」バーが表示されます。これは、図2.1に示すように、「コンテンツを有効にする」ボタンをクリックすると危険があることを意味します。

図2.1:感染したExcel文書を開くと、警告バーが表示される

このExcelファイルの内部を調べてみると、自動実行マクロ(VBA)だけでなく、Excel 4.0マクロも使用されていました。マクロ(VBA)の中にはWorkbook_Open()という自動実行関数が含まれており、Excelファイルを開くとこの関数が自動的に呼び出されます。

そのコードは以下のとおりです。

Sub Workbook_Open()
    ActiveWorkbook.Sheets("Macro1").Range("A1").Value=Environ("allusersprofile")& 
    "\KgmsgJbgP.sct"
End Sub

このコードは、「Macro1」という名のシートの「$A$1」セルに、Environ("allusersprofile")& "\KgmsgJbgP.sct"(このテスト環境では「C:\ProgramData\KgmsgJbgP.sct」)を設定するだけです。

「Macro1」は、図2.2に示すように「xl\workbook.xml」というファイルに定義されたExcel4.0のマクロを格納し、実行する非表示のシートです。

図2.2:「Workbook.xml」に定義されているExcel 4.0のマクロシート

Excel 4.0マクロは、さまざまなセルの数式を使用してコードを実行します。開始セルを指定さえすれば、コードが上から下へ、さらには左から右に向かって実行されます。

自動実行マクロ(VBA)が実行された後、Excel 4.0マクロがセル「Macro1!$A$4」から自動的に実行されます。

Excel 4.0マクロは、「Macro1」シート内のセルの集合からデータをローカルファイルに抽出します。そのファイルパス(C:\ProgramData\KgmsgJbgP.sct)が$A$1に保存されます。抽出されたデータは、VBScriptコードの一部を含むHTMLアプリケーション(.htaファイル)です。Excel 4.0マクロの最後の手順は、この「KgmsgJbgP.sct」ファイルを「mshta」コマンド(=EXEC(CONCATENATE("mshta ", CHAR(34), A1, CHAR(34))))を使って実行します。

最終的に、「mshta.exe C:\ProgramData\KgmsgJbgP.sct」コマンドが実行されます。「mshta.exe」は、HTML、ダイナミックHTML、VBScriptやJScriptなどのInternet Explorerでサポートされている1つ以上のスクリプト言語を使用してhtmlアプリケーション(.htaファイル)を実行するために使用されるWindowsのデフォルトプログラムです。

Dridexペイロードのダウンロードに使用されるHTMLアプリケーション

図3.1:抽出されたhtaファイル内の不正なVBScriptコード

図3.1に示すように、VBScriptコードには、Dridexペイロードにリンクされている10個のURLの配列(詳細については以下の「IOC」セクションを参照)が含まれています。Dridexは、forループ内のこれら10個のURLから、このVBAScriptコード中にハードコードで指定されているローカルファイル「%ALLUSERSPROFILE%\\icXBOuZukiASGnpfVowZ.dll」にダウンロードされます。Dridexが正常にダウンロードされると、「wmic.exe」(WMIコマンドライン)が実行され、新しいプロセス「rundll32.exe」が作成されます。

簡略化したコードは以下のようになります。

CreateObject("Wscript.Shell").Exec("wmic process call create \"Rundll32.exe %ALLUSERSPROFILE%\\icXBOuZukiASGnpfVowZ.dll ReportDeviceAdd\"")

最後に、Rundll32.exeはDridexのペイロードファイル「icXBOuZukiASGnpfVowZ.dll」をロードし、その「ReportDeviceAdd」というエクスポート関数を呼び出して、不正な関数を実行します。

ダウンロードしたDridexペイロードファイルへの潜入

図4.1:IDA ProにおけるDridexの亜種のエクスポート関数リスト

図4.1は、IDA ProにおけるDridexのペイロードファイルのエクスポート関数リストです。これには、次の2つの関数が含まれています。DllEntryPoint()は、このdllのエントリ関数です。もう1つの、FWroeeWqoinnmw()は、実際のエントリ関数です。ここで奇妙なのは、このDridexの亜種の出発点であるはずの「ReportDeviceAdd」の関数がないことです。

この問題を解明するために、Rundll32.exeがモジュールをロードしてから、そのエクスポート関数を呼び出すために使用する内部戦略を解析しました。図4.2は、Dridexペイロードファイルの解凍後のエクスポート関数のリストです。6つのエクスポート関数が用意されています。4番目の関数は「ReportDeviceAdd」です。

図4.2:解凍されたペイロードファイルのエクスポート機能リスト

ここでは、Rundll32.exeによってDridexのペイロードファイルがロードされる手順を説明します。

Rundll32がDLLをロードし、エクスポート関数を呼び出すために使用する手順:

  1. Rundll32.exeはAPI LoadLibrary()を呼び出してdllをメモリにロードし、PE構造に従ってデプロイします。
  2. まず、dllのエントリポイント関数、DllEntryPoint()を呼び出してモジュールを初期化します。
  3. 次に、「ReportDeviceAdd」という関数名でAPI GetProcAddress()を呼び出し、手順2で初期化したモジュールから関数アドレスを取得します。
  4. そうすると、Rundll32.exeが、手順3で取得した関数アドレスを呼び出します。

このペイロードファイルには、人に調べられないようにするためのパッカーのようなプログラムも含まれています。このプログラムは、ペイロードファイルのDllEntryPoint()が呼び出されると、手順2の解凍を行います。

この時点から、Rundll32.exeは、API GetProcAddress()を呼び出すことで、ReportDeviceAddを取得できます。

Dridexで使用されている解析防止技術

最近のマルウェアの多くは、解析されないようにコードに解析防止技術を組み込んでいます。

このDridexの亜種は、私が昨年解析した別のDridexの亜種と同様の解析防止技術を使用しています。すなわち:

  • すべてのAPIは非表示であり、名前のハッシュコードによって検知されます。
  • 定数文字列全体がメモリ内で暗号化され、使用する直前に復号化されます。
  • 一部のAPIは、意図的に例外(0x80000003)を発生させるように、巧妙に細工して呼び出されます。次に、例外ハンドラー関数内で例外を捕捉し、実際にAPIを呼び出します。

C2サーバーに送信されるパケットのフォーマット

Dridexは、被害者の感染したデバイスから機密データを収集し、そのデータをフォーマットされたパケットに格納して暗号化し、C2サーバーに送信します。

図5.1は、暗号化される最中のC2サーバーへの最初のパケットのスクリーンショットです。C2サーバーへのパケットの形式は、すべて同じものです。例として、以下でパケットのフォーマットについて詳しく説明します。スクリーンショットでは、赤色のパイプで多数のフィールドに分割されています。

選択された部分は全パケットに共通するデータであり、この解析では「パケットヘッダー」と呼ばれています。

図5.1:暗号化される前のC2サーバーへの最初のパケット

表5.1に、パケットフォーマットの各フィールドの内容を示します。

 

オフセット

長さ

データ

0x00

0x01

被害者のID文字列の長さ。

0x01

0x29

被害者のID文字列。変数。

0x2A

0x20

感染したデバイスのハードドライブのボリューム情報。

0x4A

0x02

Dridexのバージョン情報:この亜種では0x56B9。

0x4C

0x04

感染したWindowsのバージョン情報が含まれるdword。

0x50

0x04

パケットタイプの識別。0x18F8C844は最初のパケット。

0x54

0x01

Windowsプラットフォーム。32ビットは0x20、64ビットは0x40。

0x55

変数

被害者のシステムから収集したデータ。

表5.1:パケットのフィールドの復号化

- 被害者のID文字列には、コンピュータ名、アンダースコア、およびコンピュータ名、ユーザー名、Windowsシステムのインストール日を含む文字列のMD5ハッシュコードが含まれています。

- ハードディスクのボリューム情報は、「C:\」のボリューム情報とWindowsのインストール日のデータをMD5値で表したものです。

- 0x56B9は、マルウェアにハードコードされたデータであり、マルウェアのバージョンである可能性があります。

- 0x11C1B11Dは、Windowsのバージョン情報の混合データセットで、API GetVersionEx()とGetSystemInformation()の結果から取得されたものです。

- Dridexのこの亜種には、C2サーバーへの通知に使用されるパケットタイプIDが5つ含まれています。それらは、0x18F8C844、0x69BE7CEE、0x11041F01、0xD3EF7577、0x32DC1DF8です。

- 0x20に続くデータは、被害者のWindowsシステムが32ビットプラットフォームであることを示しています。

すべてのDridexパケットヘッダーのフィールド値(パケットタイプIDを除く)は、同じマシン上のすべてのパケットで同じです。

収集されたデータ(オフセット0x55から開始)は、収集されたデータサイズ(ネットワークバイトオーダーで4バイト)に収集されたデータが続く、2つのフィールドを持つパケットヘッダーに付加されます。

収集した情報のC2サーバーへの送信

以前のバージョンと同様、C2サーバーのIPアドレスとポートはデータにハードコードされています。以下は、3台のC2サーバーのIPリスト(バイナリ)です。

.data:72C6D02C         dd 2C94B67h     ; IP: 103.75.201.2
.data:72C6D030         dw 1BBh         ; port: 443
.data:72C6D032         dd 6C01DF9Eh    ; IP: 158.223.1.108
.data:72C6D036         dw 1851h        ; port: 6225
.data:72C6D038         dd 0F21C16A5h   ; IP: 165.22.28.242
.data:72C6D03C         dw 1238h        ; port: 4664

マルウェアは、forループ内で1つのIPアドレスとポートのペアを選択します。C2サーバーへの1つの接続の確立が成功すると、その接続はプロセスの存続期間を通じて使用されます。

「0x18F8C844」は、最初のパケットのパケットIDです。収集されたデータは、インストールされているソフトウェア全体(ソフトウェア名とバージョンを含む)と、感染したシステムで定義されているすべての環境変数で構成されています。

システムレジストリの「HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall」というキーの下にあるサブキーを列挙することで、インストールされているソフトウェアの情報を1つ1つ取得していきます。

また、被害者のシステムで定義されている環境変数の値も盗みます。今回使用したテストマシンでは、ALLUSERSPROFILE、APPDATA、CommonProgramFiles、COMPUTERNAME、ComSpec、FP_NO_HOST_CHECK、HOMEDRIVE、HOMEPATH、LOCALAPPDATA、LOGONSERVER、NUMBER_OF_PROCESSORS、OS、Path、PATHEXT、PROCESSOR_ARCHITECTURE、PROCESSOR_IDENTIFIER、PROCESSOR_LEVEL、PROCESSOR_REVISION、ProgramData、ProgramFiles、PSModulePath、PUBLIC、QT_AUTO_SCREEN_SCALE_FACTOR、SystemDrive、SystemRoot、TEMP、TMP、USERDOMAIN、USERNAME、USERPROFILE、VS140COMNTOOLS、およびwindirです。

API GetEnvironmentStringsW()を呼び出して、上記の環境変数の値をすべて取得します。図6.1は、メモリ上で取得した名前/値ペアのセットの一部です。

図6.1:被害者のデバイスで取得した環境変数の表示

最初のパケットが終了すると、Dridexはそのパケットを暗号化し、HTTP POSTメソッドを使用してC2サーバーに送信します。InternetConnect()、HttpOpenRequestW()、HttpSendRequestW()、HttpQueryInfoW()、InternetReadFile()などのAPIのグループを呼び出してデータを送受信します。

残念ながら、今回の解析中にC2サーバーがダウンしていたため、C2サーバーとの間でデータを送受信できませんでした。ただし、そのコードワークフローに従って、Dridexの偽のC2サーバーを作成してサーバーの動作をシミュレートし、Dridexへの受信および返信を行い、今回の研究を続行することができました。次の解析は、このシミュレーションデータに基づいています。

C2サーバーからの不正なモジュールのデプロイと永続性の実現

C2サーバーから1つ目のパケットに対する応答パケットを受信すると、サーバーは収集されたデータなしで2つ目のパケット(パケットID 0x11041F01)を送信します。応答パケットに不正なモジュール(dllファイル)が含まれているはずです。Dridexは、パケットの最初の4バイトであるパケットのハッシュコードを比較して、応答パケットを確認します。次に、Dridexは別のパケット(パケットID 0xD3EF7577)を送信し、モジュールの受信に成功したことをC2サーバーに通知します。

図7.1:2番目の応答パケットから抽出されたモジュール

2番目の応答パケットには、暗号化されたモジュール(dll)が含まれています。Dridexは受信したパケットを確認した後、図7.1の下部に表示されているメモリデータのようなモジュールを復号化します。

Dridexは、この不正なモジュールを被害者のマシンにデプロイし、スケジュールタスクを作成してそのモジュールを実行します。その方法を見てみましょう。

Dridexは、被害者のマシン上でモジュールを秘密裏に実行し続けるために、Windowsのデフォルトプログラムを使用してモジュールをロードし、実行します。選択したプログラムがロードする必要のあるWindowsプログラム(exe)とdllファイルのペアを「%windir%\system32」からランダムに選択します。次に、Dridexは選択したdllファイルを受信したモジュールで上書きできます。したがって、選択したプログラムが起動すると、選択したdll内の不正なモジュールが実行されます。

このようにして、被害者は、マルウェアモジュールではなく、Windowsのプログラムが実行されていると推測してしまいます。

図7.2は、「%windir%\system32\」から選択したばかりのWindowsプログラムとdllファイルのペアのスクリーンショットです。

図7.2:選択したWindowsプログラムとdll

Dridexは、選択したWindowsプログラム(今回は「sdclt.exe」)を、「%appdata%」フォルダの下の新規作成したフォルダに、ランダムな文字列(「Okuo」など)とともにコピーします。一方、選択したdll(「slc.dll」)をメモリに読み込み、そのデータを2つ目のパケットに対する応答から得られた不正なモジュールで上書きします。最後に、DridexはAPI WriteFile()を呼び出して、コピーしたWindowsプログラムの同じフォルダに保存します。これ以降、Windowsプログラム「sdclt.exe」が起動するたびに、不正なモジュールを含む「slc.dll」がロードされ、実行されます。

Dridexは、感染したWindowsシステムにスケジュールされたタスクを作成し、被害者のマシン上で永続性を実現します。タスクのアクションは、は、コピーされたWindowsプログラム(すなわち「sdclt.exe」)を起動するだけで、30分ごとにこのアクションを繰り返すようにトリガーされます。

図7.3は、「Tixvzwbtojdsmg」という名前のタスクが追加された「タスクスケジューラ」と、「Okuo」フォルダにコピーされた「sdclt.exe」および「slc.dll」ファイルのスクリーンショットです。

図7.3:スケジュールされたタスクへの追加およびコピーされたWindowプログラムとDLLファイル

スケジュールされたタスクに追加する以外にも、デプロイされた直後にAPI CreateProcessW()を呼び出して「sdclt.exe」を1回実行します。

終了する前に、DridexはID 0x69BE7CEEのパケットを送信し、被害者のマシンに不正なペイロードが正常にインストールされたことをC2サーバーに通知します。図7.4は、このパケットを生成して送信するためのコードスニペットです。

図7.4:パケット0x69BE7CEEを処理するコードスニペット

結論:Dridexの亜種

ここまでで、このDridexキャンペーンがどのように実行されるかについて、フィッシングメール、添付されたExcel文書内の不正なコードが実行されてHTMLアプリケーションファイルが抽出される仕組み、そして最後に、Rundll32.exeが呼び出されてダウンロードされたDridexペイロードファイルが実行される仕組みについてご理解いただけたと思います。

今回は、Dridexのこの亜種がC2サーバーと通信する仕組み、パケットに含まれるフィールド、C2サーバーに不正なモジュールを要求する仕組み、感染したシステムにモジュールがデプロイされる仕組みについて詳しく説明しました。

また、DridexがC2サーバーと通信する方法を示すフローチャートを図8.1に作成しました。このチャートには、どのようなパケットやデータがC2サーバーに送信され、いつ不正なモジュールを受信したのかが明確に示されています。これは、プロセス全体をよりよく理解するのに役立ちます。

図8.1:DridexとそのC2サーバー間の通信フローチャート

フォーティネットのソリューション

フォーティネットのお客様はすでに、FortiGuardのWebフィルタリング、AntiVirus、および以下のようなFortiEDRサービスによって、すでにこのマルウェアから保護されています。

FortiGuardのWebフィルタリングサービスは、ダウンロード用のURLを「不正なWebサイト」として評価します。

添付されたExcel文書とダウンロードした実行ファイルは「MSExcel/Dridex.AC!tr」および「W32/Dridex.HMAH!tr」として検知され、FortiGuardアンチウイルスサービスによってブロックされます。

FortiMailユーザーはFortiGuardアンチウイルスによって保護されており、元のExcel文書はフィッシングメールの悪意のある添付ファイルとして検知されます

FortiEDRは、ダウンロードした実行ファイルの振る舞いから、それを不正なファイルとして検知します。

IOC(Indicators of Compromise:侵害指標)

URL:

"hxxps[:]//assettagger[.]saleseos[.]com/Classes/PHPExcel/Shared/JAMA/examples/RLFBubHuLTnm[.]php"
"hxxps[:]//reportingdashboard[.]mobilisedev[.]co[.]uk/includes/6WSSUhQrM[.]php"
"hxxps[:]//loans[.]uhuruloans[.]com/wp-includes/sodium_compat/namespaced/Core/ChaCha20/X8av4FUl7STEot3[.]php"
"hxxps[:]//practice[.]haylawdesign[.]com/wp-content/themes/twentynineteen/template-parts/content/jE4zYiuJ0iIw[.]php"
"hxxps[:]//kings[.]inforwizztechnologies[.]com/wp-content/plugins/aapside-master/elementor/widgets/tfOSpcBiZpffptj[.]php"
"hxxps[:]//pizzaplus[.]com[.]ng/wp-content/themes/twentytwentyone/template-parts/content/TZ6qTYLx7l[.]php"
"hxxps[:]//efshub[.]com/PHPMailer-master/examples/images/zunuLqqNQIGJPht[.]php"
"hxxps[:]//user[.]kasikoi[.]info/static/lib/ckeditor/skins/moono/2h80F9GORDfIB[.]php"
"hxxps[:]//deepsource[.]in/ncsitebuilder/css/flag-icon-css/flags/1x1/wcToKXeb7FxQ[.]php"
"hxxps[:]//ebanking[.]hentostreasury[.]com/account/umSqqCiyMf[.]php"

C2サーバーのIPおよびポート:

"103.75.201.2:443" 
"158.223.1.108:6225"
"165.22.28.242:4664"

SHA-256のサンプル:

[HF7.TRANS 2021.08.09.xlsb]
59C8D87A450F0647BEA930EBA1AA692B75D82DEF1358F1601C4FE9A561B4707E
[DTCZ SHIP_2021.08.09.xlsb]
C8065BD2A1443FF988E9BA95022554F6EE302E9BCB4082C3D9B2B8D74C5A4BE5 
[icxbouzukiasgnpfvowz.dll]
6556E4029CF50C9538F4E02D0BCCA5356F28E6870E62838E164020A31B3DF096