Excelアドインの兵器化[後編]: Dridex感染チェーンのケーススタディ

A conceptual image representing targeted attacks, including the XLL Files and Dridex infection chain discussed here.

This post is also available in: English (英語)

概要

2部構成の本シリーズの前編ではXLLファイルを悪用するAgent Tesla展開の手口について簡単に説明しました。2021年12月も引き続き、DridexとAgent Teslaがまたべつの手口で初期ペイロードの配信にXLLを悪用している様子が観測されました。後編ではDridexの感染チェーンフローを掘り下げて見ていきます。

Dridexの背後にいるアクターは長年さまざまな配信メカニズムを使ってきました。2017年の初めごろは、平文のVBScriptやJavaScriptの使用が確認されています。後年になると、Microsoft Officeファイル(DOCやXLS)をZIPで圧縮したものなど、さまざまなバリエーションが観測されました。2020年にはマルウェアがDiscordなどの正規サービスを使って最終ペイロードをダウンロードしている様子が確認されました。さらに最近、2021年12月には、XLLやXLM 4.0をDiscordやOneDriveと組み合わせて悪用することで最終ペイロードをダウンロードするさまざまなDridexサンプルを受信しています。

XLLファイルとAgent Teslaを中心に見ていった前回のブログでは正規のExcel-DNAフレームワークが悪用されていることがわかりました。本稿ではそれ以外の感染チェーンを見ていきます。Dridexサンプルを配布するXLLドロッパ、Excel 4(XLM)ドロッパのさまざまなステージ(段階)について論じ、Dridexローダについても簡単に見ていきます。

パロアルトネットワークスのお客様は、Cortex XDRまたは次世代ファイアウォール用のWildFireクラウド配信セキュリティサブスクリプションにより、本稿で取り上げた攻撃から保護されています。

本稿で取り上げた攻撃 Malware, Dridex
Unit 42の関連トピック Agent Tesla, Macros

目次

XLMドロッパ
XLLドロッパ
Active Directoryのチェック
DiscordのURL
ローダの簡単な分析
アンパック段階
第1段階
第2段階
最終段階のDridexローダ
Micro VM
APIハッシュ
結論
IoC

XLMドロッパ

XLM 4.0そのものはとくに目新しいものではないのですが、2020年初めごろからマルウェアによるXML4.0の悪用手口が大きく進化しています。かつての脅威アクターは難読化されていないシンプルなマクロ式を使っていましたが、いまは複雑で隠ぺいされた亜種を多数作成し、最後にそれらをペイロードとしてrundll32などのネイティブサービスに実行させる手口を使うようになっています。

XLM 4.0マクロの悪用はかなり最近出てきたのもので、ベンダ各社はそうしたケースへの保護対策提供に苦労しています。

このサンプルでは、XLM文書がスプレッドシート2枚で構成されています。1枚目のシートには数式が、2枚目のシートにはランダムデータが入っています。以下の図1、図2を参照してください。

2枚のスプレッドシートで構成されているXLM 文書。この図のシートには数式が含まれている。赤字の「1」で示したのがHTMLアプリケーションファイルダンプを担うマクロ4.0。スクリーンショット上部に赤字2で示したのが数式からの出力内容。
図1. 画面右側の赤字の「1」はHTMLアプリケーションファイル(HTA)のダンプを担うマクロ4.0を示す。スクリーンショット上部の赤字の「2」はハイライトした数式の出力結果を示す
赤字1が示す赤い矩形はASCII値で保存されたHTAスクリプト
図2 赤字1が示す赤い矩形はASCII値で保存されたHTAスクリプト

図1で示したスプレッドシートではある計算式をMshtaで実行しようとしています。つまりこれは実際にはRTFではないと推測されます。さらに分析すると、これはやはりRTFではなくHTAであることがわかりました。Sheet1上のXLM 4.0コードは、Sheet2からASCII値を読み取り(図2)、DiscordからDridexをダウンロードするHTAファイルを生成する役割を担っています。

DiscordからDridexをダウンロードするVBScript
図3. DiscordからDridexをダウンロードするVBScript
HTAファイル内のエンコードされたDiscordのURL
図4 HTAファイル内のエンコードされたDiscordのURL

最終的に悪質なペイロードをダウンロードしてこないかぎりXLS自体についての判定はしづらいですし、このケースではHTAがRTFとしてドロップされているので、これもセキュリティ製品に判定を迷わせる要因になります。セキュリティ製品はHTAをRTFとして分析してしまい、検出しそこなうおそれがあるのです。DiscordのURLが使われていることもすりぬけやすさの要因になります。なおここではDiscordのURLを取り上げましたが、OneDriveのURLについても同じ使われかたがされていることを確認済みです。OneDrive URLの具体例は、IoCセクションのGitHubリンクを参照してください。

XLLドロッパ

本シリーズの前編で取り上げた悪意のあるXLLファイルと比べるとこのドロッパはかなりシンプルで、XLLファイルは単なるDLLなのでExcelで実行しなければなりません。検知には適切なトリガーが重要です。

XLMとXLLファイルからは約1,400件のURLが抽出されましたが、分析の時点ではもう数件しか稼働していませんでした。
図5. XLL内で見つかったDiscordのURL
このスクリーンショットにはダウンロードされたペイロードを実行するコマンドなどが表示されています。
図6 Dridexローダを実行するXLL

Active Directoryのチェック

私たちはこのXLLダウンローダとVBScriptダウンローダはいずれも同じアクターに関連していると考えています。その根拠は両方ともLOGONSERVERUSERDOMAIN環境変数が設定されているかどうかを確認するチェックを行っている点にあります。これらの環境変数が設定されていれば、そのシステムはActive Directory上にあることになります。

環境変数LOGONSERVERとUSERDOMAINをチェックするHTAドロッパ
図7 環境変数LOGONSERVERとUSERDOMAINをチェックするHTAドロッパ
環境変数LOGONSERVERとUSERDOMAINをチェックするXLLドロッパ
図8. 環境変数LOGONSERVERとUSERDOMAINをチェックするXLLドロッパ

DiscordのURL

XLMとXLLファイルからは約1,400件のURL(本稿末尾のIoCセクション参照)が抽出されましたが、分析の時点ですでに数件しか稼働しておらず、ダウンロードされていたのはDridexのみでした。興味深いのはDLLファイルがMKVとしてダウンロードされていた点で、感染チェーン開始段階ではHTAがRTFとしてドロップされる様子が確認されていました。

ローダの簡単な分析

図6からわかるように、ダウンロードされたペイロードはコマンド rundll32.exe * DirSyncScheduleDialog によって実行されます。ただし、分析をすすめるためにファイルを開いてみるとExport DirectoryにDirSyncScheduleDialogというメソッドは見当たりません。この関数名がWindowsの正規DLLのものである点は興味深いでしょう。

スクリーンショット左側はメソッドDirSyncScheduleDialogが見当たらない様子を、スクリーンショット右側はエクスポートされた関数DirSyncScheduleDialogが、正規のWindows loghours.dll内に存在している様子を示している。
図9 メソッドDirSyncScheduleDialogが見当たらない(左)。エクスポートされた関数DirSyncScheduleDialogは正規のWindows loghours.dll内に存在している(右)

アンパック段階

  1. rdataセクションから第2段階のDLLを復号してロードする
  2. 第2段階のDLLがさらに最終のDridexローダをアンパックする
  3. DirSyncScheduleDialogにジャンプする

第1段階

第1段階は機能的にはかなりシンプルで、ここで行われるのはrdataセクションから小さなDLLを復号して割り当てられたメモリに移動して実行するだけです。

ただし、解析対策が複数仕込まれています。

  1. ジャンクコードの使用
  2. INT3命令を伴う大規模ループ
  3. ldrgetprocedureaddressLdrLoadDllなどの文書化されていない関数を使用する一般的なフックの回避

ジャンクコードは手動解析の妨げにはなるかもしれませんが、INT3ブレークポイントを含む大きなループは、場合によっては実行を遅らせることがあります。

第1段階にはいくつか関数が含まれています。これらには、ローダの自明な振る舞いを反映する名前をつけました。

名前が変更された関数(左)。jump_to_allocated_memory関数(中央)。anti-vm関数とNOPで置き換えたCCバイト(右)
図10 名前が変更された関数(左)。jump_to_allocated_memory関数(中央)。anti-vm関数の0xCC(INT3)のopcodeをNOPで置き換えたもの(右)

第2段階

第1段階は、インメモリDLLに制御を渡し(図8)、さらに最終ペイロードを展開してそれに制御を移します。第2段階の内容も自明ですがいくつか興味深い解析対策が仕込まれています。

  1. Disablethreadlibrarycallsを呼び出して最終DLLが目に付きづらくする
  2. LdrLoadDllのフックの有無をチェックする
名前が変更された関数(左)。LdrLoadDllへのフックをチェック(中央)。ImportsウィンドウのdisableThreadLibraryCalls(右)
図11 名前が変更された関数(左)。LdrLoadDllへのフックをチェック(中央)。ImportsウィンドウのdisableThreadLibraryCalls(右)

最終段階のDridexローダ

ここでようやくDirSyncScheduleDialogへの呼び出しが確認できます。DridexローダがDLLサイドローディングをしていないのは興味深い点ですが、最終ペイロードはWindows正規のDLL loghours.dllとして読み込まれます。

左がDridexローダからのエクスポートテーブル、右が正規loghours.dllからのエクスポートテーブル。赤の矩形は特定行を横に並べてハイライトし、DirSyncScheduleDialogを示している。
図12. 左がDridexローダからのエクスポートテーブル、右が正規loghours.dllからのエクスポートテーブル
DridexローダのEP。開始部分に解析対策のanti-vmループがある
図13. DridexローダのEP。開始部分に解析対策のanti-vmループがある

Micro VM

Dridexはmicro VMを実装しています。micro VMはAddVectoredExceptionHandlerを使って例外ハンドラを追加し、call eax命令をエミュレートします。

get_proc_address_by_hash関数呼び出しと0xCC(INT3) 0xCC(INT3) のopcode(call eax)
図14 get_proc_address_by_hash関数呼び出しと0xCC(INT3) 0xCC(INT3) のopcode(call eax)
EXCEPTION_BREAKPOINTの場合
図15 「call eax」をエミュレートする例外ハンドラ

図15からわかるようにEXCEPTION_BREAKPOINTが発生するとcall eax命令がエミュレートされます。これはサンドボックスであれば問題にはなりませんが手動解析の妨げにはなりえます。この図からわかるとおり例外ハンドラは単一の命令しかエミュレートしていません。この2つのINT3命令をcall eaxに修正するのにたいした手間はかかりません。単純にIDAスクリプトですべてのCC CC命令をFF D0に修正すればよいでしょう。

すべてのCC CC命令をFF D0に修正するIDAスクリプトで2つのINT3命令を修正しているところ
図16. INT3命令を「call eax」で修正

API ハッシュ

APIハッシングも自明ですがこのDridexローダでは、何種類かの難読化とバリエーションが観測されました。

  1. 複数のハッシュ関数
  2. ハッシュ関数のためのマスカレードされたProlog

このDridexローダは分析妨害を意図してハッシュ関数を複数使っていることが確認されています。少なくともハッシュ関数が2つとマスカレードされたProlog関数が1つ確認されました(下図参照)。

APIハッシュ関数 sub_744102D4
図17. APIハッシュ関数 sub_744102D4
Dridexローダの使うマスカレードされたProlog関数。分析妨害を意図したもの
図18. マスカレードされたProlog関数

get_proc_address_1関数のPrologは普通ではないことがわかります。モジュールハッシュとAPIハッシュをget_proc_address_1_mas関数に渡すためにレジスタeaxedxが使われています。get_proc_address_1を呼び出すとeaxedxをセットできます。またこれらのレジスタをあらかじめセットしてからget_proc_address_1_masを呼び出すことも可能です。調査中、APIの解決に(AppCallを使うなどして)自動処理を用意するのであれば、この手の仕込みに注意が必要です。

私たちはIDAのAppCall機能を使って、ローダが使っているAPIをすべて抽出しました。抽出されたAPIからすると、このDridexローダには2021年初めに観測されたDridexローダとの違いはありません。

Dridexローダの主な機能:

  1. プロセスの権限チェック
  2. AdjustToken権限
  3. GetSystemInfo
  4. AtomBombingインジェクション技法を使いコマンド&コントロールサーバーからダウンロードしたコアペイロードをロード

Dridexローダの分析はすでに多数行われているので、本稿では感染チェーン全体で使われているちいさな検出回避技術、解析妨害技術を中心に解説しました。

結論

感染チェーンは日々進化しており、DiscordやOneDriveといった正規サービスを使って検出エンジンを回避する手口や、感染チェーンを多段階にしていく様子が、私たちの分析からは判明しています。

最後にDridexのペイロードについて簡単に見ておくと、最終ペイロードの挙動は以前のDridexバージョンと同様ですが、アンパックが1段追加され、APIハッシュ関数に新たな変更がいくつか加えられていました。これらのちょっとした技はシンプルでも強力で、マルウェアの分析がやりづらくなり、検出回避や分析妨害に役立ちます。

パロアルトネットワークスのお客様は、Cortex XDRまたは次世代ファイアウォール用のWildFireクラウド配信セキュリティサブスクリプションにより、本稿で取り上げた攻撃から保護されています。

侵害の懸念があり弊社にインシデントレスポンスに関するご相談をなさりたい場合は、infojapan@paloaltonetworks.com まで電子メールにてご連絡いただくか、下記の電話番号までお問い合わせください(ご相談は弊社製品のお客様には限定されません)。

  • 北米フリーダイヤル: 866.486.4842 (866.4.UNIT42)
  • 欧州: +31.20.299.3130
  • アジア太平洋: +65.6983.8730
  • 日本: +81.50.1790.0200

IoC

本稿で取り上げたマルウェアに関連するIoC(侵害指標)はこちらのGitHubで確認できます。