WordPressの停止作業中に4分間放置したら、海外Botにセットアップ画面を乗っ取られた話

WordPressの停止作業中に4分間放置したら、海外Botにセットアップ画面を乗っ取られた話

先日、運用していたWordPressの停止・移行作業を行っていた際、短い休憩のために wp-config.php が存在しない、または初期状態のままWeb上に数分間露出してしまう隙を作ってしまいました。

作業に戻ると、wp-config.php の中身が以下のように、見覚えのない外部の無料データベース(Free SQL Database)のホストに書き換えられていました。

define( 'DB_HOST', 'sql3.freesqldatabase.com' );

「まさか本番DBのパスワードが破られて改ざんされたのか」と肝を冷やしましたが、サーバーのアクセスログとファイルのタイムスタンプを徹底的にフォレンジック(解析)したところ、現代のインターネットを行き交う自動Botの恐ろしい挙動と、今回のインシデントの全貌が秒単位で明らかになりました。

これは、いわゆる In the middle of installation 攻撃 と呼べるタイプの事象です。同じリスクを抱える開発者のために、そのタイムラインと解析結果を共有します。

タイムライン:わずか4分14秒の全自動乗っ取り劇

サーバーログから判明した、Bot(主犯IP: 146.70.x.x)の一連のタイムラインです。

11:31:28:隙を見つけたBotの生存確認

example.com 146.70.x.x - - [11/Jun/2026:11:31:28 +0900] "GET /wordpress/ HTTP/2.0" 302 0 "-" "Mozilla/5.0..."

作業の隙を突き、Botがトップページへアクセスしました。wp-config.php がないため、WordPressコアがセットアップ画面へのリダイレクト(302)を返します。Botはこれで「このサイトは今、未設定で乗っ取れる」と判断したと考えられます。

11:31:29:1秒後にセットアップ画面を直撃

example.com 146.70.x.x - - [11/Jun/2026:11:31:29 +0900] "GET /wordpress/wp-admin/setup-config.php HTTP/2.0" 200 1384 "-" "Mozilla/5.0..."

リダイレクトを検知したわずか1秒後、Botはデータベース設定画面(setup-config.php)を直接叩き、画面の表示に成功(200 OK)しています。

ここからプログラムを介して、自身が用意した外部DB(freesqldatabase.com)の情報をフォームに注入し、送信したと見られます。

11:33:29:wp-config.phpの自動生成

example.com 146.70.x.x - - [11/Jun/2026:11:33:29 +0900] "GET /wordpress/wp-admin/install.php?language=ja HTTP/2.0" 200 2972 "https://example.com/wordpress/wp-admin/setup-config.php?step=2" "Mozilla/5.0..."

リファラーの step=2 は、DB情報を送信した直後のフェーズです。WordPressが外部DBとの疎通に成功したため、この瞬間にサーバー上に新しい wp-config.php が自動生成、または上書きされました。

実際に、サーバー上の wp-config.php のタイムスタンプ(ファイルの最終更新日時)も 11:33 を指しており、ログと完全に一致しました。

11:35:30:WordPressの初期化とコアの自動通信

example.com 120.136.x.x - - [11/Jun/2026:11:35:30 +0900] "GET /wordpress/2026/06/11/hello-world/ HTTP/1.1" 200 15836 "-" "WordPress/6.8.5; https://example.com/wordpress"
example.com 120.136.x.x - - [11/Jun/2026:11:35:31 +0900] "POST /wordpress/wp-cron.php?... HTTP/1.1" 200 0 "-" "WordPress/6.8.5..."

IP 120.136.x.x はサーバー(自ホスト)のループバック通信、User-Agentは WordPress/6.8.5 です。

セットアップが完了したトリガーで、WordPress自身がデフォルト記事(Hello World)の生成確認や、内部用の擬似Cron(wp-cron.php)を自動実行し、システムが裏で完全起動したことを示しています。

11:35:42:乗っ取り完了の最終テスト

example.com 146.70.x.x - - [11/Jun/2026:11:35:42 +0900] "GET /wordpress/wp-admin/load-scripts.php?... HTTP/2.0" 200 40552 "https://example.com/" "Mozilla/5.0..."

WordPressが立ち上がったわずか11秒後、主犯のBotがログイン・管理画面用の結合スクリプト(load-scripts.php)を読み込んでいます。

自身が設定した管理者アカウントで問題なくダッシュボードが開けるか、動作確認(ログイン確認)を行っていた可能性があります。

エンジニア的考察:User-Agentの「ダウングレード」

ログをさらに追うと、非常に興味深い不気味な挙動がありました。乗っ取り成功確認から約17分後のログです。

example.com 146.70.x.x - - [11/Jun/2026:11:53:03 +0900] "GET /wordpress/wp-admin/load-scripts.php?... HTTP/2.0" 200 40552 "-" "... Chrome/149.0.0.0 ..."

同じ主犯IP(146.70.x.x)からのアクセスですが、11:35のログと見比べると、User-Agent内のChromeのバージョンが Chrome/150.0.0.0 から Chrome/149.0.0.0 にダウングレード しています。

ここから、最初の攻撃は「未設定サイトを見つけて最速でセットアップを終わらせるスキャン専用Bot」であり、この11:53のアクセスは、乗っ取り成功のフラグを受けてコントロールサーバーから送り込まれた「次のフェーズ(マルウェア埋め込みやスパム踏み台化など)を担当する別の自動スクリプト」へバトンタッチした瞬間だったのではないかと推測されます。

不幸中の幸いと、その後の防衛戦

12:48頃、異変に気づいた私がMacから投稿一覧(edit.php)を開こうとした際のログがこちらです。

example.com [自分のMacの国内IP] - - [11/Jun/2026:12:48:46 +0900] "POST /wordpress/wp-admin/admin-ajax.php HTTP/2.0" 400 1 "https://example.com/.../edit.php?post_type=post" "Mozilla/5.0 (Macintosh;...)"

ステータスは 400 Bad Request。すでにDBの接続先が外部(攻撃者側)にすり替わっており、私のブラウザが保持していたセッションやトークン(Nonce)と整合性が取れなくなったため、WordPress側から通信を拒否された形跡です。

元の本番データは無事だった

今回の攻撃(In the middle of installation)の構造上、元の本番データベース(サーバー側)のパスワードが抜かれたり、データが盗まれたりしたわけではない ことが最大の救いでした。

攻撃者は空っぽの状態の我が家にやってきて、外から「自分の持ってきた鍵(外部DB)」を勝手にドアに取り付け、自分用の新築サイトを建てただけです。元のデータベースは接続を切られてサーバー内に残されていただけなので、情報漏洩などの最悪の実害は免れていました。

その後の防衛戦

14:40頃、私がサーバー上のWordPressディレクトリの完全削除およびメンテナンス(リダイレクト・アクセス制限)のメスを入れた瞬間のログです。

# 遅れてやってきた別組織の攻撃Bot(GCP踏み台)がトップページに突撃するも、301で弾き飛ばされる
example.com 35.192.x.x - - [11/Jun/2026:14:39:26 +0900] "GET /wordpress/ HTTP/1.1" 301 242

# 崩壊していくWordPressコア。自分自身の擬似Cron(wp-cron)すら301リダイレクトで機能不全に
example.com 120.136.x.x - - [11/Jun/2026:14:40:44 +0900] "POST /wordpress/wp-cron.php?... HTTP/1.1" 301 301

# 一方、WordPressとは無関係の静的領域(/blog/等)は、一般ユーザー(Google経由)に何の影響もなく200 OKを返し続けている
example.com 193.186.x.x - - [11/Jun/2026:14:45:40 +0900] "GET /blog/sample.html HTTP/2.0" 200 11391 "https://www.google.com/"

裏で大掃除を進める私の手と、群がろうとしては 301403 で全滅していく海外Botたちの動きが同期し、無事にサーバーの安全を奪還(完全初期化)してこのインシデントは幕を閉じました。

まとめ:得られた教訓

今回の件から得られた教訓は、以下の3つです。

  1. インターネットの自動Botは秒単位で巡回している
    「ちょっと数分だけ目を離す」「あとで設定しよう」は、現代のWebにおいては非常に危険です。未設定の露出をBotは見逃してくれません。

  2. 作業中・移行中はBasic認証やIP制限を徹底する
    WordPressのインストールや移行、あるいは一度リセットするようなメンテナンスを行う際は、wp-config.php を正しく配置し終えるまで、.htaccess 等で自分以外のアクセスを確実に遮断しておくのが鉄則です。

  3. ログは嘘をつかない
    一見「ファイル改ざん・ハッキング」に見える恐ろしい事象も、タイムスタンプとアクセスログを時系列で丁寧に紐解けば、どこから誰が入り、何をしたのか、あるいは何をしなかったのかを正確に突き止めることができます。

この記事が、WebマスターやWordPressエンジニアのセキュリティ意識の向上、そして同様のトラブルに直面した方の参考になれば幸いです。

Back to Blog

Related Posts

View All Posts »