一幅生成式抽象插画,底色为浅灰蓝色,以扁平矢量几何图形绘制。左侧,由相同的小描边方块构成的密集网格代表一个加固的代码库;最边缘的一个方块以琥珀色绘制,并延伸出一条极细的路径。这条路径穿过一道若隐若现的垂直边界,随后分成两条平行的细线,穿过右侧由细连接线和节点构成的较疏松网络,最终汇聚到半透明青色晕染层上方一个很小的实心琥珀色节点上。一条短而淡的虚线标出两根连接线与相邻连接线错位的位置。画面中不出现任何文字、数字、人物、品牌标识或组织标志。OrcaRouter 标志合成在右下角。
AI Safety Incidents

wp2shell:一个原版 WordPress RCE,仅花 25 美元、十小时就被发现

作者

Rowan Sterling

发布日期

最新模型 · 20查看全部模型 →
基准测试:Artificial Analysis · 每日更新
返回全部文章

2026年7月17日,Searchlight Cyber 发布了 wp2shell,这是一个针对 WordPress 核心的认证前远程代码执行利用链,无需插件、无需主题,也无需登录。只需向默认安装发起一个匿名请求即可:“该攻击没有任何前提条件,在未安装任何插件的 WordPress 默认安装中,匿名用户即可利用它,”该公司的公告称。该利用链串联了两个漏洞——CVE-2026-63030,即 WordPress REST API 批量端点中的一个路由混淆漏洞,项目公告将其评为严重;以及 CVE-2026-60137,即 WP_Query 的 author__not_in 参数中的 SQL 注入,公告将其评为中危。WordPress 于同日发布了 WordPress 7.0.2,项目公告将 WordPress 6.9.5、WordPress 6.8.6 和 WordPress 7.1 beta2 列为包含相同修复的版本。Searchlight 引用估计称,WordPress 站点超过 5 亿个。该利用链背后的研究员 Adam Kues 表示,它源自一次 GPT-5.6 Sol Ultra 运行,该运行基于 OpenAI 为一道数学问题发布的提示词构建:最多四个智能体,至少六小时用于搜寻,另约四小时用于升级利用,模型使用费用约为 25 美元。该记录被归档为一项研究发现——按该档案自身的标准属于高严重性,A 级置信度,未记录到现实世界的危害,日期标注为单日——而 the Orca AI Incident Archive 收录了它,并在其下方链接了原始文件。

此次披露是协调进行的。Searchlight 于7月17日暂未公布利用机制,并给防御者留出周末时间进行升级;Kues 于7月20日发布了完整的技术说明。到那时,链式漏洞利用已被独立复现:Searchlight 表示,Calif 和 Hacktron 在其他概念验证出现在 GitHub 之前重建了完整攻击链。WordPress 自己的两份安全公告列出了相同的修复版本,CISA 于7月21日将两个 CVE 都加入了其“已知被利用漏洞”目录。

两个缺陷,以及失去同步的数组

该入口点是有意设计的功能,而不是错误。WordPress 5.6 于 2020 年引入了批量端点,使客户端可以在一个 HTTP 请求内发送多个虚拟 REST 请求,例如一次性更改一组文章的标题。无论调用方是否已认证,该端点都可访问,并且每个子请求都会携带调用方提供的任何认证信息。对 WordPress REST 路由的直接请求会执行四步流水线:检查必需参数和有效参数,对它们进行清理,运行权限回调,然后执行端点回调。端点依赖该流水线来满足其类型假设——文章 ID 是整数,标题是字符串。

批量 API 将流水线拆分为两个阶段:在一个循环中验证每个子请求,在第二个循环中执行它们;它维护两个数组,$matches 和 $validation,这两个数组的条目本应按索引逐一对应。在 class-wp-rest-server.php 中,正如 Kues 所描述的那样,一个本身就是 WordPress 错误的子请求会被追加到 $validation,然后碰到 continue,从而跳过将它追加到 $matches 的那一行。从那时起,每个匹配项都会向后错位一位。执行循环会把某个索引处的子请求与该索引处记录的验证结果配对,但处理程序却匹配到了不同的路由——于是某个参数会按照一个端点的规则进行检查,然后由另一个端点的代码执行。

正是这一点,将一个看似普通的列表参数变成了注入。文章集合路由将其公开的 author_exclude 参数映射到 author__not_in。当值为数组时,WordPress 会对每个元素运行 absint 并对其进行排序;当值为标量时,它会被原样拼接到 SQL 片段中,该片段最终变成 NOT IN ($author__not_in)。因此,诸如 0) OR 1=1 -- 这样的字符串会落入查询文本。正常调用时,该路由会拒绝它,因为 author_exclude 必须是整数数组;而失步的批量调用正是让字符串通过的原因。

仍有两个障碍,而这两个障碍都通过嵌套这一手法得到了解决。批量 API 会拒绝 GET 请求,而注入点恰好位于一条 GET 路由上;而对请求方法的校验本身又是以参数校验的形式实现的,同样的不同步即可绕过它。Kues 公布的载荷先发送一个畸形的外层子请求,以打乱方法校验的同步,随后发送一个内层批量请求,其第二个子请求携带恶意的 author_exclude,投给一个并不校验该参数的处理程序,最后是执行它的那个 GET。基于 UNION 的注入会把任意数据库值以形如普通文章的行返回。

A self-built HTML card headed 'wp2shell: what is affected and what fixes it', laying out two columns of version ranges as a scannable table. The left column, labelled CVE-2026-63030, batch route confusion, critical, CVSS 9.8, lists affected WordPress 6.9.0 to 6.9.4 and 7.0.0 to 7.0.1, fixed in WordPress 6.9.5 and WordPress 7.0.2. The right column, labelled CVE-2026-60137, author__not_in SQL injection, moderate, CVSS 5.9, lists affected WordPress 6.8.0 to 6.8.5, 6.9.0 to 6.9.4 and 7.0.0 to 7.0.1, fixed in WordPress 6.8.6, WordPress 6.9.5 and WordPress 7.0.2. A footer strip notes that 7.1 beta2 also carries the fixes and that the full chain needs WordPress 6.9 or later. Small print at the bottom credits the version ranges to the two WordPress security advisories and the scores to the WPScan-assigned CVSS vectors.

模型运行:一个数学提示词,指向一个代码库

Kues 并不是从头编写这个提示词的。OpenAI 曾公布它在研究 Cycle Double Cover 猜想时使用的提示词,而 Kues 写道,他读到该模型最近解决了那个猜想,并且安全社区似乎没有人在谈论这个提示词。他的推理是,如果它足以应对高难度数学,那大概也足以用于安全研究。他对其进行了改编,并将其用于 WordPress。

这套设置是刻意收窄的。他把最新的稳定版 WordPress 克隆到一个名为 main/ 的目录中,并删除了其 .git 目录,告诉模型不要使用变更日志、git 历史或公开互联网来将代码与已修补版本做差异比较——他给出的理由是,对于发现新型漏洞而言,查阅历史或网络是浪费 token。还提供了一个空的 third_party/ 目录,以便模型如果判断该攻击链需要 WordPress 底层库中的漏洞,就能克隆 PHP 或 MySQL 源码等依赖项。任务被指定为在 MySQL 上的典型生产部署中实现预认证 RCE,最多使用四个智能体,且至少六小时。Kues 写道,他明确说明配置要求,是因为否则模型会“作弊”——通过选择极不可能的配置选项,或捏造攻击者永远无法实现的前置条件。

返回的运行输出中,有一个声称存在预认证 SQL 注入的说法。Kues 对此表示怀疑:他写道,WordPress 是有史以来被审计最密集的目标之一,而且在那个十年里从未出现过有实际意义的预认证漏洞。他在一台远程服务器上安装了一个原版 WordPress 实例,然后要求模型窃取管理员的电子邮箱地址;几分钟之内,模型就打印出了他当初用来搭建该实例的地址。随后他又问,这个只读注入能否被进一步提升权限;大约四小时后,模型回答说可以——可以提升到管理员权限,而且无需破解任何密码,也无需进行离线计算。

他自己的成本估算:消耗了每周使用额度的 50%,他按 200 美元订阅费折算约为 25 美元,而这条漏洞利用只用了略超十小时就产出。人力部分并非免费——Kues 第二天花时间弄清了模型做了什么,并写道,他理解后渗透工作所花的时间比生成它要长得多。他的结论异常直白,且限定得很窄:“我不作任何一般性断言,但我可以完全肯定地说,没有安全研究员能在没有 AI 的情况下于 10 小时内发现并完成这条漏洞利用链。”

从只读 SELECT 到管理员

提权是记录中最关键的部分,因为正是在这里,一次数据库读取变成了对服务器的控制。Kues 的叙述将其展开为六个步骤的序列,每一步都利用一个普通的 WordPress 功能来对付另一个功能。

首先,向内存中的文章缓存投毒。WordPress 会为每个请求维护一个 WP_Post 对象缓存,这样在同一次请求中多次引用同一篇文章只需进行一次数据库往返。SQL 注入可以伪造文章,因此攻击者可以精确控制被缓存的内容——但这些伪造的文章并不是数据库中的行,而且缓存会随请求结束而消失。

其次,把伪造的文章变成真实的数据行。WordPress 的嵌入功能会把解析后的嵌入内容作为oembed_cache类型的文章缓存到数据库中。通过相对路径嵌入本地文章,例如[embed]/?p=S[/embed],会让 WordPress 跳过 HTTP 获取,而且从不检查所引用的文章是否存在,因此会创建一行。三个这样的嵌入使用不同的查询字符串标记,会产生三个不同的缓存哈希,攻击者正是借此得到多个可用的数据行。

第三,绕过那个保持固定的字段。当文章的内存版本与数据库版本不一致时,WordPress 会通过一次调用将它们调和一致,该调用会显式地从嵌入输出设置 post_content。文章中除其内容之外的一切都受攻击者控制,而内容恰恰是 customize_changeset用来存储待处理主题和站点更改的 JSON 的字段。

第四,循环装置。文章有父级,而 WordPress 拒绝循环:wp_insert_post_parent 过滤器会沿树向上遍历,一旦发现循环,就会调用一次更新,将 post_parent 设为 0。该调用不会覆盖 post_content,因此伪造的内存中版本在协调后仍会保留——这是一个变更集,其 JSON 完好无损,并由真实数据行支撑。

第五,借用管理员的权限。一个更改集,如果其状态表明计划在未来执行,但日期却在过去,就会被立即应用。其 JSON 中的每个条目都会指定一个 user_id,而 Kues 的链中的条目指定的是 user_id 1,也就是管理员,因此 WordPress 会临时采用该身份来应用这项更改。第一项更改是对 nav_menus_created_posts 的一次看似无害的更新。

第六,以该身份重放请求。发布文章会触发一个动态命名的动作,{status}_{post_type}。由于文章是伪造的,该状态和类型可以是任意值——包括parse和request,这会生成parse_request钩子,并在借用的管理员身份仍然有效时,从头重新启动请求管线。原始批量请求包含一个创建新管理员的子请求;它在第一轮以访客身份失败,而在重放时成功。随后,攻击者以该新账户登录,并从 ZIP 文件上传后门插件,从而实现代码执行。

A self-built HTML card titled 'Six moves from a SELECT to a shell', drawn as six numbered panels in two columns of three. Panel 1, fabricate posts: a UNION injection over the posts collection returns attacker-shaped rows, which WordPress stores in its per-request WP_Post cache. Panel 2, seed embed rows: embedding a local post by relative path writes stored oembed_cache rows, and WordPress never checks that the referenced post exists. Panel 3, content stays fixed: reconciling memory against the database overwrites post_content, the one field a changeset needs for its JSON. Panel 4, break the cycle check: a fabricated parent loop triggers WordPress's own cycle fix, an update that resets post_parent without touching post_content. Panel 5, borrow admin authority: a past-dated customize_changeset whose entries carry user_id 1 is applied as the administrator. Panel 6, replay as admin: a fabricated post with status parse and type request fires the parse_request hook, rerunning the batch so the admin-creation subrequest succeeds. A dark footer bar states that the new administrator then logs in and uploads a backdoor plugin from a ZIP file, which is code execution. No photographs, logos or personal names appear.

这项技术附带一个条件。The Hacker News 援引 Cloudflare 的报道称,CVE-2026-63030 仅在不使用持久对象缓存时才会导致远程代码执行;注入本身从 WordPress 6.8 起就已存在,而完整利用链需要 6.9 或更高版本。默认安装没有持久对象缓存,因此 Searchlight 的“无前置条件”表述与 Cloudflare 的限定说明,是从不同角度描述了同一个默认情形。

主要文件所确立的内容

WordPress 自身的公告是最有力的佐证,因为这是厂商承认了其机理并交付了修复。GHSA-ff9f-jf42-662q 被评为严重级别,描述了 WordPress 6.9 及更高版本中存在的一个 REST API 批量路由混淆弱点,该弱点与注入相结合即可达成代码执行,并致谢 Assetnote 和 Searchlight Cyber 的 Adam Kues。GHSA-fpp7-x2x2-2mjf 被评为中危,描述了自 WordPress 6.8 及更高版本起存在的author__not_in注入,并声明这两个问题均已在 WordPress 7.0.2、WordPress 6.9.5、WordPress 6.8.6 和 WordPress 7.1 beta2 中修复。这两个 CVE 的 NVD 记录由 WPScan CNA 而非 NIST 评分:CVE-2026-63030 得分为 9.8,向量为 AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H;CVE-2026-60137 得分为 5.9,向量为 AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:N/A:N——前者是一个网络可达、无需任何权限的漏洞,后者则需要高攻击复杂度,且仅造成机密性影响。该档案条目自身的严重性字段标注为“高”,而 WordPress 将这一批量缺陷标记为“严重”;这是分别应用于整条攻击链和单个组件的两套不同量表,而非对漏洞本身存在分歧。

CISA 目录中的条目(反映在 NVD 的丰富字段中)于 2026 年 7 月 21 日添加,修复截止日期分别为:CVE-2026-63030 为 7 月 24 日,CVE-2026-60137 为 8 月 4 日。CISA 将前者命名为“WordPress Core 解释冲突漏洞”,后者命名为“WordPress Core SQL 注入漏洞”。Searchlight 还在 wp2shell.com 发布了公开检查工具,使运营人员无需等待扫描器签名即可测试实例。

这次独立复现由 Searchlight 自身记录,因此它是关于第三方的说法,而非第三方叙述:根据 7 月 20 日的文章,Calif 和 Hacktron 在其他概念验证出现在 GitHub 之前重建了完整链条。可独立验证的是其影响——数日内的概念验证、利用流量和厂商遥测数据,详见下文。

A self-built HTML card titled 'Four days from advisory to catalog', drawn as a vertical timeline of five dated rows against a blue rule, the last row in amber. 17 July 2026, disclosure: Searchlight Cyber publishes the wp2shell advisory with the mechanics withheld and WordPress releases 7.0.2, with 6.9.5, 6.8.6 and 7.1 beta2 listed as carrying the same fixes. 18 July 2026, first exploitation: watchTowr reports that by the early hours of Saturday morning UTC successful exploitation was already well underway, initially to exfiltrate hashed credentials. 20 July 2026, full account: Kues publishes the GPT-5.6 Sol Ultra write-up while Wiz publishes an in-the-wild report, with 60 percent of WordPress-using organisations holding a vulnerable instance and 25 percent exposed to the internet, falling to 50 and 10 percent within 24 hours. 21 July 2026, CISA KEV: both CVEs enter the Known Exploited Vulnerabilities catalog. 24 July and 4 August, remediation due: CISA's two deadlines. A source line at the bottom names the WordPress advisories, The Hacker News for watchTowr, Wiz, and the cisaExploitAdd and cisaActionDue fields in NVD records. No photographs, logos or personal names appear.

什么被声称但尚未确立

同一个注入漏洞出现两套致谢,这在公开记录中无法对上。WordPress 针对 CVE-2026-60137 的公告称,该漏洞“由 TF1T、dtro 和 haongo 作为一个团队发现并负责任地披露”。Searchlight 的叙述将同一个认证前注入描述为其模型运行所发现的问题,且未提及该团队;WordPress 公告仅将批量路由混淆归功于 Kues,未提及模型。两份文件均未解释这一重叠,本文找到的任何材料也无法解决它——不能排除两者是对同一漏洞的独立发现,也无法确定其中一份报告是后来的再次发现。公开记录未对此作出裁定,本文亦然。

Searchlight 7 月 20 日文章的标题数字并未得到其正文的支持。标题写道:"漏洞利用经纪人为一个 WordPress RCE 支付 50 万美元。我用 GPT5.6 Sol Ultra 和 25 美元找到了一个。"正文以具体措辞记录了这 25 美元和那十个小时;文中没有出现任何经纪人姓名、任何报价、任何往来通信,也没有为 50 万美元这一数字提供任何来源。未能找到任何独立报道为本文佐证 wp2shell 的成交价或报价。应把 50 万美元理解为标题的框架设定,而非已被确立的市场价格。

该存档条目自身的涵盖范围比它周遭的叙述要窄。它记录的是一项在披露当日得出的研究发现,未标记任何现实世界中的危害,且日期仅限一天,即2026年7月17日。这并非断言此后什么都没发生:公告发布后数小时内即有报告称出现利用流量,而CISA在四天后将这两个CVE均编入目录。该标记涵盖的是条目所描述的内容——发现与协调披露——而随后的利用情况则由其他方依据其自身证据记录如下。

公告发布后的利用

watchTowr首席安全研究员Jake Knott对The Hacker News表示:“到周六凌晨(UTC)时分,成功利用已经全面展开,最初使用公开的漏洞利用代码窃取哈希凭据,随着更多细节公开,随后又出现了远程代码执行。”同一报道援引KEVIntel遥测数据,将来自瑞士、德国、英国、印度尼西亚、立陶宛、荷兰和新加坡的13个唯一IP地址与对CVE-2026-63030的利用联系起来,并援引KEVIntel创始人Ryan Dewhurst的话说,这些请求与公开可用的概念验证相符,而且盲注、基于UNION和基于布尔值的载荷都被使用了。

Wiz 的研究人员 Shahar Dorfman 和 Gili Tikochinski 于 7 月 20 日发表文章,量化了其规模:在 CVE 发布时,使用 WordPress 的组织中有 60% 至少有一个存在漏洞的实例,25% 将存在漏洞的服务器暴露在互联网上;随着修补工作开始,这两个比例在 24 小时内降至 50% 和 10%。他们记录了通过管理员安装器上传恶意插件、针对 users 端点的用户枚举、针对 wp-config 的本地文件包含尝试,以及管理面板访问返回 HTTP 200——这是成功登录而非探测的特征。他们发现的恶意软件包括一个极简的单行 PHP 后门,以及一个伪装成名为 CMSmap 的合法 WordPress 安全插件的 150 KB webshell,该 webshell 具备文件管理、数据库访问、端口扫描和权限提升模块。

Wiz 也指出了关于可得出何种结论的局限性。未进行后利用的高频扫描很常见,这既符合机会性大规模扫描,也符合合法的安全扫描;该公司表示,它没有发现横向移动或数据外泄。这是关于某一家厂商的遥测数据所显示内容的陈述,而不是认定没有数据被窃取。

之后发生了什么变化,哪些仍未解决

对运维人员来说,应对路径并不复杂。升级到 WordPress 7.0.2、WordPress 6.9.5 或 WordPress 6.8.6 即可修复。对于无法立即更新的站点,Searchlight 给出的应急替代方案是阻止对 batch API 的匿名访问——要么安装一个完全阻止匿名访问 REST API 的插件,要么在 Web 应用防火墙上阻止 /wp-json/batch/v1 和 ?rest_route=/batch/v1,也就是在 Web 应用防火墙上进行拦截。该公司警告称,这两种做法都可能影响站点的正常使用,在更新发布之前应将其视为临时措施。wp2shell.com 上的公开检测工具可直接对实例进行测试。CISA 的目录条目还附加了合规时限:CVE-2026-63030 须在 7 月 24 日前完成修复,CVE-2026-60137 须在 8 月 4 日前完成修复。

研究问题中尚未解决的部分,是模型相对于其操作者实际贡献了什么。Kues 对分工说得很精确:模型大约在十小时内生成了这条链,而理解它所花的时间比生成它更长。他拒绝作一般性断言,只说这个十小时的结果并非人类在无辅助情况下所能达到。提示词本身并不是秘密——它源自 OpenAI 发布过的一个提示词,而 Searchlight 在报告中复现了其结构,包括忽略版本历史的指示,以及漏洞利用必须在典型生产配置中生效的要求。这一配方能否迁移到其他代码库,正是 Kues 说他不会回答的问题,而且目前也没有公布第二次运行结果。

因此,现有记录未能确立的部分虽然范围有限,却事关重要:在两个被记功的当事方当中,究竟是谁最先发现了这次注入;是否有任何漏洞经纪商真的支付了报道标题中所说的那笔金额;以及 Wiz 所观察到的那些 webshell 究竟从它们所侵入的网站上取走了什么——如果确实取走了什么的话。关于最后一点,唯一的公开说法来自 Wiz:它未发现任何横向移动或数据外泄——这是从一个视角得出的证据缺失,并且正是作为证据缺失而提出的。