
WordPress Core 4.7.0~7.1.1 を対象に、二重エンコードされた pagename トラバーサルを悪用した未認証 LFI(CVE-2026-87902)をスキャンします。オプションで PEAR config-create による RCE へのエスカレーションと一括スキャンにも対応しています。
WordPress Core get_page_template() / locate_template() パストラバーサルエクスプロイトツール
許可されたセキュリティテスト専用です。コンピュータシステムへの不正アクセスは違法です。
| 項目 | 詳細 |
|---|---|
| CVE ID | CVE-2026-87902 |
| GHSA ID | GHSA-7hp8-65ch-5whp |
| 脆弱性の種類 | CWE-98 — Include/Require のためのファイル名の不適切な制御 |
| CVSS v3.1 | 8.1 (High) / CVSS 4.0: 9.2 (Critical) |
| 影響を受けるコンポーネント | WordPress Core |
| 影響を受けるバージョン | 4.7.0 から 7.1.1 (全ブランチ) |
| 修正済みバージョン | 7.1.2 (および 4.7.37 までのバックポート) |
| 必要な認証 | なし (未認証) |
| 攻撃ベクトル | 単一の GET リクエスト |
| 発見者 | Robert Ressl (WordPress HackerOne プログラム経由) |
| 公開日 | 2026年9月22日 |
| 実環境での悪用 | あり — CISA KEV カタログに掲載 |
CVE-2026-87902 は WordPress Core における未認証のパストラバーサルおよびローカルファイルインクルージョン (LFI) の脆弱性であり、2016年以降にリリースされたすべての WordPress バージョン (4.7.0 から 7.1.1) に影響します。攻撃者はアカウントや認証を必要としません。悪意のある pagename クエリパラメータを細工することで、攻撃者は WordPress のページテンプレート解決メカニズムを悪用し、アクティブなテーマディレクトリ外にある読み取り可能な任意の .php ファイルをインクルードさせることができます。特定のサーバー条件 (PHP の register_argc_argv = On かつ読み取り可能な pearcmd.php の存在) の下では、この脆弱性はリモートコード実行 (RCE) にエスカレートされる可能性があります。
| ブランチ | 修正済みバージョン |
|---|---|
| 4.7.x | 4.7.37 |
| 5.0.x | 5.0.29 |
| 5.3.x | 5.3.25 |
| 5.9.x | 5.9.18 |
| 6.0.x | 6.0.16 |
| 6.6.x | 6.6.9 |
| 6.9.x | 6.9.9 |
| 7.0.x | 7.0.6 |
| 7.1.x | 7.1.2 |
この脆弱性は wp-includes/template.php 内の get_page_template() に存在します。pagename クエリ変数が存在する場合、この関数は page-{$pagename}.php を構築しますが、ディレクトリトラバーサルをチェックするためにその値に対して validate_file() を呼び出しません。その後、候補となるファイル名は locate_template() に渡され、この関数はそれをテーマディレクトリのパスと連結し、file_exists() のみをチェックします — 解決されたパスがテーマディレクトリ内に留まっているかどうかは検証しません。したがって、../ を含むテンプレート名は、アクティブなテーマ外にある読み取り可能な PHP ファイルに解決され、インクルードおよび実行される可能性があります。
GET /?page_id=<公開済みページ>&pagename=<二重エンコードされたトラバーサルペイロード> → WP_Query が page_id を解決し、公開済みページにマッチ (404 を回避) → get_page_template() が pagename を urldecode() し、page-{$pagename}.php を構築 → locate_template() が候補をテーマディレクトリに連結し、file_exists() で解決 → template-loader が realpath() + include を実行
WordPress は pagename に sanitize_title_for_query() を適用し、トラバーサルをブロックするためにリテラルのドット (.) をハイフン (-) に置換します。これはすでに一度デコードされた入力に対して動作し、再帰的にデコードすることはありません。攻撃者は %252e%252e%252f (二重エンコードされた ../) を送信します:
%252e → %2e、%252f → %2fsanitize_title_for_query() は %2e%2e%2f (リテラルのドットなし) を認識し、そのまま通過させるget_page_template() が内部的に再度 urldecode() を呼び出す: %2e%2e%2f → ../page- で始まるトップレベルディレクトリが含まれていること (例: page-templates/)。page_id として指定できる ID を持つ公開済みページが少なくとも1つ存在すること。.php で終わっていること (WordPress が拡張子を付加する)。Windows ホストに関する注意: Win32 は .. を字句的に正規化するため、page- ディレクトリが存在しなくてもトラバーサルが機能する場合があります。Linux では、そのディレクトリが実際に存在している必要があります。
条件:
register_argc_argv が On に設定されているpearcmd.php が存在する攻撃者はLFI経由でpearcmd.phpをインクルードし、そのconfig-createコマンドを悪用してPHPファイルをサーバーに書き込み、その後LFI経由でそのファイルを再度インクルードして任意のコマンドを実行します。
CVE-2026-87902は、スイスを拠点とするセキュリティ研究者Robert Resslによって発見され、報告されました。
2026年7月にWordPress HackerOneプログラムを通じて報告されました。WordPressセキュリティチームが修正を調整し、2026年9月22日にWordPress 7.1.2とともにリリースしました。
| 日付 | 出来事 |
|---|---|
| 2026年7月 | Robert ResslがWordPress HackerOneプログラムを通じて脆弱性を報告 |
| 2026年9月22日 | 修正を含むWordPress 7.1.2がリリースされ、アドバイザリが公開 |
| 2026年9月22日 | ブランチ7.0から4.7向けのセキュリティバックポートがリリース |
| 2026年9月23日 | 攻撃者が脆弱なサイトの探索を開始 |
| 2026年9月25日 | CISAがCVE-2026-87902をKEVカタログに追加 |
| 機能 | 説明 |
|---|---|
| バージョンフィンガープリント | meta generator、RSSフィード、OPML、readme.html、アセットの?ver=を通じてWordPressバージョンを特定 |
| スマートバージョン判定 | 修正済みバージョンのマッピングを用いて、ターゲットが影響範囲内かどうかを判定 |
| テーマの検出 | アクティブなテーマのスラッグを抽出し、親テーマを検出し、page-*ディレクトリを発見 |
| ページIDの検出 | REST API、page-id-ボディクラス、ショートリンクを通じて有効なページIDを発見 |
| LFIオラクル検証 | wp-links-opml.phpやwp-trackback.phpなどの安全なファイルを、ネガティブコントロール付きのオラクルとして使用 |
| 二重エンコードトラバーサル | sanitize_title_for_query()をバイパスするため、/と.を自動的に二重パーセントエンコード |
| PEAR RCEエクスプロイト | 一般的なPEARパスを試し、config-createを通じてマーカーファイルを書き込み・実行 |
| マススキャン | ターゲットリストのマルチスレッド同時スキャン |
| 結果出力 | 結果をvuln_lfi.txtとvuln_lfitorce.txtに保存 |
pip install requests
python3 CVE-2026-87902.py
対話式メニュー:
[1] 単一スキャン LFI [2] 単一スキャン LFI + RCE [3] マススキャン LFI [4] マススキャン LFI + RCE [5] 終了
[1]を選択し、ターゲットURLを入力します:
url > https://target.example.com
[2]を選択し、URLとコマンドを入力します(デフォルトはid):
url > https://target.example.com cmd > id
[3]または[4]を選択し、ターゲットURLを含むファイルを入力します(1行に1つ、#はコメント):
file > targets.txt
| ファイル | 内容 |
|---|---|
| vuln_lfi.txt | 確認されたLFIターゲット |
| vuln_lfitorce.txt | RCEに成功したターゲット |
TIMEOUT = 8 # リクエストタイムアウト(秒) THREADS = 200 # マススキャンの同時スレッド数 USE_ALL_ORACLES = False # すべてのオラクルを使用(より正確だが低速)
pagenameパラメータに..、%2e、%252eを含むリクエストをブロックするpage-*ディレクトリが含まれているか確認するregister_argc_argv設定を確認するこのツールは、許可されたセキュリティテストおよび教育目的のみを対象としています。ユーザーは、対象システムに対する明示的な書面による許可を取得していることを確認する必要があります。許可のない使用は、CFAA、英国のComputer Misuse Act、およびその他の国の同様の法律に違反する可能性があります。作者は、いかなる誤用に対しても責任を負いません。