WordPressの更新後、wp-content/upgradeを開いたら、
見覚えのないPHPファイルが残っていて不安になっていませんか?
この場所はWordPress本体、プラグイン、テーマの更新時に使われる一時作業領域です。
更新の途中で作られた正規ファイルが残ることもあれば、攻撃者が目立ちにくい置き場所として悪用することもあります。
そのため、PHPが一つあるという理由だけで感染と断定するのも、
一時ファイルだと思って無条件に削除するのも安全ではありません。
WordPressの復旧を多数手がけてきたよこやま良平です。わたしの現場経験をもとに、更新残骸を保全し、正規ファイルとマルウェアを切り分ける順番を解説します。
- wp-content/upgradeが更新時に果たす役割
- 正規の更新残骸と不審なPHPの見分け方
- 証拠を壊さない確認・隔離・復旧の順番
- 削除後にファイルが戻る場合の追跡方法
結論から言うと、更新状況の確認、証拠保全、正規配布物との比較、
ログによる生成元の特定、隔離後の再更新という順番で進めるのが安全です。
まずは削除ボタンを押さず、いつ・何のために作られたファイルなのかを確認しましょう。
WordPressのwp-content/upgradeにPHPが残る仕組み
wp-content/upgradeは、WordPressが更新パッケージを展開し、
インストール先へ移す前の作業を行うために使う一時ディレクトリです。
ここにファイルがあること自体は、直ちに改ざんを意味しません。
更新が正常終了しなかった場合は、展開途中のフォルダやパッケージ由来のファイルが残ることがあります。
更新中だけ使う作業場所である
WordPressの更新処理は、配布パッケージを取得して一時領域へ展開し、
必要なファイルをプラグイン、テーマ、またはWordPress本体の場所へコピーします。
つまりupgradeフォルダは、公開コンテンツを恒久的に置く場所ではありません。
通常時にPHPアプリケーションが常駐し、外部から呼び出され続ける必要もありません。
一方、展開されたプラグインやテーマには正規のPHPが含まれます。
更新中にその一部が見えることはあるため、拡張子だけでマルウェアとは判断できない点が重要です。
失敗した更新では残骸が残る
通信切断、PHPの実行時間制限、ディスク容量不足、権限不整合などで更新が止まると、
一時フォルダの後片付けまで到達せず、ファイルが残る場合があります。
管理画面に「更新失敗」と表示された直後で、ファイルの更新時刻も同じなら、
まずは正規更新の残骸という仮説を立てます。ただし、それだけで安全確定にはしません。
自動更新は人が操作していない時間にも動くため、覚えのない時刻でも正常な可能性があります。
WordPressの更新履歴、サーバーログ、通知メールを合わせて時系列を作る必要があります。
マルウェアが一時領域を悪用する場合もある
攻撃者は、管理者が普段見ないフォルダや、後で消えると思われやすい場所を選ぶことがあります。
upgrade配下も例外ではなく、再侵入用PHPや別ファイルを復元するローダーが置かれる可能性があります。
更新と無関係な時刻に単独PHPが作られた、外部から直接アクセスされた、
削除しても同じ内容が戻る場合は、単なる残骸より危険度が高い状態です。
- 更新操作や自動更新と作成時刻が一致するか
- 正規パッケージ内に同じ相対パスと内容があるか
- Webアクセスや別のPHPから参照された記録があるか
- 更新終了後も長期間残り続けているか
WordPressのwp-content/upgradeを削除前に保全する
不審なPHPを見つけた時は、削除より先に証拠を残すのが正解です。
先に消すと、侵入経路、作成元、再発条件を判断する手掛かりまで失うからです。
特に業務サイトでは、ファイル一つの駆除よりも、
同じ方法で再び置かれない状態を作ることが復旧の本来の目的になります。
サイト全体と対象ファイルを別々に保存する
まず現在のファイル一式、データベース、アクセスログ、エラーログを保全します。
そのうえでupgradeフォルダも、階層を保ったままDocumentRoot外の調査用領域へコピーします。
バックアップ先は、同じ公開ディレクトリ内に作らないでください。
URLから取得できる場所に不審PHPの複製を置くと、被害を増やす危険があります。
レンタルサーバーのファイルマネージャーを使う場合も、圧縮した原本をローカルへ保存し、
調査用コピーと復旧用バックアップを分けて管理します。
時刻・サイズ・所有者・ハッシュを記録する
完全パス、ファイル名、サイズ、更新時刻、所有者、グループ、パーミッションを記録します。
可能ならSHA-256ハッシュも残すと、後で同じファイルが再生成されたか比較できます。
確認例(読み取りだけ。実際のパスに合わせる)
find wp-content/upgrade -type f -print
stat wp-content/upgrade/調査対象.php
shasum -a 256 wp-content/upgrade/調査対象.phpLinux環境によってはstatやハッシュ計算コマンドの名称が異なります。
使えない場合は、サーバー管理画面の詳細表示とダウンロードした原本で代替できます。
調査対象を直接エディターで開くと、自動整形や保存日時の変更が起こることがあります。
編集機能ではなく、ダウンロードまたは読み取り専用表示を使うのが安全です。
稼働中の更新がないことを確認する
別の管理者が更新を実行している最中に隔離すると、サイトを壊す恐れがあります。
管理画面の更新表示、保守モード、Cron、自動更新通知、サーバー上の処理状況を先に確認します。
.maintenanceが残っていても、更新処理が生きているとは限りません。
表示だけで決めず、直近ログとファイル更新の動きが止まっているかを見ます。
攻撃が進行中で外部送信や追加改ざんが見える場合は、
証拠保全と並行してWAF、Basic認証、接続元制限などで被害拡大を抑えます。

- 対象ファイルと親フォルダの原本コピー
- 完全パス、時刻、サイズ、権限、所有者
- SHA-256ハッシュと画面記録
- 同時刻のアクセス・エラー・更新ログ
WordPressの更新残骸とマルウェアを見分ける
見分ける時は、名前、内容、配布元、生成時刻、呼び出し元の五つを組み合わせます。
どれか一つの特徴だけで白黒を決めると、正常ファイルの誤削除や感染の見逃しにつながります。
最も強い確認材料は、公式配布パッケージに同じファイルがあり、
内容のハッシュまで一致することです。見た目が似ているだけでは十分ではありません。
正規パッケージと相対パスを比較する
残骸のフォルダ名から、どのプラグインやテーマの更新だったか推測できる場合があります。
同じバージョンの公式ZIPを安全な端末へ取得し、展開後の相対パスと内容を比較します。
WordPress公式ディレクトリ外の有料製品や独自開発テーマは、
配布元の正規パッケージを用意します。検索で見つけた非公式ZIPを比較元にしてはいけません。
比較先に同名ファイルがない、同名でも内容が大きく異なる、
製品とは無関係な通信先や管理機能が含まれる場合は、要調査として扱います。
PHPの中身を機能単位で確認する
短いランダム名、画像に似せた二重拡張子、長い難読化文字列、
外部入力をそのまま実行する処理は、不審度を上げる材料になります。
eval、base64_decode、gzinflateなどはマルウェアで悪用されますが、
正規製品にも含まれることがあるため、関数名を見つけただけで削除してはいけません。
POSTやCookieから命令を受ける、任意ファイルを書き込む、管理者を追加する、
別URLへ接続してコードを取得する、といった処理のつながりを読み取ります。
文字列の一次確認例(検出だけで感染確定にはしない)
grep -RInE 'eval[[:space:]]*\(|base64_decode|gzinflate|shell_exec|assert[[:space:]]*\(' wp-content/upgrade
grep -RInE '\$_(POST|GET|COOKIE|REQUEST)' wp-content/upgrade難読化されていて安全に読めない場合は、対象をブラウザやPHPで実行せず、
原本を隔離したまま専門家へ解析を依頼してください。
アクセスログと他ファイルの参照を照合する
対象PHPへのHTTPアクセスがあれば、時刻、接続元IP、User-Agent、参照元、応答コードを確認します。
外部から直接200応答を返しているなら、更新残骸よりもバックドアを疑う根拠が強くなります。
ただし403や404でも安全とは限りません。別のPHPからincludeされる、
CronやCLIから実行される、同じサーバーの別サイトから呼ばれる可能性があるからです。
ファイル名やハッシュを、WordPress全体、Cron設定、サーバーの定期実行、
アクセスログ、エラーログで検索し、作成元と利用経路をつなげます。
更新時刻の前後を一本の時系列にする
自動更新通知、管理者の操作、ZIP取得、展開、エラー、PHP作成、外部アクセスを、
同じタイムゾーンにそろえて並べると、正常更新か攻撃かを判断しやすくなります。
サーバー時刻とWordPressの表示時刻がずれている場合は、先に差を補正します。
数時間のずれを見落とすと、無関係なアクセスを生成元だと誤認することがあります。
- 公式パッケージに存在しないPHPである
- 更新と無関係な時刻に作成・変更されている
- 外部入力の実行や追加ファイル作成を行う
- 外部アクセス、Cron、別PHPから呼び出されている
- 隔離後に同じハッシュのファイルが再生成される
WordPressのwp-content/upgradeを安全に隔離・復旧する
不審ファイルが確認できたら、単体削除ではなく、
更新の停止、隔離、正規配布物からの再構築、侵入経路の修正までを一つの作業として進めます。
画面が直った時点で終えると、別のバックドアや定期実行から同じファイルが戻ることがあります。
復旧は「表示が戻ること」ではなく「不正な生成元がなくなること」まで確認して完了です。
動作中の更新を止めて一時領域を隔離する
更新処理が動いていないことを確認したら、upgrade配下をDocumentRoot外へ移し、
Webから直接実行できない状態にします。原本は削除せず、調査用として保管します。
隔離の単位は、不審PHPだけではなく同時刻に作られた周辺ファイルも含めます。
ローダーだけを消してペイロードを残す、または逆の状態を避けるためです。
ただしwp-content/pluginsやthemesの稼働中フォルダまで、
upgradeと間違えて一括削除しないよう、完全パスを二重に確認してください。
公式配布元から更新をやり直す
一時領域を空にした後は、ディスク容量、所有者、書き込み権限、PHP制限を確認し、
公式管理画面または信頼できる配布元から対象製品を再更新します。
不審ファイルを含む残骸から、必要そうなPHPだけを選んで戻してはいけません。
設定値やユーザー作成データを保全し、プログラム本体は正規パッケージで置き換えます。
独自改修がある場合は、感染疑いの環境を正として差分を戻さず、
既知の正常なリポジトリや保全済みソースと比較して必要な変更だけを再適用します。
upgrade以外の持続化ポイントも調べる
upgrade配下のPHPは結果であり、原因が別の場所にあることが少なくありません。
管理者ユーザー、mu-plugins、通常プラグイン、テーマ、uploads、WordPressコアも確認します。
さらに.user.ini、.htaccess、wp-config.php、PHP設定、
WP-Cron、サーバーCron、SSH鍵、FTPアカウント、Application Passwordsも調査対象です。
同一サーバーに複数サイトがある場合は、別WordPressや古いCMSも含めて確認します。
一つのサイトだけ清掃しても、書き込み可能な別環境から再感染するためです。
認証情報と脆弱性の入口を閉じる
管理者、サーバー、SFTP、SSH、データベース、連携サービスの認証情報を見直し、
必要に応じて安全な端末から変更します。感染端末で変更すると新しい情報まで盗まれる恐れがあります。
WordPress本体、プラグイン、テーマを対応可能な安全版へ更新し、
使っていない製品やアカウントは、保全と依存関係の確認後に整理します。
WAFやセキュリティプラグインは再発防止の一部ですが、
すでに置かれたバックドアを自動的にすべて消す仕組みではありません。

- 更新停止と被害拡大防止を確認する
- サイト全体・ログ・upgrade原本を保全する
- 公式配布物とログで正規・不正を判定する
- 一時領域を隔離し正規パッケージで再更新する
- 持続化ポイント・認証情報・脆弱性を修正する
- 再生成と再侵入がないことを継続確認する
WordPressのupgrade復旧後に再発を確認する
復旧後は、upgradeフォルダが空になったことだけで完了にせず、
正規更新が通り、不審PHPが戻らず、サイトの主要機能が正常であることを確認します。
再発確認を省くと、数時間後のCronや翌日の自動処理でファイルが復元されても気づけません。
直後、一定時間後、次回更新後の三段階で見ると原因を切り分けやすくなります。
テスト更新で正常な作業経路を確認する
可能ならステージング環境で、信頼できる小規模な更新を一つ実行します。
upgradeに一時ファイルが作られ、処理後に片付くまでを観察します。
本番で試す場合は、直前バックアップと復元手段を用意し、
アクセスの少ない時間に対象を限定して行います。複数製品の一括更新は切り分けを難しくします。
更新が再び失敗するなら、感染と決めつけず、容量、権限、所有者、通信、
PHPメモリ、実行時間、保守モード、セキュリティ機能による遮断を確認します。
同じハッシュが戻るか監視する
隔離した不審PHPのファイル名とSHA-256を基準に、
WordPress全体と同一アカウント配下を検索し、複製や再生成を確認します。
同じ内容が戻った時は、戻った時刻の直前に動いたHTTPリクエスト、Cron、ログイン、
ファイル変更を照合します。再生成されたファイルだけを繰り返し消しても解決しません。
名前だけ変えて戻るマルウェアもあるため、ハッシュ一致だけでなく、
外部入力、難読化、書き込み先、通信先といった機能の類似も確認します。
PCとスマホの主要機能まで確認する
トップページだけでなく、管理画面ログイン、投稿表示、検索、フォーム、決済、
会員機能、画像表示、メール送信など、そのサイトに必要な操作を確認します。
攻撃者は端末、接続元、検索経由などの条件で不正表示を切り替えることがあります。
PCとスマホ、ログイン中と未ログイン、主要な流入経路を分けて見てください。
ブラウザキャッシュやCDNに古い不正応答が残る場合もあります。
サーバー原本が正常か確認した後でキャッシュを消し、再取得して表示を比べます。
数日間はログと変更を継続して見る
復旧直後だけでなく、少なくとも次回自動更新や定期処理をまたいで監視します。
サイトの更新頻度や被害範囲に応じて、監視期間を長くしてください。
新規PHP、管理者追加、Cron変更、外部通信、ログイン失敗の急増を確認し、
異常があれば復旧完了時刻を基準に時系列を作り直します。
- 正規更新がエラーなく完了する
- 不審PHPや同等機能のファイルが再生成されない
- 管理者・Cron・設定に不正変更がない
- PC・スマホ・未ログイン表示が正常である
- 一定期間のログに再侵入の痕跡がない
WordPressのwp-content/upgradeに関するよくある質問
WordPressのwp-content/upgradeは由来を確認して復旧する
wp-content/upgradeにPHPがあるだけでは、正規の更新残骸かマルウェアかを断定できません。
更新との時刻一致、公式パッケージとの比較、内容、ログ、呼び出し元を順番に確認します。
不審度が高くても、先に削除せず、原本・属性・ハッシュ・ログを保全してください。
その後に一時領域を隔離し、正規配布物から再更新して、別の生成元を取り除きます。
最後に正規更新の成功、再生成の有無、管理者やCronの不正変更、
PC・スマホ表示、一定期間のログまで確認すれば、再感染を見逃しにくくなります。
wp-content/upgradeの不審PHPを自分で判断できない時は

更新残骸かバックドアか判断できない、削除しても不審PHPが戻る、
サイト全体の感染範囲がわからない場合は、クイックレスキューへご相談ください。
- upgrade配下のPHPが安全か判断できない
- 削除しても同じ不審ファイルが戻ってくる
- 更新失敗とマルウェア感染を切り分けたい
- 証拠を残してWordPress全体を復旧したい
- 再感染しない状態まで確認してほしい
- 万一復旧できない場合やマルウェア駆除できない場合は全額返金保証で安心
- 90日間再感染保証・動作保証で安心
- 初期費用・調査費用0円で安心






