-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA512 Release date: Monday Jul 25, 2016 CVE-2016-5391 IKEv2 bogus proposal lacking DH transform causes restart URL: http://www.cve.mitre.org/cgi-bin/cvename.cgi?name=2016-5391 This alert (and any possible updates) is available at the following URLs: https://libreswan.org/security/CVE-2016-5391/ The Libreswan Project has found a vulnerability in processing IKEv2 proposals that miss a Diffie-Hellman transform for the IKE SA. A NULL pointer dererefence causes the pluto IKE daemon to crash and restart. No remote code execution is possible. Vulnerable versions: libreswan 3.17 Not vulnerable : all other versions of libreswan If you cannot upgrade to 3.18, please see the above link for a patch for this issue. Vulnerability information ========================= The IKE SA negotiation requires a Diffie-Hellman group to be agreed upon. This payload is mandatory for all IKE SA proposals during the IKE_INIT Exchange Type. It is only optional for the CREATE_CHILD_SA Exchange Type, where PFS is optional. Libreswan version 3.17 does not properly reject a proposal in IKE_INIT Exchange that lacks a Diffie-Hellman group. It dereferences a NULL pointer causing a crash and restart. Exploitation ============ A denial of service can be launched by anyone repeatedly sending such IKE packets. No authentication credentials are required. No remote code execution is possible through this vulnerability. Libreswan automatically restarts when it crashes. Workaround ========== There is no workaround. Either upgrade or use the supplied patch in the above listed resource URL. Credits ======= This vulnerability was found by the Libreswan Project when performing interop tests with strongswan version 5.4.0 which can transmit these bogus proposals. It has been assigned strongSwan issue #2051 About libreswan (https://libreswan.org/) ======================================== Libreswan is a free implementation of the Internet Protocol Security (IPsec) suite and Internet Key Exchange (IKE) protocols. It is a descendant (fork) of openswan 2.6.38. IPsec uses strong cryptography to provide both authentication and encryption services. These services allow you to build secure tunnels through untrusted networks. Everything passing through the untrusted network is encrypted by the IPsec gateway machine, and decrypted by the gateway at the other end of the tunnel. The resulting tunnel is a virtual private network (VPN). Patch ====================================================================== diff --git a/programs/pluto/ikev2_spdb_struct.c b/programs/pluto/ikev2_spdb_struct.c index 753c26e..f46b5a5 100644 - ---- a/programs/pluto/ikev2_spdb_struct.c +++ b/programs/pluto/ikev2_spdb_struct.c @@ -769,17 +769,44 @@ static int process_transforms(pb_stream *prop_pbs, struct print *remote_print_bu DBG(DBG_CONTROL, DBG_log("allowing no NULL integrity")); continue; } - -- int type_proposed = ((transform_types_found & LELEM(type)) != 0); - -- int type_matched = matching_local_proposal->matching_transform[type]->valid; - -- if (type_proposed != type_matched) { - -- DBG(DBG_CONTROLMORE, DBG_log("local proposal %d type %s failed: %s and %s", + bool local_transform_type_present = local_transforms->transform[0].valid; + bool remote_transform_type_present = ((transform_types_found & LELEM(type)) != 0); + /* + * Check that the local and remote end are + * consistent about the transform being + * present. + * + * Transform matching is not optional. + * Instead, for something like ESP/AH, DH is + * made "optional" by sending two proposals. + * One with the transform (DH) present and one + * with it absent. + */ + if (local_transform_type_present != remote_transform_type_present) { + DBG(DBG_CONTROLMORE, DBG_log("local proposal %d transform type %s failed: local %s and remote %s", + local_propnum, trans_type_name(type), + local_transform_type_present ? "present" : "absent", + remote_transform_type_present ? "present" : "absent")); + break; + } + /* + * Check that when the transform type is + * required it also matches and vice versa. + * + * Since !local_transform_type_present implies + * !remote_transform_type_matched, the above + * test is also required. + */ + bool remote_transform_type_matched = matching_local_proposal->matching_transform[type]->valid; + if (local_transform_type_present != remote_transform_type_matched) { + DBG(DBG_CONTROLMORE, DBG_log("local proposal %d transform type %s failed: local %s and remote %s", local_propnum, trans_type_name(type), - -- type_proposed ? "proposed" : "not-proposed", - -- type_matched ? "matched" : "not-matched")); + local_transform_type_present ? "present" : "absent", + remote_transform_type_matched ? "matched" : "different")); break; } } - -- /* loop finished? */ + /* loop finished cleanly? */ if (type == IKEv2_TRANS_TYPE_ROOF) { DBG(DBG_CONTROL, DBG_log("remote proposal %u matches local proposal %d", -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAEBCgAGBQJXldS9AAoJEIX/S0OzD8b5MhEP/RWjJVFG46sSDjUgWyIDvdog y6qzeeMNl1hwJo8xgtkZ4jYIsw10hx4ooVzL55rTN4bqXsU/JE2c8PVeIJ64wFiM fmmdJyvViMqQatW1C8sQkb41MtZdmbcYBPfnhHa5OIZ9HKhKxLdVN5ySkQXTLrjL 0lugEm/kDRue/f9gyrCdXcg/FpZLnvbT7XO87CAxf1pNRcjuTBBjZ6KaUtztcBNr 8fMFP6RgSxOwKskbDmD5F5T2jIUj32EEITElgr3VVk5bFwKeyCTYRBsOMeRxpmbp G8fLDIu+swETuNT244CYewopTtkR15FbIOT77KeYK+v6T2h+OOnR3D47IefRh9Py HPhGqXfY9pDZgo4ch6wui3Ek+eswfqCg4BooG0e2KvaEhFtXqfrt/Eh9FnzLochI CYvdIlopKb5oX12dsl9gcapXGzGE6RcaVnBoa4T0GPGuifOK2y+OFx7kK1ZDAPWu Gk8hOcZMV4mB38Pu8NLjyEC9b+bIvvf8ovFMG9fehi7/hfoiioHz/mlmvaXfJV8y iKSQ8qejrvuldqNNM8h/PweIcWVipxSiOtcSmVNBwD8HqofqrSOI+IWMkmlYsn79 /TerTd0l4JL81tThSGyO7JBjpHZNdpsYzzDvrmgmPpP7/n8KwYo9VveRFPZt6p4o imX4qV3DazRDoHOzjkqW =d5yb -----END PGP SIGNATURE-----