Skip to content
Permalink
Browse files Browse the repository at this point in the history
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
  • Loading branch information
greghudson committed Sep 22, 2014
1 parent 1768970 commit af0ed4d
Showing 1 changed file with 18 additions and 3 deletions.
21 changes: 18 additions & 3 deletions src/lib/kadm5/srv/svr_principal.c
Expand Up @@ -344,6 +344,20 @@ check_1_6_dummy(kadm5_principal_ent_t entry, long mask,
*passptr = NULL;
}

/* Return the number of keys with the newest kvno. Assumes that all key data
* with the newest kvno are at the front of the key data array. */
static int
count_new_keys(int n_key_data, krb5_key_data *key_data)
{
int n;

for (n = 1; n < n_key_data; n++) {
if (key_data[n - 1].key_data_kvno != key_data[n].key_data_kvno)
return n;
}
return n_key_data;
}

kadm5_ret_t
kadm5_create_principal(void *server_handle,
kadm5_principal_ent_t entry, long mask,
Expand Down Expand Up @@ -1593,7 +1607,7 @@ kadm5_randkey_principal_3(void *server_handle,
osa_princ_ent_rec adb;
krb5_int32 now;
kadm5_policy_ent_rec pol;
int ret, last_pwd;
int ret, last_pwd, n_new_keys;
krb5_boolean have_pol = FALSE;
kadm5_server_handle_t handle = server_handle;
krb5_keyblock *act_mkey;
Expand Down Expand Up @@ -1686,8 +1700,9 @@ kadm5_randkey_principal_3(void *server_handle,
kdb->fail_auth_count = 0;

if (keyblocks) {
ret = decrypt_key_data(handle->context,
kdb->n_key_data, kdb->key_data,
/* Return only the new keys added by krb5_dbe_crk. */
n_new_keys = count_new_keys(kdb->n_key_data, kdb->key_data);
ret = decrypt_key_data(handle->context, n_new_keys, kdb->key_data,
keyblocks, n_keys);
if (ret)
goto done;
Expand Down

0 comments on commit af0ed4d

Please sign in to comment.