先日、「#ssmjp 2014/04」という勉強会に参加してきました。
どの発表も興味深い内容であり、とても充実した勉強会でした。

#ssmjp 2014/04
http://connpass.com/event/5888/

その中でマルウェア解析に係る発表として、
「Perfect Unpacking ノススメ」の内容をまとめたいと思います。

ZeuSをはじめとしたマルウェアに使用される最近のパッカーは、
メモリ上にオリジナルの実行ファイルそのものを一度展開する特徴があるため、
展開された際にメモリ上からオリジナルの実行ファイルを切り出してしまえば良いという内容です。

従来のアンパック(Classic Unpacking)では、OEPを見つけ出したりIATの再構築といった面倒な作業がありましたが、今回の手法では適当(適切)なところでブレークし、メモリ上から抽出するだけでオリジナルの実行ファイルが手に入ります。
また、従来のアンパックでは、Hash("オリジナル実行ファイル")とHash("アンパックした実行ファイル")が一致しませんが、今回の手法ではHash("オリジナル実行ファイル")とHash("アンパックした実行ファイル")が一致します。

【使用ツール】
OllyDbg v1.10
FileInsight

【対象マルウェア】
今回はZeusVMというマルウェア(ZeuSの亜種)を対象とします。
ハッシュ値等は公開しません。

【方法】
OllyDbgにマルウェアを読み込ませます。


パッカーが呼び出すAPIにブレークポイントを設定します。
発表では、例として次のAPIが挙げられていました。

・WriteProcessMemory
・ZwWriteVirtualMemory
・CreateProcessW
・VirtualFree
・VirtualFreeEx
・RtlFreeHeap

今回は「CreateProcessW」にブレークポイントを設定します。
OllyDbgの逆アセンブリ画面(左上の画面)で「Ctrl」+「G」を押下します。


表示された入力欄に「CreateProcessW」と入力し、「OK」を選択すると画面が切り替わるので、先頭にブレークポイントを設定します。(「F2」を押下します。)


「F9」を押下して実行すると、「CreateProcessW」の先頭でブレークします。
「View」-「Memory」を選択するとメモリマップが表示されるので、「Ctrl」+「B」を押下し、表示された入力欄のASCIIに「MZ」と入力し、「Case Sensitive」にチェックを入れて「OK」を選択します。



メモリ上で「MZ」を検索しダンプ画面が表示されます。
マルウェアっぽい(?)実行ファイルが表示されるまで「Ctrl」+「l」を押下します。


今回の例ではヘッダに「This program cannot be run in DOS mode」といった文字列が無い、といったマルウェアっぽさが見られました。
ダンプ画面のコンテキストメニュー(右クリックで表示されるメニュー)で「Backup」-「Save data to file」を選択し、ダンプ画面に表示されたデータをファイルとして出力します。
ここでは、ファイル名を「dump.exe」としました。
次に、「dump.exe」をFileInsightに読み込ませます。


メモリ上のデータをファイルとして出力しただけであり余計なデータがあるので、必要な部分(実行ファイル)のみを切り出します。まず、「Ctrl」+「F」を押下し、表示された入力欄に「MZ」と入力し、「MZ」を検索します。
OllyDbgのダンプ画面で見つけた「MZ」を探し、「MZ」より前のデータをすべて削除します。


FileInsightにはPEファイルの構造を解析する機能があるため、セクション等の情報が画面左側に表示されます。画面左側に表示されたセクションの中で、最後のセクション(今回の例では「.reloc」)を選択すると、当該セクションの部分だけ色が変わって表示されますので、当該セクション以降をすべて削除します。
(今回の例では、0x32E00以降のデータを削除します。)


ただし、今回の対象マルウェア「ZeuS」のようにセクション外にデータ(オーバーレイ)を持っている場合には、合わせてオーバーレイも切り出す必要があります。
今回の例では、オーバーレイのサイズは0x200バイト(512バイト)であるため、0x33000(0x32E00 + 0x200 = 0x33000)以降のデータを削除します。
(赤枠で囲んだ部分がオーバーレイです。)


※ZeuSのオーバーレイのサイズは種類(亜種)ごとに異なります。
ZeuS 2.0.8.9、ZeusVMやGameOverは0x200バイト、Citadelは0x400バイトのはずです・・・たぶん。

これでアンパック作業は終了です。
試しにアンパックして得られた実行ファイルをOllyDbgに読み込ませてみます。
見慣れたアセンブラが表示されると思います。


私は趣味でZeuSの解析を行っており、
1 ZeuS内で使用されているAPIでブレーク
2 今回の方法(の簡易版※)
の順で試す手順をとっていますが、9割以上がこの手順で解析できています。

※今までは「MZ」より前のデータの削除は行っていましたが、後ろについている余計なデータの削除はしていませんでした(汗)。
そのため、今回の勉強会で正しいアンパック方法を学べてとても勉強になりました。

使用されているパッカーによっては、アンチデバッグ機能があるため、OllyDbgの例外処理の設定を変更したり、プラグインを使用しています。今回は「PhantOm」というプラグインをこっそり使用していました。
それでは。
AD