升级的几秒钟就是攻击窗口:WordPressCore未认证RCE深度分析(CVE-2026-119977·附PoC)"

admin 2026-11-06 02:48:49 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

升级的几秒钟就是攻击窗口:WordPress Core 未认证 RCE 深度分析(CVE-2026-119977·附PoC)

原创

赤霄攻防实验室
赤霄攻防实验室

赤霄攻防实验室

2026年11月5日 17:13
河北

去阅读

WordPress 昨天发了一个安全更新,今天凌晨 CISA 就把它列入了在野利用清单。这不是又一个「理论上可利用」的漏洞——攻击流量在补丁发布后 9 分钟就出现了,24 小时内一家安全厂商就拦截了 62,969 次攻击尝试。本篇完整拆解这个编号 CVE-2026-119977 的升级窗口竞争条件漏洞:它为什么不需要任何账号、为什么九年来一直存在、以及我们本地复现的全过程。

TL;DR 四行速览:
● 是什么:WordPress 核心升级流程的 TOCTOU 竞争条件(CWE-367),升级解包的数秒窗口内,未认证攻击者可抢占暂存安装器实现 RCE
● 影响谁:WordPress 4.7.0–7.1.3,25 个分支全部在列(约 2016 年至今所有版本)
● 怎么修:升级到所在分支修复版(7.1.4 / 7.0.8 / 6.9.11 … 4.7.39);升级前先封禁 wp-content/upgrade 的 Web 访问
● 看点:漏洞窗口只有几秒却挡不住攻击者轮询;修复仅三处改动但精确拆掉整条链——本篇含实测 diff 与本地复现

一、几秒钟的窗口,怎么就成了 RCE

先说结论:这个漏洞的核心不是某个函数写错了,而是一个「检查」与「使用」之间的时间差被武器化了。

WordPress 升级核心有两条路径:增量更新只替换改动文件;而全量包升级(大版本跨越、手动重装、部分托管环境默认走的方式)会先把完整的新版压缩包解压到一个暂存目录,校验完成后再复制到站点根目录。问题出在暂存目录的位置和名字:wp-content/upgrade/wordpress-版本号/——目录名就是包文件名,而官方包的命名规则是公开且固定的。

这意味着两件事。第一,这个目录在绝大多数服务器配置下可以被 HTTP 直接访问(它就在 wp-content 下,而 wp-content 本来就是 Web 可达的);第二,攻击者不需要任何信息收集,升级一开始就能算出暂存路径。更关键的是,解压出来的完整 WordPress 里包含 wp-admin/setup-config.php 和 install.php 这两个安装器文件——它们本来只该在全新安装时出现,现在却随每次升级短暂地暴露在 Web 上。

攻击者要做的就是写一个死循环脚本,反复请求「站点地址 + /wp-content/upgrade/wordpress-7.1.4/wp-admin/setup-config.php」这样的 URL。平时全是 404,无所谓,成本约等于零;一旦某次请求恰好落在解包完成到清理目录之间的几秒钟里,返回的就是一个活的、未认证的 WordPress 安装器。Wordfence 的实验室观测显示这个窗口通常只有几秒,但攻击者可以对着成千上万个站点同时轮询——攻击数据显示有源 IP 对同一小组站点持续轮询了 14.5 小时,就为等一次自动更新触发。

二、从安装器到代码执行:后半段链路

命中窗口只是开始。setup-config.php 是 WordPress 的配置向导,它的职责是把数据库凭据、认证密钥等写入 wp-config.php。攻击者与暂存目录里的这份安装器交互,本质上是操控了一个「半配置状态」的 WordPress——他提供的配置数据会被写入暂存目录内的 wp-config.php。

真正的杀伤在升级流程的后半段:核心复制阶段会把暂存目录里的文件整体提升到站点根目录。我们核对了 7.1.3 的源码,update-core.php 第 1549 行的复制跳过名单只有两项——wp-content 和 wp-includes/version.php。wp-config.php 不在名单里。也就是说,攻击者诱导写入暂存目录的任何东西,都会在复制阶段被原样搬进正在升级的站点。这就是从「抢占安装器」到「服务器端 PHP 代码执行」的完整闭环,全程不需要任何账号,攻击复杂度评了 High(AC:H)仅仅因为要赌时间窗。

补充一个容易被忽略的细节:这也是 KEV 收录理由里强调「升级窗口」的原因——站点不升级,漏洞就不触发;一旦开始升级,风险瞬间从零跳到 RCE。安全团队往往在升级时刻反而是最脆弱的,这个反直觉事实值得写进每份运维手册。

三、本地复现:可预测路径直达安装器

我们在本地搭了环境实测这条链路的前半段。构造方式与真实升级一致:下载 WordPress 7.1.3 官方包,按升级器的行为解压到 wp-content/upgrade/wordpress-7.1.3/(7.1.3 及之前版本的暂存目录名就长这样),然后模拟外部攻击者的请求。

结果毫无悬念:GET /wp-content/upgrade/wordpress-7.1.3/wp-admin/setup-config.php 返回 HTTP 200,响应体 13,837 字节,页面标题正是 WordPress 安装器的「Setup Configuration File」——一个未认证的、活的安装器界面。从发起请求到拿到安装器交互界面,中间没有任何认证层。后半段(写入半配置状态并等待提升)涉及对测试目标的实际写入操作,本篇止步于源码级验证:对照 7.1.3 与 7.1.4 的 update-core.php,跳过名单从两项变三项的差异就是铁证。

基于同样的机制,我们写了一个非破坏性验证脚本(已开源,见文末参考链接):指纹识别 WordPress 及版本 → 对照 25 个分支的影响矩阵 → 探测暂存安装器端点(纯 GET,零写入)→ 输出 VULNERABLE / PATCHED / UNKNOWN 三态结论。本地靶场验证三态全部按预期工作:暂存目录存在时判 VULNERABLE 并给出命中路径;版本 ≥ 修复版直接判 PATCHED;版本受影响但窗口未开时诚实输出 UNKNOWN 并建议持续轮询。它不能替代升级,但能让运维在升级前知道自己的窗口是否已被盯上。

四、修复拆解:三处改动拆掉整条链

WordPress 7.1.4 的修复没有大改架构,而是精确卡死了攻击链的三个环节,并为从 4.7 到 7.1 的每个分支都发布了对应的 backport 版本。

第一处,也是最主要的一处:升级器新增 get\_working\_dir\_name() 方法,暂存目录名在包名基础上追加 16 位随机后缀(wp\_generate\_password 生成)。轮询脚本从此失去目标——你可以猜到目录前缀,但猜不到那 16 个字符。第二处:复制阶段的跳过名单显式加入 wp-config.php,就算攻击者在窗口内碰到了安装器,写入的半配置状态也不会被提升到站点根。第三处:升级前在 upgrade/ 目录写入 index.php(「Silence is golden」),目录名无法通过目录列表探出——这是 WordPress 对 wp-content 及其子目录的标准加固惯例,现在补齐了最后一块。

三个动作分别对应「藏住目标、切断提升、堵住枚举」,任何一处独立生效都能大幅缩窄风险,三处叠加让这条链在 7.1.4 上不再成立。这种「不修大架构、只拆链路关键环节」的修复思路,对自研系统的漏洞处置很有参考价值。

五、在野攻击与时间线

这个漏洞的披露节奏非常快,快到防御方几乎没有喘息窗口:

10 月 28 日,WordPress 发布 7.1.4 安全更新(含 22 项修复),当日 20:30 UTC Wordfence 向付费用户推送虚拟补丁规则;规则上线9 分钟后就拦截到第一次攻击尝试;随后 21 小时内拦截 18,500+ 次请求,24 小时累计 62,969 次。10 月 31 日 CVE 正式发布(CVSS 8.1)。11 月 3 日 CISA 将其收入 KEV 目录,要求联邦机构 11 月 6 日前完成处置——从补丁发布到 KEV 收录只用了 6 天,攻击者与防御方在同一个时间窗里赛跑。

值得注意的信号:Wordfence 免费版用户要到 11 月 27 日才能拿到虚拟补丁,这 30 天差值正是开源社区需要自己扛的窗口期。如果你的站点装了防火墙插件,还要确认它以「扩展保护」模式运行——这个利用直接请求暂存 PHP 文件,根本不经过 WordPress 主程序,常规的请求钩子拦不住。

六、给运维的三步处置清单

第一步,先封路再升级。漏洞触发条件是「升级时刻」,所以正确顺序是:先在 Web 服务器层拒绝 /wp-content/upgrade/ 的所有外部请求(nginx 加一个 location 段 deny all,Apache 放 .htaccess,CDN/WAF 加路径规则同理——WordPress 读写这个目录走文件系统,封 HTTP 完全不影响升级),然后再去点更新按钮。顺序反了,你就可能在最脆弱的几秒里被命中。

第二步,确认版本到达修复线。7.1.4、7.0.8、6.9.11、6.8.12、6.7.11、6.6.11、6.5.14、6.4.14、6.3.14、6.2.15、6.1.16、6.0.18,以及 5.x / 4.x 各分支对应的 backport 版本。别只看自动更新是否开启,去仪表盘确认实际版本号;用 Composer 或流水线管理的站点尤其容易漏掉这次后台自动更新。4.6 及更早的版本没有补丁,直接迁移到受支持分支。

第三步,回溯排查。如果站点在 10 月 28 日后做过全量升级,翻一遍访问日志:任何对 wp-content/upgrade/ 下 PHP 文件的请求都值得警惕,返回 200 的优先处理;对 setup-config.php 或 install.php 的 POST 请求且响应 200,按疑似失陷处置——检查新增管理员账号、uploads 和 upgrade 目录里新出现的 PHP 文件、wp-config.php 与 mu-plugins 是否被改动。

参考

● WordPress 7.1.4 安全公告(修复版本与致谢名单)
https://wordpress.org/news/2026/10/wordpress-7-1-4/

● Wordfence 情报页(影响矩阵、修复版本全表)
https://www.wordfence.com/threat-intel/vulnerabilities/wordpress-core/wordpress-core-470-713-unauthenticated-upgrade-window-staged-installer-remote-code-execution

● Wordfence 博客:在野攻击数据与防火墙规则说明
https://www.wordfence.com/blog/2026/10/wordpress-7-1-4-security-release-rce/

● CISA KEV 收录条目(2026-11-03,处置期限 11-06)
https://www.cisa.gov/known-exploited-vulnerabilities-catalog

● 本篇验证脚本 poc.py(三态判定,非破坏性)
https://github.com/Rubby2001/CVE-POCS/tree/main/CVE-2026-119977

CTA:本篇验证脚本已开源,运维同学可直接对自有站点做升级前自查。更多漏洞深度分析与实测复盘,戳下方关注不迷路。

免责声明:本篇内容仅用于防御研究与授权安全测试,任何未经授权的利用行为均属违法。转载请注明出处「赤霄攻防实验室」。

    评论:0   参与:  0