mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 14:48:21 +00:00
Implement correct parsing of TLS record fragmentation.
Finally. Our test-case is a >400kb certificate with 10,000 alternative names. :)
This commit is contained in:
parent
47de906612
commit
ba27bb54d4
11 changed files with 37 additions and 40 deletions
|
@ -61,19 +61,15 @@ void SSL_Analyzer::DeliverStream(int len, const u_char* data, bool orig)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SSL_Analyzer::SendHandshake(uint8 msg_type, uint32 length, const u_char* begin, const u_char* end, bool orig)
|
void SSL_Analyzer::SendHandshake(const u_char* begin, const u_char* end, bool orig)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
handshake_interp->NewData(orig, (const unsigned char*) &msg_type, (const unsigned char*) &msg_type + 1);
|
|
||||||
uint32 host_length = htonl(length);
|
|
||||||
handshake_interp->NewData(orig, (const unsigned char*) &host_length, (const unsigned char*) &host_length + sizeof(host_length));
|
|
||||||
handshake_interp->NewData(orig, begin, end);
|
handshake_interp->NewData(orig, begin, end);
|
||||||
}
|
}
|
||||||
catch ( const binpac::Exception& e )
|
catch ( const binpac::Exception& e )
|
||||||
{
|
{
|
||||||
ProtocolViolation(fmt("Binpac exception: %s", e.c_msg()));
|
ProtocolViolation(fmt("Binpac exception: %s", e.c_msg()));
|
||||||
fprintf(stderr, "Handshake exception: %s\n", e.c_msg());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,7 @@ public:
|
||||||
virtual void DeliverStream(int len, const u_char* data, bool orig);
|
virtual void DeliverStream(int len, const u_char* data, bool orig);
|
||||||
virtual void Undelivered(uint64 seq, int len, bool orig);
|
virtual void Undelivered(uint64 seq, int len, bool orig);
|
||||||
|
|
||||||
void SendHandshake(uint8 msg_type, uint32 length, const u_char* begin, const u_char* end, bool orig);
|
void SendHandshake(const u_char* begin, const u_char* end, bool orig);
|
||||||
|
|
||||||
// Overriden from tcp::TCP_ApplicationAnalyzer.
|
// Overriden from tcp::TCP_ApplicationAnalyzer.
|
||||||
virtual void EndpointEOF(bool is_orig);
|
virtual void EndpointEOF(bool is_orig);
|
||||||
|
|
|
@ -23,11 +23,9 @@ refine connection SSL_Conn += {
|
||||||
return true;
|
return true;
|
||||||
%}
|
%}
|
||||||
|
|
||||||
function proc_handshake(rec: SSLRecord, msg_type: uint8, length: uint24, data: bytestring, is_orig: bool) : bool
|
function proc_handshake(rec: SSLRecord, data: bytestring, is_orig: bool) : bool
|
||||||
%{
|
%{
|
||||||
fprintf(stderr, "Forwarding to Handshake analyzer: msg_type: %u, length: %u\n", msg_type, to_int()(length));
|
bro_analyzer()->SendHandshake(data.begin(), data.end(), is_orig);
|
||||||
fprintf(stderr, "%u\n", data.end() - data.begin());
|
|
||||||
bro_analyzer()->SendHandshake(msg_type, to_int()(length), data.begin(), data.end(), is_orig);
|
|
||||||
return true;
|
return true;
|
||||||
%}
|
%}
|
||||||
};
|
};
|
||||||
|
@ -58,5 +56,5 @@ refine typeattr V2ClientMasterKey += &let {
|
||||||
};
|
};
|
||||||
|
|
||||||
refine typeattr Handshake += &let {
|
refine typeattr Handshake += &let {
|
||||||
proc : bool = $context.connection.proc_handshake(rec, msg_type, length, data, rec.is_orig);
|
proc : bool = $context.connection.proc_handshake(rec, data, rec.is_orig);
|
||||||
};
|
};
|
||||||
|
|
|
@ -43,9 +43,10 @@ refine casetype PlaintextRecord += {
|
||||||
};
|
};
|
||||||
|
|
||||||
type Handshake(rec: SSLRecord) = record {
|
type Handshake(rec: SSLRecord) = record {
|
||||||
msg_type: uint8;
|
# msg_type: uint8;
|
||||||
length: uint24;
|
# length: uint24;
|
||||||
data: bytestring &length=to_int()(length);
|
# data: bytestring &length=to_int()(length);
|
||||||
|
data: bytestring &restofdata;
|
||||||
};
|
};
|
||||||
|
|
||||||
######################################################################
|
######################################################################
|
||||||
|
|
|
@ -200,10 +200,10 @@ refine connection Handshake_Conn += {
|
||||||
return true;
|
return true;
|
||||||
%}
|
%}
|
||||||
|
|
||||||
function proc_handshake(is_orig: bool, msg_type: uint8, length: uint32) : bool
|
function proc_handshake(is_orig: bool, msg_type: uint8, length: uint24) : bool
|
||||||
%{
|
%{
|
||||||
BifEvent::generate_ssl_handshake_message(bro_analyzer(),
|
BifEvent::generate_ssl_handshake_message(bro_analyzer(),
|
||||||
bro_analyzer()->Conn(), is_orig, msg_type, length);
|
bro_analyzer()->Conn(), is_orig, msg_type, to_int()(length));
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
%}
|
%}
|
||||||
|
|
|
@ -25,10 +25,9 @@ enum HandshakeType {
|
||||||
|
|
||||||
type HandshakeRecord(is_orig: bool) = record {
|
type HandshakeRecord(is_orig: bool) = record {
|
||||||
msg_type: uint8;
|
msg_type: uint8;
|
||||||
msg_length: uint32;
|
msg_length: uint24;
|
||||||
rec: Handshake(this);
|
rec: Handshake(this);
|
||||||
# rec: bytestring &length=10 &transient;
|
} &length=(to_int()(msg_length) + 4);
|
||||||
} &length=(msg_length + 5);
|
|
||||||
|
|
||||||
type Handshake(rec: HandshakeRecord) = case rec.msg_type of {
|
type Handshake(rec: HandshakeRecord) = case rec.msg_type of {
|
||||||
HELLO_REQUEST -> hello_request : HelloRequest(rec);
|
HELLO_REQUEST -> hello_request : HelloRequest(rec);
|
||||||
|
@ -500,34 +499,14 @@ refine connection Handshake_Conn += {
|
||||||
|
|
||||||
%member{
|
%member{
|
||||||
uint32 chosen_cipher_;
|
uint32 chosen_cipher_;
|
||||||
uint8 msg_type_;
|
|
||||||
uint32 msg_length_;
|
|
||||||
%}
|
%}
|
||||||
|
|
||||||
%init{
|
%init{
|
||||||
chosen_cipher_ = NO_CHOSEN_CIPHER;
|
chosen_cipher_ = NO_CHOSEN_CIPHER;
|
||||||
msg_type_ = 0;
|
|
||||||
msg_length_ = 0;
|
|
||||||
%}
|
%}
|
||||||
|
|
||||||
function chosen_cipher() : int %{ return chosen_cipher_; %}
|
function chosen_cipher() : int %{ return chosen_cipher_; %}
|
||||||
|
|
||||||
function msg_type() : uint8 %{ return msg_type_; %}
|
|
||||||
|
|
||||||
function msg_length() : uint32 %{ fprintf(stderr, "Got length %d\n", msg_length_); return msg_length_; %}
|
|
||||||
|
|
||||||
function set_msg_type(type: uint8) : bool
|
|
||||||
%{
|
|
||||||
msg_type_ = type;
|
|
||||||
return true;
|
|
||||||
%}
|
|
||||||
|
|
||||||
function set_msg_length(len: uint32) : bool
|
|
||||||
%{
|
|
||||||
msg_length_ = len;
|
|
||||||
return true;
|
|
||||||
%}
|
|
||||||
|
|
||||||
function set_cipher(cipher: uint32) : bool
|
function set_cipher(cipher: uint32) : bool
|
||||||
%{
|
%{
|
||||||
chosen_cipher_ = cipher;
|
chosen_cipher_ = cipher;
|
||||||
|
|
|
@ -13,6 +13,7 @@ connection Handshake_Conn(bro_analyzer: BroAnalyzer) {
|
||||||
downflow = Handshake_Flow(false);
|
downflow = Handshake_Flow(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
%include ssl-defs.pac
|
||||||
%include tls-handshake-protocol.pac
|
%include tls-handshake-protocol.pac
|
||||||
|
|
||||||
flow Handshake_Flow(is_orig: bool) {
|
flow Handshake_Flow(is_orig: bool) {
|
||||||
|
@ -20,4 +21,3 @@ flow Handshake_Flow(is_orig: bool) {
|
||||||
}
|
}
|
||||||
|
|
||||||
%include tls-handshake-analyzer.pac
|
%include tls-handshake-analyzer.pac
|
||||||
%include ssl-defs.pac
|
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
10000
|
|
@ -0,0 +1,10 @@
|
||||||
|
#separator \x09
|
||||||
|
#set_separator ,
|
||||||
|
#empty_field (empty)
|
||||||
|
#unset_field -
|
||||||
|
#path ssl
|
||||||
|
#open 2015-03-12-01-22-34
|
||||||
|
#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p version cipher curve server_name resumed last_alert next_protocol established cert_chain_fuids client_cert_chain_fuids subject issuer client_subject client_issuer
|
||||||
|
#types time string addr port addr port string string string string bool string string bool vector[string] vector[string] string string string string
|
||||||
|
1426117218.083491 CXWv6p3arKYeMETxOg 192.168.6.86 61454 104.236.167.107 4433 TLSv12 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 secp256r1 104.236.167.107 F - - F FsQdqWuF9t3e4W0d (empty) - - - -
|
||||||
|
#close 2015-03-12-01-22-34
|
BIN
testing/btest/Traces/tls/tls-fragmented-handshake.pcap.gz
Normal file
BIN
testing/btest/Traces/tls/tls-fragmented-handshake.pcap.gz
Normal file
Binary file not shown.
12
testing/btest/scripts/base/protocols/ssl/fragment.test
Normal file
12
testing/btest/scripts/base/protocols/ssl/fragment.test
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
# Test a heavily fragmented tls connection
|
||||||
|
|
||||||
|
# @TEST-EXEC: cat $TRACES/tls/tls-fragmented-handshake.pcap.gz | gunzip | bro -r - %INPUT
|
||||||
|
# @TEST-EXEC: btest-diff ssl.log
|
||||||
|
# @TEST-EXEC: btest-diff .stdout
|
||||||
|
|
||||||
|
# Certificate has 10,000 alternative names :)
|
||||||
|
event x509_ext_subject_alternative_name(f: fa_file, ext: X509::SubjectAlternativeName)
|
||||||
|
{
|
||||||
|
print |ext$dns|;
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue