• サンプル1:設定ファイルへのアクセス試行 (LFI攻撃)

これは、Webサーバーの設定ファイル (.env) を盗み見ようとする、典型的な LFI (ローカルファイルインクルージョン) 攻撃の検知ログです。

# [クライアントIP] [タイムスタンプ]
# --- 攻撃検知 (1/2): HostヘッダーがIPアドレスであるため警告 (スコア+3) ---
[Sun Oct 19 10:01:01 2025] [security2:error] [client 198.51.100.55] ModSecurity: Warning. ... [id "920350"] [msg "Host header is a numeric IP address"] [hostname "203.0.113.1"] [uri "/.env"]

# --- 攻撃検知 (2/2): .env へのアクセスを致命的な脅威として検知 (スコア+5) ---
[Sun Oct 19 10:01:01 2025] [security2:error] [client 198.51.100.55] ModSecurity: Warning. ... [id "930130"] [msg "Restricted File Access Attempt"] [data "Matched Data: .env found within REQUEST_FILENAME: /.env"] [severity "CRITICAL"] [uri "/.env"]

# --- ブロック実行: 合計スコアがしきい値を超えたため、アクセスを拒否 ---
[Sun Oct 19 10:01:01 2025] [security2:error] [client 198.51.100.55] ModSecurity: Access denied with code 403 (phase 2). ... [id "949110"] [msg "Inbound Anomaly Score Exceeded (Total Score: 8)"] [uri "/.env"]

# --- 最終報告: 最終的なスコアとブロック状況を記録 ---
[Sun Oct 19 10:01:01 2025] [security2:error] [client 198.51.100.55] ModSecurity: Warning. ... [id "980170"] [msg "Anomaly Scores: (Inbound Scores: blocking=8, ... LFI=5, ...)"] [uri "/404.html"]
  • サンプル2:XSS (クロスサイトスクリプティング) 攻撃

これは、パラメータに不正なスクリプトを注入しようとするXSS攻撃の検知ログです。複数のルールが連鎖的に反応し、非常に高いスコアが付与されています。

# [クライアントIP] [タイムスタンプ]
# --- 攻撃検知 (1/4): libinjectionライブラリがXSSを検知 (スコア+5) ---
[Sun Oct 19 10:02:02 2025] [security2:error] [client 192.0.2.123] ModSecurity: Warning. ... [id "941100"] [msg "XSS Attack Detected via libinjection"] [data "XSS data found within ARGS:query: <script>alert('XSS')</script>"]

# --- 攻撃検知 (2/4): <script> タグの存在を検知 (スコア+5) ---
[Sun Oct 19 10:02:02 2025] [security2:error] [client 192.0.2.123] ModSecurity: Warning. ... [id "941110"] [msg "XSS Filter - Category 1: Script Tag Vector"] [data "Matched Data: <script> found within ARGS:query: ..."]

# --- 攻撃検知 (3/4): HTMLインジェクションとして検知 (スコア+5) ---
[Sun Oct 19 10:02:02 2025] [security2:error] [client 192.0.2.123] ModSecurity: Warning. ... [id "941160"] [msg "NoScript XSS InjectionChecker: HTML Injection"] [data "Matched Data: <script found within ARGS:query: ..."]

# --- 攻撃検知 (4/4): 'alert(' というJavaScriptメソッドを検知 (スコア+5) ---
[Sun Oct 19 10:02:02 2025] [security2:error] [client 192.0.2.123] ModSecurity: Warning. ... [id "941390"] [msg "Javascript method detected"] [data "Matched Data: alert( found within ARGS:query: ..."]

# --- ブロック実行: 合計スコアがしきい値を超えたため、アクセスを拒否 ---
[Sun Oct 19 10:02:02 2025] [security2:error] [client 192.0.2.123] ModSecurity: Access denied with code 403 (phase 2). ... [id "949110"] [msg "Inbound Anomaly Score Exceeded (Total Score: 20)"]

# --- 最終報告: XSSカテゴリで合計20点が付与されたことを記録 ---
[Sun Oct 19 10:02:02 2025] [security2:error] [client 192.0.2.123] ModSecurity: Warning. ... [id "980170"] [msg "Anomaly Scores: (Inbound Scores: blocking=20, ... XSS=20, ...)"] [uri "/404.html"]

  • サンプル3:PHPインジェクション攻撃

これは、PHPのデバッグ機能などを悪用して、サーバー上で不正なコードを実行しようとするPHPインジェクション攻撃の検知ログです。

# [クライアントIP] [タイムスタンプ]
# --- 攻撃検知 (1/2): HostヘッダーがIPアドレスであるため警告 (スコア+3) ---
[Sun Oct 19 10:03:03 2025] [security2:error] [client 203.0.113.99] ModSecurity: Warning. ... [id "920350"] [msg "Host header is a numeric IP address"] [hostname "203.0.113.1"] [uri "/"]

# --- 攻撃検知 (2/2): 'XDEBUG_SESSION_START' という危険なパラメータ名を検知 (スコア+5) ---
[Sun Oct 19 10:03:03 2025] [security2:error] [client 203.0.113.99] ModSecurity: Warning. ... [id "933150"] [msg "PHP Injection Attack: High-Risk PHP Function Name Found"] [data "Matched Data: session_start found within ARGS_NAMES:XDEBUG_SESSION_START: ..."] [severity "CRITICAL"]

# --- ブロック実行: 合計スコアがしきい値を超えたため、アクセスを拒否 ---
[Sun Oct 19 10:03:03 2025] [security2:error] [client 203.0.113.99] ModSecurity: Access denied with code 403 (phase 2). ... [id "949110"] [msg "Inbound Anomaly Score Exceeded (Total Score: 8)"]

# --- 最終報告: PHPインジェクション(PHPI)カテゴリで5点が付与されたことを記録 ---
[Sun Oct 19 10:03:03 2025] [security2:error] [client 203.0.113.99] ModSecurity: Warning. ... [id "980170"] [msg "Anomaly Scores: (Inbound Scores: blocking=8, ... PHPI=5, ...)"] [uri "/404.html"]

のように、Mod_Securityのログは、

  • いつ
  • どこから
  • どのような意図で

不正を試みたかという情報と

  • これをブロックした根拠
  • 最終的な結果

も物語っています。そのような物語からスクリプトは「最終的にどこからアクセスしてきたか」のIPアドレスのみを抜き出し、ファイルに加えます。

そして、このようなアクセスを行った者はブロックしても安心できません。攻撃者は

  • このパターン(XSS)は排除された。
  • と言うことはSQLが入っているのは間違いない。
  • LAMP構成か? 他に攻撃できる手口はないか?

として、手を替え品を替え次々と別手段を試みます。攻撃を試みた時点で「サイトの閲覧者」と名乗る資格はありません。興味本位や技術の確認などという弁解は聞く耳を持ちません。そして二度目の攻撃を許しません。そのため、ブラックリストにIPアドレスを加え、「次からはバッターボックスに立たせない」構成としています。

自分自身のロックアウト

このスクリプトには

EXCLUDE_IPS_FILE="${SCRIPT_BASE_DIR}/conf/exclude_ips.txt"

というフェイルセーフが含まれています。

  1. 実際のWAFの動きを確かめたい
  2. 記事の投稿時にコードが含まれていたため偽陽性に引っかかってしまった

を防ぐための配慮。

192.168.0.1
192.168.3.5

などの「ある程度固定化されている自分のアクセス元」を記すことで、この例外を設けます。

スクリプトの動き

  1. TorリストをダウンロードしてIPアドレスを抽出する。
  2. その日のログから不審なアクセスを試みたIPアドレスのみを抽出する。
  3. 抽出したIPアドレスリストを、過去のIPアドレスと照らし合わせて結合。
  4. 重複を排除する。
  5. 自分自身のロックアウトの回避処理。

を行い、「Torの出口ノード」と「実際にアクセスしてきた不審なアクセス元」を自動的に排除します。

余談という名のまとめ

最初、このシステムの名前は「一度見た(不審なアクセス)のIPアドレスを覚えて二度目は通用しない」という意味を込めて『ジョジョの奇妙な冒険 スターダストクルセイダーズ』からAnubisシステムと名付けていました。

しかし

  • 最終的に刀身を折られた
  • 残った刃も川に落ちて錆びが確定

で再起不能(Out of Commission)となったため、もっと相応しい名前はないかということで『ONE OUTS』というネーミングになりました。

その後、機能を拡張し、今の構成になっていますが、torの排除を組み込んだ時点で「そういえばこの名前の響きは(渡久地)東亜にも似る」とつながってしまったのも、自分のお気に入りのシステムの一つです。