マルウェアのコマンド アンド コントロールの逆転: ソケットから COM へ

reversing malware 1 news

Windows ホストでは、プログラムがインターネット経由で通信する方法が複数あります。マルウェアの一部をリバース エンジニアリングする場合、どの API が使用され、どのように機能するかを理解することが非常に重要です。これにより、送受信されるデータ、および該当する場合はコマンド構造と内部プロトコルを理解できるようになります。ネットワーキング API の選択は、インジケーターの作成方法にも影響します (これについては後で詳しく説明します)。私は、Windows マルウェアのコマンド アンド コントロール通信を、ソケット、WinInet、URLMon、および COM の 4 つの API カテゴリに分類します。この記事の主な焦点は COM です。これは、COM が最も珍しく、最も理解されておらず、リバース エンジニアリングが最も難しいためです。

ソケット

最初のグループであるソケットは、Unix に見られるのと同じ基本的なネットワーク API であるため、最も広く知られています。これは、TCP または UDP セッションへのやや未加工のセッション レベルのアクセスを提供します。これは主に DLL の ws2_32.dll によって提供されますが、これには歴史があります。ソケット API を使用するアプリケーションは、HTTP などの上位レベルのプロトコルを手動で作成する必要があります。関数の呼び出しでソケット オブジェクトが作成されます。ソケット().プロトコルが指定されるのは、この呼び出し中です (TCP または UDP)。ほとんどのマルウェア バックドアのような TCP クライアントの場合、関数接続()これにより、TCP 3 ウェイ ハンドシェイクが実行され、データの読み取りと書き込みが可能になります。一方、サーバープログラムは通常、練る()聞く()接続を待機します (ただし、練る()ソケットを特定の出力ポートに強制するためにクライアント側で使用することもできます)。機能送信()recv()TCP 接続のネットワークを介してデータを転送するために頻繁に使用されます。に送る()recvfrom()従来、UDP 接続に使用されていました。マルウェア分析の観点からすると、これにより物事が単純になります。マルウェアの一部がビーコン パケットに応答して期待している情報を理解する必要がある場合は、通常、recv()関数を使用して、次のコードがワイヤから読み取ったデータをどのように検査するかを確認してください。ただし、Windows では、ソケットをファイル ハンドルのように、ほとんどの操作で交換可能に使用できます。たとえば、プロセス (cmd.exe など) は、標準入力および標準出力として指定されたネットワーク ソケットで生成され、そのプロセスはネットワークを介して自動的に通信します。ソケット API を詳しく学ぶには、故 W. Richard Stevens の古典的な本 UNIX Network Programming Volume 1 を読むことをお勧めします。ソケット API を使用することの欠点は、HTTP などのより高いレベルのプロトコルとの対話を手動で行う必要があることです。これにより、マルウェアがリクエストを作成する方法に大きな柔軟性がもたらされますが、すべてを明示的に配置する必要があります。マルウェアの作成者は、ネットワーク上での HTTP トラフィックの見え方と、ほとんどの Web ブラウザーの見え方との間に微妙なニュアンスの違いを導入することがよくあります。これらの小さな違いが、優れたネットワーク シグネチャになります。

WinInet

WinInet API は、ソケット API よりもはるかに少ない作業で済みます。これは、HTTP、FTP、さらには GOPHER などのより高いレベルのプロトコルとのやり取りを簡素化する便利な API です! WinInet API を使用してリモート ホストと対話するには、まずInternetOpen()を呼び出し、続いてInternetConnect()またはInternetOpenURL()を呼び出す必要があります。インターネットが開かれ、接続が確立されたら、HTTP 要求を実行するために、関数 HttpOpenRequest( )を呼び出して要求を処理し、 HttpSendRequest()を呼び出して要求を送信できます。その後、 InternetReadFile()を呼び出して、サーバーからの応答を読み取ることができます。また、FTP セッションからデータを読み取るためにも使用できます。 InternetWriteFile()関数は、ネットワーク経由でデータを送信する必要があるプロトコル固有の関数の代わりに一般的に使用することもできます。 HTTP 関数を使用すると、プログラマは、User-Agent 文字列などの HTTP 要求ヘッダーで期待されるほとんどのオプションを構成できます。ただし、これらの値のすべてを指定する必要はありません。何も指定しない場合は、システムのデフォルトが使用されます。マルウェア プログラマーには、要求構造に微妙な異常を導入する柔軟性がありませんが、ソケットの場合とは異なり、既定の設定のままにしておくと、マルウェアの HTTP 要求は、ネットワーク上の正規の Internet Explorer トラフィックと実質的に同じに見えます。

URLMon

DLL urlmon.dll によって提供される URL モニカー API は、インターネット通信を実行するためのさらに別の API を提供します。バックエンドでは COM を使用しますが、この API を使用することは、直接的な COM 相互作用の見苦しくて不明瞭なリバース メソッドから離れた抽象化であるため、これを後の COM の説明とは別のカテゴリとしてリストすることにしました。マルウェアの観点から、URLMon アーセナルで最も人気のある関数は、ワンパンチノックアウト関数URLDownloadToFile()です。 Win32 API で 1 つの関数がこれほど多くの作業を行うことはめったにありません。この関数に URL (IE が理解できる任意のプロトコル) とファイル名を指定すると、COM を使用して、Internet Explorer にリソースを指定されたファイル名にダウンロードさせます。これは、Web サイトから EXE をダウンロードして起動するだけでよいドロッパー マルウェアで非常に人気があります。また、指定された URL をブラウザーのキャッシュにダウンロードし、ダウンロード先のファイルの名前を返すURLDownloadToCacheFile()関数に遭遇することもあります。 URLOpenStream()URLOpenPullStream()を使用して URL をメモリ内のバッファにダウンロードできますが、これらの関数がマルウェアで使用されることはめったにありません。

COM による Internet Explorer の制御

マルウェアのコマンド アンド コントロールに COM を使用することには、マルウェアの作成者にとって多くの利点があります。リモート ホストとのすべての通信がマルウェア プロセスではなく iexplore.exe プロセス内で実行されるため、ライブ レスポンス/揮発性データ/メモリ分析の観点からは、悪意のあるトラフィックの送信元がわかりにくくなります。リバース エンジニアリングの観点からすると、静的分析で最初に検査したときにマルウェアがネットワーク通信を行っているかどうかがすぐにはわからないため、事態は複雑になります。 COM は、今日の多くのプログラマーの間で時代遅れになり、最新のソフトウェアで使用されている他の多くのテクノロジよりも理解されていません。マルウェア アナリストは、Win32 の世界でのプログラミングのバックグラウンドによっては、COM の内部動作に特に慣れていない場合があります。

COM オブジェクトをインスタンス化する前に、関数CoInitialize()を呼び出して COM ライブラリを初期化する必要があります。これが正常に初期化されると、 CoCreateInstance()を呼び出して、Internet Explorer などの特定の COM オブジェクトのインスタンスを作成できます。この時点でどのオブジェクトがインスタンス化されているかを理解するには、 CoCreateInstance()関数の最初の引数を調べる必要があります。これは、COM オブジェクトの一意の識別子である CLSID 値になります。 COM を使用するマルウェア サンプルで見つかったCoCreateInstance()の呼び出しを次に示します。

reversing malware 1

IDA は最初の値の意味のある解釈ではなく、最初の値のデータ型を表示するだけなので、一見すると、この関数がどのオブジェクトをインスタンス化しているのかを判断するのは困難です。このコード例の最初の引数は、IDA Pro によって「rclsid」というラベルが付けられたバイナリ内のどこかに存在するグローバル変数 (実際には定数) です。この最初の引数をダブルクリックすると、IDA Pro は、変数がメモリ内でどのように見えるかを表示します。

マルウェアのリバース 2

この CLSID 値は、IDA によってデータ構造として認識され、ここではそのコンポーネントに分割して示されています。この CLSID 値を表す人間が判読できる方法は、「{0002DF01-0000-0000-C000-000000000046}」です。これらの値に自動的に名前を付ける IDA スクリプトがあればいいのですが、当面はレジストリで手動で調べることができます。 regedit を開いてキーHKEY_CLASSES_ROOTCLSIDを参照すると、それぞれ CLSID 値で名前が付けられた、かなり長いサブキーのリストが表示されます。 IDA Pro に表示される 16 進値と一致するサブキー名を見つけることで、プログラムが要求しているオブジェクト名を特定できます。これは、キーのデフォルト値に格納されています。上記のコード例で示した CLSID のキーを示す regedit のスクリーン ショットを次に示します。

マルウェアのリバース 3

このマルウェア サンプルは、Internet Explorer オブジェクトのインスタンスを作成しているようです。このオブジェクトの機能を使用するために、マルウェアはCoCreateInstance()関数 (「ppv」とラベル付けされた) の最後の引数を使用する必要があります。このパラメーターは、このオブジェクトに関連するすべてのデータ (特に関数ポインター) を含む、新しく割り当てられたデータ構造を受け取るためのポインターへのポインターです。使用可能な関数のリストは、http: //msdn.microsoft.com/en-us/library/bb159694.aspxに記載されています。ソース コード レベルから動作中の Internet Explorer オブジェクトを確認するには、次の記事を参照してください: http://support.microsoft.com/kb/167658

リバース エンジニアとして認識する必要があるこの COM オブジェクトへの最も重要な関数呼び出しは、関数Navigate()またはNavigate2( ) への呼び出しです。これは、POST データまたはパラメーター化された GET を含む HTTP 要求を実際に実行し、データをリモート コマンド アンド コントロール サーバーに送信するものです。次の画面フラグメントは、IDA Pro から見た IE COM オブジェクトのNavigate()メソッドの呼び出しを示しています。

マルウェアのリバース 4

このフラグメントでは、アクセスされている ppv 値が表示されます。これは、 CoCreateInstance()への呼び出しから入力されたものです。このデータ構造内から関数が呼び出されています。

この関数は ppv データ構造の先頭からオフセット 2Ch にあり、call 命令が構造体の先頭からこの特定のオフセットにアクセスするため、バイナリがこの関数を呼び出していることがわかります (“call dword ptr [ecx+ 2Ch ]” )。この COM インターフェイスの Microsoft ドキュメントから直接、各メンバー関数で使用される実際の内部オフセットを確認する明確な方法はないため、単純に各関数を参照する小さなテスト アプリケーションを作成しました。次に、テスト アプリケーションを逆アセンブルすると、メンバー関数へのオフセットの明確なマッピングを確認できました。次の表は、(特にマルウェアによって) 一般的に使用されるメンバー関数と、呼び出し命令で見られる関連するオフセットのマッピングです。

マルウェアのリバース 5

最終的な考え

この記事の目的は、より多くのマルウェア アナリストとインシデント レスポンダーに、マルウェア作成者が利用できるさまざまなコミュニケーション手法を認識させ、アナリストに特に COM 手法のリバース エンジニアリングを認識させ、開始できるようにすることでした。確かに、この分野ではより多くのツールやテクニックが必要ですが、すべては認識と理解から始まります。ここから取り除かなければならないことの 1 つは、マルウェア アナリストとして、単にアセンブリ言語を知っているだけでは十分ではないということです。 API の実用的な知識を得る必要があり、API に遭遇したときに API の新しい側面を学びたいという欲求に対して、完全に粘り強いとまではいかなくても、厳格でなければなりません。マルウェア アナリストが CoCreateInstance() などの呼び出しを理解していないために詳細な検査を行わずに無視すると、マルウェアの動作の非常に重要なコンポーネントを見逃す可能性があります。

参照: https://www.mandiant.com/resources/blog/reversing-malware-command-control-sockets

Comments

Copied title and URL