From 6b21167d9647f31bcc5fb67a8e6ecec197d4c86d Mon Sep 17 00:00:00 2001 From: Luke Valenta Date: Wed, 8 Nov 2017 10:07:54 -0500 Subject: [PATCH] update documentation, fix whitespace errors, add certificate extraction to ssl-verbose script --- scripts/policy/protocols/ssl/ssl-verbose.bro | 204 ++++++++++-------- src/analyzer/protocol/ssl/events.bif | 33 ++- .../protocol/ssl/tls-handshake-analyzer.pac | 26 +-- 3 files changed, 158 insertions(+), 105 deletions(-) diff --git a/scripts/policy/protocols/ssl/ssl-verbose.bro b/scripts/policy/protocols/ssl/ssl-verbose.bro index 4de466327c..42370339d0 100644 --- a/scripts/policy/protocols/ssl/ssl-verbose.bro +++ b/scripts/policy/protocols/ssl/ssl-verbose.bro @@ -3,101 +3,133 @@ ##! and certificates hashes. @load base/protocols/ssl +@load base/files/x509 +@load base/utils/directions-and-hosts module SSL; export { - redef record Info += { - # ClientHello - client_random: string &log &optional; - client_cipher_suites: string &optional; + redef record Info += { + # ClientHello + client_random: string &log &optional; + client_cipher_suites: string &log &optional; - # ServerHello - server_random: string &log &optional; + # ServerHello + server_random: string &log &optional; - # ServerKeyExchange - server_dh_p: string &log &optional; - server_dh_q: string &log &optional; - server_dh_Ys: string &log &optional; - server_ecdh_point: string &log &optional; - server_signature: string &log &optional; + # ServerKeyExchange + server_dh_p: string &log &optional; + server_dh_q: string &log &optional; + server_dh_Ys: string &log &optional; + server_ecdh_point: string &log &optional; + server_signature: string &log &optional; - # ServerCertificate - server_cert_sha1: string &log &optional; + # ServerCertificate + server_cert_sha1: string &log &optional; - # ClientKeyExchange - client_rsa_pms: string &log &optional; - client_dh_Yc: string &log &optional; - client_ecdh_point: string &log &optional; - }; + # ClientKeyExchange + client_rsa_pms: string &log &optional; + client_dh_Yc: string &log &optional; + client_ecdh_point: string &log &optional; + }; + + ## Control if host certificates offered by the defined hosts + ## will be written to the PEM certificates file. + ## Choices are: LOCAL_HOSTS, REMOTE_HOSTS, ALL_HOSTS, NO_HOSTS. + const extract_certs_pem = ALL_HOSTS &redef; } - -event ssl_client_hello(c: connection, version: count, possible_ts: time, client_random: string, session_id: string, ciphers: index_vec) &priority=5 - { - set_session(c); - c$ssl$client_random = bytestring_to_hexstr(client_random); - - local ciphers_str = ""; - for (i in ciphers) - { - ciphers_str += cipher_desc[ciphers[i]]; - if ( i != |ciphers|-1) - { - ciphers_str += ","; - } - } - c$ssl$client_cipher_suites = ciphers_str; - } - -event ssl_server_hello(c: connection, version: count, possible_ts: time, server_random: string, session_id: string, cipher: count, comp_method: count) &priority=5 - { - set_session(c); - c$ssl$server_random = bytestring_to_hexstr(server_random); - } - -event ssl_dh_server_params(c: connection, p: string, q: string, Ys: string) &priority=5 - { - set_session(c); - c$ssl$server_dh_p = bytestring_to_hexstr(p); - c$ssl$server_dh_q = bytestring_to_hexstr(q); - c$ssl$server_dh_Ys = bytestring_to_hexstr(Ys); - } - -event ssl_ecdh_server_params(c: connection, curve: count, point: string) &priority=5 - { - set_session(c); - c$ssl$server_ecdh_point = bytestring_to_hexstr(point); - } - -event ssl_server_signature(c: connection, signed_params: string) &priority=5 - { - set_session(c); - c$ssl$server_signature = bytestring_to_hexstr(signed_params); - } - -event ssl_rsa_client_pms(c: connection, pms: string) &priority=5 - { - set_session(c); - c$ssl$client_rsa_pms = bytestring_to_hexstr(pms); - } - -event ssl_dh_client_params(c: connection, Yc: string) &priority=5 - { - set_session(c); - c$ssl$client_dh_Yc = bytestring_to_hexstr(Yc); - } - -event ssl_ecdh_client_params(c: connection, point: string) &priority=5 - { - set_session(c); - c$ssl$client_ecdh_point = bytestring_to_hexstr(point); - } +# This is an internally maintained variable to prevent relogging of +# certificates that have already been seen. It is indexed on an sha1 sum of +# the certificate. +global extracted_certs: set[string] = set() &read_expire=1hr &redef; event ssl_established(c: connection) &priority=5 - { - if ( ! c$ssl?$cert_chain || |c$ssl$cert_chain| == 0 || - ! c$ssl$cert_chain[0]?$x509 ) - return; - c$ssl$server_cert_sha1 = c$ssl$cert_chain[0]$sha1; - } + { + if ( ! c$ssl?$cert_chain || |c$ssl$cert_chain| == 0 || + ! c$ssl$cert_chain[0]?$x509 ) + return; + + if ( ! addr_matches_host(c$id$resp_h, extract_certs_pem) ) + return; + + local hash = c$ssl$cert_chain[0]$sha1; + local cert = c$ssl$cert_chain[0]$x509$handle; + + c$ssl$server_cert_sha1 = hash; + + if ( hash in extracted_certs ) + # If we already extracted this cert, don't do it again. + return; + + add extracted_certs[hash]; + local filename = Site::is_local_addr(c$id$resp_h) ? "certs-local.pem" : "certs-remote.pem"; + local outfile = open_for_append(filename); + enable_raw_output(outfile); + + print outfile, x509_get_certificate_string(cert, T); + + close(outfile); + } + +event ssl_client_hello(c: connection, version: count, possible_ts: time, client_random: string, session_id: string, ciphers: index_vec) &priority=5 + { + set_session(c); + c$ssl$client_random = bytestring_to_hexstr(client_random); + + local ciphers_str = ""; + for (i in ciphers) + { + ciphers_str += cipher_desc[ciphers[i]]; + if ( i != |ciphers|-1) + { + ciphers_str += ","; + } + } + c$ssl$client_cipher_suites = ciphers_str; + } + +event ssl_server_hello(c: connection, version: count, possible_ts: time, server_random: string, session_id: string, cipher: count, comp_method: count) &priority=5 + { + set_session(c); + c$ssl$server_random = bytestring_to_hexstr(server_random); + } + +event ssl_dh_server_params(c: connection, p: string, q: string, Ys: string) &priority=5 + { + set_session(c); + c$ssl$server_dh_p = bytestring_to_hexstr(p); + c$ssl$server_dh_q = bytestring_to_hexstr(q); + c$ssl$server_dh_Ys = bytestring_to_hexstr(Ys); + } + +event ssl_ecdh_server_params(c: connection, curve: count, point: string) &priority=5 + { + set_session(c); + c$ssl$server_ecdh_point = bytestring_to_hexstr(point); + } + +event ssl_server_signature(c: connection, signed_params: string) &priority=5 + { + set_session(c); + c$ssl$server_signature = bytestring_to_hexstr(signed_params); + } + +event ssl_rsa_client_pms(c: connection, pms: string) &priority=5 + { + set_session(c); + c$ssl$client_rsa_pms = bytestring_to_hexstr(pms); + } + +event ssl_dh_client_params(c: connection, Yc: string) &priority=5 + { + set_session(c); + c$ssl$client_dh_Yc = bytestring_to_hexstr(Yc); + } + +event ssl_ecdh_client_params(c: connection, point: string) &priority=5 + { + set_session(c); + c$ssl$client_ecdh_point = bytestring_to_hexstr(point); + } + diff --git a/src/analyzer/protocol/ssl/events.bif b/src/analyzer/protocol/ssl/events.bif index feba12abb4..cad453844a 100644 --- a/src/analyzer/protocol/ssl/events.bif +++ b/src/analyzer/protocol/ssl/events.bif @@ -27,6 +27,8 @@ ## .. bro:see:: ssl_alert ssl_established ssl_extension ssl_server_hello ## ssl_session_ticket_handshake x509_certificate ssl_handshake_message ## ssl_change_cipher_spec +## ssl_dh_client_params ssl_ecdh_server_params ssl_ecdh_client_params +## ssl_rsa_client_pms event ssl_client_hello%(c: connection, version: count, possible_ts: time, client_random: string, session_id: string, ciphers: index_vec%); ## Generated for an SSL/TLS server's initial *hello* message. SSL/TLS sessions @@ -64,6 +66,8 @@ event ssl_client_hello%(c: connection, version: count, possible_ts: time, client ## .. bro:see:: ssl_alert ssl_client_hello ssl_established ssl_extension ## ssl_session_ticket_handshake x509_certificate ssl_server_curve ## ssl_dh_server_params ssl_handshake_message ssl_change_cipher_spec +## ssl_dh_client_params ssl_ecdh_server_params ssl_ecdh_client_params +## ssl_rsa_client_pms event ssl_server_hello%(c: connection, version: count, possible_ts: time, server_random: string, session_id: string, cipher: count, comp_method: count%); ## Generated for SSL/TLS extensions seen in an initial handshake. SSL/TLS @@ -106,6 +110,8 @@ event ssl_extension%(c: connection, is_orig: bool, code: count, val: string%); ## ssl_extension_server_name ssl_server_curve ssl_extension_signature_algorithm ## ssl_extension_key_share ## ssl_extension_psk_key_exchange_modes ssl_extension_supported_versions +## ssl_dh_client_params ssl_ecdh_server_params ssl_ecdh_client_params +## ssl_rsa_client_pms ssl_server_signature event ssl_extension_elliptic_curves%(c: connection, is_orig: bool, curves: index_vec%); ## Generated for an SSL/TLS Supported Point Formats extension. This TLS extension @@ -125,6 +131,8 @@ event ssl_extension_elliptic_curves%(c: connection, is_orig: bool, curves: index ## ssl_extension_server_name ssl_server_curve ssl_extension_signature_algorithm ## ssl_extension_key_share ## ssl_extension_psk_key_exchange_modes ssl_extension_supported_versions +## ssl_dh_client_params ssl_ecdh_server_params ssl_ecdh_client_params +## ssl_rsa_client_pms ssl_server_signature event ssl_extension_ec_point_formats%(c: connection, is_orig: bool, point_formats: index_vec%); ## Generated for an Signature Algorithms extension. This TLS extension @@ -143,6 +151,8 @@ event ssl_extension_ec_point_formats%(c: connection, is_orig: bool, point_format ## ssl_extension_elliptic_curves ssl_extension_application_layer_protocol_negotiation ## ssl_extension_server_name ssl_server_curve ssl_extension_key_share ## ssl_extension_psk_key_exchange_modes ssl_extension_supported_versions +## ssl_dh_client_params ssl_ecdh_server_params ssl_ecdh_client_params +## ssl_rsa_client_pms ssl_server_signature event ssl_extension_signature_algorithm%(c: connection, is_orig: bool, signature_algorithms: signature_and_hashalgorithm_vec%); ## Generated for a Key Share extension. This TLS extension is defined in TLS1.3-draft16 @@ -160,6 +170,8 @@ event ssl_extension_signature_algorithm%(c: connection, is_orig: bool, signature ## ssl_extension_elliptic_curves ssl_extension_application_layer_protocol_negotiation ## ssl_extension_server_name ssl_server_curve ## ssl_extension_psk_key_exchange_modes ssl_extension_supported_versions +## ssl_dh_client_params ssl_ecdh_server_params ssl_ecdh_client_params +## ssl_rsa_client_pms ssl_server_signature event ssl_extension_key_share%(c: connection, is_orig: bool, curves: index_vec%); ## Generated if a named curve is chosen by the server for an SSL/TLS connection. @@ -175,6 +187,8 @@ event ssl_extension_key_share%(c: connection, is_orig: bool, curves: index_vec%) ## ssl_extension_elliptic_curves ssl_extension_application_layer_protocol_negotiation ## ssl_extension_server_name ssl_extension_key_share ## ssl_extension_psk_key_exchange_modes ssl_extension_supported_versions +## ssl_dh_client_params ssl_ecdh_server_params ssl_ecdh_client_params +## ssl_rsa_client_pms ssl_server_signature event ssl_server_curve%(c: connection, curve: count%); ## Generated if a server uses an ECDH-anon or ECDHE cipher suite. This event @@ -188,7 +202,8 @@ event ssl_server_curve%(c: connection, curve: count%); ## point: The server's ECDH public key. ## ## .. bro:see:: ssl_alert ssl_client_hello ssl_established ssl_server_hello -## ssl_session_ticket_handshake ssl_server_curve ssl_dh_client_params +## ssl_session_ticket_handshake ssl_server_curve ssl_server_signature +## ssl_dh_client_params ssl_ecdh_client_params ssl_rsa_client_pms event ssl_ecdh_server_params%(c: connection, curve: count, point: string%); ## Generated if a server uses a DH-anon or DHE cipher suite. This event contains @@ -204,7 +219,9 @@ event ssl_ecdh_server_params%(c: connection, curve: count, point: string%); ## Ys: The server's DH public key. ## ## .. bro:see:: ssl_alert ssl_client_hello ssl_established ssl_server_hello -## ssl_session_ticket_handshake ssl_server_curve ssl_dh_client_params +## ssl_session_ticket_handshake ssl_server_curve ssl_server_signature +## ssl_dh_client_params ssl_ecdh_server_params ssl_ecdh_client_params +## ssl_rsa_client_pms event ssl_dh_server_params%(c: connection, p: string, q: string, Ys: string%); ## Generated if a server uses a non-anonymous DHE or ECDHE cipher suite. This event @@ -218,7 +235,8 @@ event ssl_dh_server_params%(c: connection, p: string, q: string, Ys: string%); ## public key in the server's Certificate message is used for signing. ## ## .. bro:see:: ssl_alert ssl_client_hello ssl_established ssl_server_hello -## ssl_session_ticket_handshake ssl_server_curve ssl_dh_client_params +## ssl_session_ticket_handshake ssl_server_curve ssl_rsa_client_pms +## ssl_dh_client_params ssl_ecdh_server_params ssl_ecdh_client_params event ssl_server_signature%(c: connection, signed_params: string%); ## Generated if a client uses an ECDH-anon or ECDHE cipher suite. This event @@ -230,7 +248,8 @@ event ssl_server_signature%(c: connection, signed_params: string%); ## point: The client's ECDH public key. ## ## .. bro:see:: ssl_alert ssl_client_hello ssl_established ssl_server_hello -## ssl_session_ticket_handshake ssl_server_curve ssl_dh_client_params +## ssl_session_ticket_handshake ssl_server_curve ssl_server_signature +## ssl_dh_client_params ssl_ecdh_server_params ssl_rsa_client_pms event ssl_ecdh_client_params%(c: connection, point: string%); ## Generated if a client uses a DH-anon or DHE cipher suite. This event contains @@ -242,7 +261,8 @@ event ssl_ecdh_client_params%(c: connection, point: string%); ## Yc: The client's DH public key. ## ## .. bro:see:: ssl_alert ssl_client_hello ssl_established ssl_server_hello -## ssl_session_ticket_handshake ssl_server_curve ssl_dh_server_params +## ssl_session_ticket_handshake ssl_server_curve ssl_server_signature +## ssl_ecdh_server_params ssl_ecdh_client_params ssl_rsa_client_pms event ssl_dh_client_params%(c: connection, Yc: string%); ## Generate if a client uses an RSA key exchange. This event contains the client @@ -254,7 +274,8 @@ event ssl_dh_client_params%(c: connection, Yc: string%); ## pms: The encrypted pre-master secret. ## ## .. bro:see:: ssl_alert ssl_client_hello ssl_established ssl_server_hello -## ssl_session_ticket_handshake ssl_server_curve ssl_dh_server_params +## ssl_session_ticket_handshake ssl_server_curve ssl_server_signature +## ssl_dh_client_params ssl_ecdh_server_params ssl_ecdh_client_params event ssl_rsa_client_pms%(c: connection, pms: string%); ## Generated for an SSL/TLS Application-Layer Protocol Negotiation extension. diff --git a/src/analyzer/protocol/ssl/tls-handshake-analyzer.pac b/src/analyzer/protocol/ssl/tls-handshake-analyzer.pac index 40f546a9f6..6555ccedc2 100644 --- a/src/analyzer/protocol/ssl/tls-handshake-analyzer.pac +++ b/src/analyzer/protocol/ssl/tls-handshake-analyzer.pac @@ -272,26 +272,26 @@ refine connection Handshake_Conn += { return true; %} - function proc_ecdhe_server_key_exchange(rec: HandshakeRecord, curve_type: uint8, curve: uint16, point: bytestring, signed_params: bytestring) : bool + function proc_ecdhe_server_key_exchange(rec: HandshakeRecord, curve_type: uint8, curve: uint16, point: bytestring, signed_params: bytestring) : bool %{ if ( curve_type == NAMED_CURVE ) BifEvent::generate_ssl_server_curve(bro_analyzer(), bro_analyzer()->Conn(), curve); - BifEvent::generate_ssl_ecdh_server_params(bro_analyzer(), - bro_analyzer()->Conn(), curve, new StringVal(point.length(), (const char*)point.data())); - BifEvent::generate_ssl_server_signature(bro_analyzer(), - bro_analyzer()->Conn(), new StringVal(signed_params.length(), (const char*)signed_params.data())); + BifEvent::generate_ssl_ecdh_server_params(bro_analyzer(), + bro_analyzer()->Conn(), curve, new StringVal(point.length(), (const char*)point.data())); + BifEvent::generate_ssl_server_signature(bro_analyzer(), + bro_analyzer()->Conn(), new StringVal(signed_params.length(), (const char*)signed_params.data())); return true; %} - function proc_ecdh_anon_server_key_exchange(rec: HandshakeRecord, curve_type: uint8, curve: uint16, point: bytestring) : bool + function proc_ecdh_anon_server_key_exchange(rec: HandshakeRecord, curve_type: uint8, curve: uint16, point: bytestring) : bool %{ if ( curve_type == NAMED_CURVE ) BifEvent::generate_ssl_server_curve(bro_analyzer(), bro_analyzer()->Conn(), curve); - BifEvent::generate_ssl_ecdh_server_params(bro_analyzer(), - bro_analyzer()->Conn(), curve, new StringVal(point.length(), (const char*)point.data())); + BifEvent::generate_ssl_ecdh_server_params(bro_analyzer(), + bro_analyzer()->Conn(), curve, new StringVal(point.length(), (const char*)point.data())); return true; %} @@ -313,7 +313,7 @@ refine connection Handshake_Conn += { BifEvent::generate_ssl_ecdh_client_params(bro_analyzer(), bro_analyzer()->Conn(), new StringVal(point.length(), (const char*)point.data())); return true; %} - + function proc_signedcertificatetimestamp(rec: HandshakeRecord, version: uint8, logid: const_bytestring, timestamp: uint64, digitally_signed_algorithms: SignatureAndHashAlgorithm, digitally_signed_signature: const_bytestring) : bool %{ RecordVal* ha = new RecordVal(BifType::Record::SSL::SignatureAndHashAlgorithm); @@ -340,10 +340,10 @@ refine connection Handshake_Conn += { new StringVal(g.length(), (const char*) g.data()), new StringVal(Ys.length(), (const char*) Ys.data()) ); - BifEvent::generate_ssl_server_signature(bro_analyzer(), - bro_analyzer()->Conn(), - new StringVal(signed_params.length(), (const char*) signed_params.data()) - ); + BifEvent::generate_ssl_server_signature(bro_analyzer(), + bro_analyzer()->Conn(), + new StringVal(signed_params.length(), (const char*) signed_params.data()) + ); return true; %}