あなたのWebサーバーログは、攻撃を受けたかどうかをすでに知っています。weblogcheckerはそれを読み取ります。
phpscan はあなたのPHPが露出しているかどうかを教えてくれます。phpscan hunt はWebルート内のシェルを検索します。weblogcheckerは3つ目の問い — 実際に誰かがそれらを使ったのか? — に、ほとんどのサイトがすでに持っていて誰も読まない唯一の記録、すなわちアクセスログから答えます。
あなたが所有する Apacheおよびnginxのアクセスログをストリーミング処理し、重要なやり取り — リクエストに応答するWebシェル、リダイレクトで終わるブルートフォースのバースト、200を返したエクスプロイトパターン — を見つけ出し、それぞれを重大度、信頼度、証拠としての実際のログ行、そしてそれに対して何をすべきかとともに報告します。
weblogchecker analyze /var/log/apache2/access.log
終了コード: 0 = インジケーターなし、1 = インジケーター検出、2 = 使用法エラー。
機械可読な出力には --format json を追加し、対象期間を絞り込むには
--since 2026-10-01 を追加します。.gz ログは直接読み込まれ、- は標準入力から読み込みます。
0.2.0 の新機能 — ベースライン差分。 シグネチャリストは、すでに名前が 知られているシェルしか把握できません。あなたの サイトに侵入するシェルは ランダムな名前を持っています。同じサイトの信頼できる過去のログを weblogchecker に 渡すと、以前には存在しなかった実行ファイルを報告します:
weblogchecker analyze access.log --baseline access.log.last-month
ログに初めて出現するすべての実行可能パス(.php、.phtml、.cgi、.asp、.jsp など)は、ログのみから得られる5つの弱いシグナル(2xx/3xx で応答、POST/PUT が使用、リファラなし、最大2つの IP からのアクセス、アップロード/キャッシュ/一時ディレクトリ配下に存在)でスコアリングされ、シグナル、カウント、ログ行を証拠として NEW として報告されます。初回検出だけでは低重大度の注記にとどまり、重大度はシグナルが積み重なったときにのみ上昇します(詳細は後述)。そのため、先週インストールしたプラグインがインシデントとして扱われることはありません。
PyPI から1行でインストールできます(Python 3.11 以上、標準ライブラリのみ — 依存関係ゼロ):
pip install weblogchecker
PyPIでの初回リリースは保留中です。 PyPIのトラステッドパブリッシャーが 設定されるまでは、同一のコードをGitHubからインストールしてください:
pip install git+https://github.com/PHPatch/weblogchecker.git(または以下にある署名済みリリースのtarballをダウンロードしてください)。上記のpip install weblogcheckerの行は、PyPIでの初回リリースが公開され次第機能します。
「externally-managed-environment」エラーで拒否されるシステム (Debian/UbuntuやHomebrewのPython)では、代わりにpipxを使用してください:
python3 -m pip install --user pipx # if you don't have pipx yet
pipx install weblogchecker
署名済みリリース(sdist + wheel + PGP署名 + SBOM)は
GitHub releases pageにあります。
pgp-key.asc の鍵で署名を検証してください — フィンガープリントは
BAA1 586A AD37 18C0 CE41 D288 FE23 A624 54E3 5307 です。SECURITY.md を参照してください。
| ログ内のパターン | 重大度 / 信頼度 | 重要な理由 |
|---|---|---|
| 既知のウェブシェル(c99、r57、FilesMan、b374k、WSO)が 2xx を返す | high / high | シェルが存在し、リクエストを処理した |
| 同じ名前がプローブされたが 404/403 | low / low | 誰かが探ったが、何も見つからなかった — 警告ではなく文脈情報 |
eval-stdin.php(phpunit)が応答 | high / high | 2026年10月の php2shell ウェーブで使われた UnitTest シェルが、POST されたコードを実行する |
/uploads/、/media/、/files/… 内の実行可能ファイル(.php など)が応答、特に POST | high / high | アップロードディレクトリは決してコードを実行してはならない |
| 静的ファイル(.jpg、.css…)への POST/PUT が 2xx で応答 | high / medium | ブラウザは画像に POST しない。「画像」はしばしばスクリプトである |
URI 内のエクスプロイトパターン(トラバーサル、eval(、php://、長い base64 トークン)が 2xx で応答 | high / medium | 攻撃が成功した可能性がある |
| 同じパターンがブロックされた / 404 | low / low | バックグラウンドノイズ。キャンペーンの文脈としてのみ有用 |
| wp-login.php / xmlrpc.php へのブルートフォースバースト(10分間に20回以上の POST) | medium / medium | 単一 IP、人間離れしたペース |
| そのバースト内で繰り返し失敗した後の 302 | high / medium | 正しいパスワードの形 — 乗っ取りの可能性 |
| スキャナーのユーザーエージェント(sqlmap、nuclei、nikto…) | low / low | 情報提供のみ。スキャンは侵害ではない |
--baseline ログに存在しない実行可能パスがリクエストに応答 | low → high / ≤ medium | どのブロックリストも知らない未知の名前のシェル。重大度は POST、リファラーの欠如、少数の IP、アップロードディレクトリと積み重なる |
すべての検出クラスには対処テキストが付属します。ファイルを隔離し、認証情報をローテーションし、その IP が触れたすべてをレビューしてください。ウェブシェルの検出結果は、コンパニオンツール — phpscan hunt(pip install phpscan、
github.com/PHPatch/phpscan)— を指し示します。これは、これらのログパターンが指し示すシェルをウェブルート自体でスキャンします。
このツールは phpscan と同じドクトリンのもとで構築されました:
解析は行ストリーミング方式です。ファイルがメモリに読み込まれることはなく、集約では検出結果ごとに最大5行の証拠行を保持します。このプロジェクトのフィクスチャジェネレーター(366,306行、72 MBの現実的な統合ログ)で計測したところ、控えめなVM上で7.6秒、ピークRSS 12.8 MBでした。2 GBのログでもメモリ使用量は同じで、時間は比例して増加します。
$ weblogchecker analyze access.log
weblogchecker 0.2.0 - access-log compromise analysis
Log: access.log
Lines read: 13 | parsed: 13 | unparseable (skipped): 0
Indicators found. These are leads for investigation, not proof of
compromise: work through the findings in severity order ...
SUMMARY: 10 findings (4 high, 1 medium, 5 low) across 9 incidents, 2 IPs flagged
INCIDENT TIMELINE (grouped by IP + path):
[HIGH] 198.51.100.66 /wp-content/uploads/2026/10/c99.php
classes: webshell-access, exec-in-upload-dir | requests: 6 | ...
...
1. [high severity / high confidence] Known webshell filename answered a request
198.51.100.66 /wp-content/uploads/2026/10/c99.php - 3 request(s), ...
| 198.51.100.66 - - [28/Oct/2026:03:13:40 +0000] "GET /wp-content/..." 200 ...
Remediation: Treat the named file as a live webshell until you have
proven otherwise. Locate it in the webroot and quarantine it ...
hunt)すべて無料、すべてオープンソース、いずれもエクスプロイトプローブを送信しません。
MIT — LICENSE を参照してください。セキュリティ報告:SECURITY.md を参照してください。