脅威リサーチ

フィッシングメールに添付されたHTMLファイルがQakBotの新型亜種を拡散

投稿者 Xiaopeng Zhang | 2022年9月26日

フォーティネットのFortiGuard Labsは、フィッシング攻撃の一環として、QakBotの新型亜種がフィッシングメールによって拡散されていることを確認しました。情報窃取ツールであり金融機関を標的にするトロイの木馬でもあるQakBotは、QBot、QuackBot、あるいはPinkslipbotとも呼ばれ、2007年からセキュリティリサーチャーによって捕捉、分析されています。

筆者はキャプチャしたEメールを使用して、このフィッシング攻撃とQakBotの新型亜種を詳細に分析しました。この分析記事では、添付されたHTMLファイルからQakBotの新型亜種のダウンロードと実行に至る経緯や、被害者のマシンでのQakBotの動作、被害者のデバイスから収集したデータをC2サーバーに送信する方法などを解説します。

影響を受けるプラットフォーム: Microsoft Windows
影響を受けるユーザー:     Microsoft Windowsのユーザー
影響:             被害者のデバイスを制御して、機密情報を収集
深刻度:            クリティカル

フィッシングメールと添付HTMLファイル

図1.1は、受信者に添付HTMLファイル(ScannedDocs_1586212494.html)を開かせるためにハッカーが使用したフィッシングメールを示しています。このフィッシングメールは、フォーティネットのFortiMailによってスパムとしてマークされました。

図1.1:キャプチャされたフィッシングメールの表示

このHTMLファイルにはJavaScriptコードが含まれており、受信者がWebブラウザでこのファイルを開くとそのコードが自動的に実行されます。これにより、ローカル変数が保持しているbase64文字列がデコードされます。次に、組み込み関数navigator.msSaveOrOpenBlob()が呼び出され、base64デコードされたデータ(ZIPアーカイブ)が「ScannedDocs_1586212494.zip」というローカルファイルに保存されます。図1.2は、base64文字列で表された定義済み変数と、ZIPファイル名を示しています。

図1.2:HTMLファイル内のJavaScriptスニペットコード

図1.3は、HTMLファイルを開いているMicrosoft Edgeブラウザのスクリーンショットです。ご覧のように、ZIPアーカイブは自動的に被害者のデバイスに保存されています。

図1.3:Microsoft Edgeブラウザで開かれたHTMLファイル

QakBotのダウンロードと実行

次は、ダウンロードされたZIPアーカイブの内容を見ていきましょう。これはWindowsのショートカットファイル、「ScannedDocs_1586212494.lnk」です。ご承知のとおり、「ターゲット」フィールドにコマンドを入力すると、Windowsショートカットファイルでそのコマンドを実行できます。図2.1は、このショートカットファイルとプロパティのスクリーンショットです。

図2.1:Windowsショートカットファイルとプロパティ

このショートカットは、安全なテキストファイルであると思い込ませて被害者にファイルを開かせるために、Microsoft Writeのアイコンで偽装されています。このプロパティの場合、「ターゲット」フィールドの一連のコマンドは「cmd.exe」によって実行されます。被害者がファイルをダブルクリックすると、コマンドが実行されます。

図2.1のコマンドを見てみると、主な目的は「cURL」(Client URL)を実行し、URL 194[.]36[.]191[.]227/%random%.datからローカルファイル「%ProgramData%\Flop\Tres.dod」にファイルをダウンロードすることです。cURLは、よく利用されているLinuxツールですが、Windows 10以降はWindowsにもデフォルトプログラムとして組み込まれています。

ダウンロードされたファイル(Tres.dod)はDLLファイルです。筆者が分析したところ、これはQakBotのローダープログラムに相当します。この例の場合、「regsvr32」が「regsvr32 %ProgramData%\Flop\Tres.dod」コマンドを使用してこのDLLファイルを実行します。

図2.2:QakBotローダーモジュールのリソースセクション

「regsvr32.exe」で実行されるQakBotローダーモジュール(Tres.dod)は、図2.2に示すように名前が「AAA」のリソースセクションからバイナリブロックをロードします。続いてそのバイナリブロックを復号し、ファイルレスPEファイルと、一種の自己展開機能である動的コードを取得します。次に、「regsvr32」プロセスの中でローダーモジュールによってこの機能が呼び出され、QakBotのコアモジュールであるファイルレスPEファイルが展開されます。QakBotのコアモジュールが展開されると、自己展開機能は最後のタスクとして、エントリポイントを呼び出します。図2.3は、自己展開機能がQakBotコアモジュールのエントリポイントを呼び出している様子を示しています。

図2.3:QakBotのエントリポイントを呼び出している自己展開機能

プロセスハロウイング

マルウェアは通常、プロセスハロウイングを実行して、悪意のあるコードやモジュールを他のプロセスにインジェクトします。プロセスハロウイングの目的は、検知されるのを回避することにあります。

QakBotは、被害を受けたマシンのプラットフォーム(32ビットまたは64ビット)やインストールされているアンチウイルスソフトウェアに応じて、プロセスリストからシステムプロセスを選択し、プロセスハロウイングの標的とします。このリストには、QakBotが利用できるOneDriveSetup.exe、explorer.exe、mobsync.exe、msra.exe、iexplore.exeが含まれています。

テスト環境では、「OneDriveSetup.exe」が選択されました。次に、QakBotはAPI CreateProcessW()を呼び出し、作成フラグCREATE_SUSPENDEDを使用して新しいプロセスを起動します。したがって、このプロセスは起動時に一時停止状態になっています。続いて、QakBotはメモリデータを書き換えます。たとえば、API WriteProcessMemory()を呼び出して、新規作成された「OneDriveSetup.exe」プロセスにQakBotコアモジュールを注入します。その後、インジェクトされたコアモジュールにジャンプできるよう、新しいプロセスのエントリポイントのコードを変更します。最後に、API ResumeThread()を呼び出して新しいプロセスを再開します。こうして、ターゲットプロセスでQakBotが実行されます。

図3.1のプロセスツリーには、QakBotローダー(「curl.exe」)のダウンロードから「OneDriveSetup.exe」までのすべの関連プロセスが表示されています。

図3.1:関連プロセスのプロセスツリーの概要

分析回避の手法

QakBotのコアモジュールを分析する前に、容易に分析されないようにするためQakBotが使用する、分析回避の手法を見てみましょう。

定数文字列の暗号化

定数文字列は、リサーチャーがコードを分析するための有益な情報です。QakBotは暗号化された定数文字列を保持しています。これらの文字列は、特定の関数で復号されてから使用されます。図4.1は、609DD8の関数で文字列インデックス0xA8を指定し、定数文字列「Mozilla/5.0 (Windows NT 6.1; rv:77.0) Gecko/20100101 Firefox/77.0」を取得する例を示しています。

図4.1:関数で復号された定数文字列の例

主要なWindows APIの動的取得

ほとんどのWindows APIは、QakBotの実行時に取得されます。命令が実行されるまでは、どのAPIが呼び出されるかを推測することは困難です。API CreateThread()を呼び出すインスタンスを以下に示します。dword_61F818は動的にロードされた関数テーブルで、そのオフセット+74HがCreateThread()関数です。

xor ecx, ecx
lea eax, [ebp+var_4]
push eax
mov eax, dword_61F818 ; Function table of Kernel32.dll
push ecx
push ecx
push offset thread_fun
push ecx
push ecx
mov [ebp+var_4], ecx
call dword ptr [eax+74h] ; =>; CreateThread
mov dword_61F83C, eax
test eax, eax

分析ツールの検知

QakBotはスレッド関数を保持しており、被害を受けたマシン上で分析ツールが動作しているかどうかを1秒ごとにチェックします。そのために、いくつかの分析ツールのプロセス名リストを事前に定義します。当然のことながら、このリストは復号された定数文字列です。いずれかのプロセス名が実行中のプロセスと一致すると、QakBotのワークフローに影響を与えます(C2サーバーに接続できない、など)。

事前定義されたプロセス名リストを以下に示します。

frida-winjector-helper-32.exe, frida-winjector-helper-64.exe, tcpdump.exe,windump.exe, ethereal.exe, wireshark.exe, ettercap.exe;rtsniff.exe, packetcapture.exe, capturenet.exe, qak_proxy;dumpcap.exe, CFF Explorer.exe, not_rundll32.exe, ProcessHacker.exe, tcpview.exe, filemon.exe, procmon.exe;idaq64.exe, PETools.exe, ImportREC.exe, LordPE.exe, SysInspector.exe, proc_analyzer.exe, sysAnalyzer.exe, sniff_hit.exe, joeboxcontrol.exe, joeboxserver.exe, ResourceHacker.exe, x64dbg.exe, Fiddler.exe, sniff_hit.exe, sysAnalyzer.exe

筆者はこのプロセスリストに基づいて、以下の分析ツールが含まれていると判断しましたが、これらに限定されるわけではありません。

Joe Sandbox, TcpDump, WinPcap, Wireshark, Ettercap, PacketCapture, CaptureNet, CFF Explorer, ProcessHacker, TcpView, FileMon, ProcMon, IDA pro, PETools, ImportREC, LordPE, SysInspector, SysAnalyzer, ResourceHacker, x64dbg, and Fiddler.

QakBotコアモジュールとC2サーバーとの接続

ターゲットプロセス(「OneDriveSetup.exe」など)でQakBotコアモジュールが再開されると、regsvr32.exeに含まれていない、別のエントリ関数の使用が開始されます。

QakBotはその慣例どおり、多数のスレッドを使ってタスクを実行します。タスクには、影響を受けたデバイスに関する情報収集や、その情報のC2サーバーへの送信などが含まれます。

コアモジュールのリソースセクションには、「102」と「103」という2つのバイナリデータブロックがあります。リソース「103」のデータは、RC4で暗号化された構成情報です。復号後は、文字列「10=obama189\r\n3=1655107308\r\n」となります。「obama189」はこの亜種のQakBot ID、「1655107308」はUnixエポック時刻です。

リソース「102」のデータは、RC4で暗号化されたC2サーバーリストです。「\System32\WindowsPowerShel1\v1.0\powershel1.exe」は、C2サーバーデータを復号するためのRc4キーバッファを生成する定数文字列です。

図5.1:部分的に復号されたリソース「102」のスクリーンショット

図5.1の上側は、リソース名「102」を指定してAPI FindResourceWを呼び出しているところです。下側は、C2サーバーの復号されたバイナリIPおよびポートのリストの一部です。この亜種にはIPとポートのペアが123組あります。

QakBotは接続が確立されるまで、リストされたすべてのC2サーバーを一つ一つ調べます。接続したら、そのC2サーバーに被害者のレジストリパケット(最初のパケット)を送信し、被害者を登録します。平文のレジストリパケットは次のとおりです。

 “{\”2\”:\”hrzpxm292261\”,\”8\”:9,\”1\”:18}”

キーは「2」、「8」、「1」などの文字列番号です。「2」の値は「hrzpxm292261」(被害者のID)で、ハードウェア情報を使用して生成されていました。キー「8」の値はパケットタイプ(このパケットの場合は9)を指定しています。「1」の値は、QakBotのバージョンである18です。

このパケットはRC4で暗号化された後、base64アルゴリズムを使って文字列としてエンコードされます。QakBotとC2サーバーでやり取りされるすべてのパケットは、JSON構造で格納されます。

その後、URLに「/t4」を指定し、HTTP Postメソッドを使用してデータがC2サーバーに送信されます。本文はbase64エンコードされたレジストリデータで、SSLプロトコルを介して伝送されます。図5.2は分析ツールのスクリーンショットです。左側に送信されたパケット、右側に応答データが表示されています。

図5.2:分析ツールに表示されたレジストリパケット

応答データはリバースパスを使って平文に復元されます。つまり、base64デコードとRC4復号が実行されます。

この場合の平文は「{\”8\”:5,\”16\”:3257495567,\”39\”:\”vLLO\”,\”38\”:1}」で、いくつかのローカル変数の値を設定または更新します。

C2サーバーへの機密データの送信

QakBotは被害者のデバイスから機密情報を収集し、C2サーバーに送信します。同様に、ハッカーは対応するサブモジュールをQakBotクライアントに送信し、被害者のデバイスで実行できるようにします。

QakBotはWindows API、Windowsコマンド、WMIクエリ言語(WQL)を使用して情報を収集します。以下に詳細を示します。 

Window APIs

API関数

説明

GetVersionEx()

ビルド番号などのWindowsエディション情報。Windows 10が動作するテストシステムでは「10.0.1.19043.0.0.0100」

GetComputerNameW()

コンピュータ名「DESKTOP-P952NC4」など

GetSystemMetrics()

画面のサイズ(幅と高さ)を取得します

NetGetJoinInformation()

ADドメイン(「WORKGROUP」など)を取得します

LookupAccountSidW()

ユーザー名

GetSystemInfo()

プロセッサのアーキテクチャ

CreateToolhelp32Snapshot(),

Process32FirstW(), Process32NextW()

実行されているプロセスの情報を取得します

GetModuleFileNameW()

QakBotのフルパスとターゲットプロセスのフルパス

CreatProcessW()

Windowsコマンドを実行します

WMIオブジェクトクエリ

クエリ文字列

説明

SELECT * FROM Win32_OperatingSystem

OSの情報

SELECT * FROM AntiVirusProduct

インストール済みアンチウイルスソフトウェア(Microsoft Defender、FortiClientなど)を取得します

SELECT * FROM Win32_Processor

CPUプロセッサの情報

SELECT * FROM Win32_ComputerSystem

システム環境の情報。モデル、ドメイン、製造元など

SELECT * FROM Win32_Bios

デバイスのBIOS情報

SELECT * FROM Win32_DiskDrive

ハードディスクの情報。パーティション、サイズ、モデルなど

SELECT * FROM Win32_PhysicalMemory

物理RAMスティックの詳細情報。容量、クロック速度、チャネルなど

SELECT Caption,Description,Vendor,Version,

InstallDate,InstallSource,PackageName FROM Win32_Product

インストール済みソフトウェアの情報

SELECT Caption,Description,DeviceID,

Manufacturer,Name,PNPDeviceID,Service,

Status

FROM Win32_PnPEntity

プラグアンドプレイデバイス(キーボード、マウス、CD-ROM、ネットワークアダプタなど)のプロパティ

Windowsコマンド

コマンド

説明

"ipconfig /all"

すべてのTCP/IPネットワーク構成の値

"nslookup -querytype=ALL -timeout=12 _ldap._tcp.dc._msdcs.%s"

被害者のデバイスのメインDNSサーバーにドメインのSRVレコードをクエリします

"nltest /domain_trusts /all_trusts"

信頼されたドメインの列挙

"net share"

共有リソースおよび共有名

"route print"

アクティブルートのテーブル

"netstat -nao"

被害者のデバイスでアクティブ状態の接続

"net localgroup"

ローカルグループの情報

"qwinsta"

被害者のデバイスでアクティブ状態のセッション

"arp -a"    

ARPエントリの情報

"net view /all"

リモートコンピュータ上のすべての共有を表示します

上記の表の情報をすべて収集したら、QakBotはパケットタイプ“8”:4を使用してその情報をパケットに格納します。図6.1はこのパケットのJSONデータで、RC4暗号化関数を呼び出しているところです。

図6.1:機密情報が格納されたパケット“8”:4の平文

このQakBotはC2サーバーとの接続を確立できましたが、筆者の元にサブモジュールは届いていません。現在もこの通信を監視しており、新たな発見があればこの分析記事を更新するつもりです。

結論

今回の分析記事では、添付されたHTMLファイルが、他の高リスクなファイル(MS Word、MS Excel、PDFなど)と同じく安全ではないことを実証しました。ファイルが添付されたEメールを受信したときは、十分に注意する必要があります。

次に、HTMLファイルが自動実行型のJavaScriptコードを使用して、ZIPアーカイブをドロップする方法を説明しました。さらに、偽装されたWindowsショートカットファイルがどのようにQakBotのローダーモジュールをダウンロードするかも明らかにしました。

その後、ローダーモジュールが何を復号し、選択したターゲットプロセス(今回の場合は「OneDriveSetup.exe」)でどのようにQakBotのコアモジュールを展開するかを解説しました。

最後に、QakBotのスレッドのほか、リソース「102」を復号したC2サーバーのリストからIPアドレスとポートのペアを選択し、C2サーバーとの接続に使用すること、さらには、被害者のデバイスからどのような機密データを取得してC2サーバーに送信するか、などを確認しました。

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

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

今回のフィッシングメールは、FortiMailによって「スパム」として検知されました。

QakBotとC2サーバーをダウンロードするためのURLは、FortiGuard Webフィルタリングサービスで「不正なWebサイト」に分類されました。

フィッシングメールに添付されたHTMLファイルと、ダウンロードされたQakBotローダーモジュールは、FortiGuardアンチウイルスサービスによって「JS/Agent.BLOB!tr」および「W32/Qbot.D!tr」として検知され、ブロックされます。

FortiEDRは、関連するファイルをその振る舞いに基づいて、悪意のあるファイルとして検知します。

組織においては、これらの保護対策に加えて、フォーティネットが無償で提供しているNSEトレーニングNSE 1 – 情報セキュリティ意識向上の受講をエンドユーザーに奨励することをお勧めします。このトレーニングには、インターネットの脅威に関するモジュールが含まれ、エンドユーザーはフィッシング攻撃を識別して防御する方法を学習できます。

IOC(Indicators of Compromise:侵害指標)

URL:

194[.]36[.]191[.]227/%random%.dat

ここをクリックすると、C2サーバーの完全なリストをご覧いただけます。

この攻撃に関連しているサンプルSHA-256:

[添付HTMLファイル]

FE1043A63E6F0A6FAA762771FF0C82F253E979E6E3F4ADD1C26A7BD0C4B2E14C

[QakBotのローダーモジュール]

9C3D3CD9B0FCB39117692600A7296B68DDDF2995C6D302BC9D9C8B786780BA19

  [ScannedDocs_1586212494.lnk]

          F5B6619E92D7C4698733D9514DF62AFACA99883DFAC8B9EE32A07D087F2800BF