From 67c0cc118d08813d80e177d9dc7f18b2817cc3c4 Mon Sep 17 00:00:00 2001 From: Bernhard Amann Date: Fri, 6 Jun 2014 12:50:54 -0700 Subject: [PATCH] Add two more ssl events - one triggered for each handshake message and one triggered for the tls change cipherspec message. Also - fix small bug. In case SSL::disable_analyzer_after_detection was set to F, the ssl_established event would fire after each data packet after the session is established. --- scripts/base/protocols/ssl/consts.bro | 15 +++++++ src/analyzer/protocol/ssl/events.bif | 36 +++++++++++++-- src/analyzer/protocol/ssl/ssl-analyzer.pac | 36 ++++++++++++++- .../.stdout | 45 +++++++++++++++++++ .../base/protocols/ssl/handshake-events.test | 28 ++++++++++++ 5 files changed, 155 insertions(+), 5 deletions(-) create mode 100644 testing/btest/Baseline/scripts.base.protocols.ssl.handshake-events/.stdout create mode 100644 testing/btest/scripts/base/protocols/ssl/handshake-events.test diff --git a/scripts/base/protocols/ssl/consts.bro b/scripts/base/protocols/ssl/consts.bro index 969527ed69..a19aaecbe5 100644 --- a/scripts/base/protocols/ssl/consts.bro +++ b/scripts/base/protocols/ssl/consts.bro @@ -26,6 +26,21 @@ export { const V2_CLIENT_MASTER_KEY = 302; const V2_SERVER_HELLO = 304; + ## TLS Handshake types: + const HELLO_REQUEST = 0; + const CLIENT_HELLO = 1; + const SERVER_HELLO = 2; + const SESSION_TICKET = 4; # RFC 5077 + const CERTIFICATE = 11; + const SERVER_KEY_EXCHANGE = 12; + const CERTIFICATE_REQUEST = 13; + const SERVER_HELLO_DONE = 14; + const CERTIFICATE_VERIFY = 15; + const CLIENT_KEY_EXCHANGE = 16; + const FINISHED = 20; + const CERTIFICATE_URL = 21; # RFC 3546 + const CERTIFICATE_STATUS = 22; # RFC 3546 + ## Mapping between numeric codes and human readable strings for alert ## levels. const alert_levels: table[count] of string = { diff --git a/src/analyzer/protocol/ssl/events.bif b/src/analyzer/protocol/ssl/events.bif index 593ab0fe85..4af0fe2a3f 100644 --- a/src/analyzer/protocol/ssl/events.bif +++ b/src/analyzer/protocol/ssl/events.bif @@ -24,8 +24,9 @@ ## standardized as part of the SSL/TLS protocol. The ## :bro:id:`SSL::cipher_desc` table maps them to descriptive names. ## -## .. bro:see:: ssl_alert ssl_established ssl_extension ssl_server_hello -## ssl_session_ticket_handshake x509_certificate +## .. bro:see:: ssl_alert ssl_established ssl_extension ssl_server_hello +## ssl_session_ticket_handshake x509_certificate ssl_handshake_message +## ssl_change_cipher_spec 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 @@ -59,7 +60,7 @@ 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_dh_server_params ssl_handshake_message ssl_change_cipher_spec 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 @@ -270,7 +271,7 @@ event ssl_heartbeat%(c: connection, is_orig: bool, length: count, heartbeat_type ## started. ## ## Note that :bro:id:`SSL::disable_analyzer_after_detection` has to be changed -## from its default to false for this event to be generated. +## from its default to false for this event to be generated. ## ## c: The connection. ## @@ -294,3 +295,30 @@ event ssl_encrypted_data%(c: connection, is_orig: bool, content_type: count, len ## ## response: OCSP data. event ssl_stapled_ocsp%(c: connection, is_orig: bool, response: string%); + +## This event is raised for each unencrypted SSL/TLS handshake message +## +## c: The connection. +## +## is_orig: True if event is raised for originator side of the connection. +## +## msg_type: type of the handshake message that was seen +## +## length: length of the handshake message that was seen +## +## .. bro:see:: ssl_alert ssl_established ssl_extension ssl_server_hello +## ssl_session_ticket_handshake x509_certificate ssl_client_hello +## ssl_change_cipher_spec +event ssl_handshake_message%(c: connection, is_orig: bool, msg_type: count, length: count%); + +## This event is raised when a SSL/TLS ChangeCipherSpec message is encountered +## before encryption begins. Traffic will be encrypted following this message. +## +## c: The connection. +## +## is_orig: True if event is raised for originator side of the connection. +## +## .. bro:see:: ssl_alert ssl_established ssl_extension ssl_server_hello +## ssl_session_ticket_handshake x509_certificate ssl_client_hello +## ssl_handshake_message +event ssl_change_cipher_spec%(c: connection, is_orig: bool%); diff --git a/src/analyzer/protocol/ssl/ssl-analyzer.pac b/src/analyzer/protocol/ssl/ssl-analyzer.pac index 2c242eb4cb..64d5d78df6 100644 --- a/src/analyzer/protocol/ssl/ssl-analyzer.pac +++ b/src/analyzer/protocol/ssl/ssl-analyzer.pac @@ -86,6 +86,14 @@ function version_ok(vers : uint16) : bool refine connection SSL_Conn += { + %member{ + int established_; + %} + + %init{ + established_ = false; + %} + %cleanup{ %} @@ -359,8 +367,10 @@ refine connection SSL_Conn += { function proc_ciphertext_record(rec : SSLRecord) : bool %{ if ( client_state_ == STATE_ENCRYPTED && - server_state_ == STATE_ENCRYPTED ) + server_state_ == STATE_ENCRYPTED && + established_ == false ) { + established_ = true; BifEvent::generate_ssl_established(bro_analyzer(), bro_analyzer()->Conn()); } @@ -421,6 +431,22 @@ refine connection SSL_Conn += { return true; %} + function proc_ccs(rec: SSLRecord) : bool + %{ + BifEvent::generate_ssl_change_cipher_spec(bro_analyzer(), + bro_analyzer()->Conn(), ${rec.is_orig}); + + return true; + %} + + function proc_handshake(rec: SSLRecord, msg_type: uint8, length: uint24) : bool + %{ + BifEvent::generate_ssl_handshake_message(bro_analyzer(), + bro_analyzer()->Conn(), ${rec.is_orig}, msg_type, to_int()(length)); + + return true; + %} + }; refine typeattr Alert += &let { @@ -517,3 +543,11 @@ refine typeattr EcServerKeyExchange += &let { refine typeattr DhServerKeyExchange += &let { proc : bool = $context.connection.proc_dh_server_key_exchange(rec, dh_p, dh_g, dh_Ys); }; + +refine typeattr ChangeCipherSpec += &let { + proc : bool = $context.connection.proc_ccs(rec); +}; + +refine typeattr Handshake += &let { + proc : bool = $context.connection.proc_handshake(rec, msg_type, length); +}; diff --git a/testing/btest/Baseline/scripts.base.protocols.ssl.handshake-events/.stdout b/testing/btest/Baseline/scripts.base.protocols.ssl.handshake-events/.stdout new file mode 100644 index 0000000000..c7e3a43cbe --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.ssl.handshake-events/.stdout @@ -0,0 +1,45 @@ +Handshake, 192.168.1.105, 74.125.224.79, T, 1, 169 +Handshake, 192.168.1.105, 74.125.224.79, F, 2, 81 +Handshake, 192.168.1.105, 74.125.224.79, F, 11, 1620 +Handshake, 192.168.1.105, 74.125.224.79, F, 12, 199 +Handshake, 192.168.1.105, 74.125.224.79, F, 14, 0 +Handshake, 192.168.1.105, 74.125.224.79, T, 16, 66 +CCS, 192.168.1.105, 74.125.224.79, T +Encrypted data, 192.168.1.105, 74.125.224.79, T, 22, 72 +Encrypted data, 192.168.1.105, 74.125.224.79, T, 23, 48 +Encrypted data, 192.168.1.105, 74.125.224.79, T, 23, 387 +Handshake, 192.168.1.105, 74.125.224.79, F, 4, 170 +CCS, 192.168.1.105, 74.125.224.79, F +Established, 192.168.1.105, 74.125.224.79 +Encrypted data, 192.168.1.105, 74.125.224.79, F, 22, 36 +Encrypted data, 192.168.1.105, 74.125.224.79, F, 23, 40 +Encrypted data, 192.168.1.105, 74.125.224.79, F, 23, 248 +Encrypted data, 192.168.1.105, 74.125.224.79, F, 23, 28 +Encrypted data, 192.168.1.105, 74.125.224.79, F, 23, 1312 +Encrypted data, 192.168.1.105, 74.125.224.79, F, 23, 1345 +Encrypted data, 192.168.1.105, 74.125.224.79, F, 23, 1345 +Encrypted data, 192.168.1.105, 74.125.224.79, F, 23, 161 +Encrypted data, 192.168.1.105, 74.125.224.79, F, 23, 33 +Encrypted data, 192.168.1.105, 74.125.224.79, F, 23, 28 +Encrypted data, 192.168.1.105, 74.125.224.79, F, 23, 1312 +Encrypted data, 192.168.1.105, 74.125.224.79, F, 23, 1345 +Encrypted data, 192.168.1.105, 74.125.224.79, F, 23, 1345 +Encrypted data, 192.168.1.105, 74.125.224.79, F, 23, 148 +Encrypted data, 192.168.1.105, 74.125.224.79, F, 23, 46 +Encrypted data, 192.168.1.105, 74.125.224.79, F, 23, 28 +Encrypted data, 192.168.1.105, 74.125.224.79, F, 23, 1312 +Encrypted data, 192.168.1.105, 74.125.224.79, F, 23, 1345 +Encrypted data, 192.168.1.105, 74.125.224.79, F, 23, 1345 +Encrypted data, 192.168.1.105, 74.125.224.79, F, 23, 135 +Encrypted data, 192.168.1.105, 74.125.224.79, F, 23, 59 +Encrypted data, 192.168.1.105, 74.125.224.79, F, 23, 28 +Encrypted data, 192.168.1.105, 74.125.224.79, F, 23, 1312 +Encrypted data, 192.168.1.105, 74.125.224.79, F, 23, 1345 +Encrypted data, 192.168.1.105, 74.125.224.79, F, 23, 245 +Encrypted data, 192.168.1.105, 74.125.224.79, T, 23, 32 +Encrypted data, 192.168.1.105, 74.125.224.79, F, 23, 32 +Encrypted data, 192.168.1.105, 74.125.224.79, T, 23, 92 +Encrypted data, 192.168.1.105, 74.125.224.79, F, 23, 75 +Encrypted data, 192.168.1.105, 74.125.224.79, F, 23, 28 +Encrypted data, 192.168.1.105, 74.125.224.79, T, 23, 32 +Encrypted data, 192.168.1.105, 74.125.224.79, F, 23, 32 diff --git a/testing/btest/scripts/base/protocols/ssl/handshake-events.test b/testing/btest/scripts/base/protocols/ssl/handshake-events.test new file mode 100644 index 0000000000..0dd8725b11 --- /dev/null +++ b/testing/btest/scripts/base/protocols/ssl/handshake-events.test @@ -0,0 +1,28 @@ +# This tests events not covered by other tests + +# @TEST-EXEC: bro -b -r $TRACES/tls/tls-conn-with-extensions.trace %INPUT +# @TEST-EXEC: btest-diff .stdout + +@load base/protocols/ssl + +redef SSL::disable_analyzer_after_detection=F; + +event ssl_established(c: connection) + { + print "Established", c$id$orig_h, c$id$resp_h; + } + +event ssl_handshake_message(c: connection, is_orig: bool, msg_type: count, length: count) + { + print "Handshake", c$id$orig_h, c$id$resp_h, is_orig, msg_type, length; + } + +event ssl_change_cipher_spec(c: connection, is_orig: bool) + { + print "CCS", c$id$orig_h, c$id$resp_h, is_orig; + } + +event ssl_encrypted_data(c: connection, is_orig: bool, content_type: count, length: count) + { + print "Encrypted data", c$id$orig_h, c$id$resp_h, is_orig, content_type, length; + }