1
0
mirror of https://github.com/samba-team/samba.git synced 2025-01-03 01:18:10 +03:00

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]
This commit is contained in:
Joseph Sutton 2022-06-10 19:18:53 +12:00 committed by Jule Anger
parent 89c6e36938
commit d5af460403
6 changed files with 48 additions and 8 deletions

View File

@ -271,7 +271,3 @@
^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_fast_service_ticket
^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_fast_sid_mismatch_existing
^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_fast_sid_mismatch_nonexisting
#
# Kpasswd tests
#
^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_tgt.ad_dc

View File

@ -581,7 +581,3 @@ samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_
^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_canonicalize_realm_case.ad_dc
^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_no_canonicalize_realm_case.ad_dc
^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_ticket_requester_sid_tgs.ad_dc
#
# Kpasswd tests
#
samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_tgt.ad_dc

View File

@ -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;
}

View File

@ -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 */

View File

@ -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;

View File

@ -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;