FortiGuard Labs 脅威リサーチ
このブログでは、「Warzone RATをドロップするハンガリー政府偽メール」で取り上げたマルウェアの分析中に生じた、技術的課題への対処について解説します。この攻撃の最終ペイロードであるWarzone RATは、難読化が次第に高度になっていく一連の.NETバイナリを介して展開されました。各段階では、バイナリ内のどこかから次のバイナリを読み込んでデコードし、それをメモリに読み込み、関数を呼び出して、次の段階に制御フローを渡していました。このような多段階ローダーの動的分析は困難を伴います。なぜなら、マルウェアのサンプルを再起動するたびに、さまざまな段階を調査しなければならないからです。この問題を回避するために、FortiGuard Labsは各段階から独立した実行ファイルを作成し、デバッグを効率的に行えるようにしました。その方法を以下で解説していきます。
図1は、攻撃におけるWarzone RATの段階的展開を示しています。フィッシングメールにはzipファイルが格納され、そのzipファイルには図1に示すバイナリ1)が含まれていました。
1)が実行されると、2) KeysNormalize.dllが読み込まれます。これは.NET DLL(ダイナミックリンクライブラリ)であり、メモリに解凍されます。関数sk41Ua2AFu5PANMKit.abiJPmfBfTL6iLfmaW.Y5tFvU8EY()を呼び出すことで、このDLLが実行されます。本ブログで取り上げるのは、デバッグによって3)を復元する方法です。ここではdnspyをデバッガーとして使用し、メモリからKeysNormalize.dllをダンプする方法を紹介します。このDLLは、SmartAssemblyという難読化ツールを使って難読化されていました。
第3段階の正体(Metal.dll)を突き止めてファイルにダンプするには、KeysNormalize.dllをデバッグする必要があります。しかし、デバッグを行うには次の問題を解決しなければなりません。
KeysNormalize.dllは.exeファイルではないため、ダブルクリックするだけでは実行できません。また、オリジナルの.exeファイルはKeysNormalize.dllから特定の関数を呼び出します。したがって、このDLLを実行するときには、それと同じ関数を呼び出す必要があります。
これにはいくつかの方法があります。今回はC#でラッパープログラムを作成し、KeysNormalize.dllを標準DLLとしてインポートし、関数sk41Ua2AFu5PANMKit.abiJPmfBfTL6iLfmaW.Y5tFvU8EY()を呼び出しました。これは.NET / C#開発者(私は違います)にとっては非常に簡単な方法ですが、日頃から慣れていなければ難しいかもしれません。
まず、Visual Studioを起動して新しいC#コンソールアプリ(.NET Framework)プロジェクトを作成し、.NET 4.7.2バージョンを選択します。このプロジェクトをdll_wrapperと呼ぶことにします。デフォルトでは空のクラスが読み込まれますが、図2のようにコードを変更します。
このコードはキーの押下を無期限に待機するだけで、処理は実行しません。このコードを追加するのは、デバッガーではブレークポイントを事前に挿入できないからです。こうすることで、プログラムがキーの押下を待機する間に実行を中断し、必要な場所にブレークポイントを挿入することができます。
次に、KeysNormalize.dll をプロジェクトに格納します。まず、このDLLをプロジェクトフォルダにコピーします(図3)。
KeysNormalize.dllへの参照も追加する必要があります。それには[Project(プロジェクト)] -> [Add Project Reference(プロジェクト参照の追加)] -> [Browse(参照)]をクリックし、KeysNormalize.dllを選択します。図4のように、ソリューションエクスプローラーの[References(参照)]にKeysNormalizeが表示されます。
これで、プロジェクトでKeysNormalize.dllを起動できます。次の関数を呼び出します(この関数はオリジナルのバイナリを分析すると特定できますが、それについては割愛します)。
sk41Ua2AFu5PANMKit.abiJPmfBfTL6iLfmaW.Y5tFvU8EY("4F515364", "746771", "BattleshipLiteLibrary");
そのためには、先にsk41Ua2AFu5PANMKitをインポートする必要があります。これはProgram.cs.でのKeysNormalizeのネームスペースです。続いて、上記の関数呼び出しをコードに追加します。図5のように、キー押下のループのあとに挿入します。
警告:このプログラムを実行すると、不正なペイロードが実行されます。したがって、このプログラムは隔離された安全なシステムでのみ実行してください。
これで、x86リリースバイナリのビルドが可能になりました。Visual Studioを使用するかどうかに関係なく、このプログラムを実行すると、クラッシュが発生して例外がスローされます(図6)。
エラーメッセージから、BattleshipLiteLibrary.Properties.Resources.resourcesが見つからなかったことがわかります。このリソースは、第1段階のバイナリである「Uj bejelentkezEsi adatai·pdf.exe"」すなわち「iANO"」内にあります(図7)。
これは興味深い現象です。なぜなら、KeysNormalizeは独立したDLLであるのに単独では機能できないことを意味するからです。
リソースの問題を解決するには、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フォルダに保存します。
このファイルをプロジェクトに追加するため、ソリューションエクスプローラーで[Properties]を右クリックし、[Add(追加)] / [Existing Item(既存のアイテム)]を選択します(図9)。Resources.resourcesファイルを選択し、[OK]をクリックします。
最後に、プロジェクトのネームスペースをBattleshipLiteLibraryに変更します。これにより、KeysNormalizeがリソース名を正しく検索することができます。それには次の2つの手順を実行します。
1. ソリューションエクスプローラーで[Properties]をダブルクリックし、デフォルトのネームスペースをBattleshipLiteLibraryに変更します(図10)。
2. Program.csでネームスペースを右クリックし、[Rename(名前の変更)]を選択し、名前をBattleshipLiteLibraryに変更します(図11)。
上記の手順によって、プロジェクト全体でネームスペースが変更されます。
リソースの準備が完了したので、新しいx86リリースバイナリをビルドできます。
私たちがこのような苦労をしてKeysNormalize.dllを動作させた理由は、このDLLを効率的にデバッグして次の段階をダンプするためです。
デバッグにはdnspyを使用します。dnspyでdll_wrapper.exeを読み込み、関数abiJPmfBfTL6iLfmaW.Y5tFvU8EY()への呼び出しのブレークポイントを挿入します(図12)。
デバッガーを起動し、要求に応じてキーを押すと、ブレークポイントにヒットします。ここで[Step into(ステップイン)]をクリックすると、dnspyでKeysNormalize.dll,の逆コンパイルも実行され、バイナリのデバッグも可能になります。
図13のコードを調べると以下のことがわかります。
- 76行で呼び出される関数は、リソースをビットマップとして読み込む。
- このビットマップはarrayに読み込まれ、何らかの変換処理が実行される。
- 83行で呼び出される関数は、arrayをAssemblyオブジェクトとして読み込む。つまり、次の段階はarrayに格納されている可能性が高い。
- 84行で呼び出される関数は、読み込まれたAssemblyオブジェクト内の関数を呼び出す。これにより、93行で次の段階に実行が渡される。
83行でarray をダンプでき、呼び出される関数を93行で確認できることがわかりました。
図14はメモリ内のarray 変数を示しています。ここにPEファイルが格納されています。これが、攻撃の次の段階であるMetal.dllです。
図15はmethodInfo変数を示しています。読み込まれたAssemblyオブジェクト内で呼び出された関数の名前が格納されています。関数名は「OwbdG5aNVQQYu6X20i.o9pVsMvoTr75y5TrkE.V4j9c6YCwC()」です。
この時点でさらに分析を続けるには、ダンプした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 – 情報セキュリティ意識向上には、インターネットの脅威に関するモジュールが含まれ、エンドユーザーはフィッシング攻撃を識別して自らを保護する方法を学習できます。
ファイル名 |
sha256ハッシュ |
Uj bejelentkezEsi adatai·pdf.exe |
21d09c77de01cc95209727752e866221ad3b66d5233ab52cfe5249a3867ef8d8 |
KeyNormalize.dll |
8b533ffaed24e0351e489b14aaac6960b731db189ce7ed0c0c02d4a546af8e63 |
Metall.dll |
66319bf905acac541df26fecc90843a9a60fdbc1a8a03e33f024088f586cb941 |
<Warzoneサンプル> |
27743b5b7966384cc8ef9cfef5c7a11c8b176123b84c50192926c08ab7e6d7d7 |
ネットワークアドレス |
タイプ |
171[.]22[.]30[.]72:5151 |
C2サーバー |
Warzone RATのTTPの詳細については、https://attack.mitre.org/software/S0670/でご確認いただけます。
フォーティネットのTraining Advancement Agenda(TAA)のイニシアチブである無料のサイバーセキュリティトレーニング、またはFortinet認定ネットワーク セキュリティ エキスパートプログラム、Security Academyプログラム、およびVeteransプログラムの詳細を参照してください。