Skip to content

Commit af0ed4d

Browse files
committed
Return only new keys in randkey [CVE-2014-5351]
In kadmind's randkey operation, if a client specifies the keepold flag, do not include the preserved old keys in the response. CVE-2014-5351: An authenticated remote attacker can retrieve the current keys for a service principal when generating a new set of keys for that principal. The attacker needs to be authenticated as a user who has the elevated privilege for randomizing the keys of other principals. Normally, when a Kerberos administrator randomizes the keys of a service principal, kadmind returns only the new keys. This prevents an administrator who lacks legitimate privileged access to a service from forging tickets to authenticate to that service. If the "keepold" flag to the kadmin randkey RPC operation is true, kadmind retains the old keys in the KDC database as intended, but also unexpectedly returns the old keys to the client, which exposes the service to ticket forgery attacks from the administrator. A mitigating factor is that legitimate clients of the affected service will start failing to authenticate to the service once they begin to receive service tickets encrypted in the new keys. The affected service will be unable to decrypt the newly issued tickets, possibly alerting the legitimate administrator of the affected service. CVSSv2: AV:N/AC:H/Au:S/C:P/I:N/A:N/E:POC/RL:OF/RC:C [tlyu@mit.edu: CVE description and CVSS score] ticket: 8018 (new) target_version: 1.13 tags: pullup
1 parent 1768970 commit af0ed4d

File tree

1 file changed

+18
-3
lines changed

1 file changed

+18
-3
lines changed

Diff for: src/lib/kadm5/srv/svr_principal.c

+18-3
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,20 @@ check_1_6_dummy(kadm5_principal_ent_t entry, long mask,
344344
*passptr = NULL;
345345
}
346346

347+
/* Return the number of keys with the newest kvno. Assumes that all key data
348+
* with the newest kvno are at the front of the key data array. */
349+
static int
350+
count_new_keys(int n_key_data, krb5_key_data *key_data)
351+
{
352+
int n;
353+
354+
for (n = 1; n < n_key_data; n++) {
355+
if (key_data[n - 1].key_data_kvno != key_data[n].key_data_kvno)
356+
return n;
357+
}
358+
return n_key_data;
359+
}
360+
347361
kadm5_ret_t
348362
kadm5_create_principal(void *server_handle,
349363
kadm5_principal_ent_t entry, long mask,
@@ -1593,7 +1607,7 @@ kadm5_randkey_principal_3(void *server_handle,
15931607
osa_princ_ent_rec adb;
15941608
krb5_int32 now;
15951609
kadm5_policy_ent_rec pol;
1596-
int ret, last_pwd;
1610+
int ret, last_pwd, n_new_keys;
15971611
krb5_boolean have_pol = FALSE;
15981612
kadm5_server_handle_t handle = server_handle;
15991613
krb5_keyblock *act_mkey;
@@ -1686,8 +1700,9 @@ kadm5_randkey_principal_3(void *server_handle,
16861700
kdb->fail_auth_count = 0;
16871701

16881702
if (keyblocks) {
1689-
ret = decrypt_key_data(handle->context,
1690-
kdb->n_key_data, kdb->key_data,
1703+
/* Return only the new keys added by krb5_dbe_crk. */
1704+
n_new_keys = count_new_keys(kdb->n_key_data, kdb->key_data);
1705+
ret = decrypt_key_data(handle->context, n_new_keys, kdb->key_data,
16911706
keyblocks, n_keys);
16921707
if (ret)
16931708
goto done;

0 commit comments

Comments
 (0)