【実録】WordPress で発見された脆弱性 wp2shell で、実際にあった攻撃とその復旧まで

こんにちは、ゼノクリース合同会社の齋藤です。このコラム記事では、最新の Web セキュリティに関する内容を紹介し、企業のサイトを守るための考え方と実践方法をご紹介します。

この記事の著者

ゼノクリース合同会社 代表(Web
斎藤 智樹

X:@TomokiSaito0920
スタンディングテックのWEB開発コース主任講師を務める。

今回は、私が携わっているサイトのうちの 1 つで起きた改ざんを題材にします。100 を超える不正な管理者アカウントと 10 個以上のバックドアが見つかりましたが、画面に異常はありませんでした。特定されうる情報と攻撃に使える情報は伏せています。

タイトルの wp2shell は、2026 年 7 月に発見元の Searchlight Cyber が公表した、WordPress 本体の脆弱性チェーンの通称です(CVE-2026-60137 と CVE-2026-63030 の組み合わせ)。プラグインなしの標準インストールに対して、ログインしていない攻撃者が前提条件なしで悪用できると説明されており、影響を受けるのは 6.9.0〜6.9.4 と 7.0.0〜7.0.1、修正版は 6.9.5 と 7.0.2 です。

最初のサインは「改ざん」ではなく「管理画面に入れない」でした

表側は普通に表示されるのに、管理画面にだけ入れません。実体は攻撃者が wp-admin に置いたアクセス制御ファイルで、自分のファイルだけを通す内容でした。

私自身、表側を目視して「スパム文字列も外部ホストへのリンクも無いので正常」と判断しましたが、これは誤りでした。

ページ先頭の、ブラウザに表示されない領域に、配信元のドメイン名を含まないスクリプトがありました。コード本体はブロックチェーン上にあり、そこから読み出して実行します。Google が EtherHiding として報告している手法 と共通点の多い構成です。

配信元は通報では止められず、呼び出し先も約 45 分ごとに切り替わっていたので、ドメインのブロックリストは間に合いませんでした。

「自分で見て確認した」が通用しない改ざんでした

見えなかった理由は 4 つありました。

  1. 投稿を編集する権限が無い訪問者にだけ、悪意のある JavaScript を配信していました。管理者でログイン中は出ません。
  2. 攻撃者が仕込んだプラグインは、管理画面の一覧に自分を表示しません。
  3. 埋め込まれたスクリプトは、実行後に自分自身を消します。
  4. 一度ひっかかった人が出ると、同じ回線には表示されません。誰か一人が先に踏めば、オフィスから何度見ても再現しません。

訪問者には ClickFix と呼ばれる、偽の「私はロボットではありません」画面が出ていました。

Windows キーと R、Ctrl+V、Enter を押させ、コピー済みの不正なコマンドを PowerShell / Terminal で利用者自身に実行させるように促す文面がありました。

このような攻撃は、警察庁のサイバー警察局便り でも説明されています。

(この画面が出たら指示に従わず、タブを閉じてください。正規のサービスがコマンドを実行させることはありません!)

実際に復旧した時の手順

まずは、侵入を疑う日以降に作成・変更されたファイルを洗い出しました。シェルが使える環境なら、このようなコマンドで一覧が出せます。

find uploads -type f -newermt 'YYYY-MM-DD'

本件の契約環境ではサーバー上でコマンドを実行できなかったため、FTP で取得した更新日時つきのファイル一覧を、同じ観点で調べました。

広い範囲に渡って大量の怪しいファイルがあったため、見つけたバックドアを消して回るのではなく、サイトを入れ直す選択肢を早い段階で選びました。

(ただその前に、証拠として現在のファイル一式と、更新日時を含むファイル一覧を取得しました。アクセスログも、サーバーの契約環境で自分の権限のまま取れる範囲を先に確認します。ログは保存期間を過ぎると失われることがあるので、ここは急ぎでした。)

その上で、フォルダー内で PHP が実行されないよう設定を足しました。画像しか置かない場所でスクリプトが動く必要はありません。

# uploads 直下に置く .htaccess(PHP などの実行を全面禁止)
<FilesMatch "\.(php|phtml|php[0-9]|cgi|pl)$">
  Require all denied
</FilesMatch>

WordPress 本体と無料プラグインは配布元の wordpress.org から取り直しました。

データベースは全部捨てて、汚染前と判断できたバックアップを入れ直しました。最初の不正アカウントの作成日時が分かっていたため、実際の侵入がそれより前に遡る可能性も見込んで、十分に古い日付のものを選べたのが決め手です。

バックアップ以降に書かれた記事が 2 本だけありました。これらは、WP REST API で取得し、保全しておきました。

また、攻撃者は設定ファイルからデータベースの接続情報を平文で読め、パスワードのハッシュも持ち出せたという前提で、これらを全て再発行しました。

  • WordPress の秘密鍵 (salt)
  • データベース (phpMyAdmin) のパスワード
  • WordPress の管理者権限のユーザーのパスワード
  • WordPress のアプリケーションパスワード
  • FTP のパスワード
  • サーバーの管理パネルのパスワード
  • 外部サービスの API キー

公開再開の判定は「駆除したか」ではなく観測でした

再開の可否は、作業の完了ではなく外から見える結果で判定しました。サイトマップから URL を集め、1 ページずつ状態コードと中身を確認します。

# サイトマップの URL を取り出し、状態コードと疑わしい script の有無を確認
curl -s https://example.com/sitemap.xml \
  | grep -oE 'https://[^<]+' \
  | while read -r url; do
      code=$(curl -s -o /tmp/page -w '%{http_code}' "$url")
      echo "$code $url"
      grep -qiE 'eval\(|atob\(|data:text/javascript' /tmp/page \
        && echo "  ⚠ 要確認: 疑わしいスクリプト"
    done

集めたページが全て「正常応答・注入スクリプト 0 件・エラー露出 0 件」になること、それから念の為、別回線からも同じ結果を確認してから、公開を再開しました。

外形監視を再接続し、作り直した直後のクリーンな状態で、ここを基準点にして今も差分を見続けています。

今日、自分のサイトで確認できること

この件から、このようなことを定期的に確認しておくことをおすすめします。

まず、WordPress 本体のバージョンを確認します。wp2shell の修正版(6.9.5 / 7.0.2)以上になっていれば、この経路は塞がっています。自動更新に任せているつもりでも、止まっているサイトは珍しくありません。

次に、管理者権限のユーザー数を数えます。一覧が複数ページなら表示件数を最大にしてから数えます。WP-CLI が使える環境なら、画面を介さずに数えることもできます。

wp user list --role=administrator --format=count
wp user list --role=administrator --fields=user_login,user_email

※ 管理画面の一覧に自分を表示しないよう細工するプラグイン型のバックドアもあります。画面の見た目だけを根拠にせず、データベースに近いところで数えてください。

同じ一覧で、メールアドレスのドメインも見ます。本件では wp2shell に続く部分が .invalid と .local でした。

.invalid はインターネット上に決して存在しない名前として予約されている ものなので、正規の登録では使われません。

一方で実在するドメインを騙るものや、正規のユーザー名に数文字を足しただけのものも混じっていました。

未ログイン・別回線で、トップページの HTML とヘッダーを取得します。curl で構いません。

# レスポンスヘッダーを見る(Content-Security-Policy の有無など)
curl -sSI https://example.com/

# HTML を取得し、疑わしい script を抜き出す
curl -sSL https://example.com/ | grep -iE '<script|eval\(|atob\(|data:text/javascript'

本件には Content-Security-Policy がありませんでした。CSP があれば、素性のはっきりしないスクリプトの実行をある程度抑えられます。

これらは、自社が管理・運用するサイトにのみ行ってください。他社サイトにログインを試みる確認は、もしかすると不正アクセス禁止法に触れてしまう恐れもあります。

まとめ

今回は、このサイトを狙い撃ちしたというより、wp2shell に未対応のサイトを機械的に探して回る攻撃の一部だったと考えています。

保全したアクセスログには、脆弱性の公表から数日のうちに、User-Agent 欄に CVE 番号をそのまま名乗る自動化ツールが該当の REST API エンドポイントを叩き始め、以後 2 万回を超えるリクエストで 500 MB 以上のデータを持ち出していった記録が残っていました。一方で、ログイン画面への認証成功は一度もありませんでした。入口はパスワードではなく、本体の更新の遅れです。

不正な管理者アカウントの多くは、メールドメインに wp2shell の文字列を使っていました。攻撃者が、自分の使った手口の名前をそのまま名乗っていた形です。なお、調査ではホスティング環境側の問題も確認されていません。

(バックドアのコードに対して言うのも変ですが)クオリティの低いコードであり、AI で生成したような印象を受けました。クオリティが低いのは、フロンティアモデルでマルウェアを作ろうとすると多くの場合拒否されるので、ローカル LLM などを使っていたためかもしれません。

私自身、実際に攻撃を受けてみて、外側からの継続的な観測と、保守契約の中身の確認が必要だと、改めて思いました。

  • KUSANAGI マネージドサービス(WordPress の保守、高速化、セキュリティ対策、監視、障害対応まで一貫して支援するフルマネージドサービス)
  • KUSANAGI Security Edition byGMO(OS・ミドルウェアの自動アップデート、マルウェア対策、監査、アクセス制御など、継続的な CMS セキュリティ運用の仕組みを提供)
  • WordPress 簡易脆弱性診断サービス(WordPress 本体、プラグイン、テーマのバージョンを解析し、脆弱性の有無を確認)

最新コラム、最新ニュース、おすすめセミナー等を毎月配信する公式メルマガ
「月刊KUSANAGI」の配信購読はこちら。

企業でWordPressを利用している方にも、制作されている方にもおすすめ!
WordPressやWebの情報がぎっしり詰まった情報を定期的にお届けします。

【この記事の著者】
ゼノクリース合同会社 代表(Web
齋藤智樹

在学中から高校や予備校、IT 企業に携わり、講師とソフトウェアエンジニアとして活動。
大学卒業後 (2020年4月〜) はフリーランスエンジニアとして活動を始め、以下のような幅広い業務を行う。2021年3月に、業務を拡大させるためにゼノクリース合同会社を設立。スタディングテックの WEB 開発コース主任講師も務める。