仅限授权的安全测试使用。 对您不拥有或未获得明确书面许可进行测试的 系统运行漏洞利用模式是违法的。默认模式(
CHECK)是非破坏性的,不会创建任何内容。
该 CLI 工具用于检测并(可选,使用 -U)利用
CVE-2026-90907,这是
Joomla! CMS 核心中的一个中危授权绕过漏洞(CVSS 6.9),
允许未认证的远程攻击者通过 com_users → profile.save 控制器
触发未授权的用户账户创建——即使在全局配置中禁用了公开注册。
| 字段 | 值 |
|---|---|
| CVE ID | CVE-2026-90907 |
| 严重性 | 中危 — CVSS 6.9 |
| 类型 | 授权绕过 / 访问控制不当 (CWE-862) |
| 组件 | com_users 组件,profile.save 任务 |
| 攻击向量 | 远程、未认证、同会话两步 POST |
| 修复于 | Joomla! 5.4.9 和 6.1.4(安全版本,2026-09-29) |
根据 Joomla! 安全公告(2026-09-29)及公开公告来源:
Joomla! 3.x 同样受影响但已停止支持(End-of-Life):它不会获得 官方补丁——请规划迁移。该工具的版本横幅检查仅供参考;判定基于行为(见下文)。
攻击者控制的账户是一个低权限的前端账户,无管理或后台访问权限。 尽管如此,这仍允许攻击者:
ProfileModel::save() 仅在用户名被视为合规时才 unset() $data['username']。
isUsernameCompliant 派生自用户状态 com_users.edit.profile.data,
当表单验证失败时,控制器会用完整请求填充该状态。控制器同样未能
验证传入请求的登录状态。因此,在同一个访客会话中:
privacyconsent 进行 POST → 验证失败 → 脏用户名被持久化到会话用户状态(此时尚未创建任何内容)。jform[privacyconsent][privacy]=1 重新提交 → 跳过 unset() 防护 → INSERT INTO #__users → 返回 303 重定向且 user_id > 0。user.login(字段名为 password,而非 passwd)并读取闪现消息:正确 → "you cannot access the private section"(认证通过,ACL 阻止)/ 错误 → "do not match"。差分即为证据。git clone https://github.com/aorozco-sys/CVE-2026-90907.git
cd CVE-2026-90907
pip install -r requirements.txt # only dependency: requests
# CHECK mode (default) — non-destructive: never sends consent, never creates an account
python3 joomla_cve_2026_90907.py https://ejemplo.com
# Verbose CHECK (full request/response log on stderr)
python3 joomla_cve_2026_90907.py https://ejemplo.com --no-color -v
# EXPLOIT mode (-U) — creates a real account in #__users (authorized targets only!)
python3 joomla_cve_2026_90907.py https://ejemplo.com \
-U audit.user -E [email protected] -N "CVE Audit"
# Through a proxy (e.g. Burp Suite) with a custom timeout
python3 joomla_cve_2026_90907.py https://ejemplo.com -U audit.user \
--proxy http://127.0.0.1:8080 --timeout 30
# Exploit without the differential login verification
python3 joomla_cve_2026_90907.py https://ejemplo.com -U audit.user \
--no-verify-login
| 参数 | 描述 |
|---|---|
TARGET | 基础 URL(已规范化;无尾部斜杠) |
-U/--username | 启用 EXPLOIT 模式。 不带 -U → 非破坏性 CHECK |
-P/--password | 默认:使用 secrets 生成,16 位字母数字+符号,始终打印 |
-E/--email | 默认:<username>@example.invalid |
-N/--name | 默认:CVE Audit |
-o/--output | 证据目录(默认位于当前工作目录下的 evidence_cve90907_<ts>) |
--proxy URL | 请求代理(Burp:http://127.0.0.1:8080) |
--timeout | 默认 20 秒 |
--ua | User-Agent(默认 cve-2026-90907-audit/1.0) |
--no-verify-login | 跳过登录差异检测(exploit 模式) |
--verify-ssl | 验证 TLS(默认:不验证) |
--no-color | 不使用 ANSI 颜色 |
-v/--verbose | 在 stderr 上输出完整请求/响应日志 |
| 代码 | 含义 |
|---|---|
0 | 正常 / 不受影响 / 未知 |
1 | 存在漏洞(check 中为 LIKELY,exploit 中为 CONFIRMED) |
2 | 操作错误(网络、依赖等) |
Location 中包含 profile,未重定向到登录页)+ 校验错误
闪现消息(例如要求隐私政策的提示)。最终确认 =
exploit 模式。summary.json 中。Location 中包含 user_id > 0。每次运行都会写入一个带时间戳的 -o 目录,其中包含 00_token.txt、
01_version.txt、02_w1_seed.txt、03_w2_exploit.txt、
04_login_correct.txt、05_login_wrong.txt 和 summary.json。每个文件
都记录了完整的 REQUEST(方法/URL/关键请求头/请求体)、RESPONSE(状态码、
Location、Server、提取的闪现消息、响应体前 500 字节)以及 ISO
时间戳——可直接附在渗透测试报告中。
privacyconsent,并使用不合规的
用户名(probe()):保存会因表单规则失败,不会持久化任何内容。user_id > 0(本不应如此),exploit
模式会在 W2 之前中止。user_usergroup_map 行)。MIT — 参见 LICENSE。