137 lines
4.7 KiB
Diff
137 lines
4.7 KiB
Diff
From d5af460403d3949ba266f5c74f051247cd7ce752 Mon Sep 17 00:00:00 2001
|
|
From: Joseph Sutton <josephsutton@catalyst.net.nz>
|
|
Date: Fri, 10 Jun 2022 19:18:53 +1200
|
|
Subject: [PATCH 96/99] CVE-2022-2031 s4:kpasswd: Do not accept TGTs as kpasswd
|
|
tickets
|
|
|
|
If TGTs can be used as kpasswd tickets, the two-minute lifetime of a
|
|
authentic kpasswd ticket may be bypassed. Furthermore, kpasswd tickets
|
|
are not supposed to be cached, but using this flaw, a stolen credentials
|
|
cache containing a TGT may be used to change that account's password,
|
|
and thus is made more valuable to an attacker.
|
|
|
|
Since all TGTs should be issued with a REQUESTER_SID PAC buffer, and
|
|
service tickets without it, we assert the absence of this buffer to
|
|
ensure we're not accepting a TGT.
|
|
|
|
BUG: https://bugzilla.samba.org/show_bug.cgi?id=15047
|
|
BUG: https://bugzilla.samba.org/show_bug.cgi?id=15049
|
|
|
|
Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz>
|
|
Reviewed-by: Andreas Schneider <asn@samba.org>
|
|
|
|
[jsutton@samba.org Fixed knownfail conflicts]
|
|
|
|
[jsutton@samba.org Fixed knownfail conflicts]
|
|
Conflict: remove selftest/knownfail_heimdal_kdc selftest/knownfail_mit_kdc
|
|
---
|
|
source4/kdc/kpasswd-helper.c | 20 ++++++++++++++++++++
|
|
source4/kdc/kpasswd-helper.h | 2 ++
|
|
source4/kdc/kpasswd-service-heimdal.c | 13 +++++++++++++
|
|
source4/kdc/kpasswd-service-mit.c | 13 +++++++++++++
|
|
6 files changed, 48 insertions(+), 8 deletions(-)
|
|
|
|
diff --git a/source4/kdc/kpasswd-helper.c b/source4/kdc/kpasswd-helper.c
|
|
index 55a2f5b3bf6..2ffdb79aea5 100644
|
|
--- a/source4/kdc/kpasswd-helper.c
|
|
+++ b/source4/kdc/kpasswd-helper.c
|
|
@@ -241,3 +241,23 @@ NTSTATUS kpasswd_samdb_set_password(TALLOC_CTX *mem_ctx,
|
|
|
|
return status;
|
|
}
|
|
+
|
|
+krb5_error_code kpasswd_check_non_tgt(struct auth_session_info *session_info,
|
|
+ const char **error_string)
|
|
+{
|
|
+ switch(session_info->ticket_type) {
|
|
+ case TICKET_TYPE_TGT:
|
|
+ /* TGTs are disallowed here. */
|
|
+ *error_string = "A TGT may not be used as a ticket to kpasswd";
|
|
+ return KRB5_KPASSWD_AUTHERROR;
|
|
+ case TICKET_TYPE_NON_TGT:
|
|
+ /* Non-TGTs are permitted, and expected. */
|
|
+ break;
|
|
+ default:
|
|
+ /* In case we forgot to set the type. */
|
|
+ *error_string = "Failed to ascertain that ticket to kpasswd is not a TGT";
|
|
+ return KRB5_KPASSWD_HARDERROR;
|
|
+ }
|
|
+
|
|
+ return 0;
|
|
+}
|
|
diff --git a/source4/kdc/kpasswd-helper.h b/source4/kdc/kpasswd-helper.h
|
|
index 8fad81e0a5d..94a6e2acfdd 100644
|
|
--- a/source4/kdc/kpasswd-helper.h
|
|
+++ b/source4/kdc/kpasswd-helper.h
|
|
@@ -43,4 +43,6 @@ NTSTATUS kpasswd_samdb_set_password(TALLOC_CTX *mem_ctx,
|
|
enum samPwdChangeReason *reject_reason,
|
|
struct samr_DomInfo1 **dominfo);
|
|
|
|
+krb5_error_code kpasswd_check_non_tgt(struct auth_session_info *session_info,
|
|
+ const char **error_string);
|
|
#endif /* _KPASSWD_HELPER_H */
|
|
diff --git a/source4/kdc/kpasswd-service-heimdal.c b/source4/kdc/kpasswd-service-heimdal.c
|
|
index a0352d1ad35..4d009b9eb24 100644
|
|
--- a/source4/kdc/kpasswd-service-heimdal.c
|
|
+++ b/source4/kdc/kpasswd-service-heimdal.c
|
|
@@ -253,6 +253,7 @@ krb5_error_code kpasswd_handle_request(struct kdc_server *kdc,
|
|
{
|
|
struct auth_session_info *session_info;
|
|
NTSTATUS status;
|
|
+ krb5_error_code code;
|
|
|
|
status = gensec_session_info(gensec_security,
|
|
mem_ctx,
|
|
@@ -264,6 +265,18 @@ krb5_error_code kpasswd_handle_request(struct kdc_server *kdc,
|
|
return KRB5_KPASSWD_HARDERROR;
|
|
}
|
|
|
|
+ /*
|
|
+ * Since the kpasswd service shares its keys with the krbtgt, we might
|
|
+ * have received a TGT rather than a kpasswd ticket. We need to check
|
|
+ * the ticket type to ensure that TGTs cannot be misused in this manner.
|
|
+ */
|
|
+ code = kpasswd_check_non_tgt(session_info,
|
|
+ error_string);
|
|
+ if (code != 0) {
|
|
+ DBG_WARNING("%s\n", *error_string);
|
|
+ return code;
|
|
+ }
|
|
+
|
|
switch(verno) {
|
|
case KRB5_KPASSWD_VERS_CHANGEPW: {
|
|
DATA_BLOB password = data_blob_null;
|
|
diff --git a/source4/kdc/kpasswd-service-mit.c b/source4/kdc/kpasswd-service-mit.c
|
|
index de4c6f3f622..6b051567b6e 100644
|
|
--- a/source4/kdc/kpasswd-service-mit.c
|
|
+++ b/source4/kdc/kpasswd-service-mit.c
|
|
@@ -332,6 +332,7 @@ krb5_error_code kpasswd_handle_request(struct kdc_server *kdc,
|
|
{
|
|
struct auth_session_info *session_info;
|
|
NTSTATUS status;
|
|
+ krb5_error_code code;
|
|
|
|
status = gensec_session_info(gensec_security,
|
|
mem_ctx,
|
|
@@ -344,6 +345,18 @@ krb5_error_code kpasswd_handle_request(struct kdc_server *kdc,
|
|
return KRB5_KPASSWD_HARDERROR;
|
|
}
|
|
|
|
+ /*
|
|
+ * Since the kpasswd service shares its keys with the krbtgt, we might
|
|
+ * have received a TGT rather than a kpasswd ticket. We need to check
|
|
+ * the ticket type to ensure that TGTs cannot be misused in this manner.
|
|
+ */
|
|
+ code = kpasswd_check_non_tgt(session_info,
|
|
+ error_string);
|
|
+ if (code != 0) {
|
|
+ DBG_WARNING("%s\n", *error_string);
|
|
+ return code;
|
|
+ }
|
|
+
|
|
switch(verno) {
|
|
case 1: {
|
|
DATA_BLOB password;
|
|
--
|
|
2.25.1
|