KVMで安全なMalware Labを構築する:隔離ネットワーク環境でのマルウェア解析

Virtualization tutorial - IT technology blog
Virtualization tutorial - IT technology blog

マルウェア解析に専用のlabが必要な理由

私はProxmox VEで12台のVMとコンテナを管理するhomelab環境を運用しています — productionに上げる前に何でもテストする実験場です。しかしmalware analysisの勉強を始めたとき、その環境で直接悪意あるファイルを実行するのは絶対にNGだと気づきました。ransomwareを誤って実行してしまえば、shared folderがある場合はhostや他のVMも含め、数分以内に全データが暗号化される可能性があります。

Malware labとは、以下の目的のために特別に設計された仮想マシン環境です:

  • 完全な隔離 — 実際のネットワークとインターネットから切り離し、マルウェアが本物のC2サーバーに通信できないようにする
  • 挙動の観察 — マルウェアの動作(network calls、file writes、registry changes)を外部への感染なしに観察する
  • スナップショットとロールバック — 解析のたびにクリーンな状態に戻し、次のサンプルに備える
  • 後で解析するためにhostからネットワークトラフィックを完全にキャプチャする

KVMはlibvirtが非常に細かなネットワーク制御を可能にするため、ここでは最適な選択肢です — 一般的によく使われるデフォルトのNAT設定とは異なり、外部への経路が完全にないvirtual networkを作成できます。

KVMと必要なツールのインストール

仮想化をサポートするCPUの確認

まずCPUがhardware virtualizationをサポートしているか確認します:

grep -E --color '(vmx|svm)' /proc/cpuinfo | head -3
# vmx = Intel VT-x, svm = AMD-V
# 出力がない場合 → BIOSでVT-x/AMD-Vを有効にする

Ubuntu/DebianへのKVMとサポートパッケージのインストール

sudo apt update
sudo apt install -y \
  qemu-kvm \
  libvirt-daemon-system \
  libvirt-clients \
  bridge-utils \
  virt-manager \
  tcpdump \
  wireshark-qt

# 毎回sudoが不要になるよう、ユーザーをグループに追加する
sudo usermod -aG libvirt,kvm $USER
newgrp libvirt

ホストへの追加の解析ツールのインストール

以下のツールはホストマシン(解析用VMの中ではなく)にインストールします:

# 後でmemory dumpを解析するためにvolatility3をインストール
pip3 install volatility3

# labに持ち込む前にファイルをquick-scanするためのclamav
sudo apt install -y clamav
sudo freshclam  # signatureデータベースを更新

隔離ネットワークと解析VMの設定

isolatedネットワークの作成 — NAT無し、インターネット無し

これが最も重要なステップです。libvirtの”isolated”タイプのネットワークには<forward>タグがありません。つまり外部へのルーティングが存在せず、lab内のVM同士が仮想bridgeを通じてのみ通信できます。

cat > /tmp/malware-lab-net.xml << 'EOF'
<network>
  <name>malware-lab</name>
  <bridge name="virbr-lab" stp="on" delay="0"/>
  <domain name="malware.lab"/>
  <ip address="192.168.100.1" netmask="255.255.255.0">
    <dhcp>
      <range start="192.168.100.10" end="192.168.100.50"/>
    </dhcp>
  </ip>
</network>
EOF

# ネットワークを定義、起動、自動起動に設定する
virsh net-define /tmp/malware-lab-net.xml
virsh net-start malware-lab
virsh net-autostart malware-lab

# 確認
virsh net-list --all

iptablesでこのbridgeのインターネットアクセスをブロックする

ホストレベルで第二の防御層を追加します — VMの設定が誤っていても、トラフィックは外部に漏れません:

# eth0を実際のネットワークインターフェース名に置き換える('ip link'で確認)
sudo iptables -I FORWARD -i virbr-lab -o eth0 -j DROP
sudo iptables -I FORWARD -o virbr-lab -i eth0 -j DROP

# 適用されたルールを確認
sudo iptables -L FORWARD -n -v | grep virbr-lab

# リブート後も設定が残るよう保存する
sudo apt install -y iptables-persistent
sudo netfilter-persistent save

マルウェアを実行するWindows VMの作成

マルウェアの大半はWindowsを標的としているため、少なくとも一台のWindows VMが必要です。先ほど作成したmalware-labネットワークに接続します:

virt-install \
  --name win10-malware \
  --ram 4096 \
  --vcpus 2 \
  --disk path=/var/lib/libvirt/images/win10-malware.qcow2,size=60,format=qcow2 \
  --cdrom /path/to/windows10.iso \
  --os-variant win10 \
  --network network=malware-lab \
  --graphics vnc,listen=127.0.0.1,port=5910 \
  --video vga \
  --noautoconsole

# VNCを開いてWindowsをインストールする
virt-viewer win10-malware

Windowsのインストールが完了したら、VM内でWindows DefenderとWindows Updateを無効にし(マルウェアが実行できるようにするため)、”クリーンな状態”のスナップショットを作成します:

# スナップショットを作成 — セッションごとのロールバックポイント
virsh snapshot-create-as win10-malware clean-state \
  --description "クリーンなWindows、Defender無効、解析準備完了"

# スナップショット一覧を表示
virsh snapshot-list win10-malware

C2サーバーをシミュレートするLinux VMの追加(オプションだが非常に有用)

多くのマルウェアはC2サーバーへの接続を必要とします。タイムアウトさせる代わりに、同じネットワーク内にLinux VMを作成してそれを模倣します — netcatやfakednsを使ってマルウェアに「応答」させます:

virt-install \
  --name linux-monitor \
  --ram 1024 \
  --vcpus 1 \
  --disk path=/var/lib/libvirt/images/linux-monitor.qcow2,size=20,format=qcow2 \
  --location /path/to/ubuntu-22.04-server.iso \
  --os-variant ubuntu22.04 \
  --network network=malware-lab \
  --graphics none \
  --extra-args "console=ttyS0"

# このLinux VM内でfake DNSサーバーを起動する
# pip install fakedns
# sudo python -m fakedns --ip 192.168.100.20

トラフィックのキャプチャと環境の検証

ホストからのネットワークトラフィックのキャプチャ

isolatedネットワーク内のすべてのパケットは、ホスト上のvirbr-lab bridgeを経由します。VM内に何もインストールせず、ホストから直接キャプチャできます:

# すべてのトラフィックをキャプチャし、タイムスタンプ付きのpcapファイルに保存
sudo tcpdump -i virbr-lab -w /tmp/malware-$(date +%Y%m%d-%H%M).pcap

# リアルタイム監視:DNSクエリ + マルウェアがよく使うポート
sudo tcpdump -i virbr-lab -n 'port 53 or port 80 or port 443 or port 4444'

# DNSのみ表示して、マルウェアが解決しようとするドメインを確認
sudo tcpdump -i virbr-lab -n 'port 53' -A

解析セッション自動準備スクリプト

私はこの小さなスクリプトを使って、環境のリセットとキャプチャの開始を同時に行います:

#!/bin/bash
# prep-malware-session.sh

VM_NAME="win10-malware"
SNAPSHOT="clean-state"
PCAP_DIR="$HOME/malware-captures"
SESSION=$(date +%Y%m%d-%H%M%S)

mkdir -p "$PCAP_DIR"

echo "[+] VMをクリーンなスナップショットに戻しています..."
virsh destroy "$VM_NAME" 2>/dev/null  # 実行中の場合は強制停止
virsh snapshot-revert "$VM_NAME" "$SNAPSHOT"

echo "[+] VMを起動しています..."
virsh start "$VM_NAME"

echo "[+] トラフィックキャプチャを開始しています..."
sudo tcpdump -i virbr-lab -w "$PCAP_DIR/session-$SESSION.pcap" &
TCPDUMP_PID=$!

echo "[+] セッション $SESSION の準備が完了しました。"
echo "    PCAP: $PCAP_DIR/session-$SESSION.pcap"
echo "    完了後: sudo kill $TCPDUMP_PID && virsh destroy $VM_NAME"

ネットワークが本当に隔離されているか確認する

VMが起動したら、VNCでWindows VMに接続してPowerShellを開いてテストします:

# Windows VM内で実行(PowerShell)
ping 8.8.8.8           # Request timeoutになるはず
Invoke-WebRequest https://google.com  # エラーになるはず

# またはホストからテスト:bridgeに外部へのルートがないか確認
ip route show | grep virbr-lab
# 結果は: 192.168.100.0/24 dev virbr-lab のみのはず
# デフォルトルートなし = OK

セッション後の素早いロールバック

マルウェアを実行するたびに必ず行う操作です — このステップを絶対に省略しないでください:

# VMをシャットダウン(マルウェアがshutdownプロセスをkillした場合はdestroyを使用)
virsh destroy win10-malware

# クリーンな状態にロールバック
virsh snapshot-revert win10-malware clean-state

# 次のサンプルの解析準備完了
virsh start win10-malware

見落とせないセキュリティ上の注意点

  • USBやshared folderをマウントしない — hostから解析VMへのマウントは禁止。マルウェアがここを経由してhostへ感染を拡大する可能性がある
  • clipboard sharingを無効にする — VNC/SPICEの設定で無効化する
  • 個人用マシンをhostとして使用しない — できれば専用VPSや古いbare-metalマシンを使う方がはるかに安全
  • labに持ち込む前にファイルをスキャンする — ClamAVを使って扱っているマルウェアの種類を把握する
  • 解析しないときは常にVMをシャットダウンする — マルウェアをlab内で長時間バックグラウンド実行しない

このセットアップで、reverse engineeringとマルウェアの挙動解析を学び始めるのに十分な安全なmalware labが完成します。慣れてきたら、Windows guestにFLARE-VMを統合してより充実したREツールセットを揃えたり、Cuckoo Sandboxをインストールして解析プロセスを自動化したりして拡張できます。

Share: