Emotetの再来:従来型との差異とは

感染したパソコン

“Emotet’s Return: What’s Different?” December 9, 2021 by PATRICK SCHLÄPFER (HP社マルウェアアナリスト)より

2021年11月15日、Emotetはほぼ10か月の休止期間を経て復帰して、現在、大規模な悪意のあるスパムキャンペーンで再び拡散しています。 Emotetの背後にあるマルウェア配布活動は、法執行機関によって2021年1月に中断され、活動は劇的に減少しました。 ただし、この落ち着きは一時的なものであったことが証明されており、Emotetの復帰は、ボットネットとその行為者らの回復力を示しています。 このマルウェアの復活の中で配布されている新たなバイナリで何が変更されたか疑問が生じます。この記事ではこれについて簡単に説明します。

2021年11月にHP WOLF SECURITYで隔離したマルウェア配布

11月、HPWolfSecurityの一部であるHPSureClick Enterpriseは、企業や組織に対する大規模なEmotet配布活動で配布されたマルウェアを隔離しました。 図1は、ユーザーが悪意のあるマクロを含むメールの添付Excelファイルを開いた経緯を示しています。 マクロはcmd.exeを生成して、WebサーバーからEmotetの攻撃実体ファイルをダウンロードし、実行しようとしました。 メールで配信されるマルウェアは非常に一般的なものであるため、HP Sure Clickは、電子メールで配信されたファイルを信頼できないものとして自動的に処理します。 ユーザーが添付ファイルを開くと、HP Sure Clickはマイクロ仮想マシン(micro-VM)内に隔離してファイルを開き、ホストが感染するのを防ぎます。 HP Sure Clickは、マイクロVMで潜在的に悪意のある動作も検出したため、VM内で何が起こったかを説明する動作トレースを含むアラートを生成し、ユーザー企業のセキュリティチームに送信しました(図2)。アラートの中でEMOTETが開かれたことを示す部分

図1-悪意のあるEmotetスプレッドシートを開いているユーザーを示すアラートタイムライン。

図2– HPSureClickによってキャプチャされた動作トレースからのスニペット

図2– HPSureClickによってキャプチャされた動作トレースからのスニペット

コードの類似性を見つけだす

解凍したEmotetサンプルを2つ(1つは2021年1月から、もう1つは2021年11月中旬から)を使用して、コードの違いを明確にして、新しいコードの分析に集中することを考えました。 このためにマルウェアの構造を分析して、コードの類似性に基づいて分類するThreatrayを使用しました。 このサービスは、2つのマルウェアの検体間の機能の違いを見つけて、それらを強調表示することもできます。

日付 SHA256 Hash
2021-01-26 61a47ebee921db8a16a8f070edcb86b5efd47a8d185bf4691b57e76f697981f9
2021-11-16 ba758c64519be23b5abe7991b71cdcece30525f14e225f2fa07bbffdf406e539

ThreatrayのAPIを使用してコードの類似性を取得すると、両方の検体から関数アドレスのテーブルが返されます。 両方のサンプルの列に関数アドレスがある場合、これは同様の関数が見つかったことを意味します。 2つのEmotetの検体を分析すると、類似した246個の関数のうち80個を特定できました。これは残りの機能がコードの変更または難読化である可能性があることを意味します。

図3–同様の機能を示すThreatray出力テーブル

図3–同様の機能を示すThreatray出力テーブル

さらにThreatrayの結果に基づいて、既知の関数を緑色にするIDCスクリプトを作成して分析を合理化してみました。このようにすると、マルウェアをリバースするときに未知の部分に集中できます。

図4–2021年11月のEmotetサンプルのIDAPro分解。既知の機能が緑色で表示されています

図4–2021年11月のEmotetサンプルのIDAPro分解。既知の機能は緑色で表示。

WINDOWS API 関数で解決する手法

Emotetがその機能を隠す方法の1つは、実行時にWindowsAPI関数を解決することです。 これは、関数名がインポートアドレステーブルから、または文字列として非表示になっていることを意味します。 Emotetは目的のAPI関数を見つけるため、代わりにハッシュを使用します。 ハッシュは解決ルーチンに渡され、DLLでエクスポートされたすべての関数のハッシュと比較されます。 2つのハッシュが一致する場合、DLL内の正しい関数とアドレスが検出されて、名前を参照せずにDLLを呼び出すことができます。

図5–EmotetのWindowsAPIラッパー関数

図5–EmotetのWindowsAPIラッパー関数

これらの動作を包み隠すための「ラッパー関数」は、前段階で類似性を持つものとして分類されていなかったため、WindowsAPI関数を解決するPythonスクリプトを作成しました。 11月16日のEmotetサンプルでは、109の異なる関数を解決して注釈を付けることができました。 また、サンプル間のAPI関数の違いを比較するために、2021年1月からサンプルの関数を解決しました。 次の表に、それぞれに固有のAPI関数を列挙します。

January 2021 November 2021
CryptAcquireContextW BCryptCloseAlgorithmProvider
CryptCreateHash BcryptCreateHash
CryptDecrypt BcryptDecrypt
CryptDuplicateHash BcryptDeriveKey
CryptDestroyHash BcryptDestroyHash
CryptDestroyKey BcryptDestroyKey
CryptGenKey BcryptDestroySecret
CryptEncrypt BcryptEncrypt
CryptExportKey BcryptExportKey
CryptGetHashParam BcryptFinalizeKeyPair
CryptImportKey BcryptFinishHash
CryptReleaseContext BcryptGenRandom
CryptVerifySignatureW BcryptGenerateKeyPair
CryptDecodeObjectEx BcryptGetProperty
HeapAlloc BcryptHashData
MultiByteToWideChar BcryptImportKey
WideCharToMultiByte BcryptImportKeyPair
RtlRandomEx BcryptOpenAlgorithmProvider
BcryptSecretAgreement
BcryptVerifySignature
RtlAllocateHeap
InternetQueryOptionW

EMOTETサンプルの違い

API関数の違いの1つは、新しいEmotetサンプルがBcrypt暗号化関数を使用するようになったことです。 2021年1月のEmotetサンプルでは、advapi32.dllの暗号化関数を使用しました。 この変更の説明は、Microsoftが古いAPIを廃止して、新しいAPIに切り替えることを推奨しているため、Emotetの開発者が新しい暗号化APIに切り替えたことです。

図6–MicrosoftのCryptDecryptAPIドキュメント

図6–MicrosoftのCryptDecryptAPIドキュメント

暗号化の変更に加えて、Emotetはヒープメモリを割り当てるよう関数RtlAllocateHeapを使用するようになりました。通常、プログラムはHeapAllocを呼び出し、次にRtlAllocateHeapを呼び出します。各Emotetバイナリには実行時に復号化されてヒープに保存される、暗号化された構成情報が含まれています。以前は、マルウェアをデバッグした場合、HeapAllocにブレークポイントを設定して、マルウェアのコマンドアンドコントロール(C2)アドレスなどの暗号化されていない情報を表示できました。ただし、マルウェアがRtlAllocateHeapを代わりに呼び出すため、これは新しいEmotetサンプルでは機能しません。ブレークポイントをRtlAllocateHeapに変更するだけで、目的の結果を得ることができます。ただし、この小さな変更は、自動分析システムがマルウェアから暗号化されていない情報を抽出できなくなったことを意味する可能性があるため、更新が必要になります。

Threatrayの結果で識別された関数に緑色のラッパー関数を追加すると、246個の関数のうち167個が得られます。残りの関数のいくつかは、さほど興味深くはない非常に小さな補助関数であり、他の関数は、手動で比較することにより、古いEmotetサンプルですでに見つかっている関数です。しかし、なぜこれらの関数は最初は類似性ありとしてマークされていなかったのでしょうか?これには2つの理由が考えられます。まず、Emotetはswitch caseステートメントを使用して、関数を正しい順序で呼び出す制御フローを難読化していますが、静的分析を使用してこれらを解決するのは容易ではありません。

図7–スイッチケースの難読化を示す制御フローグラフ

図7–スイッチケースの難読化を示す制御フローグラフ

次に、2番目のEmotetサンプルには、古いサンプルよりも多くの関数フラット化が含まれていることに気付きました。 これは、より多くの関数が1つの場所で呼び出され、サブ関数にネストされていないことを意味します。これにより、制御フローが変更され、古いEmotetサンプルとの類似性が低下します。 図8は、ヒープにメモリを割り当て、文字列を作成してからメモリを解放するサブ関数を呼び出す2021年1月のサンプルを示しています。

図8–2021年1月にサブ関数を呼び出してさらに実行およびAPI呼び出しを行ったサンプル

図8–2021年1月にサブ関数を呼び出してさらに実行およびAPI呼び出しを行ったサンプル

最近のサンプルでは、サブ関数が解決され、メモリを割り当てて文字列を作成するための関数呼び出しがメイン関数に移動されました(図9)。

図9–サブ関数の代わりに直接関数呼び出しを使用した2021年11月のサンプル

図9–サブ関数の代わりに直接関数呼び出しを使用した2021年11月のサンプル

結論

私たちの分析ではEmotetはほぼ10か月の休止期間中に変化を遂げました。更新された暗号化ライブラリの使用に加えて、メモリ割り当てとEmotetのコードの一部の機能構造に小さな変更がありました。 ただし、このマルウェアの大部分は従来のままであり、既存の機能がシステムを危険にさらすには充分であることを意味します。私たちの目標は、2つのサンプル間の変化を迅速かつ効率的に強調する方法を示すことであったため、これは最終的な分析ではありません。 Emotetのさらなる分析でセキュリティコミュニティをサポートするために、この記事で使用されているIDAデータベースとPythonスクリプトを共有しました。

参考 その他のEMOTETに関するブログ記事

マルウェアを確実に隔離するだけではなく、その動作も可視化するHP SCEについて

シェアする

  • このエントリーをはてなブックマークに追加

フォローする