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

一句话摘要 :
wp2shell(CVE-2026-63030)是 WordPress 核心中的免认证远程代码执行漏洞。攻击者无需登录、无需目标站安装任何插件,即可对标准安装的 WordPress 直接发起攻击并接管服务器。
技术剖析
根据 WordPress 官方公告与多家安全厂商的分析,wp2shell 的根因可概括为:REST API 批处理路由 /wp-json/batch/v1 存在“路由混淆(route confusion)”,叠加 SQL 注入,注入被链式利用后最终打通到远程代码执行。

REST API 与批处理路由
WordPress 自 4.7 起内置 REST API,其中的批处理(batch)接口允许在单个 HTTP 请求中打包多个子请求。这类“请求聚合”入口一旦在路由解析或参数处理上出现偏差,就可能被用来触及本不该匿名访问的内部逻辑——这正是本次问题的入口点。
为什么是“老问题”却又如此严重
SQL 注入常被认为是“已解决的历史问题”,但它依旧不时出现在核心 软件与依赖库中,且往往在补丁发布前就能被匿名用户触及。当注入点位于框架核心、且无需认证时,其影响会被使用量急剧放大——这也是 wp2shell 值得高度重视的原因。
影响范围

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

工作原理
REST 批处理端点()未经过认证,并运行多个子请求 调用,依赖于每个子请求单独验证和权限检查。/batch/v1
serve_batch_request_v1()构建两个并行数组——(匹配处理程序 per 子请求)和(每个子请求的验证结果)——然后对它们进行索引,分别为 调度时的偏移是一样的。路径失败的子请求会被附加到,但不附加到,因此数组会脱离步进,子请求为 在另一个子请求的处理程序下被派遣。这就是路线混乱。$matches$validationwp_parse_url()$validation$matches
PoC 对原始件进行了两次嵌套:
携带身体的请求会在批次下被派遣 操控者本身。既然被验证为帖子请求,其列表从未被检查 与批处理模式相对于,因此其子请求可以使用 —— 方法允许列表为 被绕过了。
POST /wp/v2/postsrequestsrequestsGET在该内部批处理中,条目路由请求包含帖子收集 查询参数如 、 和 。ID不需要 存在;只是一个不太可能的帖子ID用来匹配物品路线,而其模式并不匹配 验证那些仅限集合的参数。desync随后在post下派发相同的请求,其中映射到查询var,其中 该易受攻击的构建以字符串形式插值到 SQL。
GET /wp/v2/posts/999999author_excludeorderbyper_page999999get_items()author_excludeWP_Queryauthor__not_in
结果是一个基于布尔和时间的盲SQL注入,可在认证前实现。这个有色人种 还包括SQLi到管理员链中使用的UNION假后期原语。
这里实现的RCE路径如下:
使用UNION假行通过帖子集合渲染攻击者控制的内容。 渲染桥使用了 item-route 源代码——也就是 SQLi 读取的同一条路径 用于达到。
wp_posts/wp/v2/posts/999999get_items()用那个渲染图让WordPress创建真正的oEmbed缓存帖子。
通过SQLi恢复那些真实的缓存帖子ID。
在一个中毒批次请求中,将这些ID重新铸造成自定义器变更集、导航项,以及 请求钩子形状。
设同一个请求到达 ,创建一个生成的管理员。
POST /wp/v2/users以生成管理员身份登录,使用插件上传行为执行命令。
环境要求
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
union — 伪造一行通过并从 REST 读取其标题 响应为 。有效载体使用相同的源路径,因此假行作为渲染帖子存活。每人一个请求 价值。
WP_PostUNION||HEX(value)||/wp/v2/posts/999999orderby=noneper_page=500错误 — / 每次请求泄漏 ~15字节,当目标反映 MySQL 错误(例如 在)。
EXTRACTVALUEUPDATEXMLWP_DEBUG_DISPLAY盲搜索 — 布尔二分查找,每个字符~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