今日发生可怕的事情,网站莫名其妙打开成了白板,起初以为是插件冲突导致的,赶紧登录后台查看,但是却没有发现异常。于是登录了服务器,不看不知道,一看吓一跳。多增加了一个匿名的插件:

然后入侵者还干了一件好事:

我去,天都快塌了。然后快速查找入侵痕迹:
find -type f -name '*.php' -mtime 1哗啦啦,还好变更的文件没有几个,快速清理掉。代码中数据增加了管理员,在一通清理掉多余的管理员及相关权限。update wordpress 7.0.4。干净了!
事后搜索了下相关问题,然后进行了分析。
| 名称 | 详情 |
|---|---|
| 漏洞编号 | CVE-2026-63030 |
| 关联漏洞 | CVE-2026-60137 (author__not_in SQL 注入) |
| 严重等级 | Critical(可远程代码执行) |
| 发现者 | Adam Kues / Searchlight Cyber |
1. 漏洞链原理
该漏洞是双漏洞组合利用链,需要两个漏洞同时存在:
1.1 漏洞一:REST API batch 路由混淆(CVE-2026-63030)
WordPress REST API 提供批量端点 /wp-json/batch/v1,允许客户端在单次 HTTP 请求中打包多个子请求,服务端按序执行并聚合返回。
核心问题: batch 端点在执行子请求时,对每个子请求的权限验证存在路由混淆——子请求可以绕过自身的权限注册检查,执行到原本应该需要更高权限才能访问的端点。
具体来说,攻击者可以通过 batch 请求将一个不需要认证的子请求包装成另一个需要认证的子请求的上下文,从而绕过 permission_callback 检查,让一个低权限用户(甚至匿名)执行本应仅管理员可访问的 REST API 端点。
1.2 漏洞二:WP_Query 的 author__not_in 参数 SQL 注入(CVE-2026-60137)
WordPress 在 WP_Query 处理 author__not_in 参数时,未对输入做充分的转义处理,导致 SQL 注入。
该漏洞单独利用时,仅允许已认证用户查询数据库(facilitated SQL injection),危害有限。但与漏洞一组合后,攻击者可以:
1. 通过 batch 路由混淆,以低权限身份调用需要管理员权限的端点
2. 在该端点中触发 author__not_in 的 SQL 注入
3. 通过 SQL 注入写入 webshell
4. 实现远程代码执行(RCE)
2. 攻击链复现
阶段一:Batch 路由混淆
curl -X POST "https://某某某.com/?rest_route=%2Fbatch%2Fv1" -H "Content-Type: application/json;charset=UTF-8" -H "ContentType: application/json" -d '{
"requests": [
{"method": "POST", "path": "///"},
{"method": "POST", "path": "/wp/v2/posts"},
{"method": "POST", "path": "/wp/v2/block-renderer/core/paragraph"},
{"method": "POST", "path": "/batch/v1", "body": {"requests": []}}
]
}' -H "Content-Type: application/json" 攻击者通过 batch 端点提交请求时,子请求的 path 被错误地路由到一个需要管理员权限的端点上,但权限检查在 batch 层面被跳过。
阶段二:SQL 注入
在 author__not_in 参数中注入 SQL,利用 WP_Query 的缺陷读取数据库内容。
阶段三:写入文件 → RCE
通过 SQL 注入的 INTO OUTFILE 或 SELECT ... INTO DUMPFILE 将 webshell 写入 WordPress 可写目录,或直接修改模板文件注入 PHP 代码,最终实现远程代码执行。
3. 漏洞根因分析
3.1 batch 端点的架构缺陷
WordPress REST API 的 batch 机制被重构,其设计目标是减少客户端的 HTTP 往返次数,提升性能。但在实现上存在一个根本性问题:
batch/v1 → 解析子请求 → 路由分发 → 权限检查
↑
此处路由解析存在歧义
子请求 path 可以被错误匹配
到错误的注册路由上当 batch 端点处理子请求时,它没有严格按照每个子请求的原始注册路由进行权限验证,而是走了一条简化的路由解析路径,导致某些需要认证的端点被错误地当作公开端点执行。
3.2 author__not_in 的 SQL 构造缺陷
WP_Query 在处理 author__not_in 时,预期接收的是一个数字数组(用户 ID 列表),但实际实现中:
1. 未严格验证输入类型(期望 int[],实际接收了字符串)
2. 直接拼入 SQL 语句的 NOT IN 子句
3. 缺乏参数化查询或 $wpdb->prepare() 处理
$author_ids = $_GET['author__not_in']; // 未过滤
$sql .= " AND ID NOT IN ($author_ids)"; // 直接拼入 SQL4. 危害评估
| 维度 | 评级 |
|---|---|
| CVSS 评分 | 9.8(Critical) |
| 攻击复杂度 | 低(无需认证或低权限) |
| 用户交互 | 无需 |
| 可利用性 | 高 |
实际影响
1. 数据泄露:通过 SQL 注入读取数据库(用户表、选项表等)
2. 文件写入:向服务器写入任意 PHP 文件(webshell)
3. 服务器沦陷:通过 webshell 执行系统命令,完全控制服务器
4. 横向扩散:以被攻陷站点为跳板攻击同服务器上的其他站点

5. 参考链接
- WordPress 7.0.2 Release
- GHSA-ff9f-jf42-662q(CVE-2026-63030)
- GHSA-fpp7-x2x2-2mjf(CVE-2026-60137)
- WordPress 7.0.4 Release