From 897351f87ed6aafd0a931377f08b18bbf2a5d78a Mon Sep 17 00:00:00 2001 From: Johanna Amann Date: Wed, 25 Feb 2015 13:57:04 -0800 Subject: [PATCH] Extend the weak-keys policy file to also alert when encountering ssl connections with old versions as well as unsafe cipher suites. Also make the notice suppression handling of other ssl policy files a tad more robust. --- .../policy/protocols/ssl/validate-certs.bro | 9 +-- .../policy/protocols/ssl/validate-ocsp.bro | 3 +- scripts/policy/protocols/ssl/weak-keys.bro | 58 ++++++++++++++++--- .../notice-out.log | 33 +++++++++++ .../notice.log | 12 ---- .../policy/protocols/ssl/weak-keys.bro | 7 ++- 6 files changed, 95 insertions(+), 27 deletions(-) create mode 100644 testing/btest/Baseline/scripts.policy.protocols.ssl.weak-keys/notice-out.log delete mode 100644 testing/btest/Baseline/scripts.policy.protocols.ssl.weak-keys/notice.log diff --git a/scripts/policy/protocols/ssl/validate-certs.bro b/scripts/policy/protocols/ssl/validate-certs.bro index 414f0d2a54..19b0b70806 100644 --- a/scripts/policy/protocols/ssl/validate-certs.bro +++ b/scripts/policy/protocols/ssl/validate-certs.bro @@ -12,16 +12,16 @@ export { ## invalid. Invalid_Server_Cert }; - + redef record Info += { ## Result of certificate validation for this connection. validation_status: string &log &optional; }; - + ## MD5 hash values for recently validated chains along with the ## validation status message are kept in this table to avoid constant ## validation every time the same certificate chain is seen. - global recently_validated_certs: table[string] of string = table() + global recently_validated_certs: table[string] of string = table() &read_expire=5mins &synchronized &redef; } @@ -33,6 +33,7 @@ event ssl_established(c: connection) &priority=3 return; local chain_id = join_string_vec(c$ssl$cert_chain_fuids, "."); + local hash = c$ssl$cert_chain[0]$sha1; local chain: vector of opaque of x509 = vector(); for ( i in c$ssl$cert_chain ) @@ -57,7 +58,7 @@ event ssl_established(c: connection) &priority=3 local message = fmt("SSL certificate validation failed with (%s)", c$ssl$validation_status); NOTICE([$note=Invalid_Server_Cert, $msg=message, $sub=c$ssl$subject, $conn=c, - $identifier=cat(c$id$resp_h,c$id$resp_p,c$ssl$validation_status)]); + $identifier=cat(c$id$resp_h,c$id$resp_p,hash,c$ssl$validation_status)]); } } diff --git a/scripts/policy/protocols/ssl/validate-ocsp.bro b/scripts/policy/protocols/ssl/validate-ocsp.bro index 01b6853226..3beabbe59c 100644 --- a/scripts/policy/protocols/ssl/validate-ocsp.bro +++ b/scripts/policy/protocols/ssl/validate-ocsp.bro @@ -34,9 +34,10 @@ event ssl_stapled_ocsp(c: connection, is_orig: bool, response: string) &priority event ssl_established(c: connection) &priority=3 { - if ( ! c$ssl?$cert_chain || |c$ssl$cert_chain| == 0 || !c$ssl?$ocsp_response ) + if ( ! c$ssl?$cert_chain || |c$ssl$cert_chain| == 0 || ! c$ssl$cert_chain[0]?$x509 || !c$ssl?$ocsp_response ) return; + local hash = c$ssl$cert_chain[0]$sha1; local chain: vector of opaque of x509 = vector(); for ( i in c$ssl$cert_chain ) { diff --git a/scripts/policy/protocols/ssl/weak-keys.bro b/scripts/policy/protocols/ssl/weak-keys.bro index 82cc3a2b5f..3f1b1fff62 100644 --- a/scripts/policy/protocols/ssl/weak-keys.bro +++ b/scripts/policy/protocols/ssl/weak-keys.bro @@ -1,5 +1,5 @@ -##! Generate notices when SSL/TLS connections use certificates or DH parameters -##! that have potentially unsafe key lengths. +##! Generate notices when SSL/TLS connections use certificates, DH parameters +##! or cipher suites that are deemed to be insecure. @load base/protocols/ssl @load base/frameworks/notice @@ -11,17 +11,20 @@ export { redef enum Notice::Type += { ## Indicates that a server is using a potentially unsafe key. Weak_Key, + ## Indicates that a server is using a potentially unsafe version + Old_Version, + ## Indicates that a server is using a potentially unsafe cipher + Weak_Cipher }; - ## The category of hosts you would like to be notified about which have - ## certificates that are going to be expiring soon. By default, these - ## notices will be suppressed by the notice framework for 1 day after a particular - ## certificate has had a notice generated. Choices are: LOCAL_HOSTS, REMOTE_HOSTS, - ## ALL_HOSTS, NO_HOSTS + ## The category of hosts you would like to be notified about which are using weak + ## keys/ciphers/protocol_versions. By default, these notices will be suppressed + ## by the notice framework for 1 day after a particular host has had a notice + ## generated. Choices are: LOCAL_HOSTS, REMOTE_HOSTS, ALL_HOSTS, NO_HOSTS const notify_weak_keys = LOCAL_HOSTS &redef; ## The minimal key length in bits that is considered to be safe. Any shorter - ## (non-EC) key lengths will trigger the notice. + ## (non-EC) key lengths will trigger a notice. const notify_minimal_key_length = 2048 &redef; ## Warn if the DH key length is smaller than the certificate key length. This is @@ -29,6 +32,17 @@ export { ## certificate key length. However, it is very common and cannot be avoided in some ## settings (e.g. with old jave clients). const notify_dh_length_shorter_cert_length = T &redef; + + ## Warn if a server negotiates a SSL session with a protocol version smaller than + ## the specified version. By default, the minimal version is TLSv10 because SSLv2 + ## and v3 have serious security issued. + ## See https://tools.ietf.org/html/draft-thomson-sslv3-diediedie-00 + ## To disable, set to SSLv20 + const tls_minimum_version = TLSv10 &redef; + + ## Warn if a server negotiates an unsafe cipher suite. By default, we only warn when + ## encountering old export cipher suites, or RC4 (see RFC7465). + const unsafe_ciphers_regex = /(_EXPORT_)|(_RC4_)/ &redef; } # We check key lengths only for DSA or RSA certificates. For others, we do @@ -43,6 +57,7 @@ event ssl_established(c: connection) &priority=3 local fuid = c$ssl$cert_chain_fuids[0]; local cert = c$ssl$cert_chain[0]$x509$certificate; + local hash = c$ssl$cert_chain[0]$sha1; if ( !cert?$key_type || !cert?$key_length ) return; @@ -56,7 +71,32 @@ event ssl_established(c: connection) &priority=3 NOTICE([$note=Weak_Key, $msg=fmt("Host uses weak certificate with %d bit key", key_length), $conn=c, $suppress_for=1day, - $identifier=cat(c$id$resp_h, c$id$resp_h, key_length) + $identifier=cat(c$id$resp_h, c$id$resp_h, hash, key_length) + ]); + } + +# Check for old SSL versions and weak connection keys +event ssl_server_hello(c: connection, version: count, possible_ts: time, server_random: string, session_id: string, cipher: count, comp_method: count) &priority=3 + { + if ( ! addr_matches_host(c$id$resp_h, notify_weak_keys) ) + return; + + if ( version < tls_minimum_version ) + { + local minimum_string = version_strings[tls_minimum_version]; + local host_string = version_strings[version]; + NOTICE([$note=Old_Version, + $msg=fmt("Host uses protocol version %s which is lower than the safe minimum %s", host_string, minimum_string), + $conn=c, $suppress_for=1day, + $identifier=cat(c$id$resp_h, c$id$resp_h) + ]); + } + + if ( unsafe_ciphers_regex in c$ssl$cipher ) + NOTICE([$note=Weak_Cipher, + $msg=fmt("Host established connection using unsafe ciper suite %s", c$ssl$cipher), + $conn=c, $suppress_for=1day, + $identifier=cat(c$id$resp_h, c$id$resp_h, c$ssl$cipher) ]); } diff --git a/testing/btest/Baseline/scripts.policy.protocols.ssl.weak-keys/notice-out.log b/testing/btest/Baseline/scripts.policy.protocols.ssl.weak-keys/notice-out.log new file mode 100644 index 0000000000..f39d2d2adb --- /dev/null +++ b/testing/btest/Baseline/scripts.policy.protocols.ssl.weak-keys/notice-out.log @@ -0,0 +1,33 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path notice +#open 2015-02-25-21-37-10 +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p fuid file_mime_type file_desc proto note msg sub src dst p n peer_descr actions suppress_for dropped remote_location.country_code remote_location.region remote_location.city remote_location.latitude remote_location.longitude +#types time string addr port addr port string string string enum enum string string addr addr port count string set[enum] interval bool string string string double double +1398558136.430417 CXWv6p3arKYeMETxOg 192.168.18.50 62277 162.219.2.166 443 - - - tcp SSL::Weak_Key Host uses weak DH parameters with 1024 key bits - 192.168.18.50 162.219.2.166 443 - bro Notice::ACTION_LOG 86400.000000 F - - - - - +1398558136.430417 CXWv6p3arKYeMETxOg 192.168.18.50 62277 162.219.2.166 443 - - - tcp SSL::Weak_Key DH key length of 1024 bits is smaller certificate key length of 2048 bits - 192.168.18.50 162.219.2.166 443 - bro Notice::ACTION_LOG 86400.000000 F - - - - - +1398558136.542637 CXWv6p3arKYeMETxOg 192.168.18.50 62277 162.219.2.166 443 - - - tcp SSL::Weak_Key Host uses weak certificate with 2048 bit key - 192.168.18.50 162.219.2.166 443 - bro Notice::ACTION_LOG 86400.000000 F - - - - - +#close 2015-02-25-21-37-10 +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path notice +#open 2015-02-25-21-37-10 +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p fuid file_mime_type file_desc proto note msg sub src dst p n peer_descr actions suppress_for dropped remote_location.country_code remote_location.region remote_location.city remote_location.latitude remote_location.longitude +#types time string addr port addr port string string string enum enum string string addr addr port count string set[enum] interval bool string string string double double +1397165496.713940 CXWv6p3arKYeMETxOg 192.168.4.149 59062 91.227.4.92 443 - - - tcp SSL::Old_Version Host uses protocol version SSLv2 which is lower than the safe minimum TLSv10 - 192.168.4.149 91.227.4.92 443 - bro Notice::ACTION_LOG 86400.000000 F - - - - - +#close 2015-02-25-21-37-11 +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path notice +#open 2015-02-25-21-37-11 +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p fuid file_mime_type file_desc proto note msg sub src dst p n peer_descr actions suppress_for dropped remote_location.country_code remote_location.region remote_location.city remote_location.latitude remote_location.longitude +#types time string addr port addr port string string string enum enum string string addr addr port count string set[enum] interval bool string string string double double +1170717505.734145 CXWv6p3arKYeMETxOg 192.150.187.164 58868 194.127.84.106 443 - - - tcp SSL::Weak_Cipher Host established connection using unsafe ciper suite TLS_RSA_WITH_RC4_128_MD5 - 192.150.187.164 194.127.84.106 443 - bro Notice::ACTION_LOG 86400.000000 F - - - - - +1170717505.934612 CXWv6p3arKYeMETxOg 192.150.187.164 58868 194.127.84.106 443 - - - tcp SSL::Weak_Key Host uses weak certificate with 1024 bit key - 192.150.187.164 194.127.84.106 443 - bro Notice::ACTION_LOG 86400.000000 F - - - - - +#close 2015-02-25-21-37-11 diff --git a/testing/btest/Baseline/scripts.policy.protocols.ssl.weak-keys/notice.log b/testing/btest/Baseline/scripts.policy.protocols.ssl.weak-keys/notice.log deleted file mode 100644 index b44fb54b70..0000000000 --- a/testing/btest/Baseline/scripts.policy.protocols.ssl.weak-keys/notice.log +++ /dev/null @@ -1,12 +0,0 @@ -#separator \x09 -#set_separator , -#empty_field (empty) -#unset_field - -#path notice -#open 2014-04-27-07-15-32 -#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p fuid file_mime_type file_desc proto note msg sub src dst p n peer_descr actions suppress_for dropped remote_location.country_code remote_location.region remote_location.city remote_location.latitude remote_location.longitude -#types time string addr port addr port string string string enum enum string string addr addr port count string set[enum] interval bool string string string double double -1398558136.430417 CXWv6p3arKYeMETxOg 192.168.18.50 62277 162.219.2.166 443 - - - tcp SSL::Weak_Key Host uses weak DH parameters with 1024 key bits - 192.168.18.50 162.219.2.166 443 - bro Notice::ACTION_LOG 86400.000000 F - - - - - -1398558136.430417 CXWv6p3arKYeMETxOg 192.168.18.50 62277 162.219.2.166 443 - - - tcp SSL::Weak_Key DH key length of 1024 bits is smaller certificate key length of 2048 bits - 192.168.18.50 162.219.2.166 443 - bro Notice::ACTION_LOG 86400.000000 F - - - - - -1398558136.542637 CXWv6p3arKYeMETxOg 192.168.18.50 62277 162.219.2.166 443 - - - tcp SSL::Weak_Key Host uses weak certificate with 2048 bit key - 192.168.18.50 162.219.2.166 443 - bro Notice::ACTION_LOG 86400.000000 F - - - - - -#close 2014-04-27-07-15-32 diff --git a/testing/btest/scripts/policy/protocols/ssl/weak-keys.bro b/testing/btest/scripts/policy/protocols/ssl/weak-keys.bro index 42ef2ecc16..f4d51f8016 100644 --- a/testing/btest/scripts/policy/protocols/ssl/weak-keys.bro +++ b/testing/btest/scripts/policy/protocols/ssl/weak-keys.bro @@ -1,5 +1,10 @@ # @TEST-EXEC: bro -r $TRACES/tls/dhe.pcap %INPUT -# @TEST-EXEC: btest-diff notice.log +# @TEST-EXEC: cp notice.log notice-out.log +# @TEST-EXEC: bro -r $TRACES/tls/ssl-v2.trace %INPUT +# @TEST-EXEC: cat notice.log >> notice-out.log +# @TEST-EXEC: bro -r $TRACES/tls/ssl.v3.trace %INPUT +# @TEST-EXEC: cat notice.log >> notice-out.log +# @TEST-EXEC: btest-diff notice-out.log @load protocols/ssl/weak-keys