🛡️

【実録】WordPressサイトがハッキングで全削除された!発見から復旧・セキュリティ対策までの全記録

に公開
2026/02/09
2件

更新履歴

  • 2026/02/09: 読者フィードバックを受け、「やられた原因」の記述を修正。パスワード強度が主因であることを明記。DISALLOW_FILE_MODS の説明を追加。

はじめに

ある日、運営しているWordPressサイトが突然表示されなくなりました。調査の結果、AWS東京リージョンからXMLRPC経由のブルートフォース攻撃を受け、サイトのファイルが全削除されていたことが判明。

この記事では、発見から復旧、そして再発防止のセキュリティ対策まで、実際に行った全ての作業を時系列で記録しています。

同じ被害に遭った方、またはWordPressのセキュリティを強化したい方の参考になれば幸いです。

⚠️ この記事に記載されているIPアドレス、ユーザー名、パス等は一部変更しています。

サイトが表示されなくなった瞬間のスクリーンショット


1. 異変の発見

サイトにアクセスすると、WordPressの画面が一切表示されない状態でした。

  • トップページ → 表示されない
  • 管理画面(wp-admin) → 表示されない
  • サーバー自体は生きている

この時点で、単なるプラグインの不具合ではなく、サーバー上のファイルに問題があると判断しました。


ブラウザでアクセスした際のエラー画面


2. SSHでサーバーに接続して状況を確認

お名前.comのレンタルサーバーにSSHで接続し、状況を確認しました。

PEM鍵での接続

ssh -i ~/.ssh/onamae.pem ユーザー名@ホスト名

ドキュメントルートを確認

ls -la ~/public_html/

WordPressのファイルがほぼ全て削除されていることが判明しました。


3. バックアップからの復旧

幸いなことに、サーバー上の別ディレクトリにバックアップが残っていました。

バックアップの探索

find ~/ -type d -name "*backup*" 2>/dev/null

ファイルの復元

# 隠しファイル(.htaccessなど)も含めてコピー
cp -r ~/backup_data_web/xxxxx.xxx/. ~/public_html/xxxxx.xxx/

データベースの確認

ファイル復元後、データベースの状態も確認しました。

php ~/wp-cli.phar db check

幸いデータベースは無事でした。

バックアップからの復元作業


4. .htaccess の再作成

復元後、.htaccess が存在しないことに気づきました。WordPressのパーマリンクが機能しないため、手動で作成しました。

cat > .htaccess << 'EOF'
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress
EOF

chmod 644 .htaccess

これでWordPressの管理画面にアクセスできるようになりました。


5. 攻撃元の特定

WHOIS調査

サーバーのアクセスログから不審なIPアドレスを特定し、WHOIS検索を行いました。

項目 詳細
攻撃元IP 35.78.xxx.xxx
所有者 Amazon Data Services Japan
所在地 東京(AWS東京リージョン)
サービス Amazon EC2

攻撃者はAWSのEC2インスタンスを使い捨てにして攻撃していたことがわかりました。これはよくある手法で、追跡が難しいのが特徴です。

WHOIS検索の結果

ログイン履歴の分析

WordPressの管理画面でログイン履歴を確認したところ、恐ろしい事実が判明しました。

2026-01-24 02:50:08  ロック  admin_xxxxx  35.78.xxx.xxx  XMLRPC
2026-01-24 02:50:08  ロック  admin_xxxxx  35.78.xxx.xxx  XMLRPC
2026-01-24 02:50:08  ロック  admin_xxxxx  35.78.xxx.xxx  XMLRPC
...(以下、大量に続く)
  • 攻撃手法: XMLRPC経由のブルートフォース攻撃
  • 攻撃回数: 約 2,915回
  • 特徴: 同一秒に複数回のリクエスト(自動化ボット)
  • 深夜の時間帯に集中攻撃

大量のXMLRPC攻撃が記録されたログイン履歴


6. 攻撃の仕組みを理解する ― XMLRPC経由のブルートフォース攻撃とは

対策を講じる前に、今回の攻撃がどのような仕組みだったのかを整理します。

xmlrpc.php とは

WordPressに標準搭載されている外部通信用のAPIです。元々は以下のような正当な用途のために存在しています。

  • スマートフォンアプリからの投稿
  • ピンバック・トラックバック(ブログ同士の通知)
  • 外部サービスとの連携
  • Jetpackプラグインの一部機能

しかし現在は REST API(wp-json) が主流であり、xmlrpc.php が必要なケースはほぼありません。

通常のログインとXMLRPC攻撃の違い

通常のログインページ(wp-login.php)では、1回のリクエストで1つのパスワードしか試せません。

リクエスト1 → パスワード「abc123」を試す → 失敗
リクエスト2 → パスワード「password」を試す → 失敗
リクエスト3 → パスワード「admin123」を試す → 失敗

しかし xmlrpc.php の system.multicall メソッドを使うと、1回のHTTPリクエストで数百〜数千のパスワードを同時に試行できます。

<!-- 1回のリクエストで数百のパスワードを同時に試せる -->
<methodCall>
  <methodName>system.multicall</methodName>
  <params>
    <param><value><array><data>
      <value><struct>
        <member>
          <name>methodName</name>
          <value>wp.getUsersBlogs</value>
        </member>
        <member>
          <name>params</name>
          <value><array><data>
            <value>admin</value>
            <value>abc123</value>
          </data></array></value>
        </member>
      </struct></value>
      <value><struct>
        <member>
          <name>methodName</name>
          <value>wp.getUsersBlogs</value>
        </member>
        <member>
          <name>params</name>
          <value><array><data>
            <value>admin</value>
            <value>password</value>
          </data></array></value>
        </member>
      </struct></value>
      <!-- ...数百個続く -->
    </data></array></value></param>
  </params>
</methodCall>

つまり攻撃者にとって、ログインページを直接攻撃するより数百倍効率的です。

通常のログイン攻撃とXMLRPC攻撃の比較図

SiteGuardのログインURL変更では防げない理由

SiteGuardプラグインでログインURLを変更していても、xmlrpc.php は別の入口として存在し続けます。

wp-login.php   → SiteGuardでURL変更済み → 攻撃者はアクセスできない ✅
xmlrpc.php     → 保護されていない       → 攻撃者がここから侵入   ❌

SiteGuardが「ロック」と記録していたのは攻撃を検知していた証拠ですが、xmlrpc.php 経由の大量リクエストを完全にはブロックできなかった可能性があります。

今回の攻撃シナリオ(推定)

1. 攻撃者がAWS EC2(東京リージョン)でインスタンスを起動
     ↓
2. xmlrpc.php に対して system.multicall で大量のパスワードを試行
   (2,915回のログ = 実際には数万〜数十万のパスワードを試行した可能性)
     ↓
3. ユーザー名とパスワードが突破される
     ↓
4. 管理者権限でWordPressにログイン
     ↓
5. サイトのファイルを削除・改ざん

なぜxmlrpc.phpはデフォルトで有効なのか

WordPress側はレガシー互換性のために無効化していません。しかし繰り返しになりますが、現在はREST APIが主流であり、xmlrpc.php が必要なケースはほとんどありません。

使っていないなら無効化一択です。


7. セキュリティ対策の実施

7-1. xmlrpc.php を完全ブロック(最重要)

今回の攻撃経路だった xmlrpc.php を .htaccess で完全にブロックしました。

# XMLRPC を完全ブロック
<Files xmlrpc.php>
  Order allow,deny
  Deny from all
</Files>

7-2. wp-config.php の保護

データベース接続情報が記載された重要ファイルを外部からアクセスできないようにしました。

# wp-config.php を保護
<Files wp-config.php>
  Order allow,deny
  Deny from all
</Files>

7-3. ディレクトリ一覧の無効化

Options -Indexes

7-4. 攻撃元IPのブロック

<Limit GET POST>
  Order allow,deny
  Deny from 35.78.xxx.xxx
  Allow from all
</Limit>

7-5. 管理者ユーザーの変更

攻撃者にユーザー名が知られていたため、新しい管理者ユーザーを作成し、旧ユーザーを削除しました。

# 新しい管理者を作成
php ~/wp-cli.phar user create 新ユーザー名 admin@example.com \
  --role=administrator --user_pass='強力なパスワード'

# 旧ユーザーを削除(投稿を新ユーザーに引き継ぎ)
php ~/wp-cli.phar user delete 旧ユーザー名 --reassign=新ユーザーID

7-6-1. ファイルエディタの無効化

管理画面からテーマやプラグインのファイルを直接編集できないようにしました。

php ~/wp-cli.phar config set DISALLOW_FILE_EDIT true --raw

7-6-2. ファイル変更の完全無効化(DISALLOW_FILE_MODS)

2026/02/09 追記: 読者からのフィードバックを受けて追記しました。

DISALLOW_FILE_EDIT はテーマ・プラグインのエディタを無効化しますが、ZIPファイルのアップロードによるプラグイン追加は防げません。

より強固な対策として DISALLOW_FILE_MODS があります。

php ~/wp-cli.phar config set DISALLOW_FILE_MODS true --raw
設定 効果
DISALLOW_FILE_EDIT 管理画面のテーマ・プラグインエディタを無効化
DISALLOW_FILE_MODS 上記に加え、ZIPアップロード、プラグイン/テーマの追加・削除、自動更新も全て無効化

⚠️ 注意: DISALLOW_FILE_MODS を有効にすると、WordPressのセキュリティ自動更新も停止します。手動で定期的に更新する運用が必要になります。

どちらを選ぶかは、運用体制に応じて判断してください。

  • 頻繁にプラグインを追加しない&手動更新できる → DISALLOW_FILE_MODS
  • 自動更新を優先したい → DISALLOW_FILE_EDIT + 他の対策を強化

7-7. ファイル権限の適正化

# ディレクトリ: 755、ファイル: 644
find ~/public_html/xxxxx.xxx/ -type d -exec chmod 755 {} \;
find ~/public_html/xxxxx.xxx/ -type f -exec chmod 644 {} \;

# wp-config.php は特に厳しく
chmod 400 ~/public_html/xxxxx.xxx/wp-config.php

7-8. 不審なファイルの確認

バックドアが仕込まれていないかチェックしました。

# uploadsフォルダにPHPがあったら危険
find ~/public_html/xxxxx.xxx/wp-content/uploads/ -name "*.php"

# 不審なファイル名を探す
find ~/public_html/xxxxx.xxx/ -name "*.php" | grep -iE "(shell|hack|backdoor|eval|base64|tmp)"

7-9. プラグイン・テーマの最新化と整理

# 全て最新に更新
php ~/wp-cli.phar plugin update --all
php ~/wp-cli.phar theme update --all

# 不要なプラグインを削除
php ~/wp-cli.phar plugin delete hello
php ~/wp-cli.phar plugin delete akismet

セキュリティ対策を施した後の.htaccess


8. 最終的なセキュリティ対策チェックリスト

対策 効果 状態
xmlrpc.php ブロック XMLRPC攻撃の完全遮断 ✅
wp-config.php 保護 DB情報の漏洩防止 ✅
ログインURL変更(SiteGuard) ログインページの隠蔽 ✅
wp-admin IPアクセス制限 管理画面への不正アクセス防止 ✅
管理者ユーザー名変更 ユーザー名の推測防止 ✅
強力なパスワード設定 ブルートフォース対策 ✅
ファイルエディタ無効化 管理画面からの改ざん防止 ✅
ファイル権限の適正化 不正な書き込み防止 ✅
攻撃元IPブロック 特定IPからのアクセス遮断 ✅
プラグイン・テーマ最新化 既知の脆弱性対策 ✅
不要プラグイン削除 攻撃対象面の縮小 ✅
自動バックアップ設定 万が一の復元手段確保 ✅
ファイル変更の完全無効化(DISALLOW_FILE_MODS) ZIPアップロードも含めた改ざん防止 ⚠️ 検討中(自動更新とのトレードオフ)

9. 今回の教訓

やられた原因

  1. パスワードの強度が不十分だった → 英数字のみ10文字程度で、ブルートフォースで突破された(これが主因)
  2. xmlrpc.php が有効だった → 1リクエストで大量のパスワードを試行できる攻撃経路を開けていた
  3. ユーザー名が推測可能だった → ただしREST API(/wp-json/wp/v2/users)でも取得可能なため、効果は限定的
  4. 定期的なバックアップ体制が不十分だった → 復旧に時間がかかった

読者へのフィードバックを受けての補足(2026/02/09追記)
当初の記事では、XML-RPCとユーザー名を主因としていましたが、コメントでご指摘をいただき、本質的な原因はパスワード強度の不足であったと認識を改めました。十分に強いパスワード(20文字以上のランダム文字列など)であれば、XML-RPC経由でも現実的な時間で突破されることはありません。XML-RPCの無効化は「攻撃面を減らす」という意味では有効ですが、それだけで根本対策にはならない点をお伝えします。

学んだこと

  • xmlrpc.php は使わないなら必ず無効化する。これだけで今回の攻撃は防げた
  • ユーザー名は絶対に推測されにくいものにする。admin やサイト名を含む名前は危険
  • バックアップは外部ストレージに自動保存する。サーバー上だけでは不十分
  • wp-cliは復旧作業で非常に強力。管理画面にアクセスできない状態でも、SSH経由で全ての操作が可能
  • SiteGuardなどのセキュリティプラグインは必須。ログインURL変更だけでも効果大

AWSからの攻撃について

今回の攻撃元はAWS EC2の東京リージョンでした。攻撃者はクラウドサービスのインスタンスを使い捨てにすることで、追跡を困難にしています。不正利用を発見した場合は、AWSの abuse 窓口(trustandsafety@support.aws.com)に報告しましょう。


おわりに

WordPressは世界で最も使われているCMSだからこそ、攻撃の標的にもなりやすいです。

「自分のサイトは大丈夫」と思っていても、ボットは24時間365日、機械的にあらゆるサイトを攻撃し続けています。今回のサイトでも、たった1日で2,915回もの攻撃が記録されていました。

この記事が、WordPressを運営している方のセキュリティ意識向上のきっかけになれば幸いです。

今すぐできる最低限の対策:

  1. xmlrpc.php を無効化する
  2. ログインURLを変更する
  3. 管理者のユーザー名とパスワードを強化する
  4. 自動バックアップを設定する

これだけでも、攻撃の大半を防ぐことができます。


この記事が参考になったら、ぜひ「いいね」をお願いします 🙏

Discussion

AioiLightAioiLight

大変興味深い記事でした。また、ハッキング被害からの復旧もたいへん重い作業であったことだと思います。お疲れ様です。

しかし、記事の内容について、少し疑問に思うことがありましたので、共有させて頂ければと思います。

「やられた原因」の本質は、本当に XML-RPC と推測されやすいユーザー名だったのか?

XML-RPC はデフォルトで有効であることから、XML-RPC 自体に重大な問題があるとは考えづらいかと思います。
となると、ブルートフォース攻撃を受けた結果、管理画面が突破されてしまった真の原因は、弱いパスワードを使用していた、からなのではないでしょうか。

もちろん、XML-RPC 自体は古い仕組みであるため、無効化する自体に異論があるわけではありませんが、まずは、使用していたパスワードの強度はどのくらいだったのか、推測されやすいパスワードだったのか、使い回ししていたパスワードだったのか、など、より今回のハッキングを知るための重要な情報が欠けていると感じました。

また、推測されにくいユーザー名を使用しないという対策についても、REST API でユーザー名が取得できる以上、大した効果は見込めないのではないかと思いました。加えて、メールアドレスでもログインできるため、ユーザー名の対策だけでは不十分だと思います。

ファイルの編集を禁止にしたところで、悪意のあるプラグインの注入は避けられないのではないか?

記事中には DISALLOW_FILE_EDIT を true にすることで、プラグイン・テーマを編集禁止にできるとありますが、これが設定されていても ZIP ファイルのアップロードによるプラグインのアップロードは許可されているので、悪意のあるプラグインのアップロードなどの対策にならないと感じました。

ちなみに、アップロードによる追加も無効化するには DISALLOW_FILE_MODS という設定項目がありますので、こちらを設定すると、それもできなくなります。

しかし、WordPress の自動更新も止まってしまう仕様のため、セキュリティリリースを早期に適用できないという欠点があります。

77887788

コメントをいただき、ありがとうございます。

パスワードの強度について

ご指摘の通りです。当時のパスワードは英数字のみの10文字程度で、
十分な強度とは言えませんでした。これが突破された主因だと認識しています。

XML-RPCの無効化について

おっしゃる通り、強固なパスワード+ログイン試行制限があれば、
XML-RPC経由のブルートフォースも現実的には成功しません。
ただ、XML-RPCは現在ほとんど使われていないため、
攻撃面を減らすという意味で無効化を推奨しました。

DISALLOW_FILE_EDITについて

DISALLOW_FILE_MODSの情報、ありがとうございます。
記事に追記させていただきます。ご指摘の通り、
FILE_EDITだけではZIPアップロードは防げませんね。

自動更新とのトレードオフを含め、読者が判断できるよう補足いたします。

貴重なフィードバックに感謝いたします。