Skip to content
KitploitKITPLOIT
FerramentasExploitsBlog
Log in
Enviar
FerramentasExploitsBlog
Enviar

Ferramentas de Hacking, PenTest e Cibersegurança para o seu Arsenal de Segurança!

Kitploit é um diretório de ferramentas de hacking, cibersegurança e pentesting. Descubra as últimas atualizações de projetos para encontrar vulnerabilidades, analisar sistemas, automatizar testes e fortalecer sua segurança.

FeedsContatoPrivacidade© 2026 Kitploit

Diretório de Ferramentas

Categorias

Ver todas as categorias
Loading categories
KeycloakESC — Laboratório Docker reproduzível + PoC: escalonamento de Keycloak manage-users -> realm-admin via roles compostas (variante CVE-2026-94000). Validado na versão 26.8.1. | Kitploit
Ferramentas/GitHubGitHub/secfathy/keycloakesc
Autenticação e AutorizaçãoEscalada de PrivilégiosAnálise de VulnerabilidadesExploraçãoExploração de Aplicações WebTestes de PenetraçãoGerenciamento de Identidade e Acesso (IAM)Labs e Prática
GitHubsecfathy/keycloakesc

KeycloakESC

Laboratório Docker reproduzível + PoC: escalonamento de Keycloak manage-users -> realm-admin via roles compostas (variante CVE-2026-94000). Validado na versão 26.8.1.

3há 13 diasAinda não revisado

Mais Populares

Ver todos →

Descubra as ferramentas mais usadas pela nossa comunidade.

Explore todas as ferramentas

Navegue pela nossa coleção de ferramentas

Ver todas as ferramentas →
Compartilhar
Ver Repositório

Escalação de privilégios do map-role composto do Keycloak

Um laboratório Docker reproduzível e PoC para um caminho de escalada de privilégios na API REST de administração do Keycloak: um administrador delegado que possui apenas manage-users pode escalar a si mesmo (ou qualquer usuário ou grupo) para realm-admin completo, mapeando um papel composto cujo nome é comum, mas cujos filhos incluem realm-management/realm-admin.

Confirmado de ponta a ponta com a imagem oficial quay.io/keycloak/keycloak:26.8.1.

⚠️ Apenas para pesquisa autorizada. Tudo é executado contra um Keycloak descartável em localhost. Não aponte o PoC para sistemas que você não está explicitamente autorizado a testar.

  • O problema (causa raiz)
  • Prova de conceito
  • Execução verificada
  • Remediação

O problema (causa raiz)

O Keycloak 26.8.1 endureceu a entrada em grupos (CVE-2026-94000): um administrador com manage-users não pode mais adicionar um usuário a um grupo que, de forma transitiva, concede papéis de administração de realm-management. GroupUtils.checkAdminGroupRoles percorre os papéis do grupo recursivamente e chama requireMapRole em cada papel administrativo aninhado:

private static void requireMapRoleRecursive(RoleModel role, AdminPermissionEvaluator auth, Set<String> visited) {
    if (!visited.add(role.getId())) return;
    if (AdminRoles.isAdminRole(role)) auth.roles().requireMapRole(role);   // checks nested admin roles
    if (role.isComposite()) role.getCompositesStream().forEach(child -> requireMapRoleRecursive(child, auth, visited));
}

A mesma travessia recursiva nunca foi adicionada aos endpoints de mapeamento de funções. Quando uma função é mapeada diretamente para um usuário ou grupo, o servidor verifica apenas a função enviada:

// RoleMapperResource.addRealmRoleMappings — mounted on BOTH users and groups
for (RoleRepresentation role : roles) {
    RoleModel roleModel = realm.getRole(role.getName());
    auth.roles().requireMapRole(roleModel);   // posted role only — children never inspected
    roleMapper.grantRole(roleModel);
}

E o próprio filtro de privilégios baseia-se no nome da role, não no seu conteúdo. Em RolePermissionsV2.canMapRole, uma role só é considerada privilegiada quando o seu container é realm-management/master e o seu nome está em AdminRoles.ALL_ROLES:

public boolean canMapRole(RoleModel role) {
    if (isRealmAdminRole(role)) { ... }                 // isRealmAdminRole = container + ALL_ROLES.contains(name)
    if (root.hasOneAdminRole(AdminRoles.MANAGE_USERS))  // manage-users may map ANY non-admin-named role
        return true;
    ...
}

Assim, um composite chamado sneaky-composite que envolve realm-management/realm-admin passa pelo filtro — seu nome não está em ALL_ROLES, e seus filhos nunca são percorridos. A lacuna abrange três endpoints:

  • RoleMapperResource.addRealmRoleMappings — usuários e grupos
  • ClientRoleMappingsResource.addClientRoleMapping — roles de cliente em qualquer cliente

Efeito líquido: o payload privilegiado (um composite que envolve realm-admin) só precisa existir — criado por um admin real, uma importação de realm ou um processo anterior. manage-users pode então atribuí-lo, o que o modelo de ameaça da CVE-2026-94000 nunca pretendeu.

Variantes de ataque

#VariantePor que funciona
AAuto-mapear sneaky-composite → realm-admino filtro de nome não detecta o composite
BMapear outer-sneaky aninhado (→ sneaky-composite → realm-admin) em um usuárioa profundidade não é verificada
CMapear uma role de cliente em um cliente não-admin (spa/hidden-ra → realm-admin)ClientRoleMappingsResource usa o mesmo filtro
DMapear o composite em um grupo que já possui membrosAPI diferente da de join; membros existentes escalam sem nenhum join

Prova de conceito

Requisitos: Docker + Docker Compose v2, e curl + jq no host.

cp .env.example .env     # optional: pin KC_VERSION (default 26.8.1)
make up                  # start Keycloak + auto-bootstrap the vulnerable realm `app`
make logs                # wait for "Lab realm 'app' is ready"

make check               # non-destructive detection (maps, then immediately unmaps)
make exploit             # Attack A: self-escalate limited-admin -> realm-admin
make all                 # full chain: check + A + B + C + D
make reset               # undo every escalation (keep the lab running)
make clean               # tear everything down

O contêiner one-shot bootstrap constrói o cenário via API REST de administração e, em seguida, encerra:

ObjetoFinalidade
limited-admin / limitedpassAtacante — possui apenas manage-users
alice / bob / carol / daveUsuários vítimas
sneaky-composite (role de realm)Composta → realm-management/realm-admin
outer-sneaky (role de realm)Composta → sneaky-composite (um salto extra)
cliente spa + role spa/hidden-raRole de cliente não-admin → realm-admin
cliente confidential (confsecret)Alvo de impacto de leitura de segredo
grupo helpdesk (alice é membro)Alvo do ataque de mapeamento de grupo

O PoC resolve os IDs de role da forma como um chamador com manage-users realmente consegue — por meio dos endpoints .../role-mappings/.../available — porque essa conta tem acesso negado a GET /roles/{name} e GET /clients (403), mas não às listas de disponíveis. Isso mantém o script como uma reprodução honesta da perspectiva de um atacante com baixos privilégios.

Validando uma correção

Aponte o laboratório para uma build corrigida; um servidor corrigido deve retornar 403 em cada etapa de mapeamento, enquanto ainda permite o mapeamento comum de roles não-admin:

KC_VERSION=<patched-tag> docker compose up -d --force-recreate
make check        # expect: NOT vulnerable

Execução verificada

Contra quay.io/keycloak/keycloak:26.8.1 (transcrição completa em docs/demo.txt, detalhes em VALIDATION.md):

PassoAçãoResultado
Linha de baselimited-admin POST /roles403 (genuinamente de baixo privilégio)
verificaçãomapear sneaky-composite sobre si mesmo (depois desmapear)204 → VULNERÁVEL
Aauto-mapear sneaky-composite → realm-admin → criar role / extrair e-mails de usuários204 / 201 / 200
Baninhar outer-sneaky sobre bob → bob cria role204 / 201
Cspa/hidden-ra sobre carol → carol cria role204 / 201
Dmapear wrapper sobre helpdesk → membro existente alice cria role204 / 201
Controle Dmanage-users adiciona um novo membro a helpdesk403 (correção do CVE-2026-94000 intacta)

O controle D comprova a assimetria: a adição ao grupo é bloqueada, mas mapear o mesmo composite sobre o grupo (ou sobre um usuário/cliente) não é percorrido e retorna 204.


Remediação

Baixar ferramenta