abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · joomla-menu-items-api
技术分析文章:https://abraxaslabs.tech/research/joomla-menu-items-api
类别: 权限残留 可达性: 远程
Joomla CMS 6.1.3 (0f2d4de) - Open Source Matters
菜单项的管理员界面会检查 com_menus.menu.{id} 并拒绝 menutype == main。api/components/com_menus/src/Controller/ItemsController.php 没有 allowAdd / allowEdit,因此 ApiController 只要求 core.manage 以及对 com_menus 的 core.create / core.edit。
一个可以管理某个菜单的令牌用户,可以向其在 UI 中被拒绝访问的菜单(包括受保护的管理员 main 菜单)POST /api/index.php/v1/menus/administrator/items。
| ID | 暂无 CVE |
| 类别 | 权限残留 / 授权绕过 |
| 可达性 | 远程(持有 core.login.api 的 API 令牌) |
| CWE | CWE-863 |
| CVSS | 高危:8.1 CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:N |
| 产品 | Joomla CMS |
| 受影响版本 | 6.1.3 (0f2d4de4729eb951e0878fec98c7990da07915b2) |
| 认证 | 远程 API 用户,需具备 core.login.api + core.manage + 对 com_menus 的 core.create/core.edit,且非超级用户。默认情况下 core.login.api 仅限超级用户。 |
| 许可证 | GNU Affero GPL v3.0 |
| 实验环境 | 仅限 127.0.0.1 |
令牌用户仅可在菜单 A 上创建菜单项。除非其已拥有相应权限,否则仍无法安装扩展。此权限残留不会使其成为超级用户。
| 权限 | 方法 / 路径 | 类型 | 实验验证或推断 |
|---|---|---|---|
| 在其被拒绝访问的菜单上创建菜单项 | 使用 B 的 menutype 向 POST /api/index.php/v1/menus/administrator/items 发起请求 | 完整性 | 实验验证。HTTP 200,staffmenu 上的菜单项 102,标题为 poc-JOOMLA-MENU-ITEMS-API-WITNESS |
在受保护的管理员 main 菜单上植入 URL | 使用 menutype=main 发起相同的 POST 请求 | 完整性 | 实验验证 HTTP 200。UI 的 allowEdit 对 main 返回 false |
| 将员工引导至仿冒登录页或隐藏真实的管理员菜单项 | 管理员菜单上的已发布 URL 菜单项 | 完整性 / 侦察 | 根据写入操作推断。实验植入了 https://example.invalid/ |
| 编辑或删除其不拥有的菜单上的菜单项 | API 的 PATCH / DELETE 使用同样缺失的 allow* 检查 | 完整性 | 推断。实验仅验证了创建操作 |
| 安装扩展或成为超级用户 | 需要其他 ACL | 不适用 | 已排除。管理员并非超级用户 |
在此版本上已排除:同一用户在 staffmenu 上的 UI 添加/保存操作(not permitted)。在 labmenu 上的 UI 添加操作仍然有效。6.1.1 中 Groups API 的 core.admin 门控未受影响。
在 2026 年 JSST 浪潮之后,我锁定了 6.1.3 版本。管理员端的 ItemController 已经做了正确的处理:
return $user->authorise('core.create', 'com_menus.menu.' . $menutypeID);
if ($item->menutype == 'main') {
return false;
}
return $user->authorise('core.edit', 'com_menus.menu.' . (int) $menutypeID);
API 条目控制器未覆盖 allowAdd / allowEdit。默认的 ApiController 仅检查组件 core.manage 以及 core.create / core.edit。模型的 canSave 路径仅检查组件 core.edit。批量复制/移动已检查菜单资源。
已记录的误区:将 UI 的 HTTP 200 视为允许(响应体为“not permitted”);在 UI 中认为 com_menus 上的 core.manage 已足够(UI 仍以 com_menus.menu.{id} 为准);使用未配置 core.login.api 的默认 Manager。攻击场景:反向 shell。判定标准为:对 staffmenu 和 main 的 API 返回 200,且 UI 对 B 拒绝。
同一 pin 的遗留内容:levels API、media override、articles catid。
python3 joomla-menu-items-api-Abraxas-Labs.py
或
cd lab
./run.sh
仅针对 http://127.0.0.1:19530。镜像 joomla:6.1.3-php8.3-apache。
SUCCESS joomla-menu-items-api api-b-http=200 item-id=102 menutype=staffmenu api-main-http=200 ui-add-b=200 ui-save-b=200 JOOMLA-MENU-ITEMS-API-WITNESS
ui-add-b / ui-save-b 返回 HTTP 200;对 B 的拒绝体现为 UI 的“not permitted”响应体,而不是 403 状态码。
将 ItemController::allowAdd / allowEdit(以及删除操作)复制到 API 控制器上,包括其中的 main 代码块。在 canSave 中以相同方式检查菜单类型资源。
0f2d4de4729eb951e0878fec98c7990da07915b2)ItemsController.phpItemController.phpGNU Affero GPL v3.0。参见 LICENSE。仅限回环实验环境使用。不提供任何担保。