【テクニカル・上級編】 Volatility 3を用いたLinuxカーネルモジュールによるメモリダンプ解析 – インシデントレスポンス & フォレンジック(DFIR)防御ガイド

Linuxメモリフォレンジックの深淵:Volatility 3によるカーネル空間の「見えない脅威」を暴く

現代のインシデントレスポンスにおいて、ディスクフォレンジックはもはや「事後報告」に過ぎない。攻撃者がメモリ上にのみ存在するファイルレスマルウェアを展開し、カーネルモジュール(LKM)として常駐を果たした瞬間、OSの標準的なAPIは嘘をつき始める。psコマンドやnetstatで確認できる世界は、もはやハッカーの手によって改竄された「偽りの平和」だ。

我々DFIRのプロフェッショナルが対峙すべきは、このメモリの深淵に潜む「隠蔽された真実」である。今回は、Volatility 3を駆使し、Linuxカーネルレベルの不正なフックを特定するための技術的アプローチを解説する。

—

1. 境界線の崩壊:なぜLinuxメモリフォレンジックが難解なのか

Linuxのカーネル構造は極めて柔軟だが、それがそのまま攻撃者の強みとなる。特にLKMによるシステムコールテーブル(sys_call_table)の書き換えや、procfsの構造体の操作は、特権レベル(Ring 0)で実行されるため、OS自身の機能を使って検知することは不可能に近い。

Volatility 3は、従来のVolatility 2が抱えていた「プロファイル地獄(カーネルバージョンごとのプロファイル作成の苦労)」を、ISF(Intermediate Symbol File)という中間形式を採用することで解決した。これにより、シンボル情報さえ正確に生成できれば、マイナーなカーネルバージョンであっても深い解析が可能になる。

2. 実戦的アプローチ:ISFの生成とカーネルの可視化

解析の第一歩は、対象環境と完全に一致するシンボルファイルの生成だ。これがズレれば、メモリ上の構造体はただのノイズと化す。

中間シンボルファイル(ISF)の構築

まず、対象のカーネルソースまたはvmlinuxとSystem.mapを用意する。Volatility 3が提供するツール群を使用して、これをISFへ変換する。

# Volatility 3の提供するdwarf2jsonを用いて、DWARFデバッグ情報をJSON形式へ変換する
# これにより、特定のカーネルシンボルをVolatilityが解釈可能な形式に落とし込む
python3 ./dwarf2json linux --elf /boot/vmlinux-$(uname -r) --system-map /boot/System.map-$(uname -r) > kernel_symbols.json

このkernel_symbols.jsonをVolatilityのsymbolsディレクトリに配置することで、ようやく「迷宮の地図」が手に入る。

3. カーネル空間の不正フックを狩る

隠蔽されたLKMを見抜く際、私が最初に行うのは「プロセスのリスト」と「モジュールのリスト」の不一致確認だ。

不正なモジュールの特定

攻撃者は、lsmodの結果から自身のモジュールを削除する(list_delを呼び出す)手法を好む。しかし、メモリ内の構造体であるmodulesのリンクリストを辿れば、リンクから外された「幽霊」を捕まえることができる。

# Volatility 3でlinux.lsmodを実行し、リンクされていないモジュールがないか確認する
# また、linux.check_syscalls を用いてシステムコールテーブルの改竄を検証する
vol -f dump.mem linux.check_syscalls

もしcheck_syscallsの出力で、標準のシステムコールのアドレスがカーネルのコード領域外、あるいは不審なLKM領域を指している場合、それは確定的な侵害のサインだ。

フック箇所の検証サンプル

以下のコマンドは、システムコールテーブルの異常を検知するための指標となる。

# システムコールテーブルをスキャンし、異常なジャンプ先を特定する
# 出力結果がカーネルのベースアドレスから著しく乖離していれば、パッチが当てられている
vol -f dump.mem linux.check_syscalls --dump

—

4. 防御アーキテクチャへの教訓:侵害を許さないために

メモリフォレンジックは「侵害を前提とした解析」だが、アーキテクトとしては、この解析を不要にする「ガードレイル」を設計しなければならない。

1. Kernel Lockdown Modeの有効化:
LinuxカーネルのLockdown機能を有効にすることで、特権ユーザーであってもカーネルイメージの変更や、/dev/mem経由のメモリ読み書きを制限できる。これは攻撃者のLKM挿入に対する強力な防壁となる。
2. eBPFによる監視の信頼性:
従来のシステムコールフックではなく、eBPFを用いたランタイムセキュリティ(TetragonやFalcoなど)を導入すべきだ。eBPFはカーネルの機能を拡張しつつ、フックポイントを安全に管理できるため、攻撃者が低レイヤで隠蔽を試みても、イベントの改竄が困難になる。
3. 署名されたモジュールのみの読み込み:
module.sig_enforce=1の設定を徹底し、信頼された鍵で署名されていないLKMのロードを物理的に拒絶する。

結びに:泥臭い現場の視点

メモリ解析とは、単なるツールの操作ではない。攻撃者がどのタイミングでメモリを確保し、どの構造体を書き換えて足跡を消したのかという「物語」を復元する作業だ。

AIが生成するコードや自動化されたスキャンは確かに有用だが、最終的に「これが通常時の挙動とどう異なるのか」を判断するのは、人間の洞察力である。カーネル空間のわずかなオフセットのズレに違和感を抱けるか。そこに、一流のDFIRアナリストと、単なるオペレーターの境界線がある。

次のインシデントでは、psの結果を信じず、メモリの生データが語る真実を直視してほしい。そこには、攻撃者が最も隠したかった「手口」が刻まれているはずだ。

コメント

タイトルとURLをコピーしました