マルウェア解析に役立つTiny Tracerの活用例の紹介
2024年12月23日 月曜日
CONTENTS
【IIJ 2024 TECHアドベントカレンダー 12/22の記事です】
はじめに
こんにちは。IIJでSOCアナリストをしている前川です。
本記事では、マルウェア解析に活用できるTiny Tracerの概要、Tiny Tracerの機能、及びその活用方法をご紹介します。なお、本記事の執筆時点ではTiny TracerはWindowsとLinuxに対応していますが、ここではWindowsに限定して解説します。
Tiny Tracerとは
Tiny Tracerはマルウェアの実行状態を追跡・監視して、特定の挙動をした際にログを出力してくれるツールです。Tiny Tracerで調査できるマルウェアの挙動は主に次の4つです。
- マルウェアによるWindows APIの呼び出しとその引数
- セクションを跨いだコードへの遷移
- マルウェアによるsyscall(システムコール)の実行とその引数
- 特定のx86CPU命令(RDTSC、CPUID、INT)の実行
筆者がマルウェア解析でTiny Tracerを使う際は、1と2について調べることが多いです。
1を調べる理由としては、マルウェアは不正活動をする際に特定のWindows APIを使用するケースがあり、呼び出された一連のWindows APIと引数を調べることで、マルウェアが使っているテクニックを特定できる場合があるためです。また、マルウェアは不正活動に使用するWindows APIを隠し持つことが多くありますが、Tiny Tracerで監視することにより、そのWindows APIが実行されたタイミングでログに出力します。
2に関しては、マルウェアは不正活動を行うためのコードを暗号化や圧縮した状態で実行ファイル内に隠し持ち、実行時に復号や解凍を行いプロセスメモリ上に展開して実行することがあります。展開したコードに実行制御を移す挙動を、Tiny Tracerで監視することでそのコードへ遷移する場所(アドレス)を特定できるため、不正なコードを素早く発見できる場合があります。
次の図は、Tiny Tracerでマルウェアの実行を監視した際に出力されたWindows API呼び出しログの例です。
ここではWindows API呼び出しのログが4つ表示されています。マルウェアがWindows APIを呼び出す度に、1行ずつログが記録されています。
Windows API呼び出しのログフォーマットは「【Windows APIを呼び出したRVA】;【Windows APIを含む モジュール名】.【WindowsAPI名】」という形式になっています。RVAとは、Relative Virtual Addressを表し、日本語にすると相対仮想アドレスと呼ばれます。相対仮想アドレスは、実行ファイルやDLLファイルがロードされたメモリの先頭アドレスからのオフセットです。例えば、上で示したログの先頭行は「123ef;kernel32.LoadLibraryA」となっていますが、このマルウェアがアドレス0x400000にロードされていた場合、マルウェアはアドレス0x4123efからLoadLibraryAを呼び出したことになります。
このログから、マルウェアはLoadLibraryAとGetProcAddressをそれぞれ2回ずつ呼び出していることが分かります。
また、それぞれのRVAは近いアドレスを示していることから、同一関数内で連続して呼び出されたことが推測できます。上述したように、マルウェアは不正活動に使用するWindows APIを隠し持つことが多くあります。その場合、実行時にマルウェア自身でモジュールをロードしてWindows APIが存在するアドレスを特定する必要があり、その手段の1つにLoadLibraryA、GetProcAddressの使用があります。これらの呼び出し時にはモジュール名やWindows API名を引数で渡すため、引数も監視することでマルウェアが何のWindows APIを隠しているかが判明します。
なお、Windows API呼び出し時の引数はデフォルトではログに出力されないため、事前にその設定を行う必要があります。次の図は、引数を監視する設定を行った場合のWindows API呼び出しログの例です。
Tiny Tracerを使ったマルウェア解析の例
ここでは、情報窃取型マルウェアであるStealCに対してTiny Tracerを活用する例をご紹介します。
次の検体を使用します。実際に検体を解析する場合は、自身の責任のもとで行ってください。
- 9c9306c968318a95791dee86bbc6c16f6b1d0f53b5b7d682c2a48a5c6cc1a75e
まず初めに、Tiny Tracerをマルウェア解析を行う環境にインストールする必要があります。
インストール手順は開発者が手順を公開しているため、この手順にしたがってインストールします。
では、マルウェアの調査をしていきます。
まずはTiny Tracerを使用しないでStealCの挙動を調査してみます。
StealCは情報窃取型マルウェアであるため、端末に感染すると情報を収集して外部に送信することが想定されます。
実際にStealCを実行して挙動を観察してみます。
ここでは、マルウェアの動的解析を支援するツールのProcess Hacker、及びNoribenを調査に使用しました。
Process Hackerは、システムで動いているプロセスの状態をリアルタイムで表示してくれます。Noribenはマルウェアが実行時に行ったプロセス、ファイル、レジストリ、ネットワークに関する操作ログを出力してくれるツールです。
StealCを実行した際の結果は次のようになりました(StealCのファイル名はa.exeです)。
Process Hackerの様子を見ると、StealCの実行後にプロセスが表示されましたが、すぐに終了してしまいました。
次にNoribenの結果を確認します。プロセスの操作ログが1つ出力されていますが、これは筆者がマルウェアを起動したログでありマルウェアによる操作ではありません。
StealCによるファイル、レジストリの操作ログも出力されておらず、外部へのネットワーク接続もありません(Noribenが出力したログには、各処理を行ったプロセス名とプロセスIDが記載されており、そこからどれがStealCのログか判別可能です)。
StealCは本来実行するはずの不正活動を何も行わないまま終了したように見えます。
マルウェアは自身が実行されている環境を調べて解析環境と判断した場合は本来の動作を行わない場合があるため、StealCが解析環境を検知し即座に処理を終了したことが可能性の1つとして考えられます。
解析環境かどうかを判別する手法は数多く存在するため、StealCがどの手法を使っているかを1つ1つ確認するのは現実的ではありません。解析環境の判別方法としてハードウェア情報やレジストリキーなどシステムの環境をチェックする方法があります。それらの情報を取得するために特定のWindows APIを呼び出している場合、Tiny Tracerで監視しておくことで該当のコードを特定できる可能性があります。
では次にTiny TracerでStealCの挙動を調査しようと思いますが、その前にコンフィグファイルを弄ってTiny Tracerの動作を調整します。
Tiny Tracerのコンフィグファイル
Tiny Tracerはコンフィグファイルによってその動作を調整できます。コンフィグファイルはTiny Tracerのインストールフォルダから tiny_tracer\install32_64\TinyTracer.ini のパスにあります。次の画面はTinyTracer.iniをテキストエディタで開いた様子です。
コンフィグファイルには調整可能な項目がいくつかデフォルトで登録されています。コンフィグファイルのリファレンスは作者が公開しています。ここでは今回の解析において重要な項目に絞って紹介します。
- FOLLWO_SHELLCODES
本項目はマルウェアがプロセスメモリ上に展開したコード(シェルコード)に実行制御を移した後もTiny Tracerでの監視を継続するか否かを決定する項目です。コンフィグファイル内に本項目の説明が記載されていますが、本項目は0~3までの設定が可能です。今回は2を設定します。これによりマルウェアが展開したシェルコードに実行制御が移った後でも監視を継続するようになります - ANTIDEBUG、ANTIVM
マルウェアがデバッグ環境やVirtual Machine環境を検知するテクニックを使用した際にログに記録する設定です。有効にする場合は1、無効にする場合は0を設定します。Tiny Tracerが対応しているアンチデバッグ、アンチVMテクニックをマルウェアが使った場合にログに出力してくれます。今回は有効にしておきます
また今回のStealCの解析ではもう1つ設定を行う必要があります。
Tiny Tracerは解析対象のマルウェアが呼び出したほぼすべてのWindows APIをログに記録します。そのため、今回解析するStealCの実行後のログファイルは最終的に10GBを超えるサイズとなってしまいました。Tiny Tracerにはログに記録させないWindows APIを設定する機能が備わっています。TinyTracer.iniと同じフォルダ内に配置されているexcluded.txtを開き、ログに記録させないWindows APIを「【Windows APIを含むモジュール名】;【WindowsAPI名】」のフォーマットで1行ずつ登録します。今回はGetLastError、SetLastError、CharUpperW、InitializeCriticalSectionAndSpinCountの4つのWindows APIが大量に呼び出されていますが、StealCの分析には不要であるため除外します。
Tiny TracerでStealCを実行
コンフィグファイルとexcluded.txtを保存したらTiny Tracerを使ってStealCを実行します。
Tiny Tracerのインストール後、アプリケーションのアイコンを右クリックすると「Run with PIN (Tiny Tracer)」というメニューが表示されるため、これをクリックするとTiny Tracer上でStealCが起動します。なお右クリックメニューには「Run with PIN (Tiny Tracer) – as Administrator」もありますが、今回はこちらは使用しません。
StealCのアイコンを右クリックして「Run with PIN (Tiny Tracer)」を選択すると、pin.exeが起動し子プロセスとしてStealC (a.exe)が起動したことが分かります。
StealCを実行して少し経過するとStealCのCPU使用率が50%前後を推移していることが分かります(CPU使用率はProcess HackerのCPU列に表示されています)。
Tiny TracerはPINと呼ばれる動的バイナリ計装エンジンをベースに作成されており、PINがStealCのコード解析や計装(コードの挿入)を行いつつ実行しています。筆者の経験上、PINがコード解析や計装を行っている際のマルウェアのCPU使用率はこのあたりを示します。そのため、CPU使用率が50%前後を推移していれば解析はが進んでいると考えられます。
Tiny Tracerでマルウェアを実行する際の注意点として、マルウェアはPINで解析と計装を行いながら実行されているため、通常の実行と比べて実行パフォーマンスが著しく低下します。そのため、解析結果を得るまでにある程度の時間が掛かります。StealCは先に行った動的解析の結果、最終的にプロセスが終了することが分かっているので、終了するまでしばらく待ちます。
ログファイルは、実行したStealCと同じフォルダに「.tag」という拡張子が付いたファイル名で生成されます。今回の場合は「a.exe.tag」というファイル名になります。
ログファイルの解析
ではログファイルを調べていきます。今回調査したい内容はStealCが終了した原因のため、ログファイルの末尾を見てみます。
ログは全部で418行出力されており、最後は自身のプロセスを終了させるExitProcessとTerminateProcessを呼び出したログが記録されています。その直前にはSystemTimeToFileTimeが2回呼ばれていることが確認できます。SystemTimeToFileTimeは時刻の表示形式を変換するWindows APIですが、それぞれが呼び出されたアドレスが近くにあり、連続して呼ばれたように見えます。また、直後のExitProcessが呼び出されたアドレスとも近いことから、SystemTimeToFileTimeにより2点における時刻を取得して、その結果をもとにプロセスの終了判断をした可能性があると推測できます。Tiny Tracerの調査結果により、StealCの終了原因の可能性があるコードアドレスを特定できたため、デバッガやディスアセンブラを用いてコードを詳細に解析できました。本記事はTiny Tracerの紹介のため、解析の説明はここまでにします。
なおコード解析の結果、StealCは2回のSystemTimeToFileTimeで現在時刻と、ある特定の時刻をそれぞれ取得して、現在の時刻が特定の時刻を過ぎていた場合に終了する実装となっていました。つまり、有効期限が設定されていたために終了してしまったということが分かりました。
おわりに
本記事ではTiny Tracerのマルウェア解析への活用方法を紹介しました。
Tiny Tracerはマルウェア解析において非常に役立つツールですが日本語の資料は少ないため、この記事を見て興味を持ってもらえれば幸いです。
Xのフォロー&条件付きツイートで、「IoT米」と「バリーくんシール」のセットを抽選でプレゼント!
応募期間は2024/12/02~2024/12/31まで。詳細はこちらをご覧ください。
今すぐポストするならこちら→ フォローもお忘れなく!