WordPress 核心 get_page_template() / locate_template() 路径遍历漏洞利用工具
仅限授权安全测试使用。未经授权访问计算机系统属于违法行为。
| 项目 | 详情 |
|---|---|
| CVE ID | CVE-2026-87902 |
| GHSA ID | GHSA-7hp8-65ch-5whp |
| 漏洞类型 | CWE-98 — 包含/引用文件名控制不当 |
| CVSS v3.1 | 8.1(高危)/ CVSS 4.0:9.2(严重) |
| 受影响组件 | WordPress 核心 |
| 受影响版本 | 4.7.0 至 7.1.1(所有分支) |
| 修复版本 | 7.1.2(以及向下回溯至 4.7.37 的版本) |
| 所需认证 | 无(未授权) |
| 攻击向量 | 单个 GET 请求 |
| 发现者 | Robert Ressl(通过 WordPress HackerOne 项目) |
| 披露日期 | 2026 年 9 月 22 日 |
| 已在野利用 | 是 — 已列入 CISA KEV 目录 |
CVE-2026-87902 是 WordPress 核心中的一个未授权路径遍历和本地文件包含(LFI)漏洞,影响自 2016 年以来发布的每一个 WordPress 版本(4.7.0 至 7.1.1)。攻击者无需任何账户或认证。通过构造恶意的 pagename 查询参数,攻击者可使 WordPress 的页面模板解析机制包含活动主题目录之外的任意可读 .php 文件。在特定服务器条件下(PHP register_argc_argv = On 且存在可读的 pearcmd.php),该漏洞可升级为远程代码执行(RCE)。
| 分支 | 修复版本 |
|---|---|
| 4.7.x | 4.7.37 |
| 5.0.x | 5.0.29 |
| 5.3.x | 5.3.25 |
| 5.9.x | 5.9.18 |
| 6.0.x | 6.0.16 |
| 6.6.x | 6.6.9 |
| 6.9.x | 6.9.9 |
| 7.0.x | 7.0.6 |
| 7.1.x | 7.1.2 |
该漏洞位于 wp-includes/template.php 中的 get_page_template()。当存在 pagename 查询变量时,该函数会构造 page-{$pagename}.php,但未能对该值调用 validate_file() 以检查目录遍历。随后,候选文件名被传递给 locate_template(),后者将其与主题目录路径拼接,并且仅检查 file_exists() — 它并不验证解析后的路径是否仍位于主题目录内。因此,包含 ../ 的模板名称可以解析到活动主题之外的可读 PHP 文件,并被包含和执行。
GET /?page_id=<已发布页面>&pagename=<双重编码遍历载荷> → WP_Query 解析 page_id,匹配已发布页面(避免 404) → get_page_template() 对 pagename 执行 urldecode(),构造 page-{$pagename}.php → locate_template() 将候选路径与主题目录拼接,通过 file_exists() 解析 → template-loader 执行 realpath() + include
WordPress 对 pagename 应用 sanitize_title_for_query(),该函数将字面点号(.)替换为连字符(-)以阻止遍历。它作用于已解码一次的输入,且不会递归解码。攻击者发送 %252e%252e%252f(双重编码的 ../):
%252e → %2e,%252f → %2fsanitize_title_for_query() 看到 %2e%2e%2f(无字面点号)并放行get_page_template() 内部再次调用 urldecode():%2e%2e%2f → ../page- 开头的顶层目录(例如 page-templates/)。page_id 提供。.php 结尾(WordPress 会追加扩展名)。Windows 主机说明:Win32 会在词法层面规范化 ..,因此即使 page- 目录不存在,遍历也可能生效。在 Linux 上,该目录必须实际存在。
条件:
register_argc_argv 设置为 Onpearcmd.php攻击者通过 LFI 包含 pearcmd.php,并滥用其 config-create 命令向服务器写入一个 PHP 文件,然后再次通过 LFI 包含该文件以执行任意命令。
CVE-2026-87902 由常驻瑞士的安全研究员 Robert Ressl 发现并报告。
于 2026 年 7 月通过 WordPress HackerOne 项目报告。WordPress 安全团队协调了修复工作,并于 2026 年 9 月 22 日随 WordPress 7.1.2 一同发布。
| 日期 | 事件 |
|---|---|
| 2026 年 7 月 | Robert Ressl 通过 WordPress HackerOne 项目报告该漏洞 |
| 2026 年 9 月 22 日 | WordPress 7.1.2 发布并包含修复;安全公告发布 |
| 2026 年 9 月 22 日 | 针对 7.0 至 4.7 分支的安全回溯补丁发布 |
| 2026 年 9 月 23 日 | 攻击者开始探测存在漏洞的站点 |
| 2026 年 9 月 25 日 | CISA 将 CVE-2026-87902 加入 KEV 目录 |
| 功能 | 描述 |
|---|---|
| 版本指纹识别 | 通过 meta generator、RSS 源、OPML、readme.html、资源 ?ver= 识别 WordPress 版本 |
| 智能版本判定 | 使用修复版本映射判断目标是否处于受影响范围内 |
| 主题发现 | 提取当前活动主题的 slug,检测父主题,发现 page-* 目录 |
| 页面 ID 发现 | 通过 REST API、page-id- body class、短链接发现有效页面 ID |
| LFI 预言机验证 | 使用 wp-links-opml.php 和 wp-trackback.php 等安全文件作为预言机,并配合阴性对照 |
| 双重编码路径遍历 | 自动对 / 和 . 进行双重百分号编码,以绕过 sanitize_title_for_query() |
| PEAR RCE 利用 | 尝试常见 PEAR 路径,通过 config-create 写入并执行标记文件 |
| 批量扫描 | 对目标列表进行多线程并发扫描 |
| 结果输出 | 将结果持久化到 vuln_lfi.txt 和 vuln_lfitorce.txt |
pip install requests
python3 CVE-2026-87902.py
交互式菜单:
[1] Single Scan LFI [2] Single Scan LFI + RCE [3] Mass Scan LFI [4] Mass Scan LFI + RCE [5] Exit
选择 [1],输入目标 URL:
url > https://target.example.com
选择 [2],输入 URL 和命令(默认为 id):
url > https://target.example.com cmd > id
选择 [3] 或 [4],输入包含目标 URL 的文件(每行一个,# 表示注释):
file > targets.txt
| 文件 | 内容 |
|---|---|
| vuln_lfi.txt | 已确认的 LFI 目标 |
| vuln_lfitorce.txt | 成功实现 RCE 的目标 |
TIMEOUT = 8 # Request timeout (seconds) THREADS = 200 # Concurrent threads for mass scanning USE_ALL_ORACLES = False # Use all oracles (more accurate but slower)
pagename 参数中包含 ..、%2e、%252e 的请求page-* 目录register_argc_argv 设置本工具仅用于经授权的安全测试和教育目的。用户必须确保已获得目标系统的明确书面授权。未经授权的使用可能违反 CFAA、英国《计算机滥用法》以及其他国家的类似法律。作者对任何滥用行为不承担任何责任。