攻撃を知り、防ぐ

調べる材料を作る

VM の中だけで偵察・SSH の総当たり・ログインの成功を起こし、audit-logs、AccessScope、PathScope、PersonalSOC と FIM の記録を使って、どこから来て、何を試し、成功したかを、ログから組み立て直します。

  • レベル: 実践
  • 約60分
  • 2026-11-12

#調べる材料を作る

通知が届いたあと、または「何かおかしい」と感じたあとに、ログから事実を集めます。この講座で答えを探す問いは 3 つです。

  1. どこから来たか: 送信元のアドレスと、使ったアカウント
  2. 何を試したか: 偵察、総当たり、Web への攻撃の試み
  3. 成功したか: ログインの成功、入ったあとの動き

使う道具は、どれも読み取りだけです。ログを書き換えず、通信も止めません。

道具見るもの
roamswitch audit-logsjournal の直近の記録を集計し、ふだんと違う型を示す
accessscope scanWeb と SSH と認証のログを、根拠の行つきで診断する
pathscopeあるアカウントから root までの経路を調べる
personalsoc scanログと RoamSwitch の記録と、上の 2 つの結果をまとめる

封じ込めのあとの 1 時間の動き方は、封じ込めが働いたあとの最初の1時間 で扱います。ここでは、ログを読むことに絞ります。

練習の出来事を起こす

このスクリプトは、利用者を作り、アドレスを足し、nginx とタイマーを置きます(変更を伴う操作です)。使い捨ての VM で試してください。元に戻す手順は、「まとめて確かめる」の章の最後にあります。

送信元には、文書用に予約されたアドレス(198.51.100.7、203.0.113.50)を、このマシンの lo に足して使います。通信はすべてマシンの中で終わり、外には何も送りません。

sudo apt install -y nginx sshpass
cat > /tmp/make-events.sh <<'SH'
#!/bin/sh
# 練習用の出来事を、このマシンの中だけで起こす(外へは何も送らない)
ip addr add 198.51.100.7/32 dev lo     # ふつうの閲覧者(文書用のアドレス)
ip addr add 203.0.113.50/32 dev lo     # 偵察してから SSH に来る相手(文書用のアドレス)
useradd -m -s /bin/bash demo
echo 'demo:Demo-Pass-2026' | chpasswd  # 練習用のダミーのパスワード

# 1) ふつうの閲覧
for p in / /index.html /; do
  curl -s -o /dev/null --interface 198.51.100.7 -A 'Mozilla/5.0 (X11; Linux) Firefox/128.0' "http://198.51.100.7$p"
done
# 2) Web の偵察(ツールの名前を名乗る、秘密のファイルを探す、SQL・パストラバーサル)
for p in /.env /.git/config /wp-login.php /phpmyadmin/ "/index.php?id=1%27%20OR%20%271%27=%271" \
         "/cgi-bin/../../../../etc/passwd" /backup.zip /.aws/credentials; do
  curl -s -o /dev/null --path-as-is --interface 203.0.113.50 -A 'sqlmap/1.8 (https://sqlmap.org)' "http://203.0.113.50$p"
done
# 3) SSH のパスワードの総当たり(6 回失敗)のあと、成功
O="-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o LogLevel=ERROR -o PubkeyAuthentication=no"
for u in oracle test demo demo demo demo; do
  sshpass -p 'wrong-pass' ssh $O -b 203.0.113.50 $u@203.0.113.50 true 2>/dev/null
done
# 4) 入ったあと、sudo を試す(demo は sudo できない)
sshpass -p 'Demo-Pass-2026' ssh $O -b 203.0.113.50 demo@203.0.113.50 'id; echo bad | sudo -S -k id' 2>&1
# 5) 管理者の設定ミス: root で動くタイマーのスクリプトを、誰でも書き換えられる
printf '#!/bin/sh\ntar czf /var/backups/www.tgz /var/www\n' > /opt/nightly-backup.sh
chmod 777 /opt/nightly-backup.sh
printf '[Service]\nType=oneshot\nExecStart=/opt/nightly-backup.sh\n' > /etc/systemd/system/nightly-backup.service
printf '[Timer]\nOnCalendar=daily\n[Install]\nWantedBy=timers.target\n' > /etc/systemd/system/nightly-backup.timer
systemctl daemon-reload && systemctl enable --now nightly-backup.timer 2>/dev/null
SH
sudo sh /tmp/make-events.sh
実行結果
uid=1002(demo) gid=1002(demo) groups=1002(demo)
[sudo] password for demo: Sorry, try again.
[sudo] password for demo: 
sudo: no password was provided
sudo: 1 incorrect password attempt

id の行は、6 回の失敗のあと、パスワードで入れたことを示します。そのあとの sudo は、間違ったパスワードで失敗しました。ここから先は、このことを知らないつもりで、ログだけから組み立て直します。

#journal をまとめて見る

セキュリティログの監査 は、journal の直近の記録を種類ごとに数えます。初めて出た型と、急に増えた型も示します。最初に全体の様子をつかむのに使います。

集計して、もう一度実行する
sudo roamswitch audit-logs 1
出力の抜粋
  • sudo 認証失敗の行:         2 行
  • SSH 失敗の行:              14 行
  • ファイアウォール遮断の行:  0 行
  • AppArmor/LSM 拒否の行:     9 行
  • マルウェア検知の行:        0 行
  • USB 接続の行:              0 行
    数はログの行の数で、試行の回数ではありません。1 回の失敗が 2 行以上になることがあります(存在しないユーザーへの SSH ログインは「Invalid user」と「Failed password」の 2 行)。SSH の行は、パスワードの失敗、存在しないユーザー、同じ接続元からの繰り返しの切断です。成功したログインは数えません。

  ⚠ ログは直近 500 行だけを調べました。それより前の分は含みません。

  【主要イベントタイムライン】
   [Nov 12 02:35:56] [認証 / Sudo] Sudo認証失敗 / 不正昇格試行 - Nov 12 02:35:56 ubuntu sudo[1924]: pam_unix(sudo:auth): conversation failed
   [Nov 12 02:35:54] [認証 / Sudo] Sudo認証失敗 / 不正昇格試行 - Nov 12 02:35:54 ubuntu sudo[1924]: pam_unix(sudo:auth): authentication failure; logname=demo uid=1002 euid=0 tty= ruser=demo rhost=  user=demo
   [Nov 12 02:35:53] [SSH総当たり試行] SSH不正ログイン試行 - Nov 12 02:35:53 ubuntu sshd[1762]: Connection closed by authenticating user demo 203.0.113.50 port 43399 [preauth]
   [Nov 12 02:35:51] [SSH総当たり試行] SSH不正ログイン試行 - Nov 12 02:35:51 ubuntu sshd[1762]: Failed password for demo from 203.0.113.50 port 43399 ssh2

  【テンプレート異常(新規パターン・頻度急増)】
   [頻度急増 z=6.8]  <HOST> roamswitch-server-daemon[<NUM>]: <NUM>-<NUM>-<NUM>T<NUM>:<NUM>:<NUM>.<NUM>Z  WARN roamswitch_server_daemon: 🚨 [FIM ALERT] Critical path tampering detected! violations=<NUM> — 6 件 (例: Nov 12 02:35:34 ubuntu roamswitch-server-daemon[878]: 2026-11-12T02:35:34.969202Z  WARN roamswitch_server_daemon: 🚨 [FIM ALERT] Critical path tampering detected! violations=1) [学習中: 1/3]
   [頻度急増 z=4.0]  <HOST> sudo[<NUM>]: pam_unix(sudo:session): session opened for user root(uid=<NUM>) by (uid=<NUM>) — 4 件 (例: Nov 12 02:35:13 ubuntu sudo[876]: pam_unix(sudo:session): session opened for user root(uid=0) by (uid=1000)) [学習中: 1/3]
   [頻度急増 z=4.0]  <HOST> sshd[<NUM>]: Failed password for demo from <IP> port <NUM> ssh<NUM> — 4 件 (例: Nov 12 02:35:42 ubuntu sshd[1693]: Failed password for demo from 203.0.113.50 port 40033 ssh2) [学習中: 1/3]
   (ほかの頻度急増 6 件は省略)
   上記のうち少なくとも1件は、普段よりログの発生頻度が高いことを示しています。多くは一時的な負荷やまとめ処理が原因ですが、心当たりのない操作と重なる場合は詳細を確認してください。
   ヒント: この時間帯にパッケージ管理(apt/dnf/zypper/pacman)の実行履歴が見つかりました。上記の異常は通常のシステム更新に伴うものである可能性があります。

読むところは 4 つです。

  • 件数は、試した回数ではなく、ログの行の数です。出力の注記のとおり、6 回の試行が「14 行」になりました。1 回の失敗が、Failed password と Connection closed などの行を残すためです
  • 成功したログインは、この集計に出ません。数えるのは、失敗や遮断などの記録です。成功は次の章で探します
  • テンプレート異常: 行の数字やアドレスを <NUM> <IP> に畳んで型にし、型ごとの量を比べます。[学習中: 1/3] は、その型のふだんの量を、まだ学んでいる途中という印です。この回は、RoamSwitch の FIM の警告(利用者を作ったときの /etc/shadow などの変更)、SSH の Failed password、演習で使った sudo の行などが、9 件並びました。異常は手がかりで、攻撃の判定ではありません
  • ヒント: この時間に apt を使った記録があると、更新による増え方かもしれない、と添えます。この練習では、nginx を入れた分です

時刻は UTC です。日本時間は 9 時間足して読みます(02:35 は 11:35)。

同じコマンドを、続けてもう一度実行します。

sudo roamswitch audit-logs 1 | grep -c '頻度急増'
実行結果
11

2 回目も、頻度急増は消えませんでした(数は、見出しの行を含む 頻度急増 の行の数です)。手で実行する audit-logs は、sudo を付けても、デーモンが使う型の記録(基準)を進めないためです(コードで確認)。何度実行しても、デーモンの定期の監査が見る範囲は変わりません。

デーモンも、同じ監査を定期的に行います。設定ファイルの注記では、log_audit_enabled の既定は true、間隔の log_audit_interval_secs は既定 1800 秒(最小 300 秒)です。変えたときは、sudo roamswitch server restart で反映します。コードでは、デーモンの最初の監査は、起動から 1 間隔あとに動き、その 1 回は学習だけで、通知しません。2 回目からは、前回の監査のあとに増えた行だけを比べ、セキュリティに関わる型を通知の履歴に残します。初めて出た型の自動の通知は、型の記録を始めてから 7 日のあいだは出しません。

#Web と SSH のログを、根拠つきで読む

アクセスログの診断(AccessScope) は、AccessScope という同梱の道具です。nginx や auth.log などのログを自分で探し、攻撃の試みを根拠の行つきで示します。別のログに同じ送信元が出てくると、1 つの流れとしてつなげます。

ログを診断して、根拠を読む

/var/log/auth.log は root か adm グループでないと読めないため、sudo を付けます。--since 1h で期間を区切ります。区切らないと、ログに残る古い出来事も混ざります。

sudo accessscope scan --auto --since 1h --lang ja
出力の抜粋
## 最初に確認すること(成功した疑いのあるもの)

| # | 深刻度 | 確度 | 検知 | 件数 | 主な送信元 |
|---|---|---|---|---|---|
| 1 | 高 | 中 | SSH 総当たりのあとの認証成功(203.0.113.50) | 7 | 203.0.113.50 |
| 2 | 高 | 中 | 複数のログに現れた同じアドレス(203.0.113.50) ※1 | 4 | 203.0.113.50 |

## 検知

| # | 深刻度 | 確度 | 検知 | 件数 | 主な送信元 |
|---|---|---|---|---|---|
| 3 | 中 | 中 | 既知の脆弱性の悪用パスへのアクセス | 1 (1 IP) | 203.0.113.50(1) |
| 5 | 低 | 高 | 攻撃・診断ツールの User-Agent | 7 (1 IP) | 203.0.113.50(7) |
| 6 | 低 | 中 | 秘密・管理ツールの探索の連続(応答にかかわらず) | 6 (1 IP) | 203.0.113.50(6) |
| 7 | 低 | 中 | SSH 総当たりの疑い | 6 (1 IP) | 203.0.113.50(6) |
| 8 | 低 | 中 | 秘密・設定ファイル・管理画面の探索 | 5 (1 IP) | 203.0.113.50(5) |
| 9 | 低 | 中 | SQL インジェクションの試み | 1 (1 IP) | 203.0.113.50(1) |
| 10 | 低 | 中 | パストラバーサル(ファイル読み取り)の試み | 1 (1 IP) | 203.0.113.50(1) |

前の章で見えなかった成功が、いちばん上に出ました。表は次のように読みます。

  • 最初に確認すること: 攻撃が成功した疑いのあるものです。ここから見ます
  • 深刻度: 当たっていたときの被害の大きさです
  • 確度: 本当の攻撃である可能性です。高はログに証拠がある、中は可能性が高い、低は疑いの段階です
  • ふつうの閲覧者(198.51.100.7)は、どの行にも出ません

表だけでは、なぜそう判断したかが分かりません。--report で、根拠の行を書き出します。

sudo accessscope scan --auto --since 1h --lang ja --report /tmp/as-report.md
sudo cat /tmp/as-report.md
出力の抜粋(/tmp/as-report.md)
- SSH 認証ログ: イベント 15 件(失敗 4、存在しないユーザー 2、成功 1)、IP 1 件

### 1. [深刻度 高 / 確度 中] SSH 総当たりのあとの認証成功(203.0.113.50)

203.0.113.50 から、成功の直前の 60 分の間に 6 回の失敗(うちユーザー demo への失敗は 4 回、平均の間隔は 3 秒)があったあと、ユーザー demo(password)で認証に成功しました。総当たりが成功した可能性と、正当な利用者の打ち間違いの可能性があります。

auth.log:66: 2026-11-12T02:35:35.269301+00:00 ubuntu sshd[1614]: Invalid user oracle from 203.0.113.50 port 34901
auth.log:88: 2026-11-12T02:35:53.877124+00:00 ubuntu sshd[1784]: Accepted password for demo from 203.0.113.50 port 40087 ssh2

### 2. [深刻度 高 / 確度 中] 複数のログに現れた同じアドレス(203.0.113.50)

203.0.113.50 は、2 種類のログ(Web・SSH)に、Web: 偵察 → Web: 攻撃の試み → SSH: 認証の失敗の繰り返し → SSH: 失敗のあとのログインの成功 の順で現れ、そのなかにログインの成功が記録されています。結びつけの根拠はアドレスが同じことだけです。成功したログインが運用者本人のものか、攻撃者のものかは、ログからは分かりません。成功したアカウントの利用者に心当たりを確認してください(確度 低)。 Web ログのアドレスは、記録された接続元のままです(X-Forwarded-For は使っていません)。リバースプロキシや CDN の背後にあるときは、プロキシのアドレスかもしれません(--trust-forwarded-for で選べます)。

### 3. [深刻度 中 / 確度 中] 既知の脆弱性の悪用パスへのアクセス

1 個の IP から 1 件。主な送信元: 203.0.113.50(1)。普段と違う 2xx 応答: 0 件、サーバエラー(5xx): 0 件。 該当した CVE: CVE-2021-41773/CVE-2021-42013 (Apache HTTP Server 2.4.49 / 2.4.50) x1(CVE ルールパック 2026-10-19 時点の表による。パスやパラメータの形が合っただけで、成功の証拠ではありません)。

access.log:9: 203.0.113.50 - - [12/Nov/2026:02:35:35 +0000] "GET /cgi-bin/../../../../etc/passwd HTTP/1.1" 400 166 "-" "-"

レポートを読むと、最初に組み立てた 3 つの問いに答えられます。

  • どこから: 203.0.113.50。Web の偵察と SSH の総当たりが、同じアドレスから来ました
  • 何を: .env などの探索、SQL インジェクションとパストラバーサルの試み、6 回のパスワードの失敗
  • 成功したか: Web は、応答がすべて 4xx でした。SSH は、demo で成功しています

根拠の行は、ログの中身そのままです。User-Agent やパスは、送った側が自由に書けます。sqlmap と名乗っていても、本当に sqlmap とは限りません。

成功したログインは、誰のものか

レポートのとおり、ログだけでは、本人の打ち間違いか、攻撃者の推測かを決められません。アカウントの持ち主に確かめます。

  • 持ち主に心当たりがある: パスワードを変え、鍵認証だけにします
  • 心当たりがない、または確かめられない: 乗っ取られたものとして扱います。アカウントを止めてから、入ったあとに何ができたかを調べます(次の次の章)

迷ったら、止める側を選びます。止めたアカウントは、あとで戻せます。

#見る件数を絞り、結果を渡す

毎日実行すると、同じ検知が毎回並びます。見る件数の絞り込み(AccessScope) は、前回にない検知だけを出したり、自社の診断のような分かっている送信元を、理由をつけて外したりします。

調べた結果は、遮断の担当や、ほかの道具に渡します。結果の書き出し(AccessScope) は、遮断リストと、検知の一覧を書き出します。書き出すだけで、遮断も適用もしません。

新しい検知だけを見て、外して、書き出す

最初に、いまの状態を記録します。次に、別のアドレス(203.0.113.77)から、自社の脆弱性診断のつもりで探索を送ります。

sudo accessscope scan --auto --since 1h --since-last --lang ja > /dev/null
sudo ip addr add 203.0.113.77/32 dev lo
for p in /.env /.git/config /wp-config.php.bak /.aws/credentials /actuator/env /phpmyadmin/ /server-status; do
  curl -s -o /dev/null --interface 203.0.113.77 -A 'Mozilla/5.0 zgrab/0.x' "http://203.0.113.77$p"
done
sudo accessscope scan --auto --since 1h --since-last --new-only --lang ja
出力の抜粋
前回との比較に使う記録: /root/.config/accessscope/state/cli-97049aabbfbca085.json
| 前回から | 新規 1 件 / 継続 10 件 / 消えた 0 件 |
| 備考 | 新規の検知だけを表示しています(継続 10 件は省略) |

| # | 深刻度 | 確度 | IP | 段階 | リクエスト数 |
|---|---|---|---|---|---|
| 1 | 低 | 低 | 203.0.113.77 | 偵察 → 攻撃 | 7 |

新規は 1 件だけでした。比べるのは「検知の種類」と「その検知の対象」の組です。「秘密・設定ファイル・管理画面の探索」のように、送信元をまとめて 1 行にする検知は、送信元が増えても継続と数えます。送信元ごとの行(この連鎖など)だけが、新規になります。

次に、自社の診断として外すルールを書きます。reason(理由)は必須で、すべての報告に出ます。期限も付けておきます。

cat > /tmp/suppress.toml <<'T'
[[rule]]
reason  = "自社の脆弱性診断(練習)"
ip      = "203.0.113.77"
expires = 2026-11-30
T
sudo accessscope suppress check --suppress /tmp/suppress.toml --lang ja
sudo accessscope scan --auto --since 1h --suppress /tmp/suppress.toml --lang ja
出力の抜粋
| /tmp/suppress.toml | 問題なし | 1 | 0 | 0 |

1 個のファイルを確認しました。エラー 0 件、期限が近いルール 0 件、期限切れのルール 0 件。

| 除外した検知 | 5 件(ルールの理由つき)。有効なルール 1 件、別に解析した除外対象のリクエスト 7 件 |
| ルール「自社の脆弱性診断(練習)」(/tmp/suppress.toml) | 除外 5 件、除外しなかった 0 件、一致したリクエスト 7 件、期限 2026-11-30 |
| 備考 | 総合リスクと検知の件数には、除外した検知を含みません。除外した検知の一覧は --show-suppressed で見られます。 |

外した検知は、捨てずに残ります。件数と理由が報告に出て、--show-suppressed で一覧にできます。suppress check は、書式の誤りと、7 日以内に切れるルールを確かめます。

最後に、結果を遮断の担当やほかの道具に渡す形で書き出します。

sudo accessscope scan --auto --since 1h --suppress /tmp/suppress.toml --lang ja --export-blocklist nftables 2>/dev/null | grep -E '件数|入れなかった'
sudo accessscope scan --auto --since 1h --suppress /tmp/suppress.toml --lang ja --export-blocklist nftables --blocklist-include-private 2>/dev/null | tail -6
sudo accessscope scan --auto --since 1h --suppress /tmp/suppress.toml --lang ja --format csv > /tmp/findings.csv
python3 -c 'import csv
for r in csv.DictReader(open("/tmp/findings.csv")): print(r["state"], r["severity"], r["kind"], r["ips"], r["suppressed_by"], sep=",")'
出力の抜粋
# 入れなかった IP: 公式のクローラ 0 / 除外ルール 0 / 私的・予約済みの範囲 1 / 証拠が条件に届かない 0 / ヒットが少ない 0 / 上限を超えた分 0
# 件数: 0
set accessscope_blocklist_v4 {
    type ipv4_addr
    elements = {
        203.0.113.50
    }
}
active,high,ssh_bf_ok,203.0.113.50,
active,high,actor_chain,203.0.113.50,
active,medium,web_cve_path,203.0.113.50,
active,low,web_chain,203.0.113.50,
active,low,web_scan,203.0.113.50,
active,low,web_probe_walk,203.0.113.50,
active,low,ssh_bf,203.0.113.50,
active,low,web_secret_probe,203.0.113.50,
active,low,web_sqli,203.0.113.50,
active,low,web_traversal,203.0.113.50,
suppressed,medium,web_cve_path,203.0.113.77,自社の脆弱性診断(練習)
suppressed,low,web_scan,203.0.113.77,自社の脆弱性診断(練習)
suppressed,low,web_chain,203.0.113.77,自社の脆弱性診断(練習)
suppressed,low,web_secret_probe,203.0.113.77,自社の脆弱性診断(練習)
suppressed,low,web_probe_walk,203.0.113.77,自社の脆弱性診断(練習)
  • 遮断リスト: 既定では、私的・ループバック・文書用などの範囲を入れません。この練習のアドレスは文書用なので、最初は 0 件でした。--blocklist-include-private を付けると入ります。外から来た本物の攻撃なら、このオプションは要りません
  • 入る条件: 既定は、深刻度が中以上、確度が中以上、1 つの IP のヒットが 3 件以上です。外したルールに当たる IP も入りません
  • CSV: state が active(有効)か suppressed(除外)です。除外したものには、ルールの理由が付きます。--help によると、形式はほかに json と sarif も選べます
やってはいけないこと
  • 書き出した遮断リストを、確かめずにそのまま適用する。NAT やプロキシの背後では、1 つのアドレスを多くの人が使っています
  • 調べ終わる前に、ログを消したり、回したりする。消えた期間は、どの道具にも見えません
  • 外すルールを、理由も期限も書かずに増やす。何を外したかが、あとから分からなくなります

#入られたアカウントから、どこまで届くか

demo は、乗っ取られたものとして扱うと決めました。まずアカウントを止めます。次に、demo から root まで届く道がないかを、対策箇所と修正案(PathScope) で調べます。

アカウントを止めて、root までの経路を調べ、直す

usermod -L はパスワードでのログインを止めます(変更を伴う操作です)。戻すときは sudo usermod -U demo です。loginctl terminate-user は、そのアカウントのセッションを切ります。セッションが残っていなければ、「Could not terminate user: … is not logged in or lingering」と出て、終了コードは 1 です。

sudo usermod -L demo
sudo loginctl terminate-user demo
sudo passwd -S demo
sudo pathscope --start=demo --lang=ja --json-out=/tmp/ps-before.json
出力の抜粋
demo L 2026-11-12 0 99999 7 -1

| 開始ユーザー | demo |
| 経路 | 1 本 |
| 対策箇所 | 1 件 |
| 収集できなかった範囲 | 17 件 |

| 1 | ユーザー demo -[rootで動くサービス nightly-backup.service の実行ファイル /opt/nightly-backup.sh を書き換えられる]-> root(管理者権限) |

| 1 | 緊急(95点) | ユーザー demo → root(管理者権限) | rootで動くサービス nightly-backup.service の実行ファイル /opt/nightly-backup.sh を書き換えられる | 1 本 |

- ATT&CK: T1543.002 Create or Modify System Process: Systemd Service (近似) https://attack.mitre.org/techniques/T1543/002/

sudo chown root:root /opt/nightly-backup.sh
sudo chmod go-w /opt/nightly-backup.sh

- 既知の脆弱性の確認: 2026-10-19時点の同梱データを使用。対象は、(1) CISAのKEVカタログ 2026.10.16にあるもの、(2) FIRSTのEPSS(悪用される確率の推定値)が直近30日のうちに0.5以上になったもの(一度入れたものは、値が下がっても残す)、(3) 攻撃モジュール(Metasploit Framework)が公開されているもの。(1)は実際の攻撃で悪用されたもの、(2)は悪用される可能性が高いもの。(3)は公開された攻撃モジュールがあるという事実で、悪用が確認されたわけではない。いずれもローカルからrootになれるものだけが対象で、脆弱性の網羅的な検査ではない。

passwd -S の 2 番目の L が、止めた印です。PathScope の結果は、次のように読みます。

  • 経路: demo は、root で動くタイマーのスクリプトを書き換えられます。書き換えれば、次にタイマーが動いたとき、root の権限で好きなコマンドを動かせます
  • 対策箇所: 先に直すと効く場所を、優先度の順に並べます。直すコマンドの例も付きますが、自動では実行しません
  • 収集できなかった範囲: 調べられなかった 17 か所は、「安全」ではなく「未確認」です
  • 既知の脆弱性: 入っているソフトの既知の脆弱性の照合(PathScope) は、入っているソフトとカーネルの版を、同梱のデータ(CISA KEV など)と照合します。ローカルから root になれるものだけが対象です。この VM では、当たるものはありませんでした

経路があるなら、demo がすでにスクリプトを書き換えていないかも確かめます。中身と更新時刻を、作った人の記録と見比べます。

修正案のとおりに直して、履歴との比較と継続検査(PathScope) で、前回の結果と比べます。権限を変える操作です(変更を伴う操作です)。

sudo chown root:root /opt/nightly-backup.sh
sudo chmod go-w /opt/nightly-backup.sh
sudo pathscope --start=demo --lang=ja --baseline=/tmp/ps-before.json --fail-on=new > /tmp/ps2.txt; echo "終了コード: $?"
cat /tmp/ps2.txt
出力の抜粋
終了コード: 0
| 経路 | 0 本 |

demo から root・機密データへの経路は見つかりませんでした(収集できた範囲内)。

## 前回(`/tmp/ps-before.json`)からの変化

- 消えた経路: 1 本 / 増えた経路: 0 本
  - `-` `user(demo)-[systemd_writable_exec(nightly-backup.service, /opt/nightly-backup.sh)]->root`

経路が 1 本消えました。--fail-on=new は、前回になかった経路が増えたときに、終了コード 1 を返します。逆の順(直した結果を前回として、権限を戻す)で試すと、増えた経路: 1 本 と出て、終了コードは 1 でした。定期的に実行すれば、設定の変更で経路が増えたことに気づけます。

#まとめて確かめる

ボタン 1 つの状況確認(PersonalSOC) は、認証ログ、Web のログ、RoamSwitch の検知の記録を、読み取りだけで集めます。同梱の AccessScope と PathScope の結果のまとめも取り込みます。最後に、見落としがないかを 1 つの一覧で確かめます。

全体を一度に見る
sudo personalsoc scan
出力の抜粋
△ MCP の設定(Claude Code・Claude Desktop・opencode・Cursor)(この環境に該当するログがない)
△ AI エージェントの設定(Claude Code の settings.json)(この環境に該当するログがない)
○ 認証ログ(sshd)
△ auditd(この環境に該当するログがない)
○ Web アクセスログ(nginx / apache)
△ DNS クエリログ(dnsmasq / named)(この環境に該当するログがない)
○ RoamSwitch(MCP、読み取り専用)(供給網の検査は行っていない(RoamSwitch に監視フォルダーが未登録か、Pro 版限定のため))
○ 同梱の AccessScope の診断(アクセスログの深掘り。直近24時間)(読めなかったログがある(検出なしは安全の証明ではない))
○ 同梱の PathScope の分析(権限昇格の経路)(経路の起点の利用者: admin / 収集できなかった範囲が 17 か所ある(経路なしは安全の証明ではない))
△ 同じ LAN の Sensor が見ている LAN 層の脅威(不正な DHCP・ARP のなりすましなど)(Sensor が、この端末に無い、またはデーモンに届かない)

RoamSwitch の防御のカバレッジ
  いま働いている割合は 67%(全 39 技術のうち、検知 0・一部 26・見ていない 13。対応するガードが止まっている 0)

RoamSwitch の確かめられなかった設定項目
  1 件: バックアップの最新性
  測れなかった項目で、弱点とも問題なしとも数えていない(root で動かす、または RoamSwitch の診断で確かめる)。

同梱ツールの診断
  AccessScope: 総合リスク 13/100(低)。検出 高 2・中 1・低 8
  PathScope: root または機密データへの経路 1 本。遮断点 1 か所(優先度 高以上 1)。優先度の高い 1 か所で 1 本を遮断できる
  経路の起点の利用者: admin
  根拠と直し方は、AccessScope・PathScope で確認する(PersonalSOC は、結果のまとめだけを読む)。

[高/確定] SSH 総当たり後の認証成功: 203.0.113.50 (T1078)
  [認証ログ(sshd)] 203.0.113.50 から失敗 6 回の後に成功が 1 回。正規利用者の入力ミスの可能性もあるため、当該アカウントの直後の操作を確認すること。(根拠の行は、取得したログ内の番号) RoamSwitch の SSH ガードも、同じ送信元を記録している(2つの独立した記録)。
[高/有力] SSH ガード: 総当たりのあとにログインが成功: 203.0.113.50 (T1078)
  RoamSwitch の SSH ガードが、失敗 6 回のあとの成功を記録(2026年11月12日(木) 02:35:53 (UTC))。パスワードが推測された可能性がある。そのアカウントの利用者に確認すること。
[高/確定] パッケージの既知の脆弱性: brotli 1.1.0-2build2(CVE 1件) (-)
  brotli 1.1.0-2build2: 最大 CVSS は 9.8。主な CVE は CVE-2026-111497。修正版は 1.1.0-2ubuntu0.1。
[高/有力] PathScope: root または機密データへの権限昇格の経路が 1 本 (T1068)
  経路の起点の利用者: admin。遮断点は 1 か所(優先度が高以上は 1 か所)。優先度の高い 1 か所を直すと、1/1 本を遮断できる。例: sudo_nopasswd_all(admin, sudoers:/etc/sudoers.d/90-cloud-init-users:4)。直し方と全体は PathScope で確認する。
[中/有力] Web 攻撃パターン: 203.0.113.50 (T1190)
  [Web アクセスログ(nginx / apache)] 203.0.113.50 から 4 件。種別: 機密ファイル探索、SQLインジェクション、パストラバーサル/LFI。成功応答は観測されていない。(根拠の行は、取得したログ内の番号)
[中/有力] RoamSwitch の未解決の検知: RoamSwitch のガード (-)
  /etc/systemd/system/nightly-backup.timer: 新しいファイル(SSH のログインではない: サービス tart-guest-agent.service)(対処: 記録あり。1 件、最新: 2026年11月12日(木) 02:35:56 (UTC))
[中/確定] 設定の弱点: 稼働中カーネルの既知CVE露出 (-)
  ディストリビューションのカーネル更新を適用し、システムを再起動してください。

読むところは 5 つです。

  • ○ と △: ○ は読めた材料、△ は読めなかった材料です。△ の理由も書かれます。読めなかった材料は、調べていません
  • 同じ出来事が、別の記録から出る: SSH の成功は、認証ログと RoamSwitch の SSH ガードの「2つの独立した記録」として出ました。失敗の数は、どちらも 6 回です。AccessScope の検出も並びます。別々の記録が同じことを示すと、確かさが上がります
  • PathScope の 1 本: 「経路の起点の利用者: admin」のとおり、admin の sudoers(パスワードなしで何でも sudo できる)です。demo の経路は、前の章で直しました
  • 防御のカバレッジ: RoamSwitch のガードが見ている攻撃の技術の割合です。「見ていない」技術は、ほかの方法で見ます
  • 設定の弱点と、確かめられなかった項目: 総合診断で[要対策]だった項目は「設定の弱点」として並びます。[確認不能]だった項目は弱点に数えず、「RoamSwitch の確かめられなかった設定項目」の枠に、件数と名前で出ます。この例では、タイマーはあるが最後の実行を確かめられない、バックアップの最新性です。パッケージの既知の脆弱性も、RoamSwitch の脆弱性データから並びます

タイマーの作り手も、RoamSwitch の記録から分かります。重要ファイルの改ざん検知(FIM)は、/etc/systemd/system に置かれたファイルを、その場で、書いたプロセスとともに知らせます。

sudo roamswitch notifications | grep -B4 -A5 "nightly-backup.timer"
出力の抜粋
  2026-11-12T02:35:56.554262004+00:00
  クリティカルパス改ざん検知 (FIM) (1 件の改ざん)
    ホスト: ubuntu (IP: 192.168.64.7)
    ハッシュが一致しない重要システムファイル:
    /etc/systemd/system/nightly-backup.timer: 新しいファイル
      プロセス: root / /usr/bin/dash / コマンド: sh /tmp/make-events.sh (pid 1560)
      SSH のログインは見つかりませんでした(systemd サービス tart-guest-agent.service のプロセスです)
    推奨対応: `sudo roamswitch fim verify` で改ざん箇所を特定し復旧してください。
    時刻: 2026-11-12 02:35:56

PathScope が見つけた経路のタイマーは、02:35:56 UTC(日本時間 11:35:56)に、root の sh /tmp/make-events.sh が置いたものでした。SSH のログインからではなく、この VM を操作する仕組み(tart-guest-agent.service)の下で動いたことも分かります。本当の調査なら、置いた人に心当たりを確かめ、心当たりがなければ、そのスクリプトの出どころを調べます。

練習が終わったら、元に戻します。

sudo systemctl disable --now nightly-backup.timer
sudo rm -f /etc/systemd/system/nightly-backup.service /etc/systemd/system/nightly-backup.timer /opt/nightly-backup.sh
sudo systemctl daemon-reload
sudo userdel -r demo
for a in 198.51.100.7 203.0.113.50 203.0.113.77; do sudo ip addr del $a/32 dev lo; done

#見えない部分

ログから分からないこと

実機(使い捨ての Ubuntu 24.04 の VM)で確かめた範囲では、次のようになります。

  • ログに残らないことは、見えません。AccessScope のレポート自身が書くとおり、リクエストの本文、応答の中身、アプリの内部の状態は分かりません。ログが回転・削除された期間も見えません
  • audit-logs は、直近 500 行だけを読みます。忙しいサーバーでは、1 時間を指定しても、その全部を読むとは限りません。出力の注意の行で分かります
  • ログのつながりは、アドレスが同じことだけが根拠です。NAT やプロキシの背後では、別の人が同じアドレスになります
  • この練習では、何も遮断されませんでした。lo に足したアドレスは、このマシン自身のアドレスです。fail2ban は自分のアドレスを無視し(ignoreself)、RoamSwitch の SSH ガードも「除外」と記録しました。外から来た総当たりなら、遮断の対象になります
  • 検知がないことは、安全の証明ではありません。PathScope の「経路なし」も、収集できた範囲の中での話です
確認問題

AccessScope が「複数のログに現れた同じアドレス」を出しました。正しい受け取り方はどれですか

解説を見る

レポートは「結びつけの根拠はアドレスが同じことだけ」と書いています。成功したログインが誰のものかは、アカウントの持ち主に確かめます。遮断リストも、確かめてから適用します。

確認問題

sudo roamswitch audit-logs 1 を続けて 2 回実行すると、2 回目も同じ頻度急増が出ました。なぜですか

解説を見る

手での実行は、何度くり返しても基準を変えません。基準を進めて通知の履歴に残すのは、log_audit_interval_secs ごとに動くデーモンの監査です(起動後の最初の 1 回は学習だけ)。

#次に学ぶこと

扱う機能
確認した内容

2026-11-12に確認しました。対象は Linux 1.17.39 です。公開の apt の 1.17.39(同梱の AccessScope 1.0.7、PathScope 1.0.5、PersonalSOC)を入れた使い捨ての Ubuntu 24.04 の VM で、日本語と英語それぞれ新しい VM を作って全演習を実行しました。PathScope の --fail-on=new は逆の順でも確かめました。

コマンドの出力は、製品の版や環境によって変わります。違いが出たら、まず製品の版を確かめてください。