最近のアンチウィルス対策、アンチフォレンジックのテクニックとして、「Process Hollowing」というテクニックがあります。
大雑把に言うと、マルウェアが自身の中で暗号化しておいた悪意あるコードを解凍し、無害なプロセスを作成したあと、その中身のコードをゴッソリ挿げ替える、というテクニックです。
以下のブログ記事やPDFファイルが詳しく解説していますので参考に。
Process Hollowing
https://medium.com/@jain.sm/process-hollowing-930b30452279
Process Hollowing
http://www.autosectools.com/process-hollowing.pdf
このマルウェアの解析をする場合、新たに作成されて展開されたプロセスを解析することがメインになります。
私の場合、通常はこの新しいプロセスにデバッガでアタッチして解析しています。
この解析を簡略化するために、暗号化を解除された直後の実行ファイルデータをファイルにダンプして、それを解析すればいいのでは?と考えるわけです。
しかし、このダンプファイルを解析しようとした場合、インポートテーブルが上手く紐づいていなかったり、メモリのマッピングが合わなかったりして、実行できなかったりします。解凍されたコードが、素直に実行ファイルと同じじゃなかったりするためです。
そこで、アクティベートされたプロセスからIAT(Import Address Table)を分析し、FIXして実行形式ファイルに出力する方法を試してみたので、その手順をメモしておきます。
(実際には、別にこんな技使わなくてもいいかもしれませんが一応。)
ご自宅で自分の研究でやっていますが、たまにはお仕事でガッツリこういう解析したいなぁ・・・。どっかウチの会社に依頼してくれないかなw
今回のターゲットは「MegaCortex」というランサムウェア株の一つと言われている検体です。
ハッシュ値は以下のとおり。
MD5: 2B21BA38C13446B6CDD0113E719CA21C
SHA1: 7772C87601440E93C6D990F4EE31EED314E9C20D
VirusTotalでハッシュ値で検索すると以下のようにでました。SymantecがMegaCortexの名前を明記していますね。
使用するツール
今回は、「x32dbg」を使ってターゲットのプロセスから実行可能なファイルを抽出します。
「x32dbg」は「x64dbg」の32bit版です。「x64dbg」を導入すると、一緒についてきます。
x64dbg
また、プラグインに「Scylla」が入っており、このプラグインのダンプ機能やIAT分析機能、Fix Dump機能を用います。
今回はこれらがメインです(個人的な趣味でIDAも使っていますが)。
大まかな手順
最初に、おおまかな流れを書いておきます。
- デバッガで、Process Hollowingのプロセスを作成、メモリをコピーし、プロセスをResumeするところで停止。
- x32dbgを起動し、Process Hollowingのプロセスにアタッチ
- x32dbgでOEPにブレークポイント設定
- デバッガで停止していたResumeを実行
- x32dbgでブレークポイントで停止
- Scyllaで対象のプロセスのIATを分析、Importテーブルを取得
- Scyllaで対象のプロセスのPE Dumpを取得
- 取得したPE DumpをScyllaのFix Dump機能でImportテーブルを解決した実行ファイルを出力
メモリへのアタッチ
最初に、Process Hollowingのターゲットとなったプロセスにアタッチします。
Process Hollowingを行う場合には、先に示した記事の通り、無害なプロセスをSuspendで作成して、そのプロセスの中身を書き換えたあと、そのプロセスResumeします。
このため、ターゲットのプロセスのメモリの中身が書き換えられた後で、Resumueする瞬間を狙ってデバッガで停止します。
今回の検体では、メモリ上に展開された実行コードのオフセット0x0D35のcall eax (eaxがResumeThreadのアドレスを示している)で停止しました。
なお、この検体ではここに至るまでにもいくつかアンチフォレンジック、アンチ解析のテクニックが見られました。これらを破ってここまで到達することが前提条件となります。
アンチフォレンジック、アンチ解析のテクニックは、解析方法を記事にすると、その手法も晒すことになるため、「マルウェア作成の知識を与えた」とか言ってマルウェア作成罪で捕まりそうなので、日本では公開できそうにないなぁ(どうにかならんか、アノ阿呆共の魔女裁判)。
Resume直前で寸止めした後、x32dbgを起動します。このとき、ファイルは開く必要はありません。
「ファイル」メニューからアタッチを選択すると、アタッチできる32ビット実行プログラムのプロセスがリスト表示されます。
対象となるプロセスを選択してください。
プロセスIDは、Process Hackerなどのツールも使って確認してください。
プロセスIDが16進数表記されている点には注意してください。
アタッチしたプロセスは、x32dbgで実行ファイルを開いたときと同様にコードを見ることが可能です。
デバッガ機能でOEPにあたるアドレスにブレークポイントを設定します。
今回は、0x004014B0に設定します。
なお、今回のOEPは、アタッチしたプロセスの分析を別途ある程度進めていたので、ある程度推測が可能でした。OEPのアドレスの求め方はちょっと課題になりそうです。特に、今回の検体はTLSコールバックもあったので、私も最初はOEPの位置を誤って判断していました。ちゃんとPEヘッダ部分を見ればいいんでしょうけどね!
この後、Resume直前で止めていたデバッガでResumeを実行します。
今回の検体は、アタッチしたときにdllの中で止まっていたので、こちらも実行しました。
ブレークポイントで止まったことを確認してください。
ちょっと長くなりそうなので、ここで一度ぶった切りします。
次に、Scyllaを使った出力を書きます。