検知の決まりの設計

レッスン 4-2

通知の多さは、見つける力ではありません。

目安 60 分 トラック 4 検知と対応の 2 本目

読み終えたら1 つの攻撃に検知の決まりを書き、普段の動きで鳴らないことを確かめられる

この頁の流れ

  1. 1なぜ通るのか
  2. 2脆いコードと直したコード
  3. 3ログでの見え方と検知
  4. 4直し方と確かめ方
  5. 5関わる事例
  6. 6確認クイズ
  7. 7説明課題
  8. 8一次資料
  9. 9次へ

SIEM (記録を集めて突き合わせ、怪しい動きを知らせる仕組み) の中で、検知の決まり (ルール) をどう書くかを扱います。パスワードスプレーを例に、1 つのアカウントの失敗だけを数える決まりと、送り元ごとに試されたアカウントの数を数える決まりを手元で比べ、普段の動きでは鳴らないことを試験で確かめるところまで進みます。

出典を確かめた日 2026年10月27日

なぜ通るのか

ある会社では、ログインの失敗が 1 つのアカウントで 5 回続くと通知が鳴る決まりにしていました。ある晩、外の 1 つの住所から 300 のアカウントに、よくあるパスワードが 1 回ずつ試されます。どのアカウントも失敗は 1 回だけなので、通知は 1 度も鳴りません。翌朝、そのうち 1 つのアカウントが、遠くの国からログインに成功していました。

これはパスワードスプレーと呼ばれる攻撃です。MITRE ATT&CK は、よくあるパスワードを 1 つ、多くのアカウントに試し、1 つのアカウントに何度も試した時に掛かる締め出しを避ける手口と説明しています。決まりは、攻撃者がそれを知って避けることを前提に書かないと、鳴るべき時に黙ります。

SIEM と、その中の決まり

SIEM は、いろいろな機械の記録を 1 か所に集め、突き合わせ、怪しい動きを知らせる仕組みです。Microsoft は、主な部品を、記録の管理、出来事の相関、継続した見張り、インシデントへの対応の 4 つと説明しています。

名前受け持つ所
SIEMいろいろな機械の記録を集め、決まりで突き合わせて知らせる
EDR端末の中の動き (処理の起動、ファイル、通信) を見て止める
SOC知らせを受けて調べ、対応を決める人と体制

SIEM を入れても、決まりが無ければ何も鳴りません。決まりが粗ければ、毎日何百件も鳴って、誰も見なくなります。製品を選ぶより先に、何を見つけたいかを決まりの形で書けるかが問われます。

誤検知と見逃しは、片方だけ減らせない

決まりの外れ方は 2 つあります。普段の動きで鳴る誤検知と、攻撃で鳴らない見逃しです。条件を緩めれば見逃しは減りますが誤検知が増え、締めれば逆になります。

誤検知が多い決まりは、本物の通知まで埋もれさせるので、見逃しと同じ害を生みます。だから決まりは、攻撃を捕まえる試験と、普段の動きで鳴らない試験の、2 つをそろえて初めて出来上がりです。

決まりを書く時に埋める欄

Palantir が公開している Alerting and Detection Strategy の枠組みは、決まりを本番に入れる前に、目的、分類、やり方の要約、技術の背景、見えない所と前提、誤検知、確かめ方、優先度、対応の欄をすべて埋めることを求めています。とくに「見えない所」と「誤検知」を先に書くと、決まりの弱さを自分で言葉にできます。

脆いコードと直したコード

ラボの中の小さな関数で比べます。Python に付いている物だけで動き、記録は手で作った表を使います。関数には、10 分ごとに切った記録を渡す前提です。

アカウントごとに数えるか、送り元ごとに数えるか

脆いコード 1 つのアカウントの失敗だけを数える

Python

from collections import Counter

def alert(events, limit=5):
    fails = Counter(e["user"] for e in events
                    if e["result"] == "fail")
    return [u for u, n in fails.items() if n >= limit]
直したコード 送り元ごとに、試されたアカウントの数を数える

Python

from collections import defaultdict

def alert(events, users=10):
    tried = defaultdict(set)
    for e in events:
        if e["result"] == "fail":
            tried[e["ip"]].add(e["user"])
    return [ip for ip, us in tried.items() if len(us) >= users]

脆い方は、1 つのアカウントへの総当たりには効きますが、パスワードスプレーでは各アカウントの失敗が 1 回なので鳴りません。直した方は、1 つの送り元が 10 分の間に何人のアカウントで失敗したかを数えます。同じ人が何度打ち間違えても数は 1 のままなので、普段の打ち間違いでは鳴りにくくなります。

失敗のたびに鳴らすか、成功に結び付けるか

脆いコード 失敗のたびに通知する

Python

def notify(events):
    return [e for e in events if e["result"] == "fail"]
直したコード スプレーの送り元からの成功だけを急ぎにする

Python

def urgent(events, users=10):
    bad = set(alert(events, users))
    return [e for e in events
            if e["ip"] in bad and e["result"] == "ok"]

脆い方は、毎日の打ち間違いをすべて通知にするので、数日で誰も見なくなります。直した方は、スプレーの送り元からの成功を、当たってしまった疑いのあるアカウントとして急ぎの通知にします。10 分ごとに切った記録の中で順番までは見ていないので、同じ住所を使うふつうの利用者の成功も一緒に拾います。だから会社の出口のような共有の住所では鳴らないことを、下の普段の朝の試験で確かめます。スプレーそのものは記録として残し、急ぎで人を起こすのは、入られた疑いのある時に絞ります。

これはラボの最小の形です。本物の攻撃では、送り元の住所をいくつにも分けて、1 つの住所あたりの数を下げてきます。その時は、同じ時間帯に失敗したアカウントの総数や、存在しない名前への試みの多さも合わせて見ます。

ログでの見え方と検知

前のレッスンで作った形の記録に、スプレーは次のように残ります。1 行ずつは、ただの打ち間違いと見分けがつきません。

スプレーのときの記録 (一部)

記録

01:02:11 203.0.113.9 u001 login fail
01:02:13 203.0.113.9 u002 login fail
01:02:15 203.0.113.9 u003 login fail
01:02:17 203.0.113.9 u004 login fail
01:09:40 203.0.113.9 u217 login ok

1 つの住所から、短い間に違うアカウントが次々と失敗し、最後に 1 つが成功しています。決まりは、1 行ではなく、この並びを見ます。

見る物なぜ効くか
1 つの送り元が失敗したアカウントの数スプレーは、アカウントの数を増やして 1 つあたりの失敗を減らす
失敗の並びのあとの成功当たったアカウントは、すぐに使われる
存在しないアカウントの名前への試み社員の名簿を推測で作って試している
多要素認証の掛からない古い入口への試みスプレーは、守りの弱い入口に寄る

直し方と、直ったことの確かめ方

自分の PC の中だけで行います。記録は手で作り、外のサービスや他人のアカウントには試しません。

  1. 作業用のフォルダに、1 つの住所から 20 のアカウントに 1 回ずつ失敗した記録を作る
  2. 脆い alert に渡し、何も返らないこと (見逃し) を確かめる
  3. 会社の出口の住所 1 つから、4 人が打ち間違え、40 人が成功した普段の朝の記録を作る
  4. 直した alert に、両方の記録を渡す。スプレーでは住所が返り、普段の朝では何も返らないことを確かめる
  5. 下の試験を足し、直す前のコードに戻すと 1 つ目の試験が落ちることも確かめる
  6. 終わったら、作業用のフォルダごと消す
捕まえる試験と、鳴らない試験をそろえる

Python

def spray():
    return [{"ip": "203.0.113.9", "user": f"u{i:03}", "result": "fail"}
            for i in range(20)]

def office_morning():
    ev = [{"ip": "198.51.100.1", "user": f"s{i}", "result": "fail"}
          for i in range(4)]
    ev += [{"ip": "198.51.100.1", "user": f"s{i}", "result": "ok"}
           for i in range(40)]
    return ev

def test_spray_is_caught():
    assert alert(spray()) == ["203.0.113.9"]

def test_office_morning_is_quiet():
    assert alert(office_morning()) == []

1 つ目の試験は、見逃しが戻らないことを、2 つ目の試験は、誤検知が増えないことを確かめます。決まりの数字 (ここでは 10) を変える時は、両方の試験を通してから変えます。

決まりを 1 枚にまとめる

コードの前に、決まりを欄に沿って書きます。見えない所を書けない決まりは、まだ弱さが分かっていない決まりです。

検知の決まりの例

記録

目的    パスワードスプレーで当たったアカウントを早く見つける
見る記録  ログインの成否 (送り元、アカウント、時刻)
条件    10 分で 1 つの送り元が 10 以上のアカウントで失敗
急ぎ    その送り元からの成功があれば、すぐ人を呼ぶ
見えない所 送り元を多数に分けた試み、多要素認証の無い古い入口
誤検知   会社の出口や共有の回線、利用者の多い朝の始業
確かめ方  手で作ったスプレーの記録と、普段の朝の記録で試験
鳴ったら  当たったアカウントを止め、本人に確かめ、送り元を塞ぐ

関わる事例

決まりの外を通られた例が並びます。Microsoft は、2023年11月下旬から、多要素認証の無い古い試験用のアカウントにパスワードスプレーを掛けられ、そこから一部の社内メールを読まれました。気づいたのは2024年1月12日です。

Marriott では、データベースの見張りの警報が、決済カードの情報を含む表だけに掛かっていました。2014年からの侵入は、2018年9月にその表への件数の照会が警報を鳴らすまで、4 年以上見つかりませんでした。見張りの決まりが、守りたい物の一部しか見ていなかった例です。

知らせが届いても、決まりが無いと止められません。23andMe では、2023年8月に顧客のデータを売るという書き込みと問い合わせが届き、対応の担当が調べましたが、英国の ICO の処分通知によると、8月18日に「hoax (でっち上げ) のようだ」として案件を閉じています。10月に改めてデータが売りに出され、侵害が確かめられました。

一方で、検知が効いた例もあります。三菱電機では、2019年6月28日に、社内の端末で不審な動きを検知し、そこから調べを進めて第三者による侵入を確かめています。

確認クイズ

1 問目

1 つのアカウントで 5 回失敗したら鳴る決まりがあります。1 つの住所から 300 のアカウントに 1 回ずつ試された時、鳴らない理由として合うのはどれですか。

答えだと思う選択肢を押すと、その場で正誤と理由が開きます。

2 問目

新しく書いた決まりが、毎朝の始業の時刻に 30 件鳴ります。どれも会社の出口の住所からの打ち間違いでした。まずどうしますか。

答えだと思う選択肢を押すと、その場で正誤と理由が開きます。

説明課題

次のことを、自分の言葉で 3 行にまとめてください。書けたら、このレッスンは修了です。

  • パスワードスプレーを見つける決まりを 1 つ書き、それが見逃す場合と、普段の動きで鳴る場合を 1 つずつ
模範解答を見る

10 分の間に 1 つの送り元が 10 以上のアカウントで失敗したら記録し、その送り元からの成功があれば急ぎで知らせる。送り元を多数の住所に分けられると、1 つあたりの数が 10 に届かず見逃す。会社の出口の住所のように多くの人が共有する送り元では、始業の打ち間違いで鳴ることがあるので、普段の朝の記録で試験をしてから入れる。

一次資料

どれも 2026年10月27日に開いて、題と中身を確かめました。

次へ

次のレッスンは「インシデント対応」です。鳴った通知から体制を立ち上げ、最初の 1 時間に何を決めるかを扱います。

次のレッスン 4-3 インシデント対応

このレッスンにつながる物

トラック 4 検知と対応の中で

前のレッスン 4-1 記録の設計

学んだことを次につなげる

ゆめさくセキュリティは、攻撃の仕組みを知り、自分の PC の中で壊して直し、守る側の判断を身につけるための学びの場です。

ラボはすべて自分の PC の中 (127.0.0.1) で閉じます。自分が管理していない相手に試すことは扱いません。