Skip to content
KitploitKITPLOIT
OutilsExploitsBlog
Log in
Soumettre
OutilsExploitsBlog
Soumettre

Outils de Hacking, PenTest et Cybersécurité pour votre Arsenal de Sécurité !

Kitploit est un répertoire d'outils de hacking, de cybersécurité et de pentesting. Découvrez les dernières mises à jour des projets pour trouver des vulnérabilités, analyser des systèmes, automatiser les tests et renforcer votre sécurité.

FluxContactConfidentialité© 2026 Kitploit

Répertoire d'outils

Catégories

Voir toutes les catégories
Loading categories
KeycloakESC — Lab Docker reproductible + PoC : escalade de privilèges Keycloak manage-users -> realm-admin via rôles composites (variante CVE-2026-94000). Validé sur 26.8.1. | Kitploit
Outils/GitHubGitHub/secfathy/keycloakesc
Authentification et AutorisationEscalade de PrivilègesAnalyse des VulnérabilitésExploitationExploitation d'Applications WebTests d'IntrusionGestion des Identités et des Accès (IAM)Labs et Pratique
GitHubsecfathy/keycloakesc

KeycloakESC

Lab Docker reproductible + PoC : escalade de privilèges Keycloak manage-users -> realm-admin via rôles composites (variante CVE-2026-94000). Validé sur 26.8.1.

3il y a 13 joursPas encore vérifié

Populaires

Voir tout →

Découvrez les outils les plus utilisés par notre communauté.

Explorer tous les outils

Parcourez notre collection d'outils

Voir tous les outils →
Voir le dépôt
Partager

Élévation de privilèges par composition de rôles map-role dans Keycloak

Un laboratoire Docker reproductible et une PoC pour un chemin d'élévation de privilèges dans l'API REST d'administration de Keycloak : un administrateur délégué disposant uniquement de manage-users peut s'élever lui-même (ou n'importe quel utilisateur ou groupe) au statut complet de realm-admin en mappant un rôle composite dont le nom est ordinaire mais dont les enfants incluent realm-management/realm-admin.

Confirmé de bout en bout sur l'image officielle quay.io/keycloak/keycloak:26.8.1.

⚠️ Recherche autorisée uniquement. Tout s'exécute contre un Keycloak jetable sur localhost. Ne pointez pas la PoC vers des systèmes que vous n'êtes pas explicitement autorisé à tester.

  • Le problème (cause racine)
  • Preuve de concept
  • Exécution vérifiée
  • Remédiation

Le problème (cause racine)

Keycloak 26.8.1 a durci l'adhésion aux groupes (CVE-2026-94000) : un administrateur disposant de manage-users ne peut plus ajouter un utilisateur à un groupe qui accorde de manière transitive des rôles d'administration realm-management. GroupUtils.checkAdminGroupRoles parcourt les rôles du groupe récursivement et appelle requireMapRole sur chaque rôle d'administration imbriqué :

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));
}

La même traversée récursive n'a jamais été ajoutée aux endpoints de mappage de rôles. Lorsqu'un rôle est mappé directement sur un utilisateur ou un groupe, le serveur ne vérifie que le rôle soumis :

// 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);
}

Et la barrière de privilèges elle-même se base sur le nom du rôle, et non sur son contenu. Dans RolePermissionsV2.canMapRole, un rôle n'est considéré comme privilégié que lorsque son conteneur est realm-management/master et que son nom figure dans 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;
    ...
}

Ainsi, un composite nommé sneaky-composite qui englobe realm-management/realm-admin franchit le filtre — son nom n'est pas dans ALL_ROLES, et ses enfants ne sont jamais parcourus. La faille s'étend sur trois points de terminaison :

  • RoleMapperResource.addRealmRoleMappings — utilisateurs et groupes
  • ClientRoleMappingsResource.addClientRoleMapping — rôles client sur n'importe quel client

Effet net : la charge utile privilégiée (un composite englobant realm-admin) doit seulement exister — créée par un véritable administrateur, un import de realm, ou un processus antérieur. manage-users peut alors l'attribuer, ce que le modèle de menace CVE-2026-94000 n'a jamais prévu.

Variantes d'attaque

#VariantePourquoi cela fonctionne
AAuto-mapper sneaky-composite → realm-adminle filtre par nom ne détecte pas le composite
BMapper outer-sneaky imbriqué (→ sneaky-composite → realm-admin) sur un utilisateurla profondeur n'est pas vérifiée
CMapper un rôle client sur un client non-admin (spa/hidden-ra → realm-admin)ClientRoleMappingsResource utilise le même filtre
DMapper le composite sur un groupe qui a déjà des membresAPI différente de join ; les membres existants sont escaladés sans aucun join

Preuve de concept

Prérequis : Docker + Docker Compose v2, ainsi que curl + jq sur l'hôte.

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

Le conteneur bootstrap one-shot construit le scénario via l'API REST d'administration, puis se termine :

ObjetObjectif
limited-admin / limitedpassAttaquant — ne détient que manage-users
alice / bob / carol / daveUtilisateurs victimes
sneaky-composite (rôle de realm)Composite → realm-management/realm-admin
outer-sneaky (rôle de realm)Composite → sneaky-composite (un saut supplémentaire)
client spa + rôle spa/hidden-raRôle de client non-admin → realm-admin
client confidential (confsecret)Cible d'impact de lecture de secret
groupe helpdesk (alice en est membre)Cible d'attaque par mappage de groupe

Le PoC résout les ID de rôles comme un appelant disposant de manage-users le peut réellement — via les points de terminaison .../role-mappings/.../available — car ce compte se voit refuser GET /roles/{name} et GET /clients (403) mais pas les listes disponibles. Cela maintient le script comme une reproduction honnête du point de vue d'un attaquant à faibles privilèges.

Validation d'un correctif

Pointer le lab vers une build corrigée ; un serveur corrigé doit renvoyer 403 à chaque étape de mappage tout en autorisant toujours le mappage ordinaire de rôles non-admin :

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

Exécution vérifiée

Contre quay.io/keycloak/keycloak:26.8.1 (transcription complète dans docs/demo.txt, détails dans VALIDATION.md) :

ÉtapeActionRésultat
Référencelimited-admin POST /roles403 (réellement peu privilégié)
checkmapper sneaky-composite sur lui-même (puis démapper)204 → VULNÉRABLE
Aauto-mapper sneaky-composite → realm-admin → créer un rôle / extraire les e-mails des utilisateurs204 / 201 / 200
Bouter-sneaky imbriqué sur bob → bob crée un rôle204 / 201
Cspa/hidden-ra sur carol → carol crée un rôle204 / 201
Dmapper le wrapper sur helpdesk → le membre existant alice crée un rôle204 / 201
Contrôle Dmanage-users ajoute un nouveau membre à helpdesk403 (correctif CVE-2026-94000 intact)

Le contrôle D prouve l'asymétrie : l'ajout à un groupe est bloqué, mais le mappage du même composite sur le groupe (ou sur un utilisateur/client) n'est pas parcouru et renvoie 204.


Remédiation

Télécharger l’outil