FortiGuard Labs 脅威リサーチ

ヒントとテクニック:多段階で展開される.NETマルウェアのデバッグ

投稿者 Gergely Revay | 2023年1月24日

このブログでは、「Warzone RATをドロップするハンガリー政府偽メール」で取り上げたマルウェアの分析中に生じた、技術的課題への対処について解説します。この攻撃の最終ペイロードであるWarzone RATは、難読化が次第に高度になっていく一連の.NETバイナリを介して展開されました。各段階では、バイナリ内のどこかから次のバイナリを読み込んでデコードし、それをメモリに読み込み、関数を呼び出して、次の段階に制御フローを渡していました。このような多段階ローダーの動的分析は困難を伴います。なぜなら、マルウェアのサンプルを再起動するたびに、さまざまな段階を調査しなければならないからです。この問題を回避するために、FortiGuard Labsは各段階から独立した実行ファイルを作成し、デバッグを効率的に行えるようにしました。その方法を以下で解説していきます。

問題ステートメント

図1は、攻撃におけるWarzone RATの段階的展開を示しています。フィッシングメールにはzipファイルが格納され、そのzipファイルには図1に示すバイナリ1)が含まれていました。

図1:解凍プロセス

1)が実行されると、2) KeysNormalize.dllが読み込まれます。これは.NET DLL(ダイナミックリンクライブラリ)であり、メモリに解凍されます。関数sk41Ua2AFu5PANMKit.abiJPmfBfTL6iLfmaW.Y5tFvU8EY()を呼び出すことで、このDLLが実行されます。本ブログで取り上げるのは、デバッグによって3)を復元する方法です。ここではdnspyをデバッガーとして使用し、メモリからKeysNormalize.dllをダンプする方法を紹介します。このDLLは、SmartAssemblyという難読化ツールを使って難読化されていました。

第3段階の正体(Metal.dll)を突き止めてファイルにダンプするには、KeysNormalize.dllをデバッグする必要があります。しかし、デバッグを行うには次の問題を解決しなければなりません。

  1. KeysNormalize.dllを実行ファイルから切り離して実行するにはどうすればよいか?(本来は実行ファイルがDLLをメモリ内に解凍し実行します)
  2. KeysNormalize.dllがオリジナルのマルウェアと同じように次の段階をドロップできる環境を作成するにはどうすればよいか?

問題1の解決:KeysNormalize.dllを単独で実行する

KeysNormalize.dllは.exeファイルではないため、ダブルクリックするだけでは実行できません。また、オリジナルの.exeファイルはKeysNormalize.dllから特定の関数を呼び出します。したがって、このDLLを実行するときには、それと同じ関数を呼び出す必要があります。

これにはいくつかの方法があります。今回はC#でラッパープログラムを作成し、KeysNormalize.dllを標準DLLとしてインポートし、関数sk41Ua2AFu5PANMKit.abiJPmfBfTL6iLfmaW.Y5tFvU8EY()を呼び出しました。これは.NET / C#開発者(私は違います)にとっては非常に簡単な方法ですが、日頃から慣れていなければ難しいかもしれません。

Visual Studioの設定

まず、Visual Studioを起動して新しいC#コンソールアプリ(.NET Framework)プロジェクトを作成し、.NET 4.7.2バージョンを選択します。このプロジェクトをdll_wrapperと呼ぶことにします。デフォルトでは空のクラスが読み込まれますが、図2のようにコードを変更します。

図2:キーストロークを待機する基本プログラム

このコードはキーの押下を無期限に待機するだけで、処理は実行しません。このコードを追加するのは、デバッガーではブレークポイントを事前に挿入できないからです。こうすることで、プログラムがキーの押下を待機する間に実行を中断し、必要な場所にブレークポイントを挿入することができます。

KeysNormalize.dllのインポート

次に、KeysNormalize.dll をプロジェクトに格納します。まず、このDLLをプロジェクトフォルダにコピーします(図3)。

図3:プロジェクトフォルダにコピーされるKeysNormalize.dll

KeysNormalize.dllへの参照も追加する必要があります。それには[Project(プロジェクト)] -> [Add Project Reference(プロジェクト参照の追加)] -> [Browse(参照)]をクリックし、KeysNormalize.dllを選択します。図4のように、ソリューションエクスプローラーの[References(参照)]にKeysNormalizeが表示されます。

図4:プロジェクトに追加されたDLLへの参照

これで、プロジェクトでKeysNormalize.dllを起動できます。次の関数を呼び出します(この関数はオリジナルのバイナリを分析すると特定できますが、それについては割愛します)。

sk41Ua2AFu5PANMKit.abiJPmfBfTL6iLfmaW.Y5tFvU8EY("4F515364", "746771", "BattleshipLiteLibrary");

そのためには、先にsk41Ua2AFu5PANMKitをインポートする必要があります。これはProgram.cs.でのKeysNormalizeのネームスペースです。続いて、上記の関数呼び出しをコードに追加します。図5のように、キー押下のループのあとに挿入します。

図5:ライブラリのインポートとターゲット関数の呼び出し

警告:このプログラムを実行すると、不正なペイロードが実行されます。したがって、このプログラムは隔離された安全なシステムでのみ実行してください。

これで、x86リリースバイナリのビルドが可能になりました。Visual Studioを使用するかどうかに関係なく、このプログラムを実行すると、クラッシュが発生して例外がスローされます(図6)。

図6:リソースが見つからないことによる例外

エラーメッセージから、BattleshipLiteLibrary.Properties.Resources.resourcesが見つからなかったことがわかります。このリソースは、第1段階のバイナリである「Uj bejelentkezEsi adatai·pdf.exe"」すなわち「iANO"」内にあります(図7)。

図7:iANOバイナリ内のリソース

これは興味深い現象です。なぜなら、KeysNormalizeは独立したDLLであるのに単独では機能できないことを意味するからです。

問題2の解決:BattleshipLiteLibrary.Properties.Resources.resourcesを作成する

リソースの問題を解決するには、KeysNormalize.dllの要件を満たし、BattleshipLiteLibrary.Properties.Resources.resourcesというリソースを作成する必要があります。これは思ったほど簡単ではありません。リソース名は次のようにビルドされます。

<namespace>.<folders>.<filename>

ここではBattleshipLiteLibrary.Properties.Resources.resourcesというリソースを作成します。つまり、ネームスペースはBattleshipLiteLibrary.です。また、Resources.resourcesという名前のリソースをPropertiesフォルダに格納する必要があります。

リソースのコンテンツを取得するため、dnspyに移動してリソースを右クリックし、[Raw Save BattleshipLiteLibrary.Properties.Resources.resouces(BattleshipLiteLibrary.Properties.Resources.resoucesを未加工で保存)]を選択します(図8)。これにResources.resourcesという名前を付け、dll_wrapperプロジェクトのPropertiesフォルダに保存します。

図8:dnspyからリソースを保存

このファイルをプロジェクトに追加するため、ソリューションエクスプローラーで[Properties]を右クリックし、[Add(追加)] / [Existing Item(既存のアイテム)]を選択します(図9)。Resources.resourcesファイルを選択し、[OK]をクリックします。

図9:プロジェクトへのリソースファイルの追加

最後に、プロジェクトのネームスペースをBattleshipLiteLibraryに変更します。これにより、KeysNormalizeがリソース名を正しく検索することができます。それには次の2つの手順を実行します。

1.     ソリューションエクスプローラーで[Properties]をダブルクリックし、デフォルトのネームスペースをBattleshipLiteLibraryに変更します(図10)。

図10:デフォルトネームスペースの変更

2.     Program.csでネームスペースを右クリックし、[Rename(名前の変更)]を選択し、名前をBattleshipLiteLibraryに変更します(図11)。

図11:ネームスペースの変更

上記の手順によって、プロジェクト全体でネームスペースが変更されます。

リソースの準備が完了したので、新しいx86リリースバイナリをビルドできます。

次の段階のダンプ

私たちがこのような苦労をしてKeysNormalize.dllを動作させた理由は、このDLLを効率的にデバッグして次の段階をダンプするためです。

デバッグにはdnspyを使用します。dnspyでdll_wrapper.exeを読み込み、関数abiJPmfBfTL6iLfmaW.Y5tFvU8EY()への呼び出しのブレークポイントを挿入します(図12)。

図12:呼び出しのブレークポイントをKeysNormalizeに追加

デバッガーを起動し、要求に応じてキーを押すと、ブレークポイントにヒットします。ここで[Step into(ステップイン)]をクリックすると、dnspyでKeysNormalize.dll,の逆コンパイルも実行され、バイナリのデバッグも可能になります。

図13:KeysNormalizeがリソースからデータを読み込んで変換し、関数を呼び出す

図13のコードを調べると以下のことがわかります。

- 76行で呼び出される関数は、リソースをビットマップとして読み込む。

- このビットマップはarrayに読み込まれ、何らかの変換処理が実行される。

- 83行で呼び出される関数は、arrayをAssemblyオブジェクトとして読み込む。つまり、次の段階はarrayに格納されている可能性が高い。

- 84行で呼び出される関数は、読み込まれたAssemblyオブジェクト内の関数を呼び出す。これにより、93行で次の段階に実行が渡される。

83行でarray をダンプでき、呼び出される関数を93行で確認できることがわかりました。

図14はメモリ内のarray 変数を示しています。ここにPEファイルが格納されています。これが、攻撃の次の段階であるMetal.dllです。

図14:PEファイルが格納されたarray

図15はmethodInfo変数を示しています。読み込まれたAssemblyオブジェクト内で呼び出された関数の名前が格納されています。関数名は「OwbdG5aNVQQYu6X20i.o9pVsMvoTr75y5TrkE.V4j9c6YCwC()」です。

図15:呼び出された関数の名前が格納されたmethodInfo

この時点でさらに分析を続けるには、ダンプしたMetal.dllでこの関数を調べる必要があります。しかし、それはまた別の機会に譲ります。

結論

このブログでは、メモリに直接読み読み込まれて呼び出されたDLLをデバッグするために、カスタムの.NETプログラムを作成する方法を説明しました。さらに、デバッグされたバイナリの要件を満たすために、プログラムにリソースを追加する方法も紹介しました。最後に、対象のDLLをデバッグして次の段階のバイナリをダンプし、エントリポイントとなる関数を突き止めました。

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

Fortinetアンチウイルスエンジンは、以下のシグネチャを使用して上記のすべてのバイナリに対応しています。

MSIL/Kryptik.AGIJ!tr:Uj bejelentkezEsi adatai·pdf.exe
W32/PossibleThreat:KeyNormalize.dll
MSIL/Agent.UDJ!tr:Metall.dll
W32/Agent.TJS!tr:Warzoneペイロード
W32/AntiAV.NIZ!tr:権限昇格ペイロードWM_DSP

C2サーバーは、FortiGuard Webフィルタリングサービスによって「不正」に分類されており、適宜ブロックされます。

FortiMailとFortiSandboxは、この攻撃の不正な添付ファイルを検知して隔離し、フォーティネットのCDR(コンテンツ無害化)サービスがそれを無効化します。

FortiEDRは、添付された悪意ある実行ファイルとWarZone RATペイロードを、その振る舞いに基づいて「不正」として検知します。

これらの保護機能に加えて、フォーティネットはフィッシング攻撃の検知 / 理解に関するユーザートレーニングも支援します。

FortiPhishフィッシングシミュレーションサービスでは、実際の攻撃をシミュレーションし、フィッシングの脅威に対するユーザーの認識や備えをテストするほか、フィッシング攻撃を受けた場合の適切な対処方法を訓練および強化できます。

フォーティネットが無償で提供するNSEトレーニングプログラム:NSE 1 – 情報セキュリティ意識向上には、インターネットの脅威に関するモジュールが含まれ、エンドユーザーはフィッシング攻撃を識別して自らを保護する方法を学習できます。

IOC(Indicators of Compromise:侵害指標)

ファイル名

sha256ハッシュ

Uj bejelentkezEsi adatai·pdf.exe

21d09c77de01cc95209727752e866221ad3b66d5233ab52cfe5249a3867ef8d8

KeyNormalize.dll

8b533ffaed24e0351e489b14aaac6960b731db189ce7ed0c0c02d4a546af8e63

Metall.dll

66319bf905acac541df26fecc90843a9a60fdbc1a8a03e33f024088f586cb941

<Warzoneサンプル>

27743b5b7966384cc8ef9cfef5c7a11c8b176123b84c50192926c08ab7e6d7d7

 

ネットワークアドレス

タイプ

171[.]22[.]30[.]72:5151

C2サーバー

ATT&CKフレームワークのTTP

Warzone RATのTTPの詳細については、https://attack.mitre.org/software/S0670/でご確認いただけます。

フォーティネットのTraining Advancement Agenda(TAA)のイニシアチブである無料のサイバーセキュリティトレーニング、またはFortinet認定ネットワーク セキュリティ エキスパートプログラム、Security Academyプログラム、およびVeteransプログラムの詳細を参照してください。