Final touches to SSL events with record layer version.

This commit is contained in:
Johanna Amann 2018-08-23 14:18:38 -07:00
parent aa2488fb69
commit b2a0418dc5
24 changed files with 88 additions and 65 deletions

View file

@ -200,7 +200,7 @@ function finish(c: connection, remove_analyzer: bool)
} }
} }
event ssl_client_hello(c: connection, version: count, possible_ts: time, client_random: string, session_id: string, ciphers: index_vec, comp_methods: index_vec) &priority=5 event ssl_client_hello(c: connection, version: count, record_version: count, possible_ts: time, client_random: string, session_id: string, ciphers: index_vec, comp_methods: index_vec) &priority=5
{ {
set_session(c); set_session(c);
@ -212,7 +212,7 @@ event ssl_client_hello(c: connection, version: count, possible_ts: time, client_
} }
} }
event ssl_server_hello(c: connection, version: count, possible_ts: time, server_random: string, session_id: string, cipher: count, comp_method: count) &priority=5 event ssl_server_hello(c: connection, version: count, record_version: count, possible_ts: time, server_random: string, session_id: string, cipher: count, comp_method: count) &priority=5
{ {
set_session(c); set_session(c);
@ -351,7 +351,7 @@ event protocol_confirmation(c: connection, atype: Analyzer::Tag, aid: count) &pr
} }
} }
event ssl_plaintext_data(c: connection, is_orig: bool, content_type: count, record_version: count, length: count) &priority=5 event ssl_plaintext_data(c: connection, is_orig: bool, record_version: count, content_type: count, length: count) &priority=5
{ {
set_session(c); set_session(c);

View file

@ -223,7 +223,7 @@ event ssl_encrypted_heartbeat(c: connection, is_orig: bool, length: count)
} }
} }
event ssl_encrypted_data(c: connection, is_orig: bool, content_type: count, record_version: count, length: count) event ssl_encrypted_data(c: connection, is_orig: bool, record_version: count, content_type: count, length: count)
{ {
if ( !c?$ssl ) if ( !c?$ssl )
return; return;

View file

@ -76,7 +76,7 @@ event ssl_established(c: connection) &priority=3
} }
# Check for old SSL versions and weak connection keys # 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 event ssl_server_hello(c: connection, version: count, record_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) ) if ( ! addr_matches_host(c$id$resp_h, notify_weak_keys) )
return; return;

View file

@ -51,8 +51,9 @@ void DTLS_Analyzer::EndOfData(bool is_orig)
} }
void DTLS_Analyzer::SendHandshake(uint8 msg_type, uint32 length, const u_char* begin, const u_char* end, bool orig) void DTLS_Analyzer::SendHandshake(uint16 raw_tls_version, uint8 msg_type, uint32 length, const u_char* begin, const u_char* end, bool orig)
{ {
handshake_interp->set_record_version(raw_tls_version);
try try
{ {
handshake_interp->NewData(orig, (const unsigned char*) &msg_type, (const unsigned char*) &msg_type + 1); handshake_interp->NewData(orig, (const unsigned char*) &msg_type, (const unsigned char*) &msg_type + 1);

View file

@ -22,7 +22,7 @@ public:
uint64 seq, const IP_Hdr* ip, int caplen) override; uint64 seq, const IP_Hdr* ip, int caplen) override;
void EndOfData(bool is_orig) override; void EndOfData(bool is_orig) override;
void SendHandshake(uint8 msg_type, uint32 length, const u_char* begin, const u_char* end, bool orig); void SendHandshake(uint16 raw_tls_version, uint8 msg_type, uint32 length, const u_char* begin, const u_char* end, bool orig);
static analyzer::Analyzer* Instantiate(Connection* conn) static analyzer::Analyzer* Instantiate(Connection* conn)

View file

@ -71,8 +71,9 @@ void SSL_Analyzer::DeliverStream(int len, const u_char* data, bool orig)
} }
} }
void SSL_Analyzer::SendHandshake(const u_char* begin, const u_char* end, bool orig) void SSL_Analyzer::SendHandshake(uint16 raw_tls_version, const u_char* begin, const u_char* end, bool orig)
{ {
handshake_interp->set_record_version(raw_tls_version);
try try
{ {
handshake_interp->NewData(orig, begin, end); handshake_interp->NewData(orig, begin, end);

View file

@ -21,7 +21,7 @@ public:
void DeliverStream(int len, const u_char* data, bool orig) override; void DeliverStream(int len, const u_char* data, bool orig) override;
void Undelivered(uint64 seq, int len, bool orig) override; void Undelivered(uint64 seq, int len, bool orig) override;
void SendHandshake(const u_char* begin, const u_char* end, bool orig); void SendHandshake(uint16 raw_tls_version, const u_char* begin, const u_char* end, bool orig);
// Tell the analyzer that encryption has started. // Tell the analyzer that encryption has started.
void StartEncryption(); void StartEncryption();

View file

@ -42,7 +42,7 @@ refine connection SSL_Conn += {
if ( foffset == 0 && length == flength ) if ( foffset == 0 && length == flength )
{ {
//fprintf(stderr, "Complete fragment, forwarding...\n"); //fprintf(stderr, "Complete fragment, forwarding...\n");
bro_analyzer()->SendHandshake(${rec.msg_type}, length, ${rec.data}.begin(), ${rec.data}.end(), ${pdu.is_orig}); bro_analyzer()->SendHandshake(${pdu.raw_tls_version}, ${rec.msg_type}, length, ${rec.data}.begin(), ${rec.data}.end(), ${pdu.is_orig});
return true; return true;
} }
@ -131,7 +131,7 @@ refine connection SSL_Conn += {
if ( ( ~(i->message_sequence_seen) & ( ( 1<<(total_length+1) ) -1 ) ) == 0 ) if ( ( ~(i->message_sequence_seen) & ( ( 1<<(total_length+1) ) -1 ) ) == 0 )
{ {
//fprintf(stderr, "ALl fragments here. Total length %u\n", length); //fprintf(stderr, "ALl fragments here. Total length %u\n", length);
bro_analyzer()->SendHandshake(${rec.msg_type}, length, i->buffer, i->buffer + length, ${pdu.is_orig}); bro_analyzer()->SendHandshake(${pdu.raw_tls_version}, ${rec.msg_type}, length, i->buffer, i->buffer + length, ${pdu.is_orig});
} }
} }

View file

@ -12,6 +12,11 @@
## values are standardized as part of the SSL/TLS protocol. The ## values are standardized as part of the SSL/TLS protocol. The
## :bro:id:`SSL::version_strings` table maps them to descriptive names. ## :bro:id:`SSL::version_strings` table maps them to descriptive names.
## ##
## record_version: TLS version given in the record layer of the message.
## Set to 0 for SSLv2.
##
##
##
## possible_ts: The current time as sent by the client. Note that SSL/TLS does ## possible_ts: The current time as sent by the client. Note that SSL/TLS does
## not require clocks to be set correctly, so treat with care. ## not require clocks to be set correctly, so treat with care.
## ##
@ -32,7 +37,7 @@
## ssl_change_cipher_spec ## ssl_change_cipher_spec
## ssl_dh_client_params ssl_ecdh_server_params ssl_ecdh_client_params ## ssl_dh_client_params ssl_ecdh_server_params ssl_ecdh_client_params
## ssl_rsa_client_pms ## ssl_rsa_client_pms
event ssl_client_hello%(c: connection, version: count, possible_ts: time, client_random: string, session_id: string, ciphers: index_vec, comp_methods: index_vec%); event ssl_client_hello%(c: connection, version: count, record_version: count, possible_ts: time, client_random: string, session_id: string, ciphers: index_vec, comp_methods: index_vec%);
## Generated for an SSL/TLS server's initial *hello* message. SSL/TLS sessions ## Generated for an SSL/TLS server's initial *hello* message. SSL/TLS sessions
## start with an unencrypted handshake, and Bro extracts as much information out ## start with an unencrypted handshake, and Bro extracts as much information out
@ -48,6 +53,9 @@ event ssl_client_hello%(c: connection, version: count, possible_ts: time, client
## The values are standardized as part of the SSL/TLS protocol. The ## The values are standardized as part of the SSL/TLS protocol. The
## :bro:id:`SSL::version_strings` table maps them to descriptive names. ## :bro:id:`SSL::version_strings` table maps them to descriptive names.
## ##
## record_version: TLS version given in the record layer of the message.
## Set to 0 for SSLv2.
##
## possible_ts: The current time as sent by the server. Note that SSL/TLS does ## possible_ts: The current time as sent by the server. Note that SSL/TLS does
## not require clocks to be set correctly, so treat with care. This value ## not require clocks to be set correctly, so treat with care. This value
## is not sent in TLSv1.3. ## is not sent in TLSv1.3.
@ -71,7 +79,7 @@ event ssl_client_hello%(c: connection, version: count, possible_ts: time, client
## ssl_dh_server_params ssl_handshake_message ssl_change_cipher_spec ## ssl_dh_server_params ssl_handshake_message ssl_change_cipher_spec
## ssl_dh_client_params ssl_ecdh_server_params ssl_ecdh_client_params ## ssl_dh_client_params ssl_ecdh_server_params ssl_ecdh_client_params
## ssl_rsa_client_pms ## 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%); event ssl_server_hello%(c: connection, version: count, record_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 ## Generated for SSL/TLS extensions seen in an initial handshake. SSL/TLS
## sessions start with an unencrypted handshake, and Bro extracts as much ## sessions start with an unencrypted handshake, and Bro extracts as much
@ -490,17 +498,17 @@ event ssl_heartbeat%(c: connection, is_orig: bool, length: count, heartbeat_type
## ##
## is_orig: True if event is raised for originator side of the connection. ## is_orig: True if event is raised for originator side of the connection.
## ##
## record_version: TLS version given in the record layer of the message.
## Set to 0 for SSLv2.
##
## content_type: message type as reported by TLS session layer. Not populated for ## content_type: message type as reported by TLS session layer. Not populated for
## SSLv2. ## SSLv2.
## ##
## record_version: TLS version given in the record layer of the message.
## This will not be set for SSLv2.
##
## length: length of the entire message. ## length: length of the entire message.
## ##
## .. bro:see:: ssl_client_hello ssl_established ssl_extension ssl_server_hello ## .. bro:see:: ssl_client_hello ssl_established ssl_extension ssl_server_hello
## ssl_alert ssl_heartbeat ## ssl_alert ssl_heartbeat
event ssl_plaintext_data%(c: connection, is_orig: bool, content_type: count, record_version: count, length: count%); event ssl_plaintext_data%(c: connection, is_orig: bool, record_version: count, content_type: count, length: count%);
## Generated for SSL/TLS messages that are sent after session encryption ## Generated for SSL/TLS messages that are sent after session encryption
## started. ## started.
@ -512,17 +520,17 @@ event ssl_plaintext_data%(c: connection, is_orig: bool, content_type: count, rec
## ##
## is_orig: True if event is raised for originator side of the connection. ## is_orig: True if event is raised for originator side of the connection.
## ##
## record_version: TLS version given in the record layer of the message.
## Set to 0 for SSLv2.
##
## content_type: message type as reported by TLS session layer. Not populated for ## content_type: message type as reported by TLS session layer. Not populated for
## SSLv2. ## SSLv2.
## ##
## record_version: TLS version given in the record layer of the message.
## This will not be set for SSLv2.
##
## length: length of the entire message. ## length: length of the entire message.
## ##
## .. bro:see:: ssl_client_hello ssl_established ssl_extension ssl_server_hello ## .. bro:see:: ssl_client_hello ssl_established ssl_extension ssl_server_hello
## ssl_alert ssl_heartbeat ## ssl_alert ssl_heartbeat
event ssl_encrypted_data%(c: connection, is_orig: bool, content_type: count, record_version: count, length: count%); event ssl_encrypted_data%(c: connection, is_orig: bool, record_version: count, content_type: count, length: count%);
## This event contains the OCSP response contained in a Certificate Status Request ## This event contains the OCSP response contained in a Certificate Status Request
## message, when the client requested OCSP stapling and the server supports it. ## message, when the client requested OCSP stapling and the server supports it.

View file

@ -40,7 +40,7 @@
} }
BifEvent::generate_ssl_client_hello(bro_analyzer(), bro_analyzer()->Conn(), BifEvent::generate_ssl_client_hello(bro_analyzer(), bro_analyzer()->Conn(),
version, ts, new StringVal(client_random.length(), version, record_version(), ts, new StringVal(client_random.length(),
(const char*) client_random.data()), (const char*) client_random.data()),
to_string_val(session_id), to_string_val(session_id),
cipher_vec, comp_vec); cipher_vec, comp_vec);

View file

@ -23,7 +23,7 @@
BifEvent::generate_ssl_server_hello(bro_analyzer(), BifEvent::generate_ssl_server_hello(bro_analyzer(),
bro_analyzer()->Conn(), bro_analyzer()->Conn(),
version, ts, new StringVal(server_random.length(), version, record_version(), ts, new StringVal(server_random.length(),
(const char*) server_random.data()), (const char*) server_random.data()),
to_string_val(session_id), to_string_val(session_id),
ciphers->size()==0 ? 0 : ciphers->at(0), comp_method); ciphers->size()==0 ? 0 : ciphers->at(0), comp_method);

View file

@ -25,7 +25,7 @@ refine connection SSL_Conn += {
function proc_handshake(rec: SSLRecord, data: bytestring, is_orig: bool) : bool function proc_handshake(rec: SSLRecord, data: bytestring, is_orig: bool) : bool
%{ %{
bro_analyzer()->SendHandshake(data.begin(), data.end(), is_orig); bro_analyzer()->SendHandshake(${rec.raw_tls_version}, data.begin(), data.end(), is_orig);
return true; return true;
%} %}
}; };

View file

@ -56,7 +56,7 @@ refine connection SSL_Conn += {
if ( ssl_encrypted_data ) if ( ssl_encrypted_data )
BifEvent::generate_ssl_encrypted_data(bro_analyzer(), BifEvent::generate_ssl_encrypted_data(bro_analyzer(),
bro_analyzer()->Conn(), ${rec.is_orig}, ${rec.content_type}, ${rec.raw_tls_version}, ${rec.length}); bro_analyzer()->Conn(), ${rec.is_orig}, ${rec.raw_tls_version}, ${rec.content_type}, ${rec.length});
return true; return true;
%} %}
@ -65,7 +65,7 @@ refine connection SSL_Conn += {
%{ %{
if ( ssl_plaintext_data ) if ( ssl_plaintext_data )
BifEvent::generate_ssl_plaintext_data(bro_analyzer(), BifEvent::generate_ssl_plaintext_data(bro_analyzer(),
bro_analyzer()->Conn(), ${rec.is_orig}, ${rec.content_type}, ${rec.raw_tls_version}, ${rec.length}); bro_analyzer()->Conn(), ${rec.is_orig}, ${rec.raw_tls_version}, ${rec.content_type}, ${rec.length});
return true; return true;
%} %}

View file

@ -15,7 +15,7 @@ type SSLRecord(is_orig: bool) = record {
$context.connection.determine_ssl_record_layer(head0, head1, head2, head3, head4, is_orig); $context.connection.determine_ssl_record_layer(head0, head1, head2, head3, head4, is_orig);
# unmodified tls record layer version of this packet. Do not use this if you are parsing SSLv2 # unmodified tls record layer version of this packet. Do not use this if you are parsing SSLv2
raw_tls_version: int = case version of { raw_tls_version: uint16 = case version of {
SSLv20 -> 0; SSLv20 -> 0;
default -> (head1<<8) | head2; default -> (head1<<8) | head2;
} &requires(version); } &requires(version);
@ -214,4 +214,6 @@ refine connection SSL_Conn += {
return UNKNOWN_VERSION; return UNKNOWN_VERSION;
%} %}
function record_version() : uint16 %{ return 0; %}
}; };

View file

@ -889,11 +889,13 @@ refine connection Handshake_Conn += {
%member{ %member{
uint32 chosen_cipher_; uint32 chosen_cipher_;
uint16 chosen_version_; uint16 chosen_version_;
uint16 record_version_;
%} %}
%init{ %init{
chosen_cipher_ = NO_CHOSEN_CIPHER; chosen_cipher_ = NO_CHOSEN_CIPHER;
chosen_version_ = UNKNOWN_VERSION; chosen_version_ = UNKNOWN_VERSION;
record_version_ = 0;
%} %}
function chosen_cipher() : int %{ return chosen_cipher_; %} function chosen_cipher() : int %{ return chosen_cipher_; %}
@ -911,6 +913,13 @@ refine connection Handshake_Conn += {
chosen_version_ = version; chosen_version_ = version;
return true; return true;
%} %}
function record_version() : uint16 %{ return record_version_; %}
function set_record_version(version: uint16) : bool
%{
record_version_ = version;
return true;
%}
}; };

File diff suppressed because one or more lines are too long

View file

@ -3,12 +3,12 @@
# @TEST-EXEC: bro -r $TRACES/tls/tls-conn-with-extensions.trace %INPUT # @TEST-EXEC: bro -r $TRACES/tls/tls-conn-with-extensions.trace %INPUT
# @TEST-EXEC: btest-diff .stdout # @TEST-EXEC: btest-diff .stdout
event ssl_client_hello(c: connection, version: count, possible_ts: time, client_random: string, session_id: string, ciphers: index_vec, comp_methods: index_vec) event ssl_client_hello(c: connection, version: count, record_version: count, possible_ts: time, client_random: string, session_id: string, ciphers: index_vec, comp_methods: index_vec)
{ {
print comp_methods; print comp_methods;
} }
event ssl_server_hello(c: connection, version: count, possible_ts: time, server_random: string, session_id: string, cipher: count, comp_method: count) event ssl_server_hello(c: connection, version: count, record_version: count, possible_ts: time, server_random: string, session_id: string, cipher: count, comp_method: count)
{ {
print comp_method; print comp_method;
} }

View file

@ -14,7 +14,7 @@ event bro_init()
print "Start test run"; print "Start test run";
} }
event ssl_client_hello(c: connection, version: count, possible_ts: time, client_random: string, session_id: string, ciphers: index_vec, comp_methods: index_vec) &priority=5 event ssl_client_hello(c: connection, version: count, record_version: count, possible_ts: time, client_random: string, session_id: string, ciphers: index_vec, comp_methods: index_vec) &priority=5
{ {
print "Client hello", c$id$orig_h, c$id$resp_h, version; print "Client hello", c$id$orig_h, c$id$resp_h, version;
} }

View file

@ -3,7 +3,7 @@
# @TEST-EXEC: touch dpd.log # @TEST-EXEC: touch dpd.log
# @TEST-EXEC: btest-diff dpd.log # @TEST-EXEC: btest-diff dpd.log
event ssl_client_hello(c: connection, version: count, possible_ts: time, client_random: string, session_id: string, ciphers: index_vec, comp_methods: index_vec) event ssl_client_hello(c: connection, version: count, record_version: count, possible_ts: time, client_random: string, session_id: string, ciphers: index_vec, comp_methods: index_vec)
{ {
print version, client_random, session_id, ciphers; print version, client_random, session_id, ciphers;
} }

View file

@ -22,12 +22,12 @@ event ssl_change_cipher_spec(c: connection, is_orig: bool)
print "CCS", c$id$orig_h, c$id$resp_h, is_orig; print "CCS", c$id$orig_h, c$id$resp_h, is_orig;
} }
event ssl_plaintext_data(c: connection, is_orig: bool, content_type: count, record_version: count, length: count) event ssl_plaintext_data(c: connection, is_orig: bool, record_version: count, content_type: count, length: count)
{ {
print "Plaintext data", c$id$orig_h, c$id$resp_h, is_orig, SSL::version_strings[record_version], content_type, length; print "Plaintext data", c$id$orig_h, c$id$resp_h, is_orig, SSL::version_strings[record_version], content_type, length;
} }
event ssl_encrypted_data(c: connection, is_orig: bool, content_type: count, record_version: count, length: count) event ssl_encrypted_data(c: connection, is_orig: bool, record_version: count, content_type: count, length: count)
{ {
print "Encrypted data", c$id$orig_h, c$id$resp_h, is_orig, SSL::version_strings[record_version], content_type, length; print "Encrypted data", c$id$orig_h, c$id$resp_h, is_orig, SSL::version_strings[record_version], content_type, length;
} }

View file

@ -62,7 +62,7 @@ event ssl_established(c: connection) &priority=5
c$ssl$server_cert_sha1 = c$ssl$cert_chain[0]$sha1; c$ssl$server_cert_sha1 = c$ssl$cert_chain[0]$sha1;
} }
event ssl_client_hello(c: connection, version: count, possible_ts: time, client_random: string, session_id: string, ciphers: index_vec) &priority=5 event ssl_client_hello(c: connection, version: count, record_version: count, possible_ts: time, client_random: string, session_id: string, ciphers: index_vec, comp_methods: index_vec) &priority=5
{ {
set_session(c); set_session(c);
c$ssl$client_random = bytestring_to_hexstr(client_random); c$ssl$client_random = bytestring_to_hexstr(client_random);
@ -79,7 +79,7 @@ event ssl_client_hello(c: connection, version: count, possible_ts: time, client_
c$ssl$client_cipher_suites = 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 event ssl_server_hello(c: connection, version: count, record_version: count, possible_ts: time, server_random: string, session_id: string, cipher: count, comp_method: count) &priority=5
{ {
set_session(c); set_session(c);
c$ssl$server_random = bytestring_to_hexstr(server_random); c$ssl$server_random = bytestring_to_hexstr(server_random);

View file

@ -1,7 +1,7 @@
# @TEST-EXEC: bro -r $TRACES/tls/tls1.2.trace %INPUT # @TEST-EXEC: bro -r $TRACES/tls/tls1.2.trace %INPUT
# @TEST-EXEC: btest-diff .stdout # @TEST-EXEC: btest-diff .stdout
event ssl_client_hello(c: connection, version: count, possible_ts: time, client_random: string, session_id: string, ciphers: index_vec, comp_methods: index_vec) event ssl_client_hello(c: connection, version: count, record_version: count, possible_ts: time, client_random: string, session_id: string, ciphers: index_vec, comp_methods: index_vec)
{ {
print fmt("Got %d cipher suites", |ciphers|); print fmt("Got %d cipher suites", |ciphers|);
for ( i in ciphers ) for ( i in ciphers )

View file

@ -1,12 +1,12 @@
# @TEST-EXEC: bro -r $TRACES/tls/tls1.2.trace %INPUT # @TEST-EXEC: bro -r $TRACES/tls/tls1.2.trace %INPUT
# @TEST-EXEC: btest-diff .stdout # @TEST-EXEC: btest-diff .stdout
event ssl_client_hello(c: connection, version: count, possible_ts: time, client_random: string, session_id: string, ciphers: index_vec, comp_methods: index_vec) event ssl_client_hello(c: connection, version: count, record_version: count, possible_ts: time, client_random: string, session_id: string, ciphers: index_vec, comp_methods: index_vec)
{ {
print client_random; print client_random;
} }
event ssl_server_hello(c: connection, version: count, possible_ts: time, server_random: string, session_id: string, cipher: count, comp_method: count) event ssl_server_hello(c: connection, version: count, record_version: count, possible_ts: time, server_random: string, session_id: string, cipher: count, comp_method: count)
{ {
print server_random; print server_random;
} }

View file

@ -25,7 +25,7 @@ event ssl_established(c: connection)
print "established", c$id; print "established", c$id;
} }
event ssl_encrypted_data(c: connection, is_orig: bool, content_type: count, record_version: count, length: count) event ssl_encrypted_data(c: connection, is_orig: bool, record_version: count, content_type: count, length: count)
{ {
print "encrypted", c$id, is_orig, SSL::version_strings[record_version], content_type; print "encrypted", c$id, is_orig, SSL::version_strings[record_version], content_type;
} }