PHP2Shellの痕跡をログで調べる方法:見るべきログ、遡る期間、grepコマンド
PHP2Shellの痕跡をログで調べる方法。10月17日まで遡り、Nginx・Apache・PHP-FPM・WAFのログを読み取り専用のgrepで確認し、先に証拠を保全します。
PHP2Shellの痕跡をログで調べる方法:見るべきログ、遡る期間、grepコマンド
PHP2Shellの痕跡をログで調べるなら、パッチ公開日の10月21日ではなく、Amazonが最初に攻撃の試みを観測した 2026年10月17日 まで遡ります。対象はWebサーバー、PHP-FPM、PHP、WAF、アプリのログで、grepの前にコピーしてハッシュ値を記録してください。logrotateで消えたログはサーバーからは戻りません。
なお2026年10月23日に確認した情報源には、攻撃成功を示すアクセスログのシグネチャも、PHP2Shell固有のWebシェルのファイル名・パス・ハッシュもありませんでした。脆弱性の内容はPHP2Shellの脆弱性の詳細をご覧ください。
どこまで遡ればよいか
Amazonは公開4日前の10月17日にハニーポットで攻撃の試みを観測し、この日からの調査を勧めています。ログごとにタイムゾーンを確認してから突き合わせてください。たとえばNginxとApacheのアクセスログは既定でサーバーのローカル時刻をオフセット付き(例:+0700)で記録し、UTCのサーバーでは日付がずれます。余裕を見て10月16日から確認することをおすすめします。
この1週間分が残っていると決めつけず、今すぐ保存状況を確認してください。logrotateはrotateやmaxageを超えたファイルを削除します(.gzはzgrepで読めます)。消えた世代もバックアップや転送先の収集基盤に残っている場合があります。
タイのコンピューター犯罪法第26条の対象事業者には90日以上の通信記録保存義務があります(同法のログ保存)。
ログはどこにあり、何がわかるか
| ログ | 場所 | わかること | 限界 |
|---|
| Nginx アクセス/エラー | 設定のaccess_log、error_log | メソッド、パス、ステータス | combined形式はボディとContent-Typeを記録しない |
| Apache アクセス/エラー | Debian/Ubuntu:/var/log/apache2/、RHEL/Fedora:/var/log/httpd/ | mod_phpでerror_log未設定かつlog_errors有効ならPHPのエラーも | mod_phpは最も高リスク。優先して確認 |
| PHP-FPM | php-fpm.confとプール設定 | 時間超過で終了されたワーカー | プールのaccess.logはデフォルト無効 |
| PHPエラーログ | php.iniのerror_log | メモリ枯渇などのFatal error | log_errorsオフなら新規エラーは自動記録されない(既存分や他のログは残る) |
| WAF/プロキシ | 製品ごと | ボディを記録していれば見える | 設定次第 |
| アプリのログ | フレームワークごと | アップロード等。記録していればボディ由来の情報も | アプリごとに異なる |
| ファイアウォールの送信ログ | FW/セキュリティグループ | Webサーバーの接続先 | 事前の有効化が必要 |
台数が多ければ、収集範囲、1日の取り込み量、保存期間をzcrLogとzcrSIEMの公開価格と比べてください。
実際のパスは設定で確認します。Nginxはaccess_log/error_log(include先も)、ApacheはCustomLog/ErrorLog(/etc/apache2または/etc/httpd配下)、PHP-FPMはerror_log等です。
ステップ0:調べる前に証拠を保全する
NIST SP 800-86は、ログを含め原本と取得コピーのメッセージダイジェストを比べるよう勧めています。現行とローテーション済みのファイルを一度に取得し、書き込み中のファイルは取得時刻を記録します。コピーはサーバー外で調べます。ファイル・プロセス・通信の確認はPHP2Shellのインシデント対応で扱います。
根本策は書き込み時点でログを外へ送ることで、syslogを受信し90日〜2年保存、SHA-256で完全性をチェックするzcrLogの役割です。
ログで確認できる兆候
以下は既存ログ(のコピー)を検索するだけのコマンドで、combined形式(4列目時刻、6列目メソッド、7列目パス、9列目ステータス)が前提です。WINは時刻フィールドだけを10月16〜23日で照合し、URL等の日付には反応しません。
WIN='^[^ ]+ [^ ]+ [^ ]+ \[(1[6-9]|2[0-3])/Oct/2026:'
1. PHPスクリプトへのPOST ― AWSによると原因はPHPがアプリより先に行うmultipart/form-dataの処理で、Sansecも注意を促しています。Content-Typeは記録されないため、メソッドとパスで見ます。
zgrep -hE "$WIN" access.log* \
| awk '$6 == "\"POST" {p=$7; sub(/\?.*/,"",p); print p}' | sort | uniq -c | sort -rn | head -30
2. 特定エンドポイントでの4xx/5xxの急増 ― AWSは、攻撃者が値を送れるルートで繰り返されるエラーやタイムアウトの確認を勧めています。
zgrep -hE "$WIN" access.log* \
| awk '$9 ~ /^[45]/ {p=$7; sub(/\?.*/,"",p); print $9, p}' | sort | uniq -c | sort -rn | head -30
3. 1〜2個のIPからしかアクセスされないPHPパス ― CISAは、Webシェルは通常設置者しかアクセスしないため頻度分析が有効だとしています(NSAは誤検知に注意)。実IPを記録する設定がなければ$1はプロキシのアドレスかもしれません。
zgrep -hE "$WIN" access.log* \
| awk '{p=$7; sub(/\?.*/,"",p); if (p ~ /\.php$/) print $1, p}' | sort -u \
| awk '{print $2}' | sort | uniq -c | sort -n | head -30
4. アップロード用フォルダ内の.phpへのリクエスト ― CISAが挙げるWebルート内の不審なファイルの兆候です(フォルダ名はアプリに合わせて)。
zgrep -hE "$WIN" access.log* \
| awk '{p=$7; sub(/\?.*/,"",p); if (p ~ /\/(uploads?|cache|tmp)\// && p ~ /\.php$/) print $6, p, $9}' \
| sort | uniq -c | sort -rn
5. メモリ枯渇とタイムアウトの繰り返し ― Sansecはメモリ不足によるFatal errorを挙げています。前2つはPHPエンジン、3つ目はPHP-FPMのワーカー強制終了のメッセージです(php-srcより)。
zgrep -HE 'Allowed memory size|Maximum execution time|execution timed out' \
error.log* php-fpm.log*
-Hでファイル名を残し、ファイルが無い・読めないというエラーも見逃さないでください。注目は10月16〜17日以降の特定ルートへの集中です。memory_limit=-1で実際に動くワーカーでは「Allowed memory size」だけが出なくなります。タイムアウトは別で、PHP-FPMのrequest_terminate_timeoutは独立した設定です。
6. 子プロセスと外部接続 ― AmazonとカナダのCCCSは、PHPに関連する想定外のプロセスや送信接続の確認を勧めています。過去分はEDRやファイアウォールの送信ログがある場合のみ見えます(FirewallのSyslog送信設定)。
7. PHP_SESSION_UPLOAD_PROGRESSはボディの中 ― Amazonはこの文字列を含むPOSTを探すよう勧めています。デフォルトで有効なアップロード進捗機能のフィールド名で、combined形式には残りません。ボディを記録したWAF・プロキシやアプリのログなら見える可能性があります(WAFでどこまで防げるか)。
zgrep -F -c -- 'PHP_SESSION_UPLOAD_PROGRESS' '/path/to/body-capture.log.gz'
パスは実際のファイルに置き換えてください。-cは一致した行数で、リクエスト数や攻撃回数ではありません。正規のフォームも使う名前なので、ヒットは侵害の証拠ではありません。Amazonが公開した送信元IPは共有の匿名化ネットワークで、遮断ではなく調査の手がかりです。
この方法の限界
2026年10月23日に確認した情報源には、攻撃成功を示すアクセスログのシグネチャも、PHP2Shell固有のWebシェルのファイル名・パス・ハッシュもなく、見つかるのは「疑わしいもの」です。AWSも、エラーがないことは安全の証拠ではないとしています。侵害の可能性があるサーバー上のログは改ざんされ得るため、OWASPは早めの読み取り専用コピーを勧めています。Apacheの文書のとおり、ログには未エスケープのクライアントデータ(制御文字を含む)が入り得るため、生ログは慎重に扱ってください。
異常が見つかったら調査を止め、PHP2Shellのインシデント対応に移ってください。
次回に備えたログ設定
# Nginx(http ブロック):Content-Type、リクエストサイズ、処理時間を追加
log_format hunt '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" "$http_user_agent" '
'"$content_type" $request_length $request_time';
access_log logs/access_hunt.log hunt;
# Apache:%I には mod_logio が必要
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-agent}i\" \"%{Content-Type}i\" %I %D" hunt
CustomLog "logs/access_hunt_log" hunt
PHPではlog_errors=On、error_reporting=E_ALL、有効なerror_logを設定し(AWS推奨)、PHP-FPMではaccess.logを有効にします。
無料のツールでどこまでできるか
数台ならzgrepとawkで手元の証拠を無料で検索・集計できますが、攻撃成功の証明や、未記録のボディ・過去のプロセスや通信の再現はできません。
ログを外へ送れば今後の消失やサーバー上の証拠への依存は減りますが、削除済みの記録は戻らず、侵害されたサーバーのログが完全で正しい保証もありません。Nginxはsyslog:プレフィックス(既定UDP 514)で送れます。PHPとPHP-FPMのerror_log = syslogはローカルのsyslogに渡るだけで、外部転送には別途設定が要ります。受信先の一つが、มศอ. 4003.1-2560 認証のコンプライアンス向けログ保存システムzcrLogです。今回問題になったのは、10月17日のログがまだ残っているかどうかでした。古いログをアーカイブに保管して復元できるため、次回は送っておいた生ログの検索から始められます。PHPのパッチ適用の代わりにはなりません。
一括検索はzcrSIEMの役割です。zcrLogなしで導入でき、独自条件やSigmaの検知ルールと、質問文をクエリに変換し実行前に確認できる脅威ハンティング機能があります。兆候をルールやクエリにできるのは、そのイベントを収集している場合だけです。デモページとAI-Assisted Threat Huntingもご覧ください。
zcrはソフトウェアを提供し、実際の調査作業はパートナーを通じて行います。
📞 無料相談
関連記事
関連製品
zcrLog ・ zcrSIEM ・ 料金 ・ デモ
出典
- Amazon Threat Intelligence identifies PHP2Shell exploitation prior to public disclosure in MadPot — AWS Security Blog、2026年10月21日:10月17日の初観測、
PHP_SESSION_UPLOAD_PROGRESS、匿名化ネットワークのIP
- Using AWS WAF to apply mitigations for PHP2Shell — AWS Security Blog、2026年10月22日更新:multipartが原因、ルート上の繰り返しエラー、エラーがないことは証拠ではない、エラーログ設定
- PHP2Shell — Sansec、2026年10月22日更新
- AL26-026 Critical vulnerabilities impacting PHP — カナダ・サイバーセキュリティセンター、2026年10月21日
- PHP security release 8.5.12, 8.4.27, 8.3.36, 8.2.35 — php.net、2026年10月20〜21日
- Compromised Web Servers and Web Shells — CISA
- Mitigating Web Shells — NSA
- NIST SP 800-86 — 原本とコピーのダイジェスト比較(ログファイルを含む)、稼働中のファイルは取得中に変わり得る
- OWASP Logging Cheat Sheet
- Nginx:ngx_http_log_module、error_log、コアモジュールの変数、Logging to syslog
- Apache:Log Files、mod_log_config、Distros default layout
- PHP:PHP-FPM設定、エラー処理の設定、memory_limit、セッションの設定、php-srcソースコード(zend_alloc.c、zend_execute_API.c、fpm_request.c)
- manページ:logrotate、zgrep、grep、uniq、awk (POSIX)
- Computer-Related Crime Act B.E. 2550(2560年改正を含む英訳) — タイ・デジタル経済社会省:第26条