diff options
author | Greg Hudson <ghudson@mit.edu> | 2015-03-24 12:02:37 -0400 |
---|---|---|
committer | Tom Yu <tlyu@mit.edu> | 2015-05-13 20:05:48 -0400 |
commit | b0c571e709c72da799ccc15fb5755f7910170e33 (patch) | |
tree | 41f3ccc5410b6786be5c06bbf9b380dcfca0a4e9 | |
parent | 3d56ca44fc331bc6dfd0ee114b7f185d0ac55a2a (diff) | |
download | krb5-b0c571e709c72da799ccc15fb5755f7910170e33.zip krb5-b0c571e709c72da799ccc15fb5755f7910170e33.tar.gz krb5-b0c571e709c72da799ccc15fb5755f7910170e33.tar.bz2 |
Prevent requires_preauth bypass [CVE-2015-2694]
In the OTP kdcpreauth module, don't set the TKT_FLG_PRE_AUTH bit until
the request is successfully verified. In the PKINIT kdcpreauth
module, don't respond with code 0 on empty input or an unconfigured
realm. Together these bugs could cause the KDC preauth framework to
erroneously treat a request as pre-authenticated.
CVE-2015-2694:
In MIT krb5 1.12 and later, when the KDC is configured with PKINIT
support, an unauthenticated remote attacker can bypass the
requires_preauth flag on a client principal and obtain a ciphertext
encrypted in the principal's long-term key. This ciphertext could be
used to conduct an off-line dictionary attack against the user's
password.
CVSSv2 Vector: AV:N/AC:M/Au:N/C:P/I:P/A:N/E:POC/RL:OF/RC:C
(cherry picked from commit e3b5a5e5267818c97750b266df50b6a3d4649604)
(cherry picked from commit df8afc60d970a7176a55ffe7ce21cfd57ba423cd)
ticket: 8194 (new)
version_fixed: 1.12.4
status: resolved
-rw-r--r-- | src/plugins/preauth/otp/main.c | 10 | ||||
-rw-r--r-- | src/plugins/preauth/pkinit/pkinit_srv.c | 4 |
2 files changed, 9 insertions, 5 deletions
diff --git a/src/plugins/preauth/otp/main.c b/src/plugins/preauth/otp/main.c index bf9c6a8..7941b4a 100644 --- a/src/plugins/preauth/otp/main.c +++ b/src/plugins/preauth/otp/main.c @@ -42,6 +42,7 @@ static krb5_preauthtype otp_pa_type_list[] = struct request_state { krb5_kdcpreauth_verify_respond_fn respond; void *arg; + krb5_enc_tkt_part *enc_tkt_reply; }; static krb5_error_code @@ -159,6 +160,9 @@ on_response(void *data, krb5_error_code retval, otp_response response) if (retval == 0 && response != otp_response_success) retval = KRB5_PREAUTH_FAILED; + if (retval == 0) + rs.enc_tkt_reply->flags |= TKT_FLG_PRE_AUTH; + rs.respond(rs.arg, retval, NULL, NULL, NULL); } @@ -263,8 +267,6 @@ otp_verify(krb5_context context, krb5_data *req_pkt, krb5_kdc_req *request, krb5_data d, plaintext; char *config; - enc_tkt_reply->flags |= TKT_FLG_PRE_AUTH; - /* Get the FAST armor key. */ armor_key = cb->fast_armor(context, rock); if (armor_key == NULL) { @@ -298,12 +300,14 @@ otp_verify(krb5_context context, krb5_data *req_pkt, krb5_kdc_req *request, goto error; } - /* Create the request state. */ + /* Create the request state. Save the response callback, and the + * enc_tkt_reply pointer so we can set the TKT_FLG_PRE_AUTH flag later. */ rs = k5alloc(sizeof(struct request_state), &retval); if (rs == NULL) goto error; rs->arg = arg; rs->respond = respond; + rs->enc_tkt_reply = enc_tkt_reply; /* Get the principal's OTP configuration string. */ retval = cb->get_string(context, rock, "otp", &config); diff --git a/src/plugins/preauth/pkinit/pkinit_srv.c b/src/plugins/preauth/pkinit/pkinit_srv.c index 1179216..279415a 100644 --- a/src/plugins/preauth/pkinit/pkinit_srv.c +++ b/src/plugins/preauth/pkinit/pkinit_srv.c @@ -306,7 +306,7 @@ pkinit_server_verify_padata(krb5_context context, pkiDebug("pkinit_verify_padata: entered!\n"); if (data == NULL || data->length <= 0 || data->contents == NULL) { - (*respond)(arg, 0, NULL, NULL, NULL); + (*respond)(arg, EINVAL, NULL, NULL, NULL); return; } @@ -318,7 +318,7 @@ pkinit_server_verify_padata(krb5_context context, plgctx = pkinit_find_realm_context(context, moddata, request->server); if (plgctx == NULL) { - (*respond)(arg, 0, NULL, NULL, NULL); + (*respond)(arg, EINVAL, NULL, NULL, NULL); return; } |