Bug#929665: unblock: heimdal/7.5.0+dfsg-3
Package: release.debian.org
Severity: normal
User: release.debian.org@packages.debian.org
Usertags: unblock
Please unblock package heimdal
* Security fixes for CVE-2018-16860 and CVE-2019-12098.
* FTBFS bug fix.
Note I excluded the changes to the certificates from the following patch,
because a diff of these is meaningless (even more so for the binary
files). The updated certificates required to fix the FTBFS.
diff -Nru --exclude '002*' heimdal-7.5.0+dfsg/debian/changelog heimdal-7.5.0+dfsg/debian/changelog
--- heimdal-7.5.0+dfsg/debian/changelog 2018-06-02 10:01:46.000000000 +1000
+++ heimdal-7.5.0+dfsg/debian/changelog 2019-05-21 18:04:35.000000000 +1000
@@ -1,3 +1,20 @@
+heimdal (7.5.0+dfsg-3) unstable; urgency=high
+
+ * CVE-2018-16860: Samba AD DC S4U2Self/S4U2Proxy unkeyed checksum.
+ Closes: #928966.
+ * CVE-2019-12098: Always confirm PA-PKINIT-KX for anon PKINIT.
+ Closes: #929064.
+ * Update test certificates to pre 2038 expiry. Closes: #923930.
+
+ -- Brian May <bam@debian.org> Tue, 21 May 2019 18:04:35 +1000
+
+heimdal (7.5.0+dfsg-2.1) unstable; urgency=medium
+
+ * Non-maintainer upload
+ * Add patch to create headers before building (Closes: 906623)
+
+ -- Hilko Bengen <bengen@debian.org> Sun, 28 Oct 2018 15:10:44 +0100
+
heimdal (7.5.0+dfsg-2) unstable; urgency=medium
* Replace "MAXHOSTNAMELEN" with "MaxHostNameLen" in kdc/kx509.c for The
diff -Nru --exclude '002*' heimdal-7.5.0+dfsg/debian/patches/0017-CVE-2018-16860-Heimdal-KDC-Reject-PA-S4U2Self-with-u.patch heimdal-7.5.0+dfsg/debian/patches/0017-CVE-2018-16860-Heimdal-KDC-Reject-PA-S4U2Self-with-u.patch
--- heimdal-7.5.0+dfsg/debian/patches/0017-CVE-2018-16860-Heimdal-KDC-Reject-PA-S4U2Self-with-u.patch 1970-01-01 10:00:00.000000000 +1000
+++ heimdal-7.5.0+dfsg/debian/patches/0017-CVE-2018-16860-Heimdal-KDC-Reject-PA-S4U2Self-with-u.patch 2019-05-21 18:04:35.000000000 +1000
@@ -0,0 +1,145 @@
+From: Isaac Boukris <iboukris@gmail.com>
+Date: Tue, 14 May 2019 09:03:18 -0400
+Subject: CVE-2018-16860 Heimdal KDC: Reject PA-S4U2Self with unkeyed checksum
+
+S4U2Self is an extension to Kerberos used in Active Directory to allow
+a service to request a kerberos ticket to itself from the Kerberos Key
+Distribution Center (KDC) for a non-Kerberos authenticated user
+(principal in Kerboros parlance). This is useful to allow internal
+code paths to be standardized around Kerberos.
+
+S4U2Proxy (constrained-delegation) is an extension of this mechanism
+allowing this impersonation to a second service over the network. It
+allows a privileged server that obtained a S4U2Self ticket to itself
+to then assert the identity of that principal to a second service and
+present itself as that principal to get services from the second
+service.
+
+There is a flaw in Samba's AD DC in the Heimdal KDC. When the Heimdal
+KDC checks the checksum that is placed on the S4U2Self packet by the
+server to protect the requested principal against modification, it
+does not confirm that the checksum algorithm that protects the user
+name (principal) in the request is keyed. This allows a
+man-in-the-middle attacker who can intercept the request to the KDC to
+modify the packet by replacing the user name (principal) in the
+request with any desired user name (principal) that exists in the KDC
+and replace the checksum protecting that name with a CRC32 checksum
+(which requires no prior knowledge to compute).
+
+This would allow a S4U2Self ticket requested on behalf of user name
+(principal) user@EXAMPLE.COM to any service to be changed to a
+S4U2Self ticket with a user name (principal) of
+Administrator@EXAMPLE.COM. This ticket would then contain the PAC of
+the modified user name (principal).
+
+==================
+CVSSv3 calculation
+==================
+
+CVSS:3.0/AV:N/AC:H/PR:L/UI:N/S:U/C:H/I:H/A:H (7.5)
+
+=========================
+Workaround and Mitigation
+=========================
+
+If server does not take privileged actions based on Kerberos tickets
+obtained by S4U2Self nor obtains Kerberos tickets via further
+S4U2Proxy requests then this issue cannot be exploited.
+
+Note that the path to an exploit is not generic, the KDC is not harmed
+by the malicious checksum, it is the client service requesting the
+ticket being mislead, because it trusted the KDC to return the correct
+ticket and PAC.
+
+It is out of scope for Samba to describe all of the possible tool
+chains that might be vulnerable. Here are two examples of possible
+exploits in order to explain the issue more clearly.
+
+1). SFU2Self might be used by a web service authenticating an end user
+via OAuth, Shibboleth, or other protocols to obtain a S4U2Self
+Kerberos service ticket for use by any Kerberos service principal the
+web service has a keytab for. One example is acquiring an AFS token
+by requesting an afs/cell@REALM service ticket for a client via
+SFU2Self. With this exploit an organization that deploys a KDC built
+from Heimdal (be it Heimdal directly or vendor versions such as found
+in Samba) is vulnerable to privilege escalation attacks.
+
+2). If a server authenticates users using X509 certificates, and then
+uses S4U2Self to obtain a Kerberos service ticket on behalf of the
+user (principal) in order to authorize access to local resources, a
+man-in-the-middle attacker could allow a non-privileged user to access
+privileged resources being protected by the server, or privileged
+resources being protected by a second server, if the first server uses
+the S4U2Proxy extension in order to get a new Kerberos service ticket
+to obtain access to the second server.
+
+In both these scenarios under conditions allowing man-in-the-middle
+active network protocol manipulation, a malicious user could
+authenticate using the non-Kerborized credentials of an unprivileged
+user, and then elevate its privileges by intercepting the packet from
+the server to the KDC and changing the requested user name (principal).
+
+The only Samba clients that use S4U2Self are:
+
+- the "net ads kerberos pac dump" (debugging) tool.
+
+- the CIFS proxy in the deprecated/developer-only NTVFS file
+server. Note this code is not compiled or enabled by default.
+
+In particular, winbindd does *not* use S4U2Self.
+
+Finally, MIT Kerberos and so therefore the experimental MIT KDC backend
+for Samba AD is understood not to be impacted.
+
+===============
+Further Reading
+===============
+
+There is more detail on and a description of the protocols in
+
+[MS-SFU]: Kerberos Protocol Extensions: Service for User and Constrained
+Delegation Protocol
+https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-sfu/
+
+=======
+Credits
+=======
+
+Originally reported by Isaac Boukris and Andrew Bartlett of the Samba
+Team and Catalyst.
+
+Patches provided by Isaac Boukris.
+
+Advisory written by Andrew Bartlett of the Samba Team and Catalyst,
+with contributions from Isaac Boukris, Jeffrey Altman and Jeremy
+Allison.
+
+BUG: https://bugzilla.samba.org/show_bug.cgi?id=13685
+Change-Id: I4ac69ebf0503eb999a7d497a2c30fe4d293a8cc8
+Signed-off-by: Isaac Boukris <iboukris@gmail.com>
+Reviewed-by: Andrew Bartlett <abartlet@samba.org>
+Signed-off-by: Andrew Bartlett <abartlet@samba.org>
+Reviewed-by: Jeffrey Altman <jaltman@auristor.com>
+Signed-off-by: Jeffrey Altman <jaltman@auristor.com>
+---
+ kdc/krb5tgs.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/kdc/krb5tgs.c b/kdc/krb5tgs.c
+index b6ccb68..992da62 100644
+--- a/kdc/krb5tgs.c
++++ b/kdc/krb5tgs.c
+@@ -1988,6 +1988,13 @@ server_lookup:
+ goto out;
+ }
+
++ if (!krb5_checksum_is_keyed(context, self.cksum.cksumtype)) {
++ free_PA_S4U2Self(&self);
++ kdc_log(context, config, 0, "Reject PA-S4U2Self with unkeyed checksum");
++ ret = KRB5KRB_AP_ERR_INAPP_CKSUM;
++ goto out;
++ }
++
+ ret = _krb5_s4u2self_to_checksumdata(context, &self, &datack);
+ if (ret)
+ goto out;
diff -Nru --exclude '002*' heimdal-7.5.0+dfsg/debian/patches/0018-CVE-2019-12098-krb5-always-confirm-PA-PKINIT-KX-for-.patch heimdal-7.5.0+dfsg/debian/patches/0018-CVE-2019-12098-krb5-always-confirm-PA-PKINIT-KX-for-.patch
--- heimdal-7.5.0+dfsg/debian/patches/0018-CVE-2019-12098-krb5-always-confirm-PA-PKINIT-KX-for-.patch 1970-01-01 10:00:00.000000000 +1000
+++ heimdal-7.5.0+dfsg/debian/patches/0018-CVE-2019-12098-krb5-always-confirm-PA-PKINIT-KX-for-.patch 2019-05-21 18:04:35.000000000 +1000
@@ -0,0 +1,169 @@
+From: Luke Howard <lukeh@padl.com>
+Date: Tue, 7 May 2019 13:15:15 +1000
+Subject: CVE-2019-12098: krb5: always confirm PA-PKINIT-KX for anon PKINIT
+
+RFC8062 Section 7 requires verification of the PA-PKINIT-KX key excahnge
+when anonymous PKINIT is used. Failure to do so can permit an active
+attacker to become a man-in-the-middle.
+
+Introduced by a1ef548600c5bb51cf52a9a9ea12676506ede19f. First tagged
+release Heimdal 1.4.0.
+
+CVSS:3.0/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:L/A:N (4.8)
+
+Change-Id: I6cc1c0c24985936468af08693839ac6c3edda133
+Signed-off-by: Jeffrey Altman <jaltman@auristor.com>
+Approved-by: Jeffrey Altman <jaltman@auritor.com>
+(cherry picked from commit 38c797e1ae9b9c8f99ae4aa2e73957679031fd2b)
+---
+ lib/krb5/init_creds_pw.c | 20 +++++++++++
+ lib/krb5/krb5_locl.h | 1 +
+ lib/krb5/pkinit.c | 92 ++++++++++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 113 insertions(+)
+
+diff --git a/lib/krb5/init_creds_pw.c b/lib/krb5/init_creds_pw.c
+index 1eece17..9ec07d0 100644
+--- a/lib/krb5/init_creds_pw.c
++++ b/lib/krb5/init_creds_pw.c
+@@ -2267,6 +2267,26 @@ krb5_init_creds_step(krb5_context context,
+ &ctx->req_buffer,
+ NULL,
+ NULL);
++ if (ret == 0 && ctx->pk_init_ctx) {
++ PA_DATA *pa_pkinit_kx;
++ int idx = 0;
++
++ pa_pkinit_kx =
++ krb5_find_padata(rep.kdc_rep.padata->val,
++ rep.kdc_rep.padata->len,
++ KRB5_PADATA_PKINIT_KX,
++ &idx);
++
++ ret = _krb5_pk_kx_confirm(context, ctx->pk_init_ctx,
++ ctx->fast_state.reply_key,
++ &ctx->cred.session,
++ pa_pkinit_kx);
++ if (ret)
++ krb5_set_error_message(context, ret,
++ N_("Failed to confirm PA-PKINIT-KX", ""));
++ else if (pa_pkinit_kx != NULL)
++ ctx->ic_flags |= KRB5_INIT_CREDS_PKINIT_KX_VALID;
++ }
+ if (ret == 0)
+ ret = copy_EncKDCRepPart(&rep.enc_part, &ctx->enc_part);
+
+diff --git a/lib/krb5/krb5_locl.h b/lib/krb5/krb5_locl.h
+index 4d524ce..f16fbc0 100644
+--- a/lib/krb5/krb5_locl.h
++++ b/lib/krb5/krb5_locl.h
+@@ -208,6 +208,7 @@ struct _krb5_get_init_creds_opt_private {
+ #define KRB5_INIT_CREDS_CANONICALIZE 1
+ #define KRB5_INIT_CREDS_NO_C_CANON_CHECK 2
+ #define KRB5_INIT_CREDS_NO_C_NO_EKU_CHECK 4
++#define KRB5_INIT_CREDS_PKINIT_KX_VALID 32
+ struct {
+ krb5_gic_process_last_req func;
+ void *ctx;
+diff --git a/lib/krb5/pkinit.c b/lib/krb5/pkinit.c
+index 0adb65e..69b11ec 100644
+--- a/lib/krb5/pkinit.c
++++ b/lib/krb5/pkinit.c
+@@ -1220,6 +1220,98 @@ pk_rd_pa_reply_enckey(krb5_context context,
+ return ret;
+ }
+
++/*
++ * RFC 8062 section 7:
++ *
++ * The client then decrypts the KDC contribution key and verifies that
++ * the ticket session key in the returned ticket is the combined key of
++ * the KDC contribution key and the reply key.
++ */
++KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
++_krb5_pk_kx_confirm(krb5_context context,
++ krb5_pk_init_ctx ctx,
++ krb5_keyblock *reply_key,
++ krb5_keyblock *session_key,
++ PA_DATA *pa_pkinit_kx)
++{
++ krb5_error_code ret;
++ EncryptedData ed;
++ krb5_keyblock ck, sk_verify;
++ krb5_crypto ck_crypto = NULL;
++ krb5_crypto rk_crypto = NULL;
++ size_t len;
++ krb5_data data;
++ krb5_data p1 = { sizeof("PKINIT") - 1, "PKINIT" };
++ krb5_data p2 = { sizeof("KEYEXCHANGE") - 1, "KEYEXCHANGE" };
++
++ heim_assert(ctx != NULL, "PKINIT context is non-NULL");
++ heim_assert(reply_key != NULL, "reply key is non-NULL");
++ heim_assert(session_key != NULL, "session key is non-NULL");
++
++ /* PA-PKINIT-KX is optional unless anonymous */
++ if (pa_pkinit_kx == NULL)
++ return ctx->anonymous ? KRB5_KDCREP_MODIFIED : 0;
++
++ memset(&ed, 0, sizeof(ed));
++ krb5_keyblock_zero(&ck);
++ krb5_keyblock_zero(&sk_verify);
++ krb5_data_zero(&data);
++
++ ret = decode_EncryptedData(pa_pkinit_kx->padata_value.data,
++ pa_pkinit_kx->padata_value.length,
++ &ed, &len);
++ if (ret)
++ goto out;
++
++ if (len != pa_pkinit_kx->padata_value.length) {
++ ret = KRB5_KDCREP_MODIFIED;
++ goto out;
++ }
++
++ ret = krb5_crypto_init(context, reply_key, 0, &rk_crypto);
++ if (ret)
++ goto out;
++
++ ret = krb5_decrypt_EncryptedData(context, rk_crypto,
++ KRB5_KU_PA_PKINIT_KX,
++ &ed, &data);
++ if (ret)
++ goto out;
++
++ ret = decode_EncryptionKey(data.data, data.length,
++ &ck, &len);
++ if (ret)
++ goto out;
++
++ ret = krb5_crypto_init(context, &ck, 0, &ck_crypto);
++ if (ret)
++ goto out;
++
++ ret = krb5_crypto_fx_cf2(context, ck_crypto, rk_crypto,
++ &p1, &p2, session_key->keytype,
++ &sk_verify);
++ if (ret)
++ goto out;
++
++ if (sk_verify.keytype != session_key->keytype ||
++ krb5_data_ct_cmp(&sk_verify.keyvalue, &session_key->keyvalue) != 0) {
++ ret = KRB5_KDCREP_MODIFIED;
++ goto out;
++ }
++
++out:
++ free_EncryptedData(&ed);
++ krb5_free_keyblock_contents(context, &ck);
++ krb5_free_keyblock_contents(context, &sk_verify);
++ if (ck_crypto)
++ krb5_crypto_destroy(context, ck_crypto);
++ if (rk_crypto)
++ krb5_crypto_destroy(context, rk_crypto);
++ krb5_data_free(&data);
++
++ return ret;
++}
++
+ static krb5_error_code
+ pk_rd_pa_reply_dh(krb5_context context,
+ const heim_octet_string *indata,
diff -Nru --exclude '002*' heimdal-7.5.0+dfsg/debian/patches/fix-missing-headers heimdal-7.5.0+dfsg/debian/patches/fix-missing-headers
--- heimdal-7.5.0+dfsg/debian/patches/fix-missing-headers 1970-01-01 10:00:00.000000000 +1000
+++ heimdal-7.5.0+dfsg/debian/patches/fix-missing-headers 2019-05-21 18:04:35.000000000 +1000
@@ -0,0 +1,31 @@
+Index: heimdal/lib/hcrypto/Makefile.am
+===================================================================
+--- heimdal.orig/lib/hcrypto/Makefile.am
++++ heimdal/lib/hcrypto/Makefile.am
+@@ -104,6 +104,11 @@ TESTS = $(PROGRAM_TESTS) $(SCRIPT_TESTS)
+ LDADD = $(lib_LTLIBRARIES) $(LIB_roken) $(LIB_openssl_crypto)
+ test_rand_LDADD = $(LDADD) -lm
+
++ALL_OBJECTS = $(libhcrypto_la_OBJECTS)
++ALL_OBJECTS += $(test_rand_OBJECTS)
++ALL_OBJECTS += $(libhctest_la_OBJECTS)
++$(ALL_OBJECTS): | install-build-headers
++
+ libhcrypto_la_SOURCES = \
+ $(ltmsources) \
+ aes.c \
+Index: heimdal/lib/hx509/Makefile.am
+===================================================================
+--- heimdal.orig/lib/hx509/Makefile.am
++++ heimdal/lib/hx509/Makefile.am
+@@ -147,8 +147,8 @@ HX509_PROTOS = $(srcdir)/hx509-protos.h
+
+ $(ALL_OBJECTS): $(HX509_PROTOS)
+
+-$(libhx509_la_OBJECTS): $(srcdir)/hx_locl.h
+-$(libhx509_la_OBJECTS): ocsp_asn1.h pkcs10_asn1.h
++$(ALL_OBJECTS): $(srcdir)/hx_locl.h
++$(ALL_OBJECTS): ocsp_asn1.h pkcs10_asn1.h
+
+ $(srcdir)/hx509-protos.h: $(dist_libhx509_la_SOURCES)
+ $(heim_verbose)cd $(srcdir) && perl ../../cf/make-proto.pl -R '^(_|^C)' -E HX509_LIB -q -P comment -o hx509-protos.h $(dist_libhx509_la_SOURCES) || rm -f hx509-protos.h
diff -Nru --exclude '002*' heimdal-7.5.0+dfsg/debian/patches/series heimdal-7.5.0+dfsg/debian/patches/series
--- heimdal-7.5.0+dfsg/debian/patches/series 2018-06-02 10:01:46.000000000 +1000
+++ heimdal-7.5.0+dfsg/debian/patches/series 2019-05-21 18:04:35.000000000 +1000
@@ -14,3 +14,8 @@
disable_iprop
canonical_host
0016-Add-back-in-base64_encode-and-base64_decode.patch
+fix-missing-headers
+0017-CVE-2018-16860-Heimdal-KDC-Reject-PA-S4U2Self-with-u.patch
+0018-CVE-2019-12098-krb5-always-confirm-PA-PKINIT-KX-for-.patch
+0020-Fixes-https-github.com-heimdal-heimdal-issues-533.patch
+0021-Regenerate-certs-so-that-they-expire-before-the-2038.patch
unblock heimdal/7.5.0+dfsg-3
-- System Information:
Debian Release: 10.0
APT prefers testing
APT policy: (500, 'testing')
Architecture: amd64 (x86_64)
Kernel: Linux 4.19.0-5-amd64 (SMP w/8 CPU cores)
Kernel taint flags: TAINT_PROPRIETARY_MODULE, TAINT_WARN, TAINT_OOT_MODULE, TAINT_UNSIGNED_MODULE
Locale: LANG=en_AU.UTF-8, LC_CTYPE=en_AU.UTF-8 (charmap=UTF-8), LANGUAGE=en_AU.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash
Init: systemd (via /run/systemd/system)
LSM: AppArmor: enabled
Reply to: