2026年9月1日
2026年9月1日
WordPressのマルウェアを検出・除去する手順|WP-CLIでの改ざん確認と復旧
WordPress のサイトがマルウェアに感染すると、訪問者が別のサイトへ転送されたり、検索結果に「このサイトはハッキングされている可能性があります」と表示されたりします。この記事では、サーバーに SSH で入れる環境を前提に、感染の調べ方と取り除き方を順に説明します。コマンドは WP-CLI と Linux の標準的なコマンドです(2026年10月時点)。
感染を疑う症状
- 検索結果やスマートフォンからのアクセスだけ、別のサイトへ転送される
- 身に覚えのない管理者ユーザーや、知らないプラグインがある
- Google Search Console の「セキュリティの問題」に警告が出る、ブラウザーに危険なサイトの警告が出る
- 記事に見覚えのないリンクやスクリプトが入っている
- サーバー会社から、迷惑メールの送信や不審なプロセスについて連絡が来た
ログイン中の管理者には正常に見せ、ログアウト状態や検索エンジンからのアクセスにだけ不正な動きをするものが多いため、確認はログアウトした状態や別の端末でも行います。
まず行うこと
- 今の状態を丸ごと保存する。調査や、誤って消したファイルを戻すために使います。感染したまま保存したものなので、復元用のバックアップとは分けて保管します
- 必要なら、作業中はメンテナンス表示にするか、Basic 認証などで一時的に公開を止める
- 別の、感染していないパソコンから、ホスティングの管理画面・FTP/SSH・データベースのパスワードを変える準備をする(変更は除去の後にもう一度行います)
cd /var/www/example.com # WordPress を置いたディレクトリー
wp db export ~/infected-$(date +%Y%m%d).sql
tar czf ~/infected-files-$(date +%Y%m%d).tar.gz .
感染より前の、きれいなバックアップがある場合は、それを戻すのが早いことが多いです。ただし、侵入の入口(古いプラグインや漏れたパスワード)をふさがないと再び感染するため、後半の「再発を防ぐ」も行います。
感染箇所を調べる
WordPress本体のファイルを照合する
wp core verify-checksums は、WordPress 本体のファイルを wordpress.org が公開しているチェックサムと照合し、書き換えられたファイルや、本来は無いファイルを報告します。
wp core verify-checksums
wp core verify-checksums --include-root
--include-root を付けると、ドキュメントルート直下にある WordPress 以外のファイルも警告します。wp-config.php やサーバー会社が置いたファイルも出るので、一つずつ見て判断します。
プラグインのファイルを照合する
wp plugin verify-checksums --all
wordpress.org のプラグインディレクトリにあるプラグインは、公開されているチェックサムと照合できます。有料プラグインなど wordpress.org に無いものは照合できないため、後の手順で配布元から入れ直します。テーマには同じ照合コマンドがありません。
アップロードフォルダーのPHPと最近変わったファイル
wp-content/uploads は画像などを置く場所で、通常は PHP ファイルがありません。ここにある PHP はバックドア(再侵入用の裏口)であることが多いです。
find wp-content/uploads -type f -name '*.php'
# 最近14日間に変更された PHP ファイルを日付順に表示(GNU find)
find . -type f -name '*.php' -mtime -14 -printf '%TY-%Tm-%Td %TH:%TM %p\n' | sort
攻撃者はファイルの日付も書き換えられるため、日付だけで判断しません。
不審なコードを文字列で探す
難読化したコードでよく使われる関数の組み合わせを探します。正規のプラグインが使っていることもあるので、見つかったファイルは中身を見て判断します。
grep -rlE 'eval\(base64_decode|eval\(gzinflate|gzinflate\(base64_decode|str_rot13\(' wp-content --include='*.php'
管理者・must-useプラグイン・cronを確認する
wp user list --role=administrator --fields=ID,user_login,user_email,user_registered
wp plugin list --status=must-use
wp plugin list --status=dropin
wp cron event list --fields=hook,next_run_relative,recurrence
wp-content/mu-plugins に置かれたプラグインは管理画面で無効にできず、プラグイン一覧でも目立たないため、不正なコードが置かれやすい場所です。cron は、知らないフック名の予定が無いかを見ます。
データベースを確認する
記事本文やオプションにスクリプトや不正なリンクが入っていないか検索します。
wp option get siteurl
wp option get home
wp db search '<script' wp_posts wp_options --table_column_once
wp db search 'eval(' wp_options --table_column_once
siteurl と home が自分のサイトのURLになっているかを確かめます。<script はテーマやプラグインの正規の設定にも含まれるため、見つかった行は中身を確認してから直します。
外部のスキャンを併用する
- Wordfence Security(wordpress.org で配布されているプラグイン):サーバー上のファイルをスキャンし、本体・プラグインの改ざんや既知のマルウェアを報告する
- Sucuri SiteCheck(
sitecheck.sucuri.net):外から公開ページを調べるサービス。サーバー内のファイルは見えないため、見つからなくても感染していないとは言えない
感染したサイトでは、スキャン用のプラグイン自体が書き換えられることもあります。スキャンの結果と、上のコマンドでの確認を組み合わせて判断します。
マルウェアを取り除く
WordPress本体を入れ直す
今と同じバージョンの本体をダウンロードし直して上書きします。--skip-content を付けると、既定のテーマとプラグインを含めずにダウンロードします。wp-config.php は本体の配布物に含まれないので上書きされません。
wp core download --version=$(wp core version) --skip-content --force
wp core verify-checksums
上書きでは、本来は無いファイルは消えません。verify-checksums で「File should not exist」と出たファイルは、中身を確認してから削除します。
プラグインとテーマを入れ直す
wp plugin list --fields=name,version,status
# 例: akismet を同じバージョンで入れ直す
wp plugin install akismet --version=5.3 --force
wordpress.org にあるプラグインとテーマは、同じバージョンを --force で入れ直します。有料のものは配布元から新しくダウンロードし直します。使っていないプラグインとテーマは、入れ直さずに削除します。自作のテーマは、Git などで管理している元のファイルと比べます。
アップロードフォルダーと不審なファイルを消す
前の手順で見つけた wp-content/uploads の PHP ファイルなど、不正と判断したファイルを削除します。消す前に、最初に取った保存ファイルに含まれていることを確かめておきます。
データベースの不正なデータを消す
不正なスクリプトが入った記事やオプションは、一つずつ内容を確かめて直します。base64_decode などの文字列を wp search-replace で一括で消す方法は使いません。正規のデータまで書き換えて、サイトやプラグインが動かなくなるためです。
# 知らない管理者を削除し、その人の投稿は自分のアカウント(ID 1 の例)に移す
wp user delete 15 --reassign=1
# 知らない cron の予定を削除する
wp cron event delete 不審なフック名
パスワードと秘密鍵を変える
除去が終わったら、漏れた可能性のある認証情報をすべて変えます。
- WordPress の全管理者のパスワード
- データベースのパスワード(変えたら
wp-config.phpのDB_PASSWORDも直す) - FTP・SSH・ホスティングの管理画面のパスワード
wp-config.phpの認証用キーとソルト
wp config shuffle-salts
キーとソルトを変えると、ログイン中のすべてのユーザーがログアウトされます。攻撃者が持っているかもしれないログイン状態も無効になります。
Googleの警告を解除する
Google Search Console の「セキュリティと手動による対策」→「セキュリティの問題」に問題が表示されている場合は、除去が終わってから「審査をリクエスト」で、何を直したかを書いて送ります。審査が終わると警告が外れます。
再発を防ぐ
- WordPress 本体・プラグイン・テーマを更新し、使っていないものは削除する
- 管理者に2段階認証を設定し、ログイン試行を制限する
- 管理画面からファイルを編集できないよう、
wp-config.phpにdefine( 'DISALLOW_FILE_EDIT', true );を書く - ファイルとディレクトリーの権限を見直す
- バックアップを、感染しても書き換えられない別の場所に、複数世代残す
除去しても数日で同じ症状が戻る場合は、どこかに裏口が残っています。自分で探しきれないときは、サーバー会社やセキュリティ会社の復旧サービスに相談することも検討します。
関連する設定は次の記事も参照してください。
- WordFenceのスキャン機能でマルウェアを検出・駆除する方法
- Sucuri Securityの設定方法|整合性チェック・監査ログ・ハードニング
- WordPressのファイルパーミッションをセキュリティ面から見直す
- テーマ・プラグインファイルエディターを無効化する(DISALLOW_FILE_EDIT)
- WordPressの二要素認証(2FA)を全ユーザーに強制する方法
まとめ
- 作業の前に、感染した状態のファイルとデータベースを保存する
wp core verify-checksumsとwp plugin verify-checksums --allで本体とプラグインの改ざんを調べるwp-content/uploadsの PHP、mu-plugins、知らない管理者と cron を確認する- 本体・プラグイン・テーマは入れ直し、データベースは一行ずつ確かめて直す
- 除去後に全パスワードを変え、
wp config shuffle-saltsでログイン状態を無効にする