Windows イベント ID 4625:ログイン失敗の読み方

4625 イベントの全フィールド、ステータスコードの意味、そして打ち間違えた利用者と辞書を回しているボットネットを見分ける方法。

約 8 分で読めます

4625 とは何か

イベント ID 4625——「アカウントがログオンに失敗しました」——は、認証の試行が拒否されるたびに、理由を問わず Windows のセキュリティログへ書き込まれます。パスワード誤り、存在しないアカウント、無効化されたアカウント、許可時間外のログオン、いずれも同じです。成功時の対になるイベントは 4624 です。

インターネットに面した Windows サーバーで最も有用な単一のイベントです。ブルートフォース攻撃が成功する前に可視化されるのが、まさにここだからです。ファイアウォール層の防御が行うことはすべて、このストリームを読むところから始まります。

公開されているはずのサーバーで 4625 がまったく見えないなら、サーバーが静かなのではなく監査が無効です。確認して有効にしてください:

cmd
auditpol /get /subcategory:"Logon"
auditpol /set /subcategory:"Logon" /success:enable /failure:enable

意味のあるフィールド

4625 のレコードは冗長で、大半はノイズです。情報を担うのは 5 つのフィールドです:

  • アカウント名(「ログオンに失敗したアカウント」の下)——試されたユーザー名。実際の攻撃では、あなたのマシンに存在したことのない名前の行進になります。
  • ソースネットワークアドレス——試行の発信元 IP。あなたが行動の根拠にするのはこのフィールドです。ローカルコンソールからのログオンでは空になります。
  • ログオンタイプ——どの方法でログオンが試みられたか。10 は RemoteInteractive(RDP)、3 は Network(SMB、またはゲートウェイ経由の一部の RDP)、2 は物理コンソール、5 はサービス、4 はタスクスケジューラ。
  • 失敗の理由と状態 / サブ状態——何が誤りだったかを示す 16 進コード。有用な区別はここにあります。
  • ワークステーション名——クライアントが自己申告したホスト名。攻撃ツールはしばしばゴミや乱数文字列を送るか、空のままにします。それ自体が手がかりです。

ステータスコードの読み解き

読むべきはサブ状態フィールドです。上位の状態はたいてい汎用の 0xC000006D が入っています。次の 5 つを覚えれば、ほとんどの 4625 は一目で分類できます:

  • 0xC0000064——そのアカウント名は存在しません。ほぼ常に攻撃です。自分の利用者は自分のユーザー名を知っています。
  • 0xC000006A——アカウントは存在するがパスワードが誤り。実在の利用者の打ち間違いか、有効なユーザー名を当てたボットのどちらかです。
  • 0xC0000234——アカウントがロックアウトされている。これが連続して現れるなら、ロックアウトポリシーがあなたに対して利用されています。
  • 0xC0000072——アカウントが無効。攻撃者が見つけた休眠アカウントで、まだ試し続けている場合が多いです。
  • 0xC000006F / 0xC0000070——許可時間外のログオン、または許可されていないワークステーションから。まれであり、無視するより調査すべきものです。

攻撃と打ち間違いを見分ける

3 つの手がかりが両者を分けます。自動的に処置する前には、3 つとも揃っていることが望ましいです。

頻度と持続性。人は 1 分のうちに 2、3 回試し、そのあと入れるか、あなたに電話してきます。ボットは何時間も一定の頻度を保ち、一晩中、休みなく、誰にも電話しません。

アカウントの多様性。人は 1 つのアカウント、自分のものだけを試します。ボットは一覧を順に辿ります——administrator、admin、user、test、sql、backup、scan——そしてその大半はあなたのマシンに存在せず、それが上記の 0xC0000064 の特徴になります。

送信元。自社の人間は既知のわずかなアドレスからログインします。攻撃はホスティングのレンジから、数百回ごとに別のアドレスへ移りながら、しばしば同じ 1 時間のうちに複数の国から届きます。

次のコマンドは直近 1 日の失敗を送信元アドレスとアカウントで集計し、3 つの手がかりを一度に見せます:

powershell
Get-WinEvent -FilterHashtable @{LogName='Security'; Id=4625; StartTime=(Get-Date).AddDays(-1)} |
  ForEach-Object {
    $d = ([xml]$_.ToXml()).Event.EventData.Data
    [pscustomobject]@{
      IP      = ($d | Where-Object Name -eq 'IpAddress')['#text']
      Account = ($d | Where-Object Name -eq 'TargetUserName')['#text']
      Status  = ($d | Where-Object Name -eq 'SubStatus')['#text']
    }
  } |
  Group-Object IP |
  Sort-Object Count -Descending |
  Select-Object -First 15 Count, Name,
    @{n='Accounts'; e={ ($_.Group.Account | Select-Object -Unique) -join ', ' }}

イベントを読むことから、遮断することへ

4625 を手で読むのは診断であって防御ではありません。あなたがクエリを実行する頃には、攻撃はもう 1 週間続いています。何かを変えるのは、それを継続的に行い、しきい値をファイアウォール規則へ変換することだけです。

素朴な実装は、セキュリティログを購読し、送信元ごとに失敗を数え、線を越えたら New-NetFirewallRule を呼びます。動きはします。そして、この種のスクリプトが必ずぶつかる問題にぶつかります。規則が数千に膨らんでファイアウォールが這うようになり、負荷でログが回ってイベントを取り逃がし、再起動後にスクリプトが静かに死に、1 件の誤判定が管理者を唯一の入口から締め出します。

RDP Protector はこのループをサービスとして実行します。数千ではなく 1 つの統合ファイアウォール規則、遮断より常に優先されるホワイトリスト、そしてローカルで下される判断——だからネットワークが持たないときにも持ちこたえます。読んでいるのは上に示したのと同じイベントストリームであり、あなたから隠されているものはありません。

FAQ

イベント 4625 と 4624 の違いは何ですか?
4624 はログオン成功を、4625 は失敗を記録します。どちらもセキュリティログにあり、フィールド構成も同じなので、上記のクエリは ID を変えるだけでどちらにも使えます。4625 の連続のあと、同じ送信元アドレスから 4624 が現れる並びは、決して見たくないものです。推測が成功したという意味だからです。
4625 イベントのログオンタイプ 3 は何を意味しますか?
ログオンタイプ 3 はネットワークログオンで、コンソールではなくネットワーク越しに認証する接続です。SMB のファイル共有アクセスや、前段のゲートウェイ次第では一部の RDP 経路が含まれます。ホストへの直接 RDP は通常タイプ 10(RemoteInteractive)として記録されます。タイプ 3 の失敗が大量にある場合、RDP に加えて SMB も公開されていることがほとんどです。
ソースネットワークアドレスが空欄やハイフンなのはなぜですか?
ネットワーク由来ではないログオン——物理コンソール、一部のサービスやタスクスケジューラのログオン——で起こり、まれに試行が早い段階で失敗してアドレスが記録されなかった場合にも起こります。周辺のフィールドがログオンタイプ 2、4、5 を示しているなら、アドレスが空なのは想定どおりで、異常の兆候ではありません。
セキュリティログは 4625 イベントをどれくらい保持しますか?
いっぱいになって回るまでです。実際の攻撃下では数週間ではなく数時間になりえます——既定の 20 MB は 1 日数千件では速く埋まります。調査のためにログに頼るなら、最大サイズを引き上げるかイベントをホスト外へ転送してください。さもないと、見に行く前に必要な証拠が失われています。

手作業でログを読むのをやめる

エージェントはまさにこのイベントストリームを監視し、継続的にファイアウォール規則へ変換します。1 台永年無料、カード不要。