top of page

実践:mquireでLinux メモリフォレンジックを

10月4日
読了時間: 8分

Linux のメモリフォレンジックは、面白い一方で、最初の一歩が重い分野です。特に面倒なのが、対象カーネルに合ったデバッグシンボルやプロファイルの準備です。

インシデント対応では、解析したいマシンが都合よく標準構成とは限りません。独自カーネル、古いカーネル、更新済みの環境、すでに消えているパッケージ。そうした現実にぶつかると、メモリダンプは手元にあるのに、解析環境の準備で止まってしまうことがあります。

そこで試したいのが「mquire」 です。


mquire は、Linux メモリダンプの中に残っている BTF や Kallsyms を使い、外部のデバッグシンボルにできるだけ頼らずに解析するツールです。さらに面白いのは、プロセス、オープンファイル、ネットワーク接続、カーネルモジュール、dmesg などを SQL で横断的に調べられる ことです。


つまり、mquire は「メモリダンプを読むツール」というより、Linux の実行状態をメモリから再構成して、SQL で調査するためのツールとして見ると分かりやすいです。


今回やること


この記事では、Ubuntu VM 上で次の流れを試します。

1. mquire をビルドする
2. AVML で Linux メモリダンプを取得する
3. mquire で OS 情報を確認する
4. プロセス一覧を見る
5. オープンファイルを見る
6. ネットワーク接続を見る
7. カーネルモジュールと dmesg を確認する
8. メモリ上に残るファイルを抽出する

最終的には、sshd を例にして、プロセス、通信、オープンファイルをメモリダンプから追ってみます。


検証環境

Host OS      : Windows / macOS / Linux
Guest OS     : Ubuntu 24.04 LTS
CPU          : x86_64
Memory       : 4GB 以上推奨
Tool         : mquire
Memory Dump  : AVML で取得した LiME 形式

mquire は比較的新しい Linux カーネルの機能に依存します。まず試すなら、Ubuntu 24.04 LTS のような新しめの環境を使うのが安全です。


1. mquire をビルドする

mquire は Rust 製です。Ubuntu に必要なパッケージを入れて、ソースからビルドします。

sudo apt update
sudo apt install -y git curl build-essential pkg-config

Rust を導入します。

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
source "$HOME/.cargo/env"

mquire を取得します。

git clone https://github.com/trailofbits/mquire
cd mquire
cargo build --release

ビルドできたら、PATH の通った場所に配置します。

sudo install -m 0755 target/release/mquire /usr/local/bin/mquire
mquire --help

ここでヘルプが表示されれば準備完了です。




2. メモリダンプを取得する


mquire で解析するには、まず Linux のメモリダンプを取得する必要があります。ここでは AVML を使います。AVML は Microsoft が公開している Linux 向けの揮発性メモリ取得ツールです。x86_64 Linux 上で動く静的バイナリとして配布されており、対象マシン上でカーネルモジュールをビルドせずにメモリ取得できるのが扱いやすい点です。


まず、作業ディレクトリを作ります。

mkdir -p ~/mquire-lab/toolscd ~/mquire-lab/tools

AVML の最新版は GitHub Releases から取得します。リリース番号は変わるため、まず現在の最新版を確認してからダウンロードします。2026年4月時点では v0.17.0 が公開されています。

# 例:バージョンは GitHub Releases で確認して置き換えるAVML_VERSION="v0.17.0"wget "https://github.com/microsoft/avml/releases/download/${AVML_VERSION}/avml"chmod +x avml

PATH の通った場所に配置します。

sudo install -m 0755 avml /usr/local/bin/avml

動作確認します。

avml --help

ここでヘルプが表示されれば、AVML の導入は完了です。


それでは、メモリダンプに移ります。まずは、作業ディレクトリを作ります。

mkdir -p ~/mquire-lab
cd ~/mquire-lab

次のコマンドでメモリダンプを取得します。

sudo avml ubuntu-memory.lime

ここで注意したいのは、最初は圧縮オプションを使わないことです。まずは非圧縮のメモリダンプで動作確認した方が、トラブルの切り分けが楽です。


3. mquire で OS 情報を確認する

最初に、mquire がメモリダンプを読めるか確認します。

mquire query ~/mquire-lab/ubuntu-memory.lime \
  "SELECT * FROM os_version" \
  --format table

ここでカーネルバージョンやアーキテクチャが表示されれば、解析の入口には立てています。


この段階でエラーになる場合は、メモリダンプの形式、カーネルの BTF 対応、Kallsyms の有無を疑います。


4. テーブル一覧を確認する

mquire の便利なところは、メモリ上の情報をテーブルとして扱えることです。

mquire query ~/mquire-lab/ubuntu-memory.lime ".tables"

対話シェルも使えます。

mquire shell ~/mquire-lab/ubuntu-memory.lime

シェル内では、次のように操作できます。

.tables
.schema tasks
SELECT * FROM tasks LIMIT 5;
.exit

最初に見るべき中心テーブルは tasks です。これは Linux のプロセス情報に相当します。


5. プロセス一覧を見る

まずは、メモリダンプ内に残っているプロセスを確認します。

mquire query ~/mquire-lab/ubuntu-memory.lime \
  "SELECT pid, tgid, comm, command_line FROM tasks LIMIT 20" \
  --format table

調査では、コマンドラインが残っているプロセスを優先して見ます。

SELECT pid, tgid, comm, command_line
FROM tasks
WHERE command_line IS NOT NULL
LIMIT 50;

ライブ環境で ps aux を見るのとは少し感覚が違います。mquire は、取得時点のメモリからプロセス構造を辿っているため、実行状態の断面を見るイメージです。


6. プロセスツリーを見る

プロセスの親子関係を見たい場合は、.task_tree が使えます。

mquire command ~/mquire-lab/ubuntu-memory.lime ".task_tree" | head -n 50

スレッドも含めたい場合は、次のようにします。

mquire command ~/mquire-lab/ubuntu-memory.lime \
  ".task_tree --show-threads" | head -n 50

プロセス一覧だけでは分からない起動関係を確認できるので、調査初動ではかなり便利です。


7. オープンファイルを確認する

次に、プロセスが開いていたファイルを見ます。

mquire query ~/mquire-lab/ubuntu-memory.lime \
  "SELECT t.pid, t.comm, tof.path
   FROM tasks t
   JOIN task_open_files tof ON tof.task = t.virtual_address
   LIMIT 50" \
  --format table

特定のプロセスに絞る場合は、次のようにします。

mquire query ~/mquire-lab/ubuntu-memory.lime \
  "SELECT t.pid, t.comm, tof.path
   FROM tasks t
   JOIN task_open_files tof ON tof.task = t.virtual_address
   WHERE t.comm LIKE '%ssh%'
   LIMIT 50" \
  --format table

ここで見たいのは、単にファイル名ではありません。

見るべきポイントは、次のようなものです。

- 一時ディレクトリ配下の不審なファイル
- 削除済みと思われるファイル
- 認証情報や設定ファイル
- SQLite などのローカル DB
- エージェントやサービスが開いているログファイル

メモリフォレンジックでは、ディスク上にはもう残っていない手がかりが、プロセスの open file や page cache 側に残ることがあります。


8. ネットワーク接続を見る

外部通信の痕跡も確認します。

mquire query ~/mquire-lab/ubuntu-memory.lime \
  "SELECT * FROM network_connections LIMIT 30" \
  --format table

SSH に関係する通信だけを見るなら、次のようにします。

mquire query ~/mquire-lab/ubuntu-memory.lime \
  "SELECT *
   FROM network_connections
   WHERE local_port = 22 OR remote_port = 22" \
  --format table

ネットワーク接続を見るときは、単体で判断しない方がよいです。

network_connections
  ↓
tasks
  ↓
task_open_files
  ↓
memory_mappings

この順番で見ると、「どの通信があり、それを持っていたプロセスは何で、そのプロセスが何を開いていたか」までつなげやすくなります。


9. カーネルモジュールを見る

不審なカーネルモジュールがないか確認します。

mquire query ~/mquire-lab/ubuntu-memory.lime \
  "SELECT name, state, version FROM kernel_modules LIMIT 50" \
  --format table

通常のサーバーでは見慣れないモジュール名や、想定外のドライバが出てきた場合は、別途確認します。rootkit 調査では、カーネルモジュールの一覧だけで判断するのは危険ですが、初動確認としては有効です。


10. dmesg を見る

カーネルログも確認します。

mquire query ~/mquire-lab/ubuntu-memory.lime \
  "SELECT * FROM dmesg LIMIT 50" \
  --format table

クラッシュ、ドライバ読み込み、ファイルシステムエラー、異常なモジュールロードなどが残っていないか見ます。ライブ環境でログがローテートされていても、メモリ側に痕跡が残っている可能性があります。


11. メモリ上のファイルを抽出する

mquire では、page cache に残っているファイル内容を抽出できます。

mkdir -p ~/mquire-lab/extracted

mquire command ~/mquire-lab/ubuntu-memory.lime \
  ".dump ~/mquire-lab/extracted"

抽出結果を確認します。

find ~/mquire-lab/extracted -type f | head -n 30

この機能はかなり強力です。削除済みファイルや一時ファイルの一部が、メモリ上に残っていれば回収できる可能性があります。


ただし、万能ではありません。メモリに載っていないファイルは当然抽出できませんし、内容が部分的にしか残っていないこともあります。


sshd の痕跡を追う


実運用の一例として、SSH 接続がある状態の VM からメモリダンプを取り、sshd の痕跡を追います。


1. SSH の状態を確認する

sudo systemctl status ssh || sudo systemctl status sshd
ss -tanp | grep ssh
who

2. メモリダンプを取得する

sudo avml ~/mquire-lab/ssh-hands-on.lime

3. sshd プロセスを探す

mquire query ~/mquire-lab/ssh-hands-on.lime \
  "SELECT pid, tgid, comm, command_line
   FROM tasks
   WHERE comm LIKE '%ssh%' OR command_line LIKE '%ssh%'" \
  --format table

4. SSH 通信を探す

mquire query ~/mquire-lab/ssh-hands-on.lime \
  "SELECT *
   FROM network_connections
   WHERE local_port = 22 OR remote_port = 22" \
  --format table

5. sshd が開いているファイルを見る

mquire query ~/mquire-lab/ssh-hands-on.lime \
  "SELECT t.pid, t.comm, tof.path
   FROM tasks t
   JOIN task_open_files tof ON tof.task = t.virtual_address
   WHERE t.comm LIKE '%ssh%'
   LIMIT 50" \
  --format table

この流れだけでも、メモリダンプからかなり多くのことが分かります。

- sshd プロセスが存在したか
- どの PID / TGID だったか
- SSH 関連の通信が残っているか
- sshd がどのファイルを開いていたか

メモリフォレンジックの入口としては、ここまでできれば十分です。


まとめ


mquire は、Linux メモリフォレンジックの敷居をかなり下げてくれるツールです。

特に良いのは、調査対象を SQL でつなげられることです。プロセス、ファイル、ネットワーク、カーネル情報を別々に見るのではなく、テーブルとして横断できる。これは、実際の調査でかなり扱いやすい考え方です。

もちろん、mquire だけでインシデント調査が完結するわけではありません。ディスクイメージ、ログ、EDR、ネットワークログと突き合わせる必要があります。


それでも、ライブレスポンスで取りこぼした情報を、メモリダンプから後追いできる価値は大きいです。Linux メモリフォレンジックを試す最初のツールとして、mquire はかなり面白い選択肢です。

bottom of page