Skip to content
KitploitKITPLOIT
ツールエクスプロイトブログ
Log in
提出
ツールエクスプロイトブログ
提出

ハッキング、侵入テスト、サイバーセキュリティツールをあなたのセキュリティアーセナルに!

Kitploitはハッキング、サイバーセキュリティ、ペネトレーションテストのツールディレクトリです。最新のプロジェクトアップデートを見つけて、脆弱性の発見、システム分析、テストの自動化、セキュリティの強化を行いましょう。

フィードお問い合わせプライバシー© 2026 Kitploit

ツールディレクトリ

カテゴリ

すべてのカテゴリを見る
Loading categories
ツール/GitHubGitHub/secfathy/keycloakesc
認証と認可特権昇格脆弱性分析エクスプロイトウェブアプリケーション悪用ペネトレーションテストアイデンティティ&アクセス管理 (IAM)ラボと実践
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 に含まれておらず、その子要素が走査されることもありません。このギャップは3つのエンドポイントにまたがります:

  • RoleMapperResource.addRealmRoleMappings — ユーザーとグループ
  • ClientRoleMappingsResource.addClientRoleMapping — 任意のクライアント上のクライアントロール

正味の影響: 特権ペイロード(realm-admin をラップするコンポジット)は、存在するだけで十分です — 実際の管理者、レルムインポート、または以前のプロセスによって作成されたものです。その後 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 コンテナは、管理 REST API 経由でシナリオを構築してから終了します:

オブジェクト目的
limited-admin / limitedpass攻撃者 — manage-users のみを保持
alice / bob / carol / dave被害ユーザー
sneaky-composite(レルムロール)コンポジット → realm-management/realm-admin
outer-sneaky(レルムロール)コンポジット → sneaky-composite(追加で1ホップ)
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 を参照してください。

ツールをダウンロード