
Joomla 6.1.3 - Alta - Remota - ACL - GET /api/v1/users/levels vaza níveis de visualização
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · joomla-levels-api
Análise: https://abraxaslabs.tech/research/joomla-levels-api
Classe: Privilégio remanescente Alcance: Remoto
Joomla CMS 6.1.3 (0f2d4de) - Open Source Matters
Usuários Administradores -> Níveis de Acesso de Visualização exige core.admin em com_users (LevelController::allowSave e exclusão). O webservice de Grupos já faz o mesmo (GroupsController, 6.1.1). LevelsController não possui substituição de allowAdd, allowEdit ou delete, então ApiController permite a passagem de core.manage mais core.create.
Um token de API da classe Manager, concedido core.login.api sem core.admin, pode criar níveis de acesso de visualização que a interface proíbe.
| ID | ainda sem CVE |
| Classe | Privilégio remanescente / bypass de autorização |
| Alcance | Remoto (token de API com core.login.api) |
| CWE | CWE-863 |
| CVSS | Médio: 6.1 CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:H/I:H/A:N |
| Produto | Joomla CMS |
| Afetado | 6.1.3 (0f2d4de4729eb951e0878fec98c7990da07915b2) |
| Autenticação | Token de API para Manager (grupo 6) com core.login.api e gerenciamento/criação/edição de com_users. Sem core.admin. O padrão de core.login.api é apenas Super User. |
| Licença | GNU Affero GPL v3.0 |
| Laboratório | apenas 127.0.0.1 |
Usar um token de API que não seja de Super User para alterar quais grupos veem quais páginas. Ele não se torna Super User apenas com este privilégio remanescente. Trata-se de controle de visibilidade de conteúdo, não de tomada de controle do site.
| Privilégio | Método / caminho | Tipo | Comprovado em laboratório ou inferido |
|---|---|---|---|
| Criar um nível de acesso de visualização | POST /api/index.php/v1/users/levels JSON title, rules (ids de grupo) | integridade | Comprovado em laboratório. HTTP 200, #__viewlevels id=7, título poc-level-JOOMLA-LEVELS-API-WITNESS |
| Editar um nível existente (lista de grupos / título) | PATCH /api/index.php/v1/users/levels/{id} | integridade | Inferido. Mesmo controller, sem allowEdit. Laboratório apenas criou. |
| Excluir um nível | DELETE /api/index.php/v1/users/levels/{id} | integridade / disponibilidade de linhas de ACL | Inferido. Mesma substituição ausente. O laboratório não executou DELETE. |
| Expor um artigo, módulo ou item de menu exclusivo para membros | Nível novo ou corrigido cujas rules incluam Public / Guest / Registered | reconhecimento (visibilidade de conteúdo) | Inferido a partir de #__viewlevels.rules. O laboratório inseriu a linha; não reaplicou ACL a um artigo ativo. |
| Ocultar uma página de Registered, ou adicionar o grupo do atacante a um nível Special | Mesmo PATCH / criação | integridade | Inferido. Mesmo armazenamento. |
| Alterar grupos de usuários a partir da API | POST /api/index.php/v1/users/groups | n/a | Comprovado em laboratório fechado. HTTP 403 (GroupsController core.admin) |
| Abrir Usuários -> Níveis de Acesso de Visualização no administrador | GET /administrator/index.php?option=com_users&view=levels | n/a | Comprovado em laboratório fechado. HTTP 403 |
| Salvar um nível pela interface | POST ... task=level.save | n/a | Comprovado em laboratório fechado. HTTP 403 (LevelController::allowSave exige core.admin) |
Acessar a API com um Manager padrão (sem core.login.api) | Token Bearer / X-Joomla-Token | n/a | Inferido fechado. O padrão de core.login.api é apenas Super User (grupo 8). Este laboratório o concede ao grupo 6 primeiro. |
| RCE via Super User / instalador | n/a | n/a | Fechado. Manager permanece Manager. |
Fixe o irmão de Groups:
public function allowAdd($data = [])
{
return $this->app->getIdentity()->authorise('core.admin', $this->option);
}
UI do Administrador:
protected function allowSave($data, $key = 'id')
{
return $this->app->getIdentity()->authorise('core.admin', $this->option)
&& parent::allowSave($data, $key);
}
Tentativas erradas já registradas: tratar a Groups API como ainda aberta (ela retorna 403); acessar a API como um Manager comum sem antes conceder core.login.api (o padrão é somente Super User, mesma configuração do CVE-2026-71574 / 72531 / 48904); interpretar o 403 da UI como a história completa (o que sobra é a API). Teatro: um reverse shell. O oráculo é API 200 mais Groups 403 mais UI 403.
Mesmos resquícios de pin: menu items API, media override, articles catid.
python3 joomla-levels-api-Abraxas-Labs.py
ou
cd lab
./run.sh
Destino apenas http://127.0.0.1:19520. Imagem joomla:6.1.3-php8.3-apache mais mariadb:11.4.
SUCCESS joomla-levels-api api-http=200 level-id=7 groups-api=403 ui-view=403 ui-save=403 JOOMLA-LEVELS-API-WITNESS
Copie core.admin allowAdd / allowEdit / delete de GroupsController para LevelsController. Mantenha a verificação da interface do administrador.
0f2d4de4729eb951e0878fec98c7990da07915b2)LevelsController.phpcore.admin (6.1.1) · CVE-2026-71574GNU Affero GPL v3.0. Consulte LICENSE. Apenas laboratório de loopback. Sem garantias.