WordPressの自動バックアップが壊れていた|乗っ取りを疑って調べたら、届いていたのは空のSQLだっ

AIとWeb制作

昨日、自分のドメインから自分宛てに、身に覚えのないデータベースのバックアップメールが届いた話を書いた。添付には圧縮されたSQLファイルが付いていて、送信元は更新をほぼ止めている古いサイトだった。

そのときの状況と、最初に何を確認しようとしたかは、こちらに書いている。

あの記事は「管理画面はこれから見る」というところで終わっている。その後、実際に見た。結論から書くと、侵入された形跡は出てこなかった。ただ、代わりに別のものが出てきた。

管理画面には、拍子抜けするほど何もなかった

まずユーザー一覧を見た。ここに覚えのない管理者アカウントが増えていたら、その時点でほぼ黒だと思っていた。

登録されていたのは自分ひとりだけだった。権限も昔のまま。記事の投稿者欄も自分の名前しか出てこない。

正直、少し拍子抜けした。頭の中では「見た瞬間に知らないアカウントが並んでいる」画を何度か想像していたので、何もないと逆に落ち着かない。見落としているだけではないか、という気持ちが残る。

とりあえず管理者パスワードは変更した。何も出てこなくても、これはやっておくべきことだった。

ログにはスキャンの跡ばかりで、ログイン成功はなかった

次にサーバーのアクセスログとエラーログを落として、前日ぶんを追いかけた。

出てきたのは、大量のスキャンだった。存在しない管理用ファイルや、有名なプラグインの脆弱性を狙ったパスへのアクセスが延々と並んでいる。放置しているサイトでも、こんなに叩かれているのかと思った。

ただ、それらはほぼ全部が失敗している。ログインが成功した記録は見つからなかった。

エラーログのほうは、想像と全然違うものが主因だった。ずっと前に作ったまま忘れていたサブドメインが、リダイレクトのループを起こしていた。攻撃とは何の関係もない、単なる設定の置き忘れだ。

そして問題のメールが送られた時刻に、WordPressの定期実行の処理が動いた記録があった。秒単位でメールの送信時刻と一致している。つまり、誰かが管理画面に入って手動でボタンを押したのではなく、仕込まれたままの定期実行が周期どおりに動いただけ、という形になる。

このあたりのログの読み解きは、AIにかなり手伝ってもらった。行数が多いので、人間が目で追うより先に「不審なパターンだけ抜き出して」と頼んだほうが早い。ただ、抜き出された結果をどう解釈して、何を止めるかは自分で決めるしかない。

この線引きについては、以前まとめて考えたことがある。

決め手は、添付ファイルの中身が空だったことだった

いちばん効いたのは、添付されていたSQLファイルを実際に開いてみたことだ。

思いつきに近かった。乗っ取りかどうかを判断するのに、中身を見るという発想が最初はなかった。ヘッダーとログばかり見ていて、手元にある一番の物証を開いていなかった。

開いてみたら、26KBしかなかった。中はテーブルの構造定義だけで、データを入れるINSERT文が一件も入っていない。

過去に同じ仕組みで送られてきたファイルも探して比較した。そちらは67MBあった。中身が全部詰まった、まともなバックアップだ。

ここで「あれ?」となった。

もし攻撃者がデータベースを抜く目的でこれを走らせたのなら、中身が入っていないと意味がない。空のダンプを外へ送っても、何の得にもならない。しかも送信先は外部ではなく、自分のドメイン内のアドレスだった。

盗む目的にしては、あまりにも噛み合わない。

「バックアップが動いた」のではなく「バックアップが壊れていた」

ここまで来て、見え方が反転した。

私はずっと「止めたはずのバックアップが、なぜか動いた」と考えていた。でも実際に起きていたのは、たぶんこうだ。バックアップの設定は消えずに残っていて、周期が来て動いた。ところがサーバー側のデータベース関連のツールがどこかの時点で更新され、その影響でダンプ処理が失敗した。失敗したまま、空のファイルを添付してメールだけが飛んできた。

これが今のところ一番ありそうな説だと思っている。ただ、断定はできない。サーバー側で何がいつ更新されたかまでは追い切れていないし、原因の切り分けを終える前にプラグインを消してしまったので、もう同じ状況を再現できない。

引っかかっているのは、皮肉な構造のほうだ。このメールが届かなければ、バックアップが壊れていることに永久に気づかなかった。「正常に動いていると思っていた仕組みが、実は空を吐いていた」というほうが、乗っ取りよりよほど怖い気もしてくる。

もっとも、これは「バックアップとして機能していなかった」という話であって、もともとメール添付でデータベースを送る設定自体が良くない。経路が暗号化されている保証はないし、受信箱が破られたら丸ごと持っていかれる。攻撃がなかったとしても、止めるべきものだった。

侵入されていなくても、消すものはたくさんあった

結局この日にやったのは、こういうことだ。

バックアップ系のプラグインを削除。ついでに、使っていないプラグインを全部消した。以前入れたまま放置していたものが、思っていたよりたくさん残っていた。サーバー上にあったバックアップの保存用ディレクトリも、中身を確認したうえで削除した。

使っていないプラグインは、動いていなくてもファイルはそこにある。脆弱性が見つかれば、有効化していなくても踏み台になりうる。ログにあれだけスキャンが並んでいるのを見た直後だったので、残しておく気になれなかった。

そのうえで、レンタルサーバー側が用意しているWordPress向けのセキュリティ機能を有効にした。管理画面へのアクセス制限や、海外からのアクセス制限といったものだ。前から使えたのに、有効にしていなかった。

リダイレクトループを起こしていた放置サブドメインも消した。攻撃とは関係ないが、動いていないものを公開したままにしておく理由がない。

そもそも「更新できない」状態だったことに気づいた

作業の途中で、もう一つ分かったことがある。

このサイト、管理画面からWordPress本体やプラグインを更新しようとすると、ダウンロードの段階で必ず失敗していた。出ていたのは、通信先の証明書を検証できないという意味のエラーだ。更新ファイルを取りに行けないので、そもそも更新のしようがない。

私は最初、サーバー側の問題だと思った。PHPが外部と通信するときに使う証明書の設定が足りていないか、PHPのバージョンを変えたときに設定がずれたのだろう、と。そういう見立てを添えてサーバー会社へ問い合わせた。

返ってきた答えは、その仮説とは違った。

原因は、WordPress本体に同梱されている証明書ファイルのほうだった。このサイトのWordPressはバージョンが古いままなので、同梱されている証明書の情報も古い。だから今の認証局に対応できず、通信の検証に失敗していた。

つまり、サーバーが古かったのではなく、放置していたWordPress自身が古すぎて、自分で自分の更新を取りに行けなくなっていた。原因は外ではなく中にあった。これは考えていなかった。

対応は難しくなかった。案内された手順どおり、WordPressの公式リポジトリから最新の証明書ファイルを落として、サイト内の該当ファイルに上書きするだけだ。ファイルを1つ差し替えて管理画面に戻ったら、あっさり更新が通るようになった。

ちなみに、そのサポートの返信には「本回答は生成AIによる調査・回答文作成を活用しています」と明記されていた。私がログ解析にAIを使い、サポート側もAIで回答を作り、その結果ファイル1つで解決している。少し不思議な気分になった。

これは少しこたえた。私はずっと「作り直す予定だから更新を止めている」と思っていた。でも実際には、途中から「止めていた」のではなく「できなくなっていた」のかもしれない。自分の意思で放置していたつもりが、いつの間にか動かせない状態になっていた、という話になる。

作り直すという判断そのものは、今も間違っていないと思っている。

「段階移行しかない」も、確かめていない思い込みだった

証明書を直した時点では、私はこう考えていた。

更新できるようになったとはいえ、バージョンが離れすぎている。いきなり最新版まで上げるのは危ないし、サーバーのPHPを新しくすると管理画面が動かなくなるかもしれない。だからリニューアルのタイミングで段階的に移行するしかない、と。サーバー会社への返信にも、そう書いて送っている。

ところが、そのあと実際にやってみたら、PHPのバージョンを上げても管理画面は動いた。そのままWordPress本体も最新版まで更新できてしまった。

拍子抜けしたし、少し笑ってしまった。今日だけで、確かめていない思い込みを二回はずしている。一つ目は「原因はサーバー側だろう」、二つ目は「一気に上げるのは無理だろう」。どちらも、試す前に結論を出していた。

もちろん、動いたからといって全部が安全になったわけではない。長く放置していたテーマや残っている設定が、新しいバージョンで問題を出す可能性はまだある。しばらくは表示を見て回るつもりでいる。

分かったのは「たぶん違う」までで、「絶対に安全」ではない

今の結論は、侵入された可能性は低い、というところで止めている。

管理者は自分ひとり。ログインの成功記録なし。メールは自分のサーバーから自分宛て。添付は空。全部が同じ方向を指している。

それでも「絶対に安全」とは書けない。ログの保存期間より前に何かあった可能性は消せないし、私が見た範囲が全部だとも言い切れない。

昨日の記事に「多分大丈夫と、確認したは違う」と書いた。今日やったのは、その「確認した」を少しだけ増やす作業だった。増やしてみて分かったのは、確認すればするほど、侵入とは別のところから問題が出てくるということだ。壊れたバックアップ、使っていないプラグインの山、更新できない環境、忘れていたサブドメイン。どれも攻撃されていなくても存在していた穴だった。

残りのサブドメインの整理は、まだ手つかずで残っている。次はそこからやるつもりでいる。

不安から始まった調査だったが、終わってみると、怖かったのは攻撃者ではなく、自分が何年も見ていなかったという事実のほうだった。

この記事を読んで、何か感じるものはありましたか?
読んで何か感じるものがあったら、そっと「いいね」を押してもらえると嬉しいです。

関連記事

目次