Skip to content
KitploitKITPLOIT
도구익스플로잇블로그
Log in
제출
도구익스플로잇블로그
제출

해킹, 침투 테스트 및 사이버 보안 도구를 당신의 보안 무기고에!

Kitploit은 해킹, 사이버 보안 및 침투 테스트 도구 디렉토리입니다. 최신 프로젝트 업데이트를 발견하여 취약점을 찾고, 시스템을 분석하고, 테스트를 자동화하고, 보안을 강화하세요.

피드문의개인정보© 2026 Kitploit

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
KeycloakESC — 재현 가능한 Docker 랩 + PoC: 복합 역할을 통한 Keycloak manage-users -> realm-admin 권한 상승 (CVE-2026-94000 변종). 26.8.1에서 검증됨. | Kitploit
도구/GitHubGitHub/secfathy/keycloakesc
Authentication & AuthorizationPrivilege EscalationVulnerability AnalysisExploitationWeb Application ExploitationPenetration TestingIdentity & Access Management (IAM)Labs & Practice
GitHubsecfathy/keycloakesc

KeycloakESC

재현 가능한 Docker 랩 + PoC: 복합 역할을 통한 Keycloak manage-users -> realm-admin 권한 상승 (CVE-2026-94000 변종). 26.8.1에서 검증됨.

313일 전아직 검토되지 않음

인기

모두 보기 →

커뮤니티에서 가장 많이 사용되는 도구를 찾아보세요.

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유
저장소 보기

Keycloak 복합 map-role 권한 상승

Keycloak의 관리자 REST API에서 권한 상승 경로에 대한 재현 가능한 Docker 랩 및 PoC: 오직 manage-users 만 보유한 위임된 관리자가 이름은 평범하지만 자식에 realm-management/realm-admin이 포함된 복합 역할을 매핑함으로써 자기 자신(또는 임의의 사용자나 그룹)을 완전한 realm-admin 으로 승격시킬 수 있습니다.

공식 이미지 quay.io/keycloak/keycloak:26.8.1에 대해 엔드투엔드로 확인되었습니다.

⚠️ 승인된 연구 전용입니다. 모든 것은 localhost의 일회용 Keycloak에 대해 실행됩니다. 명시적으로 테스트 권한을 받지 않은 시스템에 PoC를 향하게 하지 마십시오.

  • 문제 (근본 원인)
  • 개념 증명
  • 검증된 실행
  • 완화 조치

문제 (근본 원인)

Keycloak 26.8.1은 그룹 가입을 강화했습니다(CVE-2026-94000): manage-users 관리자는 이제 전이적으로 realm-management 관리자 역할을 부여하는 그룹에 사용자를 추가할 수 없습니다. GroupUtils.checkAdminGroupRoles는 그룹의 역할을 재귀적으로 순회하며 중첩된 모든 관리자 역할에 대해 requireMapRole을 호출합니다:

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

동일한 재귀적 탐색이 역할 매핑 엔드포인트에는 추가되지 않았습니다. 역할이 사용자나 그룹에 직접 매핑될 때, 서버는 게시된 역할만 확인합니다:

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

그리고 권한 게이트 자체는 역할의 이름을 기준으로 판단하며, 그 내용물을 기준으로 하지 않습니다. RolePermissionsV2.canMapRole에서 역할은 그 컨테이너가 realm-management/master이고 그 이름이 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;
    ...
}

그래서 realm-management/realm-admin을 감싸는 sneaky-composite라는 이름의 컴포지트는 게이트를 통과합니다. 그 이름은 ALL_ROLES에 없고, 그 자식들은 결코 순회되지 않습니다. 이 격차는 세 개의 엔드포인트에 걸쳐 있습니다:

  • RoleMapperResource.addRealmRoleMappings — 사용자 및 그룹
  • ClientRoleMappingsResource.addClientRoleMapping — 모든 클라이언트의 클라이언트 역할

순 효과: 권한 있는 페이로드(realm-admin을 감싸는 컴포지트)는 단지 존재하기만 하면 됩니다 — 실제 관리자, realm 가져오기, 또는 이전 프로세스에 의해 생성된 것입니다. 그런 다음 manage-users가 이를 할당할 수 있으며, 이는 CVE-2026-94000 위협 모델이 결코 의도하지 않은 것입니다.

공격 변형

#변형작동하는 이유
Asneaky-composite → realm-admin 자기 매핑이름 게이트가 컴포지트를 놓침
B중첩된 outer-sneaky(→ sneaky-composite → realm-admin)를 사용자에 매핑깊이가 확인되지 않음
C비관리자 클라이언트의 클라이언트 역할 매핑(spa/hidden-ra → realm-admin)ClientRoleMappingsResource가 동일한 게이트를 사용함
D이미 구성원이 있는 그룹에 컴포지트를 매핑join과 다른 API; 기존 구성원은 join 없이 권한 상승

개념 증명

요구 사항: Docker + Docker Compose v2, 그리고 호스트의 curl + jq.

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

원샷 bootstrap 컨테이너는 admin REST API를 통해 시나리오를 구축한 뒤 종료됩니다:

객체용도
limited-admin / limitedpass공격자 — manage-users만 보유
alice / bob / carol / dave피해 사용자
sneaky-composite (realm 역할)컴포지트 → realm-management/realm-admin
outer-sneaky (realm 역할)컴포지트 → sneaky-composite (한 단계 추가)
spa 클라이언트 + spa/hidden-ra 역할비관리자 클라이언트 역할 → realm-admin
confidential 클라이언트 (confsecret)시크릿 읽기 영향 대상
helpdesk 그룹 (alice가 구성원)그룹 매핑 공격 대상

PoC는 manage-users 호출자가 실제로 할 수 있는 방식으로 역할 ID를 확인합니다 — 즉 .../role-mappings/.../available 엔드포인트를 통해 — 해당 계정은 GET /roles/{name} 및 GET /clients가 거부(403)되지만 available 목록은 그렇지 않기 때문입니다. 이는 스크립트를 정직한 저권한 공격자 관점의 재현으로 유지합니다.

수정 사항 검증

랩을 패치된 빌드로 지정하세요; 수정된 서버는 일반적인 비관리자 역할 매핑은 여전히 허용하면서 모든 매핑 단계에서 403을 반환해야 합니다:

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

검증된 실행

quay.io/keycloak/keycloak:26.8.1 대상 (전체 기록은 docs/demo.txt, 세부 사항은 VALIDATION.md):

단계동작결과
기준선limited-admin POST /roles403 (실제로 낮은 권한)
checksneaky-composite를 자기 자신에 매핑 (이후 매핑 해제)204 → 취약
Asneaky-composite를 자기 자신에 매핑 → realm-admin → 역할 생성 / 사용자 이메일 덤프204 / 201 / 200
Bouter-sneaky를 bob에 중첩 → bob이 역할 생성204 / 201
Cspa/hidden-ra를 carol에 매핑 → carol이 역할 생성204 / 201
D래퍼를 helpdesk에 매핑 → 기존 멤버 alice가 역할 생성204 / 201
D 대조manage-users가 새 멤버를 helpdesk에 가입시킴403 (CVE-2026-94000 수정 유지)

D 대조는 비대칭성을 입증한다: 그룹 가입은 차단되지만, 동일한 컴포지트를 그룹(또는 사용자/클라이언트)에 매핑하는 것은 순회되지 않고 204를 반환한다.


교정

  1. RolePermissionsV2.canMapRole / RolePermissions.checkAdminRoles에서 호출자가 모든 중첩된 관리자 역할을 매핑할 수 있는 경우가 아니라면 AdminRoles.isAdminRoleOrComposite(role)이 true일 때 역할을 거부하도록 한다 — GroupUtils.requireMapRoleRecursive를 그대로 따른다.
  2. RoleMapperResource.addRealmRoleMappings (사용자 및 그룹)와 ClientRoleMappingsResource.addClientRoleMapping에 대해 해당 순회를 실행한다.
  3. manage-users가 sneaky-composite, 중첩 래퍼, realm-admin을 컴포지트하는 비관리자 클라이언트 역할, 또는 멤버가 있는 그룹에 래퍼를 매핑할 수 없음을 검증하는 테스트 커버리지를 추가한다. 기존 그룹 가입 테스트만으로는 충분하지 않다.

전체 기술 보고서: report/report.md.

레이아웃

docker-compose.yml               Keycloak + one-shot bootstrap container
bootstrap/setup-realm.sh         Builds the vulnerable realm via the admin REST API
poc/kc_composite_maprole_poc.sh  Detection + exploitation + cleanup PoC (curl/jq)
report/report.md                 Full technical write-up
VALIDATION.md / docs/demo.txt    Verified run evidence

라이선스

MIT — LICENSE 참조.

도구 다운로드