krb5 commit [krb5-1.13]: Return only new keys in randkey [CVE-2014-5351]

Tom Yu tlyu at mit.edu
Mon Sep 22 17:29:07 EDT 2014


https://github.com/krb5/krb5/commit/3bf9e33f9d66c0eef486cbd83f9e4f13a74d12c3
commit 3bf9e33f9d66c0eef486cbd83f9e4f13a74d12c3
Author: Greg Hudson <ghudson at mit.edu>
Date:   Thu Aug 21 13:52:07 2014 -0400

    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 at mit.edu: CVE description and CVSS score]
    
    (cherry picked from commit af0ed4df4dfae762ab5fb605f5a0c8f59cb4f6ca)
    
    ticket: 8018
    version_fixed: 1.13
    status: resolved

 src/lib/kadm5/srv/svr_principal.c |   21 ++++++++++++++++++---
 1 files changed, 18 insertions(+), 3 deletions(-)

diff --git a/src/lib/kadm5/srv/svr_principal.c b/src/lib/kadm5/srv/svr_principal.c
index 5d358bd..d4e74cc 100644
--- a/src/lib/kadm5/srv/svr_principal.c
+++ b/src/lib/kadm5/srv/svr_principal.c
@@ -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,
@@ -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;
@@ -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;


More information about the cvs-krb5 mailing list