245 lines
9.7 KiB
Diff
245 lines
9.7 KiB
Diff
|
From 67ca47ba4092811029eec02f8af9c34ba7662924 Mon Sep 17 00:00:00 2001
|
||
|
From: Julien Rische <jrische@redhat.com>
|
||
|
Date: Mon, 9 Oct 2023 15:47:03 +0200
|
||
|
Subject: [PATCH] ipa-kdb: Ensure Bronze-Bit check can be enabled
|
||
|
|
||
|
MIT krb5 1.19 and older do not implement support for PAC ticket
|
||
|
signature to protect the encrypted part of tickets. This is the cause of
|
||
|
the Bronze-Bit vulnerability (CVE-2020-17043). The Bronze-Bit attack
|
||
|
detection mechanism introduced in a847e248 relies on the content of the
|
||
|
PAC.
|
||
|
|
||
|
However, since CVE-2022-37967, the content of the PAC can no longer be
|
||
|
trusted if the KDC does not support PAC extended KDC signature (aka.
|
||
|
PAC full checksum). This signature is supported in MIT krb5 since
|
||
|
version 1.21.
|
||
|
|
||
|
Support for the PAC extended KDC signature was backported downstream to
|
||
|
krb5 1.18.2 for CentOS 8 Stream (dist-git commit 7d215a54). This makes
|
||
|
the content of the PAC still trustworthy there.
|
||
|
|
||
|
This commit disables the Bronze-Bit attack detection mechanism at build
|
||
|
time in case krb5 does not provide the krb5_pac_full_sign_compat()
|
||
|
function.
|
||
|
|
||
|
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
|
||
|
---
|
||
|
daemons/ipa-kdb/ipa_kdb.h | 4 ++++
|
||
|
daemons/ipa-kdb/ipa_kdb_kdcpolicy.c | 7 +++++++
|
||
|
daemons/ipa-kdb/ipa_kdb_mspac.c | 4 ++++
|
||
|
3 files changed, 15 insertions(+)
|
||
|
|
||
|
diff --git a/daemons/ipa-kdb/ipa_kdb.h b/daemons/ipa-kdb/ipa_kdb.h
|
||
|
index 02b2cb631..c6926f7d5 100644
|
||
|
--- a/daemons/ipa-kdb/ipa_kdb.h
|
||
|
+++ b/daemons/ipa-kdb/ipa_kdb.h
|
||
|
@@ -367,6 +367,8 @@ krb5_error_code ipadb_is_princ_from_trusted_realm(krb5_context kcontext,
|
||
|
const char *test_realm, size_t size,
|
||
|
char **trusted_realm);
|
||
|
|
||
|
+#if KRB5_KDB_DAL_MAJOR_VERSION <= 8
|
||
|
+# ifdef HAVE_KRB5_PAC_FULL_SIGN_COMPAT
|
||
|
/* Try to detect a Bronze-Bit attack based on the content of the request and
|
||
|
* data from the KDB.
|
||
|
*
|
||
|
@@ -379,6 +381,8 @@ krb5_error_code ipadb_is_princ_from_trusted_realm(krb5_context kcontext,
|
||
|
krb5_error_code
|
||
|
ipadb_check_for_bronze_bit_attack(krb5_context context, krb5_kdc_req *request,
|
||
|
bool *detected, const char **status);
|
||
|
+# endif
|
||
|
+#endif
|
||
|
|
||
|
/* DELEGATION CHECKS */
|
||
|
|
||
|
diff --git a/daemons/ipa-kdb/ipa_kdb_kdcpolicy.c b/daemons/ipa-kdb/ipa_kdb_kdcpolicy.c
|
||
|
index 1032dff0b..ee0546c01 100644
|
||
|
--- a/daemons/ipa-kdb/ipa_kdb_kdcpolicy.c
|
||
|
+++ b/daemons/ipa-kdb/ipa_kdb_kdcpolicy.c
|
||
|
@@ -185,11 +185,18 @@ ipa_kdcpolicy_check_tgs(krb5_context context, krb5_kdcpolicy_moddata moddata,
|
||
|
const char **status, krb5_deltat *lifetime_out,
|
||
|
krb5_deltat *renew_lifetime_out)
|
||
|
{
|
||
|
+#if KRB5_KDB_DAL_MAJOR_VERSION <= 8
|
||
|
+# ifdef HAVE_KRB5_PAC_FULL_SIGN_COMPAT
|
||
|
krb5_error_code kerr;
|
||
|
|
||
|
kerr = ipadb_check_for_bronze_bit_attack(context, request, NULL, status);
|
||
|
if (kerr)
|
||
|
return KRB5KDC_ERR_POLICY;
|
||
|
+# else
|
||
|
+# warning Support for Kerberos PAC extended KDC signature is missing.\
|
||
|
+ This makes FreeIPA vulnerable to the Bronze-Bit exploit (CVE-2020-17049).
|
||
|
+# endif
|
||
|
+#endif
|
||
|
|
||
|
*status = NULL;
|
||
|
*lifetime_out = 0;
|
||
|
diff --git a/daemons/ipa-kdb/ipa_kdb_mspac.c b/daemons/ipa-kdb/ipa_kdb_mspac.c
|
||
|
index b4e22d431..05d5b407d 100644
|
||
|
--- a/daemons/ipa-kdb/ipa_kdb_mspac.c
|
||
|
+++ b/daemons/ipa-kdb/ipa_kdb_mspac.c
|
||
|
@@ -3299,6 +3299,8 @@ krb5_error_code ipadb_is_princ_from_trusted_realm(krb5_context kcontext,
|
||
|
return KRB5_KDB_NOENTRY;
|
||
|
}
|
||
|
|
||
|
+#if KRB5_KDB_DAL_MAJOR_VERSION <= 8
|
||
|
+# ifdef HAVE_KRB5_PAC_FULL_SIGN_COMPAT
|
||
|
krb5_error_code
|
||
|
ipadb_check_for_bronze_bit_attack(krb5_context context, krb5_kdc_req *request,
|
||
|
bool *detected, const char **status)
|
||
|
@@ -3471,3 +3473,5 @@ end:
|
||
|
ipadb_free_principal(context, proxy_entry);
|
||
|
return kerr;
|
||
|
}
|
||
|
+# endif
|
||
|
+#endif
|
||
|
--
|
||
|
2.43.0
|
||
|
|
||
|
From 27b96c17dd51d076e04d97662b7c788658a5094a Mon Sep 17 00:00:00 2001
|
||
|
From: Julien Rische <jrische@redhat.com>
|
||
|
Date: Jan 26 2024 09:35:57 +0000
|
||
|
Subject: ipa-kdb: Disable Bronze-Bit check if PAC not available
|
||
|
|
||
|
|
||
|
The Bronze-Bit check introduced in commit
|
||
|
a847e2483b4c4832ee5129901da169f4eb0d1392 requires the MS-PAC to be
|
||
|
present in the evidence ticket in order for S4U2Proxy requests to be
|
||
|
accepted. This actually requires SIDs to be set.
|
||
|
|
||
|
However, domains that were initialized before commit
|
||
|
e527857d000e558b3288a7a210400abaf2171237 may still not have SIDs
|
||
|
configured. This would results in all S4U2Proxy requests to fail
|
||
|
(including all the HTTP API requests).
|
||
|
|
||
|
This present commit disables the check for the Bronze-Bit exploit
|
||
|
(CVE-2020-17049) in case the domain is not able to generate PACs.
|
||
|
Instead, it prints a warning message in the KDC logs each time a
|
||
|
S4U2Proxy request is processed.
|
||
|
|
||
|
Fixes: https://pagure.io/freeipa/issue/9521
|
||
|
|
||
|
Signed-off-by: Julien Rische <jrische@redhat.com>
|
||
|
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
|
||
|
|
||
|
---
|
||
|
|
||
|
diff --git a/daemons/ipa-kdb/ipa_kdb.h b/daemons/ipa-kdb/ipa_kdb.h
|
||
|
index c6926f7..621c235 100644
|
||
|
--- a/daemons/ipa-kdb/ipa_kdb.h
|
||
|
+++ b/daemons/ipa-kdb/ipa_kdb.h
|
||
|
@@ -370,17 +370,21 @@ krb5_error_code ipadb_is_princ_from_trusted_realm(krb5_context kcontext,
|
||
|
#if KRB5_KDB_DAL_MAJOR_VERSION <= 8
|
||
|
# ifdef HAVE_KRB5_PAC_FULL_SIGN_COMPAT
|
||
|
/* Try to detect a Bronze-Bit attack based on the content of the request and
|
||
|
- * data from the KDB.
|
||
|
+ * data from the KDB. This check will work only if the domain supports MS-PAC.
|
||
|
*
|
||
|
* context krb5 context
|
||
|
* request KDB request
|
||
|
- * detected Set to "true" if a bronze bit attack is detected and the
|
||
|
- * pointer is not NULL. Remains unset otherwise.
|
||
|
+ * supported If not NULL, set to "false" in case the Bronze-Bit exploit
|
||
|
+ * detection process silently failed to complete because the
|
||
|
+ * domain does not meet requirements. Set to "true" otherwise.
|
||
|
+ * detected If not NULL, set to "true" if a Bronze-Bit attack is detected.
|
||
|
+ * Set to "false" otherwise.
|
||
|
* status If the call fails and the pointer is not NULL, set it with a
|
||
|
* message describing the cause of the failure. */
|
||
|
krb5_error_code
|
||
|
ipadb_check_for_bronze_bit_attack(krb5_context context, krb5_kdc_req *request,
|
||
|
- bool *detected, const char **status);
|
||
|
+ bool *supported, bool *detected,
|
||
|
+ const char **status);
|
||
|
# endif
|
||
|
#endif
|
||
|
|
||
|
diff --git a/daemons/ipa-kdb/ipa_kdb_kdcpolicy.c b/daemons/ipa-kdb/ipa_kdb_kdcpolicy.c
|
||
|
index ee0546c..713e9a0 100644
|
||
|
--- a/daemons/ipa-kdb/ipa_kdb_kdcpolicy.c
|
||
|
+++ b/daemons/ipa-kdb/ipa_kdb_kdcpolicy.c
|
||
|
@@ -188,10 +188,18 @@ ipa_kdcpolicy_check_tgs(krb5_context context, krb5_kdcpolicy_moddata moddata,
|
||
|
#if KRB5_KDB_DAL_MAJOR_VERSION <= 8
|
||
|
# ifdef HAVE_KRB5_PAC_FULL_SIGN_COMPAT
|
||
|
krb5_error_code kerr;
|
||
|
+ bool supported;
|
||
|
|
||
|
- kerr = ipadb_check_for_bronze_bit_attack(context, request, NULL, status);
|
||
|
+ kerr = ipadb_check_for_bronze_bit_attack(context, request, supported, NULL,
|
||
|
+ status);
|
||
|
if (kerr)
|
||
|
return KRB5KDC_ERR_POLICY;
|
||
|
+
|
||
|
+ if (!supported)
|
||
|
+ krb5_klog_syslog(LOG_WARNING, "MS-PAC not available. This makes "
|
||
|
+ "FreeIPA vulnerable to the Bronze-Bit exploit "
|
||
|
+ "(CVE-2020-17049). Please generate SIDs to enable "
|
||
|
+ "PAC support.");
|
||
|
# else
|
||
|
# warning Support for Kerberos PAC extended KDC signature is missing.\
|
||
|
This makes FreeIPA vulnerable to the Bronze-Bit exploit (CVE-2020-17049).
|
||
|
diff --git a/daemons/ipa-kdb/ipa_kdb_mspac.c b/daemons/ipa-kdb/ipa_kdb_mspac.c
|
||
|
index 05d5b40..a18beff 100644
|
||
|
--- a/daemons/ipa-kdb/ipa_kdb_mspac.c
|
||
|
+++ b/daemons/ipa-kdb/ipa_kdb_mspac.c
|
||
|
@@ -3303,11 +3303,14 @@ krb5_error_code ipadb_is_princ_from_trusted_realm(krb5_context kcontext,
|
||
|
# ifdef HAVE_KRB5_PAC_FULL_SIGN_COMPAT
|
||
|
krb5_error_code
|
||
|
ipadb_check_for_bronze_bit_attack(krb5_context context, krb5_kdc_req *request,
|
||
|
- bool *detected, const char **status)
|
||
|
+ bool *supported, bool *detected,
|
||
|
+ const char **status)
|
||
|
{
|
||
|
krb5_error_code kerr;
|
||
|
const char *st = NULL;
|
||
|
size_t i, j;
|
||
|
+ bool in_supported = true, in_detected = false;
|
||
|
+ struct ipadb_context *ipactx;
|
||
|
krb5_ticket *evidence_tkt;
|
||
|
krb5_authdata **authdata, **ifrel = NULL;
|
||
|
krb5_pac pac = NULL;
|
||
|
@@ -3327,6 +3330,21 @@ ipadb_check_for_bronze_bit_attack(krb5_context context, krb5_kdc_req *request,
|
||
|
goto end;
|
||
|
}
|
||
|
|
||
|
+ ipactx = ipadb_get_context(context);
|
||
|
+ if (!ipactx) {
|
||
|
+ kerr = KRB5_KDB_DBNOTINITED;
|
||
|
+ goto end;
|
||
|
+ }
|
||
|
+
|
||
|
+ /* Handle the case where the domain is not able to generate PACs (probably
|
||
|
+ * because SIDs are not set). In this case, we just skip the Bronze-Bit
|
||
|
+ * check. */
|
||
|
+ if (!ipactx->mspac) {
|
||
|
+ in_supported = false;
|
||
|
+ kerr = 0;
|
||
|
+ goto end;
|
||
|
+ }
|
||
|
+
|
||
|
evidence_tkt = request->second_ticket[0];
|
||
|
|
||
|
/* No need to check the Forwardable flag. If it was not set, this request
|
||
|
@@ -3451,8 +3469,7 @@ ipadb_check_for_bronze_bit_attack(krb5_context context, krb5_kdc_req *request,
|
||
|
/* This evidence ticket cannot be forwardable given the privileges
|
||
|
* of the proxy principal.
|
||
|
* This is a Bronze Bit attack. */
|
||
|
- if (detected)
|
||
|
- *detected = true;
|
||
|
+ in_detected = true;
|
||
|
st = "S4U2PROXY_BRONZE_BIT_ATTACK_DETECTED";
|
||
|
kerr = EBADE;
|
||
|
goto end;
|
||
|
@@ -3464,6 +3481,10 @@ ipadb_check_for_bronze_bit_attack(krb5_context context, krb5_kdc_req *request,
|
||
|
end:
|
||
|
if (st && status)
|
||
|
*status = st;
|
||
|
+ if (supported)
|
||
|
+ *supported = in_supported;
|
||
|
+ if (detected)
|
||
|
+ *detected = in_detected;
|
||
|
|
||
|
krb5_free_authdata(context, ifrel);
|
||
|
krb5_pac_free(context, pac);
|
||
|
|