1From fc98f520caefff2e5ee9a0026fdf5109944b3562 Mon Sep 17 00:00:00 2001 2From: Joseph Sutton <josephsutton@catalyst.net.nz> 3Date: Wed, 7 Jul 2021 11:47:44 +1200 4Subject: [PATCH] Fix KDC null deref on bad encrypted challenge 5 6The function ec_verify() in src/kdc/kdc_preauth_ec.c contains a check 7to avoid further processing if the armor key is NULL. However, this 8check is bypassed by a call to k5memdup0() which overwrites retval 9with 0 if the allocation succeeds. If the armor key is NULL, a call 10to krb5_c_fx_cf2_simple() will then dereference it, resulting in a 11crash. Add a check before the k5memdup0() call to avoid overwriting 12retval. 13 14CVE-2021-36222: 15 16In MIT krb5 releases 1.16 and later, an unauthenticated attacker can 17cause a null dereference in the KDC by sending a request containing a 18PA-ENCRYPTED-CHALLENGE padata element without using FAST. 19 20[ghudson@mit.edu: trimmed patch; added test case; edited commit 21message] 22 23ticket: 9007 (new) 24tags: pullup 25target_version: 1.19-next 26target_version: 1.18-next 27 28CVE: CVE-2021-36222 29 30Upstream-Status: Backport 31[https://github.com/krb5/krb5/commit/fc98f520caefff2e5ee9a0026fdf5109944b3562] 32 33Signed-off-by: Yi Zhao <yi.zhao@windriver.com> 34--- 35 src/kdc/kdc_preauth_ec.c | 3 ++- 36 src/tests/Makefile.in | 1 + 37 src/tests/t_cve-2021-36222.py | 46 +++++++++++++++++++++++++++++++++++ 38 3 files changed, 49 insertions(+), 1 deletion(-) 39 create mode 100644 src/tests/t_cve-2021-36222.py 40 41diff --git a/src/kdc/kdc_preauth_ec.c b/src/kdc/kdc_preauth_ec.c 42index 7e636b3f9..43a9902cc 100644 43--- a/src/kdc/kdc_preauth_ec.c 44+++ b/src/kdc/kdc_preauth_ec.c 45@@ -87,7 +87,8 @@ ec_verify(krb5_context context, krb5_data *req_pkt, krb5_kdc_req *request, 46 } 47 48 /* Check for a configured FAST ec auth indicator. */ 49- realmstr = k5memdup0(realm.data, realm.length, &retval); 50+ if (retval == 0) 51+ realmstr = k5memdup0(realm.data, realm.length, &retval); 52 if (realmstr != NULL) 53 retval = profile_get_string(context->profile, KRB5_CONF_REALMS, 54 realmstr, 55diff --git a/src/tests/Makefile.in b/src/tests/Makefile.in 56index fc6fcc0c3..1a1938306 100644 57--- a/src/tests/Makefile.in 58+++ b/src/tests/Makefile.in 59@@ -166,6 +166,7 @@ check-pytests: unlockiter s4u2self 60 $(RUNPYTEST) $(srcdir)/t_cve-2012-1015.py $(PYTESTFLAGS) 61 $(RUNPYTEST) $(srcdir)/t_cve-2013-1416.py $(PYTESTFLAGS) 62 $(RUNPYTEST) $(srcdir)/t_cve-2013-1417.py $(PYTESTFLAGS) 63+ $(RUNPYTEST) $(srcdir)/t_cve-2021-36222.py $(PYTESTFLAGS) 64 $(RM) au.log 65 $(RUNPYTEST) $(srcdir)/t_audit.py $(PYTESTFLAGS) 66 $(RUNPYTEST) $(srcdir)/jsonwalker.py -d $(srcdir)/au_dict.json \ 67diff --git a/src/tests/t_cve-2021-36222.py b/src/tests/t_cve-2021-36222.py 68new file mode 100644 69index 000000000..57e04993b 70--- /dev/null 71+++ b/src/tests/t_cve-2021-36222.py 72@@ -0,0 +1,46 @@ 73+import socket 74+from k5test import * 75+ 76+realm = K5Realm() 77+ 78+# CVE-2021-36222 KDC null dereference on encrypted challenge preauth 79+# without FAST 80+ 81+s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 82+a = (hostname, realm.portbase) 83+ 84+m = ('6A81A0' '30819D' # [APPLICATION 10] SEQUENCE 85+ 'A103' '0201' '05' # [1] pvno = 5 86+ 'A203' '0201' '0A' # [2] msg-type = 10 87+ 'A30E' '300C' # [3] padata = SEQUENCE OF 88+ '300A' # SEQUENCE 89+ 'A104' '0202' '008A' # [1] padata-type = PA-ENCRYPTED-CHALLENGE 90+ 'A202' '0400' # [2] padata-value = "" 91+ 'A48180' '307E' # [4] req-body = SEQUENCE 92+ 'A007' '0305' '0000000000' # [0] kdc-options = 0 93+ 'A120' '301E' # [1] cname = SEQUENCE 94+ 'A003' '0201' '01' # [0] name-type = NT-PRINCIPAL 95+ 'A117' '3015' # [1] name-string = SEQUENCE-OF 96+ '1B06' '6B7262746774' # krbtgt 97+ '1B0B' '4B5242544553542E434F4D' 98+ # KRBTEST.COM 99+ 'A20D' '1B0B' '4B5242544553542E434F4D' 100+ # [2] realm = KRBTEST.COM 101+ 'A320' '301E' # [3] sname = SEQUENCE 102+ 'A003' '0201' '01' # [0] name-type = NT-PRINCIPAL 103+ 'A117' '3015' # [1] name-string = SEQUENCE-OF 104+ '1B06' '6B7262746774' # krbtgt 105+ '1B0B' '4B5242544553542E434F4D' 106+ # KRBTEST.COM 107+ 'A511' '180F' '31393934303631303036303331375A' 108+ # [5] till = 19940610060317Z 109+ 'A703' '0201' '00' # [7] nonce = 0 110+ 'A808' '3006' # [8] etype = SEQUENCE OF 111+ '020112' '020111') # aes256-cts aes128-cts 112+ 113+s.sendto(bytes.fromhex(m), a) 114+ 115+# Make sure kinit still works. 116+realm.kinit(realm.user_princ, password('user')) 117+ 118+success('CVE-2021-36222 regression test') 119-- 1202.25.1 121 122