WordPress wp2shell 漏洞复盘:REST API 批处理路由混淆一路杀到 RCE

摸鱼大王.
42

前言

今天群里有人甩了条安恒的漏洞通告过来,标题挺唬人——WordPress REST API 批处理路由混淆与 SQL 注入远程代码执行漏洞,CVSS 9.8。我自己就是 WordPress 跑的博客,这种「未授权 RCE」级别的洞,不管三七二十一先看一眼。

看完原文又去翻了一圈官方公告和研究团队原文,发现通告里只提了一个 CVE,实际是两个 CVE 串在一起的链条利用。而且影响范围也比原文写的更广——6.8 分支也中招。这里记一下,免得后面自己又忘了。

漏洞概览:wp2shell,一条链杀到 RCE

这次漏洞代号 wp2shell,由 Searchlight Cyber 的安全研究团队 Adam Kues 报告。核心是 WordPress 核心代码里两个问题串起来:

  • CVE-2026-63030:REST API /batch/v1 端点的路由混淆。处理批量子请求时,serve_batch_request_v1() 构建了 $matches(处理程序)和 $validation(验证结果)两个并行数组。但当子请求路径在 wp_parse_url() 解析失败时,该子请求只被追加到 $validation,没进 $matches数组错位了,后续子请求就被错配到别的处理程序上。
  • CVE-2026-60137:借着上面的错位,攻击者把 GET 参数(如 author_exclude)塞进内层 POST 请求里。这个参数到了 WP_Query没经过净化就直接拼到 SQL 语句里,形成布尔型 + 时间型盲注。

光 SQL 注入已经够烦了,但作者把链拉满了:通过注入读数据库 → 拿到管理员密码哈希 → 离线破解 → 后台上传恶意插件 → 任意代码执行。从「未授权」一路杀到「拿 shell」,这就是 wp2shell 名字的由来。

CVSS 9.8,攻击复杂度低,无需任何权限,无需用户交互,通过网络直接可达。500万+ WordPress 站点都在射程内。

影响范围:6.8 也在里面,别只看 7.0

安恒原文只写了 6.9.0-6.9.4、7.0.0-7.0.1。但去 WordPress 官方公告一看,6.8 分支也受影响(只中了第一个 CVE,没中第二个,但也得修)。完整范围如下:

  • WordPress 6.8.0 - 6.8.5(仅 CVE-2026-60137)
  • WordPress 6.9.0 - 6.9.4(两个 CVE 全中)
  • WordPress 7.0.0 - 7.0.1(两个 CVE 全中)
  • WordPress 7.1 beta1(两个 CVE 全中)

6.8 之前的版本不受影响。安全版本是 6.8.6 / 6.9.5 / 7.0.2 / 7.1 beta2

我自己的站是 7.0.1,正好在坑里。 表情包

技术原理:数组错位是怎么发生的

这块我边看边记,方便理解。REST API 的 batch 端点允许一次请求里塞多个子请求,本意是减少 HTTP 往返。处理逻辑大概是这样:

  • 遍历每个子请求,用 wp_parse_url() 解析它的 path。
  • 根据解析结果,把对应的处理程序追加到 $matches,把验证结果追加到 $validation
  • 两个数组按下标一一对应,后续按 $matches[i] 取处理程序,$validation[i] 取验证结果。

坑在哪?wp_parse_url() 解析失败时(比如构造了畸形的 path),代码只往 $validation 追加,没往 $matches 追加。$matches 少了一个元素,下标全错位。第 N 个子请求拿到的处理程序,其实是第 N+1 个的。

攻击者就利用这个错位:把一个本该走 A 处理程序的请求,送到本该走 B 处理程序的逻辑里。B 处理程序恰好接受 author_exclude 这种 GET 参数,并把它喂给 WP_Query。WP_Query 没对这个参数做类型/格式校验,直接拼进 SQL。注入就成立了。

盲注虽然慢,但稳。一点点把 wp_users 表里的 user_pass 字段 dump 出来,拿到 phpass 哈希,离线爆破。WordPress 默认用户名 admin 加弱口令哈希,破解不算难。拿到管理员账号后,后台「上传插件」上传个伪装成 .zip 的恶意插件,激活,shell 就落地了。

整个链路零前置条件——不需要插件,不需要特殊配置,开箱即用的 WordPress 就能打。

自查:先看自己中没中

三步:

  • 看版本:后台「仪表盘 → 更新」或者首页右下角的「概览」能看到当前版本。在 6.8.0-6.8.5、6.9.0-6.9.4、7.0.0-7.0.1、7.1 beta1 范围内的,全中。
  • 用官方检测工具:研究团队放了个在线检测站点 wp2shell.com,输自己的域名就能扫。
  • 查日志:翻 Nginx access log,找路径含 /wp-json/batch/v1?rest_route=/batch/v1 的异常批量请求。短时间内大量这种请求,基本就是被探测了。

修复:能升级就别拖

官方 7 月 17 日发了强制自动更新,受影响版本的站点大部分应该已经自动升上去了。手动升级的话:

  • 7.0 分支 → 升到 7.0.2
  • 6.9 分支 → 升到 6.9.5
  • 6.8 分支 → 升到 6.8.6
  • 7.1 测试分支 → 升到 7.1 beta2

后台「更新」页面点「立即更新」,或去 WordPress.org 下载 7.0.2 手动覆盖。升级前备份数据库和文件,别偷懒。

临时缓解:暂时升不了怎么办

如果暂时没法升级(比如改过核心代码、插件兼容性没测完),先做应急:

  • WAF 拦截:在 Nginx 或 WAF 层拦掉 /wp-json/batch/v1?rest_route=/batch/v1 两条路径。我是直接在 Nginx 加了几行:
# 拦掉匿名访问的 batch API
location ~ ^/wp-json/batch/v1 {
    if ($http_authorization = "") {
        return 403;
    }
}

# 拦掉 rest_route 查询参数形式
if ($arg_rest_route ~* "^/batch/v1") {
    return 403;
}
  • 插件禁用:装个 Disable WP REST API 之类的插件,直接禁掉匿名用户的 REST API 访问。风险是可能影响部分依赖 REST API 的功能(比如区块编辑器、某些插件的回调)。
  • Searchlight Cyber 的应急插件:研究团队放了个自定义插件 disable-batch-api-for-unauth.php,放到 wp-content/plugins/ 下启用,强制 REST Batch API 需身份验证。比全局禁用 REST API 影响面小。

这几个都是临时措施,可能影响合法业务,升级到安全版本后记得撤掉。

小结

这次 wp2shell 漏洞几个关键点记一下:

  • 两个 CVE 的组合链,不是单点。光看安恒通告只提了 63030,容易漏掉 60137。
  • 6.8 分支也受影响(只中 60137),别只盯着 6.9/7.0。
  • 从路由混淆 → SQL 注入 → 读密码哈希 → 上传插件 → RCE,整条链零前置条件,开箱即用就能打。
  • 官方已强制自动更新,先确认自己站是不是已经升上去了。没升的赶紧手动升。
  • 暂时升不了的,WAF 拦 /batch/v1 是最简单的应急。

安全这事儿,没有「小站不会被盯上」这一说。扫描器是无差别扫的,你的站只要暴露在公网,就在候选名单里。该升就升,别拖。

摸鱼小窝」 (blog.aistu.cn)版权所有,引用、转载时必须标明原文出处!

Comments | NOTHING

    加载中

消息盒子
# 消息加载中 #