Blame SOURCES/Fix-KDC-null-deref-on-bad-encrypted-challenge.patch

27013b
From 4e8579f0a41b66ed8029f21a52082e1c27ab3996 Mon Sep 17 00:00:00 2001
f4b6e2
From: Joseph Sutton <josephsutton@catalyst.net.nz>
f4b6e2
Date: Wed, 7 Jul 2021 11:47:44 +1200
f4b6e2
Subject: [PATCH] Fix KDC null deref on bad encrypted challenge
f4b6e2
f4b6e2
The function ec_verify() in src/kdc/kdc_preauth_ec.c contains a check
f4b6e2
to avoid further processing if the armor key is NULL.  However, this
f4b6e2
check is bypassed by a call to k5memdup0() which overwrites retval
f4b6e2
with 0 if the allocation succeeds.  If the armor key is NULL, a call
f4b6e2
to krb5_c_fx_cf2_simple() will then dereference it, resulting in a
f4b6e2
crash.  Add a check before the k5memdup0() call to avoid overwriting
f4b6e2
retval.
f4b6e2
f4b6e2
CVE-2021-36222:
f4b6e2
f4b6e2
In MIT krb5 releases 1.16 and later, an unauthenticated attacker can
f4b6e2
cause a null dereference in the KDC by sending a request containing a
f4b6e2
PA-ENCRYPTED-CHALLENGE padata element without using FAST.
f4b6e2
f4b6e2
[ghudson@mit.edu: trimmed patch; added test case; edited commit
f4b6e2
message]
f4b6e2
f4b6e2
(cherry picked from commit fc98f520caefff2e5ee9a0026fdf5109944b3562)
f4b6e2
f4b6e2
ticket: 9007
f4b6e2
version_fixed: 1.18.4
f4b6e2
f4b6e2
(cherry picked from commit c4a406095b3ea4a67ae5b8ea586cbe9abdbae76f)
f4b6e2
---
f4b6e2
 src/kdc/kdc_preauth_ec.c      |  3 ++-
f4b6e2
 src/tests/Makefile.in         |  1 +
f4b6e2
 src/tests/t_cve-2021-36222.py | 46 +++++++++++++++++++++++++++++++++++
f4b6e2
 3 files changed, 49 insertions(+), 1 deletion(-)
f4b6e2
 create mode 100644 src/tests/t_cve-2021-36222.py
f4b6e2
f4b6e2
diff --git a/src/kdc/kdc_preauth_ec.c b/src/kdc/kdc_preauth_ec.c
f4b6e2
index 7e636b3f9..43a9902cc 100644
f4b6e2
--- a/src/kdc/kdc_preauth_ec.c
f4b6e2
+++ b/src/kdc/kdc_preauth_ec.c
f4b6e2
@@ -87,7 +87,8 @@ ec_verify(krb5_context context, krb5_data *req_pkt, krb5_kdc_req *request,
f4b6e2
     }
f4b6e2
 
f4b6e2
     /* Check for a configured FAST ec auth indicator. */
f4b6e2
-    realmstr = k5memdup0(realm.data, realm.length, &retval);
f4b6e2
+    if (retval == 0)
f4b6e2
+        realmstr = k5memdup0(realm.data, realm.length, &retval);
f4b6e2
     if (realmstr != NULL)
f4b6e2
         retval = profile_get_string(context->profile, KRB5_CONF_REALMS,
f4b6e2
                                     realmstr,
f4b6e2
diff --git a/src/tests/Makefile.in b/src/tests/Makefile.in
f4b6e2
index 3f88f1713..0ffbebf56 100644
f4b6e2
--- a/src/tests/Makefile.in
f4b6e2
+++ b/src/tests/Makefile.in
f4b6e2
@@ -158,6 +158,7 @@ check-pytests: unlockiter s4u2self
f4b6e2
 	$(RUNPYTEST) $(srcdir)/t_cve-2012-1015.py $(PYTESTFLAGS)
f4b6e2
 	$(RUNPYTEST) $(srcdir)/t_cve-2013-1416.py $(PYTESTFLAGS)
f4b6e2
 	$(RUNPYTEST) $(srcdir)/t_cve-2013-1417.py $(PYTESTFLAGS)
f4b6e2
+	$(RUNPYTEST) $(srcdir)/t_cve-2021-36222.py $(PYTESTFLAGS)
f4b6e2
 	$(RM) au.log
f4b6e2
 	$(RUNPYTEST) $(srcdir)/t_audit.py $(PYTESTFLAGS)
f4b6e2
 	$(RUNPYTEST) $(srcdir)/jsonwalker.py -d $(srcdir)/au_dict.json \
f4b6e2
diff --git a/src/tests/t_cve-2021-36222.py b/src/tests/t_cve-2021-36222.py
f4b6e2
new file mode 100644
f4b6e2
index 000000000..57e04993b
f4b6e2
--- /dev/null
f4b6e2
+++ b/src/tests/t_cve-2021-36222.py
f4b6e2
@@ -0,0 +1,46 @@
f4b6e2
+import socket
f4b6e2
+from k5test import *
f4b6e2
+
f4b6e2
+realm = K5Realm()
f4b6e2
+
f4b6e2
+# CVE-2021-36222 KDC null dereference on encrypted challenge preauth
f4b6e2
+# without FAST
f4b6e2
+
f4b6e2
+s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
f4b6e2
+a = (hostname, realm.portbase)
f4b6e2
+
f4b6e2
+m = ('6A81A0' '30819D'          # [APPLICATION 10] SEQUENCE
f4b6e2
+     'A103' '0201' '05'         #  [1] pvno = 5
f4b6e2
+     'A203' '0201' '0A'         #  [2] msg-type = 10
f4b6e2
+     'A30E' '300C'              #  [3] padata = SEQUENCE OF
f4b6e2
+     '300A'                     #   SEQUENCE
f4b6e2
+     'A104' '0202' '008A'       #    [1] padata-type = PA-ENCRYPTED-CHALLENGE
f4b6e2
+     'A202' '0400'              #    [2] padata-value = ""
f4b6e2
+     'A48180' '307E'            #  [4] req-body = SEQUENCE
f4b6e2
+     'A007' '0305' '0000000000' #   [0] kdc-options = 0
f4b6e2
+     'A120' '301E'              #   [1] cname = SEQUENCE
f4b6e2
+     'A003' '0201' '01'         #    [0] name-type = NT-PRINCIPAL
f4b6e2
+     'A117' '3015'              #    [1] name-string = SEQUENCE-OF
f4b6e2
+     '1B06' '6B7262746774'      #     krbtgt
f4b6e2
+     '1B0B' '4B5242544553542E434F4D'
f4b6e2
+                                #     KRBTEST.COM
f4b6e2
+     'A20D' '1B0B' '4B5242544553542E434F4D'
f4b6e2
+                                #   [2] realm = KRBTEST.COM
f4b6e2
+     'A320' '301E'              #   [3] sname = SEQUENCE
f4b6e2
+     'A003' '0201' '01'         #    [0] name-type = NT-PRINCIPAL
f4b6e2
+     'A117' '3015'              #    [1] name-string = SEQUENCE-OF
f4b6e2
+     '1B06' '6B7262746774'      #     krbtgt
f4b6e2
+     '1B0B' '4B5242544553542E434F4D'
f4b6e2
+                                #     KRBTEST.COM
f4b6e2
+     'A511' '180F' '31393934303631303036303331375A'
f4b6e2
+                                #   [5] till = 19940610060317Z
f4b6e2
+     'A703' '0201' '00'         #   [7] nonce = 0
f4b6e2
+     'A808' '3006'              #   [8] etype = SEQUENCE OF
f4b6e2
+     '020112' '020111')         #    aes256-cts aes128-cts
f4b6e2
+
f4b6e2
+s.sendto(bytes.fromhex(m), a)
f4b6e2
+
f4b6e2
+# Make sure kinit still works.
f4b6e2
+realm.kinit(realm.user_princ, password('user'))
f4b6e2
+
f4b6e2
+success('CVE-2021-36222 regression test')