筆者に限らず、Webサーバを運用すると必ずと言っていいほど見かけるアクセスがあります。
GET /wp-login.php
GET /wp-admin/
GET /wp-config.php
GET /config.php
GET /.env
言わずと知れたWordpress/laravel管理画面のURLやDB情報などが飛び交う重要ファイル。
「うちはWordPressじゃないんだけど?」
と思う人も多いでしょう。実際、筆者のVPSもWordPressを詰んでいません。(公開しているWordpressは専用サービスを借りています)
それでも毎日のように飛んできます。では、攻撃者は何を考えて「見たらアクセスするのが礼儀」レベルでアクセスしてきているのでしょうか。
インターネットは「総当たり」の世界
多くの人は、「誰かが自分のサイトを狙っている」と考えがちです。
しかし実際には逆です。攻撃者は運営元をまず見ません。彼らが見ているのは
「世界中に存在する何千万台ものWebサーバ」
です。ですから
WordPress
Laravel
Node.js
Next.js
Joomla
Drupal
といった利用者が非常に多い技術から順番に試します。
WordPressが最優先になる理由
WordPressは世界中のWebサイトのかなりの割合を占めています。つまり、攻撃者は
「WordPressだけ狙う」
だけでも膨大な成果が期待できます。さらに
- 古いプラグイン
- 更新されていないテーマ
- 初期設定のままの管理画面
なども珍しくありません。攻撃者から見ると、WordPressは「狙う価値が非常に高い標的」です。
そして、Wordpressは
/wp-config.php
/wp-config-sample.php
/wp-login.php
など、「アキレス腱となるファイル」がほぼ決まっているという「やりやすい」材料です。
実際のログ
以下は実際に筆者のサーバへ届いたログを、IPアドレスやホスト名をダミー化したものです。
なぜ、この手の攻撃者情報を晒さないかというと「テロリストに名前を与える必要はない」という哲学と、「誰がやったかは問題ではない。私が興味があるのは何をしたかである」という考えです。
[Mon Jul 06 01:06:34.509624 2026] [security2:error] [pid 111111:tid 222222222222222] [client 192.0.2.1:40372] [client 192.0.2.1] ModSecurity: Warning. Matched phrase "config.php" at REQUEST_FILENAME. [file "/usr/share/modsecurity-crs/coreruleset/rules/REQUEST-930-APPLICATION-ATTACK-LFI.conf"] [line "150"] [id "930130"] [msg "Restricted File Access Attempt"] [data "Matched Data: config.php found within REQUEST_FILENAME: /config.php"] [severity "CRITICAL"] [ver "OWASP_CRS/4.28.0"] [tag "application-multi"] [tag "language-multi"] [tag "platform-multi"] [tag "attack-lfi"] [tag "paranoia-level/1"] [tag "OWASP_CRS"] [tag "OWASP_CRS/ATTACK-LFI"] [tag "capec/1000/255/153/126"] [hostname "example.com"] [uri "/config.php"] [unique_id "DUMMY_UNIQUE_ID_000001AAAAA"]
[Mon Jul 06 01:06:34.510601 2026] [security2:error] [pid 111111:tid 222222222222222] [client 192.0.2.1:40372] [client 192.0.2.1] ModSecurity: Access denied with code 403 (phase 2). Operator GE matched 5 at TX:blocking_inbound_anomaly_score. [file "/usr/share/modsecurity-crs/coreruleset/rules/REQUEST-949-BLOCKING-EVALUATION.conf"] [line "233"] [id "949110"] [msg "Inbound Anomaly Score Exceeded (Total Score: 5)"] [ver "OWASP_CRS/4.28.0"] [tag "anomaly-evaluation"] [tag "OWASP_CRS"] [hostname "example.com"] [uri "/config.php"] [unique_id "DUMMY_UNIQUE_ID_000001AAAAA"]
[Mon Jul 06 01:06:34.511256 2026] [security2:error] [pid 111111:tid 222222222222222] [client 192.0.2.1:40372] [client 192.0.2.1] ModSecurity: Warning. Unconditional match in SecAction. [file "/usr/share/modsecurity-crs/coreruleset/rules/RESPONSE-980-CORRELATION.conf"] [line "119"] [id "980170"] [msg "Anomaly Scores: (Inbound Scores: blocking=5, detection=5, per_pl=5-0-0-0, threshold=5) - (Outbound Scores: blocking=0, detection=0, per_pl=0-0-0-0, threshold=4) - (SQLI=0, XSS=0, RFI=0, LFI=5, RCE=0, PHPI=0, HTTP=0, SESS=0, COMBINED_SCORE=5)"] [ver "OWASP_CRS/4.28.0"] [tag "reporting"] [tag "OWASP_CRS"] [hostname "example.com"] [uri "/__jailhouse_lock/topgear.html"] [unique_id "DUMMY_UNIQUE_ID_000001AAAAA"]
[Mon Jul 06 01:06:40.426322 2026] [security2:error] [pid 333333:tid 444444444444444] [client 192.0.2.1:35882] [client 192.0.2.1] ModSecurity: Warning. Matched phrase "wp-config-" at REQUEST_FILENAME. [file "/usr/share/modsecurity-crs/coreruleset/rules/REQUEST-930-APPLICATION-ATTACK-LFI.conf"] [line "150"] [id "930130"] [msg "Restricted File Access Attempt"] [data "Matched Data: wp-config- found within REQUEST_FILENAME: /wp-config-sample.php"] [severity "CRITICAL"] [ver "OWASP_CRS/4.28.0"] [tag "application-multi"] [tag "language-multi"] [tag "platform-multi"] [tag "attack-lfi"] [tag "paranoia-level/1"] [tag "OWASP_CRS"] [tag "OWASP_CRS/ATTACK-LFI"] [tag "capec/1000/255/153/126"] [hostname "example.com"] [uri "/wp-config-sample.php"] [unique_id "DUMMY_UNIQUE_ID_000002BBBBB"]
[Mon Jul 06 01:06:40.427672 2026] [security2:error] [pid 333333:tid 444444444444444] [client 192.0.2.1:35882] [client 192.0.2.1] ModSecurity: Access denied with code 403 (phase 2). Operator GE matched 5 at TX:blocking_inbound_anomaly_score. [file "/usr/share/modsecurity-crs/coreruleset/rules/REQUEST-949-BLOCKING-EVALUATION.conf"] [line "233"] [id "949110"] [msg "Inbound Anomaly Score Exceeded (Total Score: 5)"] [ver "OWASP_CRS/4.28.0"] [tag "anomaly-evaluation"] [tag "OWASP_CRS"] [hostname "example.com"] [uri "/wp-config-sample.php"] [unique_id "DUMMY_UNIQUE_ID_000002BBBBB"]
[Mon Jul 06 01:06:40.428290 2026] [security2:error] [pid 333333:tid 444444444444444] [client 192.0.2.1:35882] [client 192.0.2.1] ModSecurity: Warning. Unconditional match in SecAction. [file "/usr/share/modsecurity-crs/coreruleset/rules/RESPONSE-980-CORRELATION.conf"] [line "119"] [id "980170"] [msg "Anomaly Scores: (Inbound Scores: blocking=5, detection=5, per_pl=5-0-0-0, threshold=5) - (Outbound Scores: blocking=0, detection=0, per_pl=0-0-0-0, threshold=4) - (SQLI=0, XSS=0, RFI=0, LFI=5, RCE=0, PHPI=0, HTTP=0, SESS=0, COMBINED_SCORE=5)"] [ver "OWASP_CRS/4.28.0"] [tag "reporting"] [tag "OWASP_CRS"] [hostname "example.com"] [uri "/__jailhouse_lock/topgear.html"] [unique_id "DUMMY_UNIQUE_ID_000002BBBBB"]
要約するとこんな形です。
[client 192.0.2.1]
GET /config.php
REQUEST-930
Restricted File Access Attempt
↓
REQUEST-949
Inbound Anomaly Score Exceeded
↓
HTTP 403
数秒後、
GET /wp-config-sample.php
REQUEST-930
Restricted File Access Attempt
↓
REQUEST-949
Inbound Anomaly Score Exceeded
↓
HTTP 403
となりました。
このログから読み取れること
筆者がこのログに着目したのは
config.php
↓
wp-config-sample.php
という順番です。これは、
- 「PHPかな?」
- 「WordPressかな?」
という判定ルーチンそのもの。人間ならこの順番にはなりません。典型的な自動スキャナです。
さらに注目したい点
以前紹介した、ModSecurityのカスタム設定。
HostヘッダーがIPアドレスなら遮断
Hostヘッダーが存在しなければ遮断
というカスタムルール。今回は一切反応しませんでした。
つまり攻撃者は
- DNSで名前解決
- 正しいHostヘッダーを付与
- 普通のHTTPリクエスト
を組み立てています。IPアドレスへ適当に投げるだけのBOTより一段階上です。
そのためにModSecurityは通常の検査を実施し、
REQUEST-930
↓
REQUEST-949
↓
403
という流れで処理しています。
筆者が「教材」と述べた面白い理由
このログには、
OWASP CRSの典型的な動きがそのまま残っています。
CRS:930
危険なリクエストを検知
↓
CRS:949
異常スコアが閾値を超えた
↓
処理:403アクセス拒否
つまり、「ModSecurityがどのように判断して遮断するのか」を学ぶ教材として非常に分かりやすいログです。
そして一番重要なこと
今回の攻撃は、筆者個人を狙ったものではありません。世界中のWordPressサイトを探す途中で、たまたま筆者のLAMPサーバへ届いただけです。(何せ、動いているのは全く別のCMSです)
しかし、その「たまたま」からでも学べることはたくさんあります。
ログには、
- 攻撃者が何を探しているのか
- どんな順番で調べるのか
- WAFがどこで判断したのか
がすべて残っています。
サーバ管理者にとってログは「嫌なもの」ではなく、攻撃者の思考を無料で教えてくれる教材です。