漏洞简介

wp2shell(CVE-2026-63030)是WordPress核心中的免认证远程代码执行漏洞,影响全球约5亿站点。攻击者无需登录或安装插件即可利用REST API批处理路由的漏洞接管服务器。官方已发布7.0.2紧急更新,建议立即升级。

c8c29453-f793-481d-b7a6-99c2436f3527.png

一句话摘要 :

wp2shell(CVE-2026-63030)是 WordPress 核心中的免认证远程代码执行漏洞。攻击者无需登录、无需目标站安装任何插件,即可对标准安装的 WordPress 直接发起攻击并接管服务器。

技术剖析

根据 WordPress 官方公告与多家安全厂商的分析,wp2shell 的根因可概括为:REST API 批处理路由 /wp-json/batch/v1 存在“路由混淆(route confusion)”,叠加 SQL 注入,注入被链式利用后最终打通到远程代码执行。

ae810f20-f6e5-436c-9d46-89b888603194.png

REST API 与批处理路由

WordPress 自 4.7 起内置 REST API,其中的批处理(batch)接口允许在单个 HTTP 请求中打包多个子请求。这类“请求聚合”入口一旦在路由解析或参数处理上出现偏差,就可能被用来触及本不该匿名访问的内部逻辑——这正是本次问题的入口点。

为什么是“老问题”却又如此严重

SQL 注入常被认为是“已解决的历史问题”,但它依旧不时出现在核心 软件与依赖库中,且往往在补丁发布前就能被匿名用户触及。当注入点位于框架核心、且无需认证时,其影响会被使用量急剧放大——这也是 wp2shell 值得高度重视的原因。

影响范围

73009e2e-7f9f-4c28-9299-6452e0838909.png

由于 WordPress 占据了全球内容管理系统的极大份额,任何核心级别的免认证 RCE 都意味着海量站点在补丁落地前处于暴露状态。攻击者往往会在漏洞披露后的数天内展开大规模自动化扫描与利用,因此“是否已升级”几乎直接决定了一个站点在这波风暴中的生死。

受影响版本

a09dd8da-057b-490b-83b2-efccb4a353d5.png


工作原理

REST 批处理端点()未经过认证,并运行多个子请求 调用,依赖于每个子请求单独验证和权限检查。/batch/v1

serve_batch_request_v1()构建两个并行数组——(匹配处理程序 per 子请求)和(每个子请求的验证结果)——然后对它们进行索引,分别为 调度时的偏移是一样的。路径失败的子请求会被附加到,但不附加到,因此数组会脱离步进,子请求为 在另一个子请求的处理程序下被派遣。这就是路线混乱。$matches$validationwp_parse_url()$validation$matches

PoC 对原始件进行了两次嵌套:

  1. 携带身体的请求会在批次下被派遣 操控者本身。既然被验证为帖子请求,其列表从未被检查 与批处理模式相对于,因此其子请求可以使用 —— 方法允许列表为 被绕过了。POST /wp/v2/postsrequestsrequestsGET

  2. 在该内部批处理中,条目路由请求包含帖子收集 查询参数如 、 和 。ID不需要 存在;只是一个不太可能的帖子ID用来匹配物品路线,而其模式并不匹配 验证那些仅限集合的参数。desync随后在post下派发相同的请求,其中映射到查询var,其中 该易受攻击的构建以字符串形式插值到 SQL。GET /wp/v2/posts/999999author_excludeorderbyper_page999999get_items()author_excludeWP_Queryauthor__not_in

结果是一个基于布尔和时间的盲SQL注入,可在认证前实现。这个有色人种 还包括SQLi到管理员链中使用的UNION假后期原语。

这里实现的RCE路径如下:

  1. 使用UNION假行通过帖子集合渲染攻击者控制的内容。 渲染桥使用了 item-route 源代码——也就是 SQLi 读取的同一条路径 用于达到。wp_posts/wp/v2/posts/999999get_items()

  2. 用那个渲染图让WordPress创建真正的oEmbed缓存帖子。

  3. 通过SQLi恢复那些真实的缓存帖子ID。

  4. 在一个中毒批次请求中,将这些ID重新铸造成自定义器变更集、导航项,以及 请求钩子形状。

  5. 设同一个请求到达 ,创建一个生成的管理员。POST /wp/v2/users

  6. 以生成管理员身份登录,使用插件上传行为执行命令。

环境要求

Python 3.8+ 和标准库。没有第三方依赖。


检查——非破坏性漏洞检查

先打印被动的WordPress标记和公开版本提示,然后发送一个良性的批处理标记 探针。一个易受攻击的批处理实现返回HTTP 207,其路由混淆标记模式为 、 , , 。parse_path_failedblock_cannot_readrest_batch_not_allowed

标记探针基于WordPress核心修复。该错误请求会生成;请求作为批次允许的间隔器;该路由不允许批量处理,但如果 汉德勒是匿名联系的; 给出 。在脆弱构建上 解析错误会使批处理数组偏离步阶,因此分派了间隔器请求 在块渲染器处理器下。固定构建保持数组对齐,所以这三者全部都是这样 该探针不应出现图案。///parse_path_failed/wp/v2/posts/wp/v2/block-renderer/...block_cannot_read/batch/v1rest_batch_not_allowed

默认情况下,会停止,不会发送SQLi负载。当你使用 还想要一个有效的SQLi确认。确认先尝试 UNION 读取原语,并且 如果无法进行UNION反射,则退回配对定时探针。check--confirm-sqli

信号是独立的:版本提示只是提示,标记图案显示路线 显示有有效载荷进入数据库。WAF可以阻挡有效载荷, 所以确认失败并不能证明漏洞不存在。--confirm-sqli

./wp2shell.py check http://target
./wp2shell.py check targets.txt          # scan every URL in the file

读取——通过SQL注入提取数据

./wp2shell.py read http://target                      # server fingerprint
./wp2shell.py read http://target --preset users       # user logins and password hashes
./wp2shell.py read http://target --query "SELECT @@version"

默认情况下,提取为 ,尝试以下顺序使用可用方法:--technique auto

  1. union — 伪造一行通过并从 REST 读取其标题 响应为 。有效载体使用相同的源路径,因此假行作为渲染帖子存活。每人一个请求 价值。WP_PostUNION||HEX(value)||/wp/v2/posts/999999orderby=noneper_page=500

  2. 错误 — / 每次请求泄漏 ~15字节,当目标反映 MySQL 错误(例如 在)。EXTRACTVALUEUPDATEXMLWP_DEBUG_DISPLAY

  3. 搜索 — 布尔二分查找,每个字符~8次请求;将帖子集合头读取为真/假信号,无需反射值。X-WP-Total

力一,且 。这些读取路径不写数据库行。--technique union|error|blind

shell — 命令执行

使用和,登录时会使用提供的管理员凭证和使用方式 WordPress 插件上传行为。--user--passwordshell

没有凭据时,先运行预授权的SQLi到管理员桥,登录时生成的 管理员,然后上传插件壳。shell

./wp2shell.py shell http://target --user admin --password '<recovered>' --cmd id
./wp2shell.py shell http://target --user admin --password '<recovered>' -i   # interactive shell
./wp2shell.py shell http://target --cmd id                                   # pre-auth bridge
./wp2shell.py shell http://target -i                                         # pre-auth interactive

选项


选项

适用于

描述

--proxy URL

全部

通过HTTP代理(例如Burp)路由流量。

--timeout N

全部

请求超时。

--sleep N

检查

时序备回使用的延迟。--confirm-sqli

--samples N

检查

时序回退时使用的时序对。--confirm-sqli

--confirm-sqli

检查

同时发送一个活跃的SQLi确认有效载荷。

--preset

阅读

fingerprint或 。users

--technique

阅读

auto(默认)、(带内,伪造帖子)、(带内,需要可见的数据库错误),或 。unionerrorblind

--query

阅读

一个标量SQL表达式,需要读取。

--prefix

阅读

数据库表前缀(默认)。wp_

--max-length N

阅读

每个数值可读的最大字符数(默认128个)。

--user / --password

贝壳

可选管理员凭证;省略两者,使用预授权桥接。

--cmd

贝壳

执行命令(使用时省略)。-i

-i / --interactive

贝壳

部署后打开一个交互式 shell。

poc下载

项名称

链接

wp2shell

wp2shell-poc-main.zip