CVE-2017-11368 (published 2017-08-09T18:29Z)

In MIT Kerberos 5 (aka krb5) 1.7 and later, an authenticated attacker can cause a KDC assertion failure by sending invalid S4U2Self or S4U2Proxy requests.

Severity: MEDIUM
CVSS v2 base score: 4.0 (AV:N/AC:L/Au:S/C:N/I:N/A:P)
CVSS v3 base score: 6.5, MEDIUM (CVSS:3.0/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:H)

Weakness information:
cwe_id: CWE-617
cwe_name: Reachable Assertion
description: The product contains an assert() or similar statement that can be triggered by an attacker, which leads to an application exit or other behavior that is more severe than necessary.
extended_description: 
            While assertion is good for catching logic errors and reducing the chances of reaching more serious vulnerability conditions, it can still lead to a denial of service.
            For example, if a server handles multiple simultaneous connections, and an assert() occurs in one single connection that causes all other connections to be dropped, this is a reachable assertion that leads to a denial of service.
         
         

Fix information:
repo_url: https://github.com/krb5/krb5
commit_details: repo_url: https://github.com/krb5/krb5
author: Greg Hudson
author_date: 2017-07-13 12:14:20-04:00
msg: Prevent KDC unset status assertion failures

Assign status values if S4U2Self padata fails to decode, if an
S4U2Proxy request uses invalid KDC options, or if an S4U2Proxy request
uses an evidence ticket which does not match the canonicalized request
server principal name.  Reported by Samuel Cabrero.

If a status value is not assigned during KDC processing, default to
"UNKNOWN_REASON" rather than failing an assertion.  This change will
prevent future denial of service bugs due to similar mistakes, and
will allow us to omit assigning status values for unlikely errors such
as small memory allocation failures.

CVE-2017-11368:

In MIT krb5 1.7 and later, an authenticated attacker can cause an
assertion failure in krb5kdc by sending an invalid S4U2Self or
S4U2Proxy request.

  CVSSv3 Vector: AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:H/E:H/RL:O/RC:C

ticket: 8599 (new)
target_version: 1.15-next
target_version: 1.14-next
tags: pullup
repository: repo_url: https://github.com/krb5/krb5
repo_name: krb5/krb5
description: mirror of MIT krb5 repository
repo_language: C
owner: krb5
file_changes: filename: do_as_req.c
change_type: ModificationType.MODIFY
diff: @@ -366,8 +366,8 @@ finish_process_as_req(struct as_req_state *state, krb5_error_code errcode)
     did_log = 1;
 
 egress:
-    if (errcode != 0)
-        assert (state->status != 0);
+    if (errcode != 0 && state->status == NULL)
+        state->status = "UNKNOWN_REASON";
 
     au_state->status = state->status;
     au_state->reply = &state->reply;

programming_language: C
filename: do_tgs_req.c
change_type: ModificationType.MODIFY
diff: @@ -823,7 +823,8 @@ process_tgs_req(struct server_handle *handle, krb5_data *pkt,
     free(reply.enc_part.ciphertext.data);
 
 cleanup:
-    assert(status != NULL);
+    if (status == NULL)
+        status = "UNKNOWN_REASON";
     if (reply_key)
         krb5_free_keyblock(kdc_context, reply_key);
     if (errcode)

programming_language: C
filename: kdc_util.c
change_type: ModificationType.MODIFY
diff: @@ -1220,8 +1220,10 @@ kdc_process_for_user(kdc_realm_t *kdc_active_realm,
     req_data.data = (char *)pa_data->contents;
 
     code = decode_krb5_pa_for_user(&req_data, &for_user);
-    if (code)
+    if (code) {
+        *status = "DECODE_PA_FOR_USER";
         return code;
+    }
 
     code = verify_for_user_checksum(kdc_context, tgs_session, for_user);
     if (code) {
@@ -1320,8 +1322,10 @@ kdc_process_s4u_x509_user(krb5_context context,
     req_data.data = (char *)pa_data->contents;
 
     code = decode_krb5_pa_s4u_x509_user(&req_data, s4u_x509_user);
-    if (code)
+    if (code) {
+        *status = "DECODE_PA_S4U_X509_USER";
         return code;
+    }
 
     code = verify_s4u_x509_user_checksum(context,
                                          tgs_subkey ? tgs_subkey :
@@ -1624,6 +1628,7 @@ kdc_process_s4u2proxy_req(kdc_realm_t *kdc_active_realm,
      * that is validated previously in validate_tgs_request().
      */
     if (request->kdc_options & (NON_TGT_OPTION | KDC_OPT_ENC_TKT_IN_SKEY)) {
+        *status = "INVALID_S4U2PROXY_OPTIONS";
         return KRB5KDC_ERR_BADOPTION;
     }
 
@@ -1631,6 +1636,7 @@ kdc_process_s4u2proxy_req(kdc_realm_t *kdc_active_realm,
     if (!krb5_principal_compare(kdc_context,
                                 server->princ, /* after canon */
                                 server_princ)) {
+        *status = "EVIDENCE_TICKET_MISMATCH";
         return KRB5KDC_ERR_SERVER_NOMATCH;
     }
 

programming_language: C