CVE-2022-2031 s4:kdc: Reject tickets during the last two minutes of their life
authorJoseph Sutton <josephsutton@catalyst.net.nz>
Mon, 30 May 2022 07:18:17 +0000 (19:18 +1200)
committerJule Anger <janger@samba.org>
Sun, 24 Jul 2022 07:23:56 +0000 (09:23 +0200)
For Heimdal, this now matches the behaviour of Windows. The object of
this requirement is to ensure we don't allow kpasswd tickets, not having
a lifetime of more than two minutes, to be passed off as TGTs.

An existing requirement for TGTs to contain a REQUESTER_SID PAC buffer
suffices to prevent kpasswd ticket misuse, so this is just an additional
precaution on top.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=15047

Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz>
Reviewed-by: Andreas Schneider <asn@samba.org>
selftest/knownfail_heimdal_kdc
source4/kdc/wdc-samba4.c

index 84f265b312ba0b5bee9aa441cbf60c711868a3f4..6148467e0301392b37781fc01f3e14c00ac3c5a3 100644 (file)
@@ -51,7 +51,6 @@
 # Kpasswd tests
 #
 ^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_from_rodc.ad_dc
-^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_ticket_requester_sid_tgs.ad_dc
 ^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_wrong_key.ad_dc
 ^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_wrong_key_server.ad_dc
 ^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_wrong_key_service.ad_dc
index 7f99233440e77b9cb681b34ef130533cea30eb92..ae0dc22fd49a63651d581d1e00650bf5e4aa749a 100644 (file)
@@ -772,6 +772,32 @@ static krb5_error_code samba_wdc_reget_pac(void *priv, astgs_request_t r,
                                krbtgt = &signing_krbtgt_hdb;
                        }
                }
+       } else if (!krbtgt_skdc_entry->is_trust) {
+               /*
+                * We expect to have received a TGT, so check that we haven't
+                * been given a kpasswd ticket instead. We don't need to do this
+                * check for an incoming trust, as they use a different secret
+                * and can't be confused with a normal TGT.
+                */
+               krb5_ticket *tgt = kdc_request_get_ticket(r);
+
+               struct timeval now = krb5_kdc_get_time();
+
+               /*
+                * Check if the ticket is in the last two minutes of its
+                * life.
+                */
+               KerberosTime lifetime = rk_time_sub(tgt->ticket.endtime, now.tv_sec);
+               if (lifetime <= CHANGEPW_LIFETIME) {
+                       /*
+                        * This ticket has at most two minutes left to live. It
+                        * may be a kpasswd ticket rather than a TGT, so don't
+                        * accept it.
+                        */
+                       kdc_audit_addreason((kdc_request_t)r,
+                                           "Ticket is not a ticket-granting ticket");
+                       return KRB5KRB_AP_ERR_TKT_EXPIRED;
+               }
        }
 
        ret = samba_wdc_reget_pac2(context,