この章では、WinDbg ではなく Volatility 31 を使用してシステムのクラッシュダンプ(フルメモリダンプ)を解析する方法を簡単に紹介します。
Volatility 3 とは、インシデントレスポンスとマルウェア解析によく用いられるオープンソースのメモリフォレンジックフレームワークです。
Volatility 3 を使用すると、ダンプした物理メモリ内のデータから様々な情報を取得できます。
例えば、ダンプファイル内からのファイルの取得や端末の稼働情報の確認などは、Volatility 3 の機能を使用することでより簡単に行うことが可能です。
もくじ
- Volatility 3 をセットアップする
- Volatility 3 でクラッシュダンプを解析する
- クラッシュダンプから端末の通信状況を調査する
- クラッシュダンプから実行中のプロセスとコマンドラインの一覧を取得する
- プロセスメモリから実行ファイルをダンプする
- フルメモリダンプからファイルオブジェクトを収集する
- あとがき
- 各章へのリンク
Volatility 3 をセットアップする
フルメモリダンプを解析するために Volatility 3 のセットアップを行います。
Volatility 3 をセットアップする最も簡単な方法は、以下の公式リポジトリの Quick Start の手順です。
Volatility 3:
https://github.com/volatilityfoundation/volatility3
Volatility 3 は Python 製のツールなので、Python3 がインストールされている環境であればプラットフォームを問わず使用できます。
以下のコマンドは、Windows 端末でコマンドプロンプトから Volatility 3 を使用する場合の手順です。(事前に Git と Python3 をインストールする必要があります)
$ git clone https://github.com/volatilityfoundation/volatility3.git
$ cd volatility3
$ pip3 install -r requirements.txt
$ python3.exe vol.py -h
・・・
Volatility 3 Framework 2.5.2
usage: volatility [-h] [-c CONFIG] [--parallelism [{processes,threads,off}]] [-e EXTEND] [-p PLUGIN_DIRS]
[-s SYMBOL_DIRS] [-v] [-l LOG] [-o OUTPUT_DIR] [-q] [-r RENDERER] [-f FILE] [--write-config]
[--save-config SAVE_CONFIG] [--clear-cache] [--cache-path CACHE_PATH] [--offline]
[--single-location SINGLE_LOCATION] [--stackers [STACKERS ...]]
[--single-swap-locations [SINGLE_SWAP_LOCATIONS ...]]
plugin ...
ただし、本書では Volatility 3 を使用する環境として、Ubuntu 20.04 の WSL 上でセットアップした REMnux というマルウェア解析用の Linux ディストリビューションを使用しています。
REMnux:
Volatility 3 を使用するために REMnux をセットアップする必要はありませんので、環境については好みに合わせてセットアップしていただいて問題ありません。
Volatility 3 でクラッシュダンプを解析する
本章では、付録 A の「フルメモリダンプからファイルの中身を参照する」で使用したシステムのフルメモリダンプ(SAMPLE_DUMP.DMP)を Volatility 3 で解析してみます。
まずは、xxd SAMPLE_DUMP.DMP | head
コマンドを実行して、ダンプファイルの先頭のバイト列を確認します。
$ xxd SAMPLE_DUMP.DMP | head
00000000: 5041 4745 4455 3634 0f00 0000 614a 0000 PAGEDU64....aJ..
00000010: 00a0 1a00 0000 0000 0000 0000 00bb ffff ................
64 bit システムで取得したフルメモリダンプのファイルは _DMP_HEADER64
構造体から始まりますが、この構造体の先頭に埋め込まれているシグネチャが PAGEDU64
である場合には、Volatility 3 を使用した解析を行うことが可能です。(解析対象のファイルは、カーネルモードとユーザモードの両方の情報を含むシステムのフルメモリダンプである必要があります)2
実際に、vol3 -f SAMPLE_DUMP.DMP windows.info.Info
コマンドを実行することで、以下のようにフルメモリダンプからシステム情報を取得することができました。
クラッシュダンプから端末の通信状況を調査する
WinDbg での解析に使用していたシステムのフルメモリダンプを Volatility 3 でも解析できることが分かったので、システムクラッシュが発生した際の端末の通信状況を調査してみます。
フルメモリダンプから端末の通信を追跡するためには、 vol3 -f SAMPLE_DUMP.DMP windows.netstat.NetStat
コマンドを使用します。3
NetStat モジュールを使用することで、以下のようにメモリダンプ内の情報から端末の通信先のアドレスやポート番号、通信を行っているプロセス名などを特定できます。
同等の情報は、NetScan モジュールを使用して vol3 -f SAMPLE_DUMP.DMP windows.netscan.NetScan
コマンドを実行することでも取得することが可能です。
※ なお、NetScan モジュールは Pool tag quick scanning という手法でメモリ内の情報を解析しており、NetStat モジュールを使用する場合と比較してマルウェアなどによって隠蔽された情報を収集できる可能性が高い利点があるようです。
クラッシュダンプから実行中のプロセスとコマンドラインの一覧を取得する
PsList モジュール5や PsScan モジュール6を使用することで、クラッシュダンプから実行中のプロセスの一覧に関する情報を収集できます。
以下は、vol3 -f SAMPLE_DUMP.DMP windows.pslist.PsList
コマンドを実行した場合の出力結果です。
vol3 -f SAMPLE_DUMP.DMP windows.psscan.PsScan
コマンドで PsScan モジュールを使用する場合も同等の情報を取得できます。
他にも、vol3 -f SAMPLE_DUMP.DMP windows.pstree.PsTree
コマンドを実行することで、プロセスツリー形式で情報を出力できる PsTree モジュール7を使用できます。
また、CmdLine モジュール8を使用することでプロセスのコマンドラインの情報をダンプすることも可能です。
vol3 -f SAMPLE_DUMP.DMP windows.cmdline.CmdLine
コマンドで CmdLine モジュールを使用すると、以下の出力を得ることができました。
プロセスメモリから実行ファイルをダンプする
Volatility 3 を使用すると、付録 A の「ダンプファイルから WinDbg で実行ファイルを抽出する」と同じようにプロセスのメモリから実行ファイルを抽出することが可能です。
ただし、「ダンプファイルから WinDbg で実行ファイルを抽出する」に記載した通り、この方法で抽出した実行ファイルは元のファイルと完全に同一のファイルではない点に注意してください。
プロセスから実行ファイルをダンプする際には、前項と同じく PsList モジュールを使用できます。
すでに、vol3 -f SAMPLE_DUMP.DMP windows.pslist.PsList
コマンドで D4C.exe の PID が 3392 であることを特定済みなので、この情報を用いて D4C.exe をダンプしてみます。
REMnux$ vol3 -f SAMPLE_DUMP.DMP windows.pslist.PsList
Volatility 3 Framework 2.4.2
Progress: 100.00 PDB scanning finished
PID PPID ImageFileName Offset(V) Threads Handles SessionId Wow64 CreateTime ExitTime File output
・・・
3392 14168 D4C.exe 0xcb0c950ea0c0 3 - 3 False 2023-10-05 12:01:45.000000 N/A Disabled
プロセスメモリから実行ファイルをダンプする場合は vol3 -o /tmp -f SAMPLE_DUMP.DMP windows.pslist.PsList --pid 3392 --dump
コマンドを使用します。
このコマンドの -o /tmp
では、ダンプする実行ファイルの出力先を指定しています。
また、--pid 3392
には、D4C.exe のプロセスの PID を指定しています。
このコマンドを実行したことで、以下の通り tmp ディレクトリに pid.3392.0x7ff6d3e40000.dmp というファイルが保存されました。
このファイル pid.3392.0x7ff6d3e40000.dmp は Windows の実行ファイル(PE ファイル)ですので、dump.exe とリネームして Windows システムで実行してみます。
ダンプしたファイルを実行した結果、元の D4C.exe と同じようなメニュー画面を起動することを確認できました。
フルメモリダンプからファイルオブジェクトを収集する
Volatility 3 の FileScan モジュール9 を使用すると、メモリ内の情報からファイルオブジェクトを収集できます。
FileScan モジュールによるファイルオブジェクトの列挙を行う場合、 vol3 -f SAMPLE_DUMP.DMP windows.filescan.FileScan
コマンドを実行します。
今回は付録 A の「フルメモリダンプからファイルの中身を参照する」で使用したシステムのフルメモリダンプ(SAMPLE_DUMP.DMP)と同じダンプファイルを Volatility 3 で解析しています。
そのため、no-cached-file.txt や Microsoft Defender ウイルス対策のイベントログのファイルオブジェクトが存在する Offset が、WinDbg で特定したファイルオブジェクトのアドレスと一致していることを確認できます。(例えば、Windbg で調査した際には no-cached-file.txt のファイルオブジェクトが存在するアドレスは ffffc40861f5f720 と表示されていました)
REMnux$ vol3 -f SAMPLE_DUMP.DMP windows.filescan.FileScan
Volatility 3 Framework 2.4.2
Progress: 100.00 PDB scanning finished
Offset Name Size
・・・
0xc40861920440 \Windows\System32\winevt\Logs\Microsoft-Windows-Windows Defender%4Operational.evtx 216
・・・
0xc40861f5f720 \Users\Vuln\Desktop\no-cached-file.txt 216
ファイルオブジェクトのアドレスを特定できた場合、付録 A の「フルメモリダンプからファイルの中身を参照する」と同じように Volatility 3 を使用してメモリダンプからファイルをダンプすることが可能です。
Volatility 3 を使用してメモリダンプからファイルをダンプするには、DumpFiles モジュール10 を使用します。
DumpFiles モジュールを使用するために、vol3 -o /tmp -f SAMPLE_DUMP.DMP windows.dumpfiles.DumpFiles --virtaddr <ファイルオブジェクトのオフセット>
コマンドを実行します。
-o /tmp
では抽出したファイルの保存先のパスを指定しています。
以下は、no-cached-file.txt のファイルオブジェクトのオフセットを指定した場合の出力結果です。
コマンドは正常に実行できているものの、何のファイルも出力されませんでした。
このように、Volatility 3 を使用する場合にも、メモリダンプからシステム内のすべてのファイルをダンプできるわけではありません。
付録 A の「フルメモリダンプからファイルの中身を参照する」で確認した通り、no-cached-file.txt などのキャッシュマネージャによってキャッシュされていないファイルについては Volatility 3 でも取得することはできませんでした。
そこで次に、Microsoft Defender ウイルス対策のイベントログファイルのオフセットを指定してみます。
こちらは、コマンド実行時に DataSectionObject と SharedCacheMap のアドレスがコンソールに表示され、tmp ディレクトリ配下にファイルがダンプされました。
ここでダンプされたファイル file.0xc40861920440.0xc40861b5c350.DataSectionObject.Microsoft-Windows-Windows Defender%4Operational.evtx.dat
をリネームしてイベントビューアで参照することで、ダンプファイルを取得した端末のイベントログを復元できていることを確認できました。
ちなみに、付録 A の「フルメモリダンプからファイルの中身を参照する」では 1 つの VACB エントリが記述するキャッシュ用のスロットのサイズは 256 KB であると説明しました。
今回ダンプファイルから取得した Microsoft Defender ウイルス対策のイベントログファイルの実際のサイズは 68 KB でしたので、DumpFiles モジュールで取得した file.0xc40861920440.0xc40861582a20.SharedCacheMap.Microsoft-Windows-Windows Defender%4Operational.evtx.vacb
という VACB ファイルのサイズは 256 KB でした。
一方で、実際のサイズが 2116 KB である System イベントのファイルを DumpFiles モジュールでダンプすると、VACB ファイルのサイズは 9 エントリ分の 2304 KB になりました。
もちろん、この System イベントのファイルもイベントビューアで参照できました。
以上の通り、システムのメモリ内でキャッシュマネージャにキャッシュされているファイルであれば、DumpFiles モジュールは複数の VACB エントリを追跡して元のファイルを抽出できます。
あとがき
本書を最後までお読みいただき誠にありがとうございます。
今回は、Windows システムのフルメモリダンプやアプリケーションのプロセスダンプの取得方法、アプリケーションやシステムクラッシュ、またユーザモードメモリリークの原因をダンプファイルから特定する方法を紹介しました。
一般に、システムやアプリケーションのトラブルシューティングのためにダンプファイルの解析にトライされる方は IT 技術者全体の中でも比較的少ない割合ではないかと思います。
その理由としては例えば、ダンプファイルの解析を始めるために、レジスタやメモリ、仮想アドレス(VA)/相対仮想アドレス(RVA)、さらには OS の低レベルな動作やアセンブリ言語など、一般に難解とされる様々な知識が必要である点などがあるかと思います。
実際に私も、プログラムの解析やデバッグを初めたばかりのころは、これらの前提知識に関する理解が足りず、非常に苦労した記憶があります。
しかし、私はダンプファイルの解析に取り組む方が少ないより大きな理由として、「ダンプファイルの解析を始めるきっかけの少なさ」があると考えています。
より具体的に言うと、ダンプファイルの解析に関する情報が非常に少ないことが課題であると感じています。
本書のまえがきで述べた通り、絶版になっている書籍を除くと、Windows のダンプ解析について詳細な解説をしている日本語の書籍は現在、私が知る限り一冊もありません。
(唯一、インサイド Windows のコラムにはダンプファイルの解析のために有益な情報が数多く記載されていますが、第 6 版までは存在していたダンプファイルの解析に関する章が第 7 版では削除されてしまっている状況です)
このような状況の中で、Windows のダンプファイルの解析に関心を持ってもらうきっかけや、これから解析に取り組む方の最初のとっかかりになることを目的に本書を執筆いたしました。
本書で紹介することができた内容は非常に初歩的な内容に留まりますが、問題の原因がシンプルな場合にはダンプファイルから原因を特定することは難しくないことを感じていただけたかと思います。
本書が、少しでもこれから Windows のダンプ解析に取り組む方の役に立てば幸いです。
改めて、本書に興味を持ち、最後までお読みいただき誠にありがとうございました。
各章へのリンク
- まえがき
- 1 章 環境構築
- 2 章 WinDbg の基本操作
- 3 章 解析に必要な前提知識
- 4 章 アプリケーションのクラッシュダンプを解析する
- 5 章 システムクラッシュ時のフルメモリダンプを解析する
- 6 章 プロセスダンプからユーザモードアプリケーションのメモリリーク事象を調査する
- 7 章 フルメモリダンプからユーザモードメモリリーク事象を調査する
- 付録 A WinDbg の Tips
- 付録 B Volatility 3 でクラッシュダンプを解析する
-
Volatility 3 https://volatility3.readthedocs.io/en/latest/
↩ -
Volatility - Crash Address Space https://github.com/volatilityfoundation/volatility/wiki/Crash-Address-Space
↩ -
volatility3.plugins.windows.netstat module https://volatility3.readthedocs.io/en/latest/volatility3.plugins.windows.netstat.html#module-volatility3.plugins.windows.netstat
↩ -
volatility3.plugins.windows.netscan module https://volatility3.readthedocs.io/en/latest/volatility3.plugins.windows.netscan.html
↩ -
volatility3.plugins.windows.pslist module https://volatility3.readthedocs.io/en/latest/volatility3.plugins.windows.pslist.html
↩ -
volatility3.plugins.windows.psscan module https://volatility3.readthedocs.io/en/latest/volatility3.plugins.windows.psscan.html
↩ -
volatility3.plugins.windows.pstree module https://volatility3.readthedocs.io/en/latest/volatility3.plugins.windows.pstree.html
↩ -
volatility3.plugins.windows.cmdline module https://volatility3.readthedocs.io/en/latest/volatility3.plugins.windows.cmdline.html
↩ -
volatility3.plugins.windows.filescan module https://volatility3.readthedocs.io/en/latest/volatility3.plugins.windows.filescan.html
↩ -
volatility3.plugins.windows.dumpfiles module https://volatility3.readthedocs.io/en/latest/volatility3.plugins.windows.dumpfiles.html
↩