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

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

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

피드문의개인정보© 2026 Kitploit

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
CVE-2026-18963-Exploit — Keycloak CVE-2026-18963용 익스플로잇으로, reset-credentials 우회를 통해 인증되지 않은 계정 탈취를 가능하게 합니다. 안전한 탐지, 비파괴적 증명, 전체 계정 탈취, 사용자 이름 열거, 취약한 버전과 패치된 버전을 포함한 랩이 포함되어 있습니다. | Kitploit
도구/GitHubGitHub/snizi/cve-2026-18963-exploit
Authentication & AuthorizationVulnerability AnalysisExploitationWeb Application ExploitationPenetration Testing
GitHubsnizi/cve-2026-18963-exploit

CVE-2026-18963-Exploit

Keycloak CVE-2026-18963용 익스플로잇으로, reset-credentials 우회를 통해 인증되지 않은 계정 탈취를 가능하게 합니다. 안전한 탐지, 비파괴적 증명, 전체 계정 탈취, 사용자 이름 열거, 취약한 버전과 패치된 버전을 포함한 랩이 포함되어 있습니다.

저장소 보기
4312511개월 전Kitploit 검토 완료

인기

모두 보기 →

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

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유

CVE-2026-18963 — Keycloak reset-credentials 우회 → 인증되지 않은 계정 탈취

CVE Affected Python Dependencies

오직 사용자 이름 또는 이메일 주소만 알면, 인증되지 않은 공격자는 임의의 Keycloak 계정에 임의의 비밀번호를 설정할 수 있습니다. 비밀번호 재설정 이메일은 실제 피해자에게 전달되며 절대 필요하지 않습니다 — 공격자는 사서함을 읽지도, 링크를 클릭하지도 않으며, 사전 자격 증명이나 세션을 보유하지 않습니다.

영향받는 버전: Keycloak 26.0.0 – 26.7.1. 26.7.2에서 수정됨.


취약한가요?

명령 하나면 충분합니다. 유효한 사용자 이름이 필요 없고 부작용도 없습니다 — 이메일을 보내지 않고, 계정에 기록하지 않으며, 악용 가능한 단계 전에 중지됩니다.```bash git clone https://github.com/Snizi/CVE-2026-18963-Exploit cd CVE-2026-18963-Exploit

python3 cve_2026_18963_poc.py
--base https://sso.example.com --realm YOUR_REALM
--client-id account
--redirect-uri https://sso.example.com/realms/YOUR_REALM/account/
--safe-check

Python 3.9+, 표준 라이브러리만 사용합니다. 설치할 것이 없습니다.

| 종료 | 판정 | 의미 |
|:---:|---|---|
| `0` | 🔴 **취약** | 대기 상태의 이메일 게이트가 응답됨 — 버그 자체입니다 |
| `2` | 🟢 **패치됨** | 흐름이 로그인으로 분기되어 그대로 유지됨 (fix #51844 존재) |
| `2` | 🟡 **완화됨** | reset-credentials에 도달할 수 없음 — *비밀번호 찾기*가 꺼져 있음. **패치가 아닙니다.** |
| `3` | ⚪ **판정 불가** | 인식할 수 없는 응답 — **통과로 읽지 마세요** |

realm별로 실행하세요 — *비밀번호 찾기*는 realm별 설정이며 `master`도 포함됩니다.
세부 사항과 검사에 사용자가 필요하지 않고 아무것도 건드리지 않는 이유는
[§4a](#4a-safe-detection---safe-check--start-here)에 있습니다.

**이미 노출된 사실을 알고 있나요?** [시정 조치](#8-remediation) 및
[탐지 / 위협 헌팅](#9-detection)으로 이동하세요.

### 대상 없이 시도해 보기

이 저장소는 동일한 realm을 대상으로 취약한 **26.7.1**과 패치된 **26.7.2**를
나란히 구동하는 랩을 제공하며, 비밀번호 재설정 이메일이 도착하고 계정이 탈취되는
동안 읽히지 않은 채 남아 있는지 지켜볼 수 있는 사서함도 함께 제공합니다.```bash
cd lab && docker compose up -d

python3 ../cve_2026_18963_poc.py --base http://localhost:8080 \
  --realm poc --client-id poc-app --safe-check   # VULNERABLE
python3 ../cve_2026_18963_poc.py --base http://localhost:8100 \
  --realm poc --client-id poc-app --safe-check   # PATCHED

⚠️ 승인된 테스트만 허용됩니다

이 저장소는 방어자, 사고 대응자 및 승인된 침투 테스터를 위해 존재합니다. 소유한 시스템 또는 서면 허가를 받은 시스템에서만 실행하십시오. 모든 항목에는 자체 포함된 취약 실습 환경 (lab/)이 함께 제공되므로, 버그 작동 방식을 배우기 위해 외부를 건드릴 필요가 없습니다. 승인 없이 제3자 인프라를 대상으로 지정하는 것은 대부분의 관할권에서 불법이며, 이 프로젝트가 지원하는 행위가 아닙니다.

참고 자료: keycloak#51833 · GHSA-4gv3-mc9p-5wqc · 수정 keycloak#51844


목차

  • 1. 근본 원인
  • 2. 영향을 받는 버전(레거시 라인 포함)
  • 3. 실습 환경
  • 4. 사용법
    • 4a. 안전한 탐지 (--safe-check) — 여기서 시작
    • 4b. 비파괴적 증명 (--check)
    • 4c. 전체 장악
    • 4d. 사용자 이름 열거 (--enum)
  • 5. 사용자 정의 로그인 테마
  • 6. 알려진 한계 — PKCE
  • 7. 수행된 검증
  • 8. 해결 방법
  • 9. 탐지
  • 작성자

1. 근본 원인

두 가지 결함이 연결되어 있습니다. 어느 것도 단독으로는 악용할 수 없습니다.

결함 1 — 범위가 지정되지 않은 스티키 플래그

services/src/main/java/org/keycloak/authentication/DefaultAuthenticationFlow.java

processAction() — tryAnotherWay라는 폼 키를 포함한 모든 POST:```java processor.getAuthenticationSession().setAuthNote( AuthenticationProcessor.AUTHENTICATION_SELECTOR_SCREEN_DISPLAYED, "true"); return createSelectAuthenticatorsScreen(model);

그 메모는 **어떤 실행 세트가 설정했는지 기록하지 않는 단순 불리언(boolean)**입니다. 이 플래그는 제출된 `authenticationExecution` 매개변수를 처리하는 분기에서만 해제됩니다. 해당 매개변수를 생략하면 — 이 PoC가 전체적으로 그렇게 하듯이 — 인증 세션 수명 동안 플래그는 계속 설정된 상태로 유지됩니다.

`processFlow()` — 플래그가 truthy인 동안에는 정상적인 흐름 평가가 건너뛰어집니다:```java
if (Boolean.parseBoolean(authSession.getAuthNote(AUTHENTICATION_SELECTOR_SCREEN_DISPLAYED))) {
    String lastExecutionId = authSession.getAuthNote(CURRENT_AUTHENTICATION_EXECUTION);
    if (lastExecutionId != null) {
        AuthenticationExecutionModel executionModel =
            realm.getAuthenticationExecutionById(lastExecutionId);
        if (executionModel != null)
            return createSelectAuthenticatorsScreen(executionModel);   // <-- attacker-usable form
    }
}

현재 대기 중인 실행을 대상으로 하는 제출 가능한 양식을 렌더링하며, 세션을 *"이메일을 기다리는 중"*에 고정하는 대신입니다.

핵심은 processResult() case FORK:입니다 — 재설정 이메일 보내기가 실행되면 CURRENT_AUTHENTICATION_EXECUTION = <reset-credential-email execution id>를 기록하고 브라우저를 로그인 페이지로 포크(fork)합니다. 대기 중인 실행이 바로 이메일 게이트입니다.

결함 2 — 이메일 게이트는 액션 토큰을 전혀 확인하지 않습니다

`services/src/main/java/org/keycloak/authentication/authenticators/resetcred/ResetCredentialEmail.java````java @Override public void action(AuthenticationFlowContext context) { context.getUser().setEmailVerified(true); context.success(); }

무조건적이다. 흐름이 유효한 액션 토큰에 의해 재개되었는지 검증하는 것이 없으므로,
`action()`에 *도달하는 것*은 사서함 제어를 증명하는 것과 동등하게 취급된다.

### 체인```
tryAnotherWay POST            → sticky AUTHENTICATION_SELECTOR_SCREEN_DISPLAYED="true"
submit victim identifier      → mail sent to victim, e-mail execution parked (FORK)
re-enter reset-credentials    → sticky flag serves a form targeting the parked e-mail execution
POST that form                → ResetCredentialEmail.action() → success() → gate bypassed
                              → flow advances to UPDATE_PASSWORD → attacker sets the password

HTTP 요청 6개, 인증 없음, authenticationExecution 매개변수는 어느 시점에도 없습니다.

수정 사항 (PR #51844)

  • 이제 노트는 model.getId()를 저장하며, processFlow()는 오직 그 값이 CURRENT_AUTHENTICATION_EXECUTION과 같을 때만 이를 인정하고, 그렇지 않으면 제거합니다. 공격에서는 두 값이 서로 다릅니다 (choose-user id vs. e-mail-gate id) — 패치가 감지하는 것이 정확히 이것이고, --safe-check가 기준으로 삼는 신호도 정확히 이것입니다.
  • ResetCredentialEmail.action()은 이제 다음을 요구합니다: context.getUser().getId().equals(authNote(ACTION_TOKEN_USER_ID)) 그렇지 않으면 INVALID_USER로 실패합니다.

2. 영향을 받는 버전 (레거시 라인 포함)

라인취약 버전커뮤니티 수정
레거시 (WildFly 기반 Keycloak, ≤ 17)영향 없음—
Quarkus 17 – 25.x영향 없음—
26.026.0.0 – 26.0.17없음
26.126.1.0 – 26.1.5없음
26.226.2.0 – 26.2.16없음
26.326.3.0 – 26.3.5없음
26.426.4.0 – 26.4.1426.4.15 (벤더 백포트 태그)
26.526.5.0 – 26.5.7없음
26.626.6.0 – 26.6.526.6.6 (벤더 백포트 태그)
26.726.7.0 – 26.7.126.7.2

이 CVE에서 "레거시"가 의미하는 것

  • 레거시 릴리스는 자동으로 안전하지 않습니다 — 특정한 이유 때문에 안전합니다. 스티키 불리언 노트는 커밋 6a9e60bb에 의해 26.0.0에서 도입되었으며, "다른 방법 시도" 인증자 선택 화면을 재설정 흐름에 추가했습니다. 그보다 오래된 것은 단순히 해당 코드 경로가 없습니다. 여기에는 오래된 WildFly 기반 배포판과 RH-SSO 7.x가 포함되며, 이들은 이 버그의 영향을 받지 않지만 수명 종료 상태로 남아 다른 많은 취약점에 노출되어 있습니다. 레거시 빌드에 머무르는 것은 해결책이 아닙니다.
  • 레거시 26.x 라인이 실제 문제입니다. 26.7.2는 유일하게 수정된 릴리스로 커뮤니티 트레인에 배포되었습니다. 배포가 26.0 – 26.6에 머물러 있다면, 해당 라인에는 패치 릴리스가 없습니다 — 수정에는 포인트 릴리스가 아닌 마이너 버전 업그레이드가 필요합니다. 26.4.15 / 26.6.6 태그는 벤더 백포트이며 커뮤니티 이미지와 서로 바꿔 쓸 수 없습니다.
  • 많은 장기 운영 배포가 호환성 때문에 이전 26.x에 고정되어 있기 때문에, "우리 라인은 완전히 패치되어 있다"는 말이 여기서는 흔하면서도 잘못된 가정입니다. 실행 중인 빌드를 확인하세요. 업데이트 정책이 아니라요.

전제 조건: realm에서 비밀번호 찾기가 활성화되어 있어야 하며 그리고 연결된 자격 증명 재설정 흐름은 기본 제공되는 reset-credential-email 인증자를 사용해야 합니다.


3. 실습 환경

이 저장소는 취약한 Keycloak과 패치된 Keycloak을 모두 포함하며, 동일한 realm을 가져오고, 재설정 메일을 캡처하기 위해 Mailpit도 포함합니다 — 계정이 탈취되는 동안 메일이 도착하고 읽히지 않은 채로 남아 있는 것을 지켜볼 수 있습니다.```bash cd lab docker compose up -d

| 서비스 | URL | 버전 |
|---|---|---|
| `kc-vuln` | http://localhost:8080 | 26.7.1 — **취약** |
| `kc-patched` | http://localhost:8100 | 26.7.2 — **패치된 대조군** |
| `kc-mailpit` | http://localhost:8025 | 피해자의 사서함 |

Realm `poc`, 퍼블릭 클라이언트 `poc-app`, 사용자 `victim` / `OriginalPassw0rd!`, Keycloak
관리자 `admin` / `admin`.
도구 다운로드