Let TLS analyzer fail better when no longer in sync with the data stream. The

version field in each record-layer packet is now re-checked.
This commit is contained in:
Bernhard Amann 2014-05-08 11:32:52 -07:00
parent 012156e9f1
commit 9014629a7d
3 changed files with 22 additions and 7 deletions

View file

@ -265,9 +265,8 @@ event ssl_session_ticket_handshake%(c: connection, ticket_lifetime_hint: count,
## ssl_alert ssl_encrypted_heartbeat ## ssl_alert ssl_encrypted_heartbeat
event ssl_heartbeat%(c: connection, is_orig: bool, length: count, heartbeat_type: count, payload_length: count, payload: string%); event ssl_heartbeat%(c: connection, is_orig: bool, length: count, heartbeat_type: count, payload_length: count, payload: string%);
## Generated for SSL/TLS heartbeat messages that are sent after session encryption ## Generated for SSL/TLS messages that are sent after session encryption
## started. Generally heartbeat messages should rarely be seen in normal TLS traffic. ## started.
## Heartbeats are described in :rfc:`6520`.
## ##
## Note that :bro:id:`SSL::disable_analyzer_after_detection` has to be set to false. ## Note that :bro:id:`SSL::disable_analyzer_after_detection` has to be set to false.
## Otherwhise this event will never be thrown. ## Otherwhise this event will never be thrown.
@ -276,11 +275,13 @@ 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.
## ##
## content type: message type as reported by TLS session layer
##
## length: length of the entire heartbeat message. ## length: length of the entire heartbeat 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_heartbeat%(c: connection, is_orig: bool, length: count%); event ssl_encrypted_data%(c: connection, is_orig: bool, 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. See ## message, when the client requested OCSP stapling and the server supports it. See

View file

@ -365,9 +365,8 @@ refine connection SSL_Conn += {
bro_analyzer()->Conn()); bro_analyzer()->Conn());
} }
if ( ${rec.content_type} == HEARTBEAT ) BifEvent::generate_ssl_encrypted_data(bro_analyzer(),
BifEvent::generate_ssl_encrypted_heartbeat(bro_analyzer(), bro_analyzer()->Conn(), ${rec.content_type}, ${rec.is_orig}, ${rec.length});
bro_analyzer()->Conn(), ${rec.is_orig}, ${rec.length});
return true; return true;
%} %}

View file

@ -44,6 +44,8 @@ type SSLRecord(is_orig: bool) = record {
}; };
length : int = case version of { length : int = case version of {
# fail analyzer if the packet cannot be recognized as TLS.
UNKNOWN_VERSION -> 0;
SSLv20 -> (((head0 & 0x7f) << 8) | head1) - 3; SSLv20 -> (((head0 & 0x7f) << 8) | head1) - 3;
default -> (head3 << 8) | head4; default -> (head3 << 8) | head4;
}; };
@ -748,6 +750,19 @@ refine connection SSL_Conn += {
function determine_ssl_record_layer(head0 : uint8, head1 : uint8, function determine_ssl_record_layer(head0 : uint8, head1 : uint8,
head2 : uint8, head3: uint8, head4: uint8) : int head2 : uint8, head3: uint8, head4: uint8) : int
%{ %{
// re-check record layer version to be sure that we still are synchronized with
// the data stream
if ( record_layer_version_ != UNKNOWN_VERSION && record_layer_version_ != SSLv20 )
{
uint16 version = (head1<<8) | head2;
if ( version != SSLv30 && version != TLSv10 &&
version != TLSv11 && version != TLSv12 )
{
bro_analyzer()->ProtocolViolation(fmt("Invalid version late in TLS connection. Packet reported version: %d", version));
return UNKNOWN_VERSION;
}
}
if ( record_layer_version_ != UNKNOWN_VERSION ) if ( record_layer_version_ != UNKNOWN_VERSION )
return record_layer_version_; return record_layer_version_;