#状況
「ランサムウェア用おとりファイルが反応(ホスト隔離の直前)」と「ランサムウェア・カナリア発火」が、続けて届きました。あなたは、業務のデータを /srv に置いた Linux サーバーの当番です。
この講座は、通知が届いてから復旧するまでの判断と手順を扱います。検知の仕組みと設定は ランサムウェア に、自動で止める方針の決め方は 自動隔離の方針の設定 にあります。ここでは、使い捨ての VM で実際に起こし、その場で何を読み、どの順で動くかを確かめます。
扱う機能は、大量暗号化の検知、おとりファイルによる検知、通知の履歴、インシデントのタイムライン、封じ込め時の証拠の自動採取 です。
進める順番は、次のとおりです。
| 順番 | すること |
|---|---|
| 1. 読む | 通知の履歴で、何が起き、何が止まったかを知る |
| 2. 保つ | 確認応答で、上限の時間を過ぎても全面の隔離を保つ |
| 3. 調べる | 書き手、証拠、壊れたファイルの数を確かめてから、書き手を終わらせる |
| 4. 戻す | バックアップを確かめてから戻し、最後に隔離を解く |
| 5. 見守る | 同じ検知が、もう一度出ないかを見る |
#起こす前に、戻せる状態を作る
本番でも、復旧の材料はバックアップだけです。演習でも、先にバックアップと、ファイルごとのハッシュの一覧を作ります。
ファイルを作る操作です(変更を伴う操作です)。最後の章で消します。練習用の2つのファイルを作ります。make-data.sh は、平文のダミーのファイルを 300 個作ります。overwrite-demo.py は、指定したフォルダーの下のファイルを、同じ大きさのランダムなバイト列で上書きします。暗号化はせず、鍵もありません。
cd ~
cat > make-data.sh <<'S'
#!/bin/sh
# 練習用: 中身が平文のダミーのファイルを 300 個作る
mkdir -p /srv/appdata
for i in $(seq 1 300); do
yes "order $i: dummy record for practice" | head -c 8192 > /srv/appdata/order_$i.csv
done
S
cat > overwrite-demo.py <<'S'
# 練習用: フォルダーの下のファイルを、同じ大きさのランダムなバイト列で上書きする
import os, sys, time
for root, dirs, files in os.walk(sys.argv[1]):
for name in sorted(files):
path = os.path.join(root, name)
with open(path, "r+b") as f:
f.write(os.urandom(os.path.getsize(path)))
time.sleep(0.2)
S
sudo sh make-data.sh
sudo tar -czf /var/backups/appdata.tgz -C /srv appdata
cd /srv && sudo sha256sum appdata/* | sudo tee /var/backups/appdata.sha256 > /dev/null; cd ~
ls /srv/appdata | wc -l
sudo journalctl -u roamswitch-server -b | grep -oE 'following these folders.*|Total monitored canaries.*' | tail -2
sudo ls -A /srv300
following these folders roots=["/srv"]
Total monitored canaries: 16
.roamswitch_security_canary_do_not_delete.pdf
.roamswitch_security_canary_do_not_delete.xlsx
.roamswitch_security_canary_do_not_delete.zip
appdata/srv は、大量暗号化の監視が見ているフォルダーです。おとりのファイルも3つあります。フォルダーの下を全部たどる書き手は、おとりにも当たります。
バックアップは /srv の外に置きました。監視の外ですが、同じディスクです。本番では、別のディスクか別のサーバーに置きます。
#起こして、通知を読む
上書きのスクリプトを、root で /srv に向けて動かします。サーバーで権限を取られたあとの動きを、まねたものです。
ホスト全体の通信を止める操作です(変更を伴う操作です)。SSH の保守用のポートは残りますが、必ず使い捨ての環境で試してください。元に戻す手順は、復旧の章にあります。
sudo setsid -f python3 overwrite-demo.py /srv > /dev/null 2>&1 < /dev/null
sleep 30
sudo roamswitch notifications 2026-11-12T01:26:07.114715005+00:00
ランサムウェア・カナリア発火
🚨 カナリア(おとり)ファイルが改ざん / 暗号化書き込みされました
ホスト: ubuntu (IP: 192.168.64.3)
対象デコイ: /srv/.roamswitch_security_canary_do_not_delete.pdf
疑わしいプロセス: python3 (PID: 1871)
実行した封じ込め: プロセスを凍結し、ホストをAir-Gap隔離しました
時刻: 2026-11-12 01:26:07
プロセス: root / /usr/bin/python3.12 / コマンド: python3 overwrite-demo.py /srv (pid 1871)
親プロセス: systemd / サービス: tart-guest-agent.service
暗号化されたファイルの復号ツールを探す(公開されている場合だけ・無償): No More Ransom https://www.nomoreransom.org/ja/decryption-tools.html / 警察庁 https://www.npa.go.jp/bureau/cyber/countermeasures/ransom.html
2026-11-12T01:26:07.029755454+00:00
🚨 ランサムウェア用おとりファイルが反応(ホスト隔離の直前)
おとりファイルの異常: 改ざん / 暗号化書き込み
対象: /srv/.roamswitch_security_canary_do_not_delete.pdf
疑わしいプロセス: python3(PID: 1871)
この直後にホストを隔離します。結果は復旧後(または許可リスト経由)に別途通知します。
プロセス: root / /usr/bin/python3.12 / コマンド: python3 overwrite-demo.py /srv (pid 1871)
親プロセス: systemd / サービス: tart-guest-agent.service
原因のプロセスが終わっても、この隔離は自動では解除しません。確認してから sudo roamswitch emergency-restore で解除してください。確認応答のないまま上限時間(既定60分)が過ぎると縮退に移り、縮退中は sudo roamswitch server ack で解除します。通知の履歴は、新しいものが上です。下から読むと、起きた順になります。
- 隔離の直前の通知(おとりファイルによる検知): PID 1871 が、おとりの
.pdfを書き換えました。最後の行が、解除のしかたです。書き手が終わっても、自動では解けません - カナリア発火: 「実行した封じ込め」の行のとおり、書き手は凍結され、ホストは隔離されました。最後の行は、公開されている復号ツールの探し先です
- プロセスの行: 2つの通知が、同じ PID とコマンドを指しています。同じ書き手による1つの出来事として扱えます
書き手は /srv の中を名前の順にたどるので、最初に .pdf のおとりを書き換えます。実行の記録(sudo roamswitch events search --pid 1871)では、書き手が動き始めたのは 01:26:06.809 です。おとりの改ざんの検知は 01:26:06.817 で、約 8 ミリ秒後でした。凍結は 01:26:07.030 です。時刻は UTC です。日本時間は 9 時間進めた 10:26 です。
大量暗号化の検知(大量暗号化の検知)は、既定では知らせるだけです(entropy_watch_freeze=false)。おとりの改ざんは、Server Edition では、ホストの隔離まで進みます。この演習では、書き手が appdata に進む前に凍結されたので、大量暗号化の通知は出ませんでした。同じ書き手を、おとりの無い /srv/appdata だけに向けると、大量暗号化の通知だけが来て、書き手は動き続けました。そのときは、通知の PID を自分で止めます(この講座の最後の判断を参照)。
#隔離を保つ
隔離の中でも、SSH の保守用のポート(既定は 22 番)には入れます。最初にすることは、隔離が働いていることと、書き手が止まっていることを確かめ、確認応答を返すことです。
確認応答は、隔離の扱いを変える操作です(変更を伴う操作です)。隔離そのものは、復旧の章で解きます。
sudo roamswitch server ebpf | sed -n 5,7p
sudo roamswitch frozen list
P=$(pgrep -f '^python3 overwrite-demo.py /srv'); echo "P=$P"
ps -o pid,stat,cmd -p $P
curl -sS -m 5 -o /dev/null https://example.com; echo "curl rc=$?"
sudo roamswitch server ack 現在の隔離状態: [隔離中: host_with_maintenance_ssh]
隔離対象PID: [1871]
保守用開放ポート: [22]
PID 1871 python3
理由: カナリアファイル改ざん
凍結時刻: 2026-11-12T01:26:07.030528623+00:00
誤検知だった場合: roamswitch frozen resume <PID> (強制終了はしていないため、停止位置からそのまま再開します)
P=1871
PID STAT CMD
1871 Ts python3 overwrite-demo.py /srv
curl: (28) Resolving timed out after 5002 milliseconds
curl rc=28
✓ 現在の緊急隔離(43秒経過)を確認しました。確認済みの間は自動で縮退・復旧せず、現在の隔離を維持します。
解除するには: sudo roamswitch emergency-restore読み方は次のとおりです。
host_with_maintenance_ssh: ホスト全体の隔離です。開いているのは 22 番だけですSTATのT: 書き手は SIGSTOP で止まっています。終了はしていません。frozen resumeをすると、続きから上書きを再開しますcurl rc=28: 外への通信は止まっています- 確認応答の行: 「確認済みの間は自動で縮退・復旧せず」とあります。ここから先は、人が
emergency-restoreを実行するまで、全面の隔離が続きます
おとりの改ざんは、確度の高い隔離です。書き手が終わっても、凍結のままでも、自動では解けません。確認応答が変えるのは、上限(isolation_hard_cap_secs、既定 3600 秒)を過ぎたあとの扱いです。
- 調べるのに 1 時間を超えそう: 上限の前に確認応答を返します。上限を過ぎても、全面の隔離のまま保ちます
- 確認応答を返さずに、上限を過ぎた: 縮退に移ります。縮退中の
server ackは、隔離を解く操作です。まだ解かないなら、縮退中にserver ackを打ちません - 自分の作業と分かった(誤検知): 確認応答は要りません。
frozen resume <PID>で書き手を再開し、emergency-restoreで隔離を解きます
確認応答を返さずに、凍結中の書き手を kill しても、この VM では隔離が続きました。
P=2560
現在の隔離状態: [隔離中: host_with_maintenance_ssh]
隔離対象PID: [2560 (終了済み)]
curl: (28) Resolving timed out after 5002 milliseconds
curl rc=28上限までの間は、確認応答のあるなしにかかわらず、隔離は続きます。
#書き手と、被害の範囲を調べる
隔離を保ったまま、何が、どこまで書き換えたかを確かめます。書き手を終わらせるのは、証拠を確かめたあとです。
読むだけの操作と、時系列の書き出しです(/root/incident.jsonl を作ります)。証拠バンドルのフォルダーは root だけが開けるので、一覧も sudo sh -c の中で取ります。
sudo roamswitch timeline | head -n 32
B=$(sudo sh -c 'ls -d /var/lib/roamswitch/incident-evidence/*/' | tail -1)
sudo roamswitch-incident-capture verify "$B"
sudo cat "$B/process/cmdline.txt"; echo
sudo cat "$B/process/fd_targets.txt"; echo
cd /srv && sudo sha256sum --quiet -c /var/backups/appdata.sha256 2>/dev/null | wc -l; cd ~
sudo roamswitch timeline --export /root/incident.jsonl 2026-11-12T01:26:50.268817172+00:00 [Canary] 対応中
server の隔離: 確認された(きっかけ: ランサムウェア用おとりファイルの改ざん、段階: 完全)
実施した対応: 隔離に確認応答
2026-11-12T01:26:06.817500072+00:00 [Canary] 対応中
おとりのファイルが改ざんされた: /srv/.roamswitch_security_canary_do_not_delete.pdf(改ざん / 暗号化書き込み)
プロセス: python3 (pid 1871)
親プロセス系譜: systemd
MITRE ATT&CK: T1486 (Data Encrypted for Impact)
実施した対応: 封じ込めた(凍結または隔離)
証拠バンドル: 20261112T012607Z-c5745d06-1879 manifest sha256:2656878eea2f7d46 (6 ファイル)
└─ 2026-11-12T01:26:07.300535570+00:00 [Incident Capture] 対応中
インシデント証拠バンドルを保存しました: /var/lib/roamswitch/incident-evidence/20261112T012607Z-c5745d06-1879
プロセス: python3 (pid 1871)
親プロセス系譜: systemd
実施した対応: 証拠を保存
証拠バンドル: 20261112T012607Z-c5745d06-1879 manifest sha256:2656878eea2f7d46 (6 ファイル)
2026-11-12T01:25:31.038112055+00:00 [FIM] 記録のみ
ログの改ざんの比較の基準を作り直した
実施した対応: 記録のみ
整合性OK: バンドルはmanifest.jsonの記録と一致しています
アンカー: manifest.json は取得時の記録と一致しています
python3 overwrite-demo.py /srv
0 -> /dev/null
1 -> /dev/null
2 -> /dev/null
0
4件を /root/incident.jsonl にJSON Lines形式で書き出しました。読み方は次のとおりです。
- タイムライン(インシデントのタイムライン): おとりの改ざんと封じ込め、証拠の保存、確認応答が、1本の時系列に並びます。確認応答も記録に残ります。いちばん下の
[FIM]の行は、デーモンの起動のときにログの比較の基準を作った記録で、「記録のみ」です。この出来事とは関係ありません - 証拠バンドル(封じ込め時の証拠の自動採取): 封じ込めのとき、凍結した書き手の
/procの情報(コマンドライン、開いていたファイル、親プロセスなど)を自動で保存していました。verifyで、保存したときから変わっていないことを確かめます - 開いていたファイル(
fd_targets.txt): 凍結の時点で開いていたのは/dev/nullだけでした。書きかけのファイルは無かったことが分かります - 0: バックアップのハッシュと合わないファイルの数です。書き手は
appdataに進む前に凍結されたので、300 個のどれも書き換えられていません - 親プロセス系譜: この演習では
systemdです。本番でsshdや Web サーバーの名前が出ていれば、そこが侵入の経路の手がかりです
調べ終えたら、書き手を終わらせます。プロセスを終了する操作です(変更を伴う操作です)。終了したプロセスは、元に戻せません。
P=$(pgrep -f '^python3 overwrite-demo.py /srv'); echo "P=$P"
sudo kill -9 $P
sleep 420
pgrep -f '^python3 overwrite-demo.py /srv' || echo "no writer"
sudo roamswitch server ebpf | sed -n 5,6p
curl -sS -m 5 -o /dev/null https://example.com; echo "curl rc=$?"P=1871
no writer
現在の隔離状態: [隔離中: host_with_maintenance_ssh]
隔離対象PID: [1871 (終了済み)]
curl: (28) Resolving timed out after 5002 milliseconds
curl rc=28書き手は終わりましたが、隔離は続いています。PID の横に「終了済み」と出ます。
#ファイルを戻し、隔離を解き、見守る
戻すのは、原因を止めたあとです。順番は、バックアップを確かめる → 戻す → 確かめる → 隔離を解くです。隔離を解いてから戻すと、残っている書き手や経路に、戻したファイルをまた書き換えられるおそれがあります。
ファイルを上書きする操作です(変更を伴う操作です)。まず、別の場所に展開して、ハッシュの一覧と合うかを確かめます。
sudo rm -rf /var/tmp/restore-test; sudo mkdir /var/tmp/restore-test
sudo tar -xzf /var/backups/appdata.tgz -C /var/tmp/restore-test
cd /var/tmp/restore-test && sudo sha256sum --quiet -c /var/backups/appdata.sha256 && echo "backup: all 300 files match"; cd ~
sudo cp -a /var/tmp/restore-test/appdata/. /srv/appdata/
cd /srv && sudo sha256sum --quiet -c /var/backups/appdata.sha256 && echo "/srv/appdata: all 300 files match"; cd ~backup: all 300 files match
/srv/appdata: all 300 files matchバックアップが壊れていないことを先に確かめ、それから /srv/appdata に戻しました。戻したあとも、300 個すべてが元のハッシュと一致しました。この演習では書き換えは 0 個でしたが、本番では、どのファイルが書き換えられたかを先に知ることはできません。戻す手順は同じです。
次に、隔離を解きます。ホスト全体の通信を戻す操作です(変更を伴う操作です)。原因が消えたと確かめられないので、emergency-restore は RESTORE の入力を求めます。端末でないところ(パイプなど)から実行すると、「対話できない環境では、実行しません。」と出て、入力を受けずに終了コード 2 で終わります。最後の再起動で、ふだんの守りの規則を入れ直します。
sudo roamswitch emergency-restore
sudo roamswitch server restart
sleep 12
sudo head -c 32 /srv/.roamswitch_security_canary_do_not_delete.pdf; echo
sudo roamswitch notifications | grep -E '^ [^ ]' | sed -n 2,5p
curl -sS -m 5 -o /dev/null https://example.com; echo "curl rc=$?" 現在の状態:
隔離中(原因: ランサムウェア用おとりファイルの改ざん, 段階: 全面)
⚠️ 隔離の原因が解消したことを、確認できていません。この状態でネットワークを元に戻すと、原因が残っている場合、その影響を受けたまま通信が再開します。
続けるには RESTORE と入力してください: RESTORE
🔄 緊急遮断・隔離ルールを全解除し、ベースラインへ復旧中...
(中略)
次のファイアウォールのテーブルは、隔離ではないので残しました:
- roamswitch_server: サーバーの受信の規則(ssh_ports・allowed_ports だけを通す、ふだんの防御)
✓ ネットワークを復旧しました。
ポートスキャンの検知など、ここで外した規則は、再起動まで戻りません。戻すには: sudo systemctl restart roamswitch-server
原因が残っている可能性があります(原因が消えたことは確かめられていません)。何が起きたかは roamswitch timeline で確かめてください。
🔄 roamswitch-server サービスを再起動中...
✓ roamswitch-server サービスを正常に再起動しました。
%PDF-1.4 ROAMSWITCH_CANARY_INTEG
2026-11-12T01:34:37.458317902+00:00
【遅延送信】 📝 隔離インシデントを確認済みにしました
2026-11-12T01:34:37.450850569+00:00
【遅延送信】 ランサムウェア・カナリア発火
curl rc=0プロンプトで RESTORE と入力すると、隔離の規則が外れ、「ネットワークを復旧しました」と出ます。ふだんの受信の規則(roamswitch_server)は、隔離ではないので残ります。おとりも元の中身に戻っています。最後の curl rc=0 で、外への通信が戻ったことが分かります。
通知の履歴 には、【遅延送信】 の付いた通知が並びました。隔離の間に外の通知先へ送れなかった通知を、解いたあとで送り直したものです。隔離の最中は、外の通知先に届いていないことがあります。当番に連絡するときは、通知先ではなく、サーバーの通知の履歴を正とします。
解いた直後は、同じ検知がもう一度出ないかを見ます。本番では、侵入の経路を塞ぎ、使われたアカウントの鍵やパスワードを替えたあとも、しばらく見続けます。
ファイルを消す操作です(変更を伴う操作です)。/root/incident.jsonl と証拠バンドルは、本番なら残します。
sleep 60
sudo journalctl -u roamswitch-server --since -75s | grep -c -e burst -e 'TAMPERED'
sudo roamswitch server ebpf | sed -n 5p
sudo rm -rf /srv/appdata /var/tmp/restore-test /var/backups/appdata.tgz /var/backups/appdata.sha256
rm -f ~/make-data.sh ~/overwrite-demo.py0
現在の隔離状態: [隔離なし]この 1 分間、大量暗号化とおとりの改ざんの記録は 0 件でした。隔離もありません。
おとりの無いフォルダーだけが書き換えられると、届くのは大量暗号化の通知だけです。ホストは隔離されず、書き手も止まっていません。
- 通知の PID に心当たりがない: すぐに
sudo kill -STOP <PID>で止めます。止めれば、終了させずに証拠を残せます。そのあとは、この講座の「調べる」からと同じです - 心当たりがある(自分のバックアップ、アプリの正規の処理): 書き込みの量と場所がふだんどおりかを確かめ、記録して終えます
- 毎回、人が止めるまで待てない:
entropy_watch_freeze=trueにして再起動します。次からは、書き手を自動で凍結します(自動隔離の方針の設定)
- 縮退に移ったあとで、隔離を保つつもりで
server ackを打つ。縮退中の確認応答は、隔離を解きます - 凍結中の書き手を、
frozen resumeで再開する。誤検知と分かったとき以外は、上書きの続きが始まります - 隔離を解いてから、バックアップを戻す。経路が残っていれば、戻したファイルがまた書き換えられます
- バックアップを確かめずに、上から戻す。壊れたバックアップで、残っていた正しいファイルまで上書きします
#見えない部分
- 凍結までに書かれた分は戻りません。この演習の書き手は、最初におとりに当たったので、
appdataの書き換えは 0 個でした(日本語と英語の 2 回とも)。業務のファイルを先に書き換える書き手なら、おとりに当たるまでの分は書き換えられます。戻せるのは、バックアップがあるときだけです - 上限を過ぎたあとの縮退は、この講座では起こしていません。確かめたのは、書き手を終わらせても、確認応答があってもなくても、7 分のあいだ隔離が続いたことです。縮退は 自動隔離の方針の設定 で、上限を 120 秒にして試しています
- 証拠バンドルのパケットキャプチャは取れていません。この VM には
tsharkが無く、バンドルの記録はskippedでした。保存されたのは、プロセスの情報だけです - 侵入の経路は、この演習にはありません。書き手は、VM の管理経路から直接動かしました。本番では、親プロセスと、ログイン・Web のログから調べます
- 演習の書き手は、ランダムなバイト列で上書きするだけです。暗号文を別のファイルに書いて元を消す形、名前を変えて被せる形の見え方は、ランサムウェア で扱います
おとりの改ざんでホストが隔離され、書き手は凍結されています。調べ終わるまで 2 時間かかりそうです。全面の隔離のまま保つには、どうしますか
解説を見る
確認応答のない隔離は、上限(既定 60 分)を過ぎると縮退に移ります。全面のときの確認応答は、隔離を保ちます。縮退中の確認応答は、隔離を解きます。
書き手を止め、証拠を確かめました。次の順番で正しいものはどれですか
解説を見る
戻す前にバックアップを確かめ、戻したあとに結果を確かめます。隔離を解くのは最後です。
#次に学ぶこと
- 検知の仕組み、監視するフォルダーの足し方、乱数の記録は ランサムウェア で扱います
- 凍結と隔離を自動でするかどうかは 自動隔離の方針の設定 で決めます
- 隔離が働いたあとの1時間の進め方は 封じ込めが働いたあとの最初の1時間 にあります
対応する攻撃手法 (ATT&CK): T1486
2026-11-12に確認しました。対象は Linux 1.17.39 です。公開版 1.17.39 の入った使い捨ての Ubuntu 24.04 の VM で、root の書き手で /srv を上書きし、おとりの改ざんの通知・凍結と隔離、確認応答、証拠バンドルの検証、書き手を kill して 7 分待つこと(確認応答のあるとき・ないとき)、バックアップからの復元と端末での RESTORE の入力による解除と curl での確認を、日本語と英語で別の VM で実行し、おとりの無いフォルダーだけに向けたときの大量暗号化の通知も確かめました。
コマンドの出力は、製品の版や環境によって変わります。違いが出たら、まず製品の版を確かめてください。