From 0a6104fe6615822376db875dce0ee11df38c6f3c Mon Sep 17 00:00:00 2001 From: Seth Hall Date: Thu, 3 May 2012 10:52:24 -0400 Subject: [PATCH] More bugfixs, cleanup, and test for SSL analyzer - SSL related files and classes renamed to remove the "binpac" term. - A small fix for DPD scripts to make the DPD log more helpful if there are multiple continued failures. Also, fixed the SSL analyzer to make it stop doing repeated violation messages for some handshake failures. - Added a $issuer_subject to the SSL log. - Created a basic test for SSL. --- scripts/base/frameworks/dpd/main.bro | 3 + scripts/base/protocols/ssl/main.bro | 3 + src/Analyzer.cc | 6 +- src/CMakeLists.txt | 2 +- src/{SSL-binpac.cc => SSL.cc} | 17 +++--- src/{SSL-binpac.h => SSL.h} | 13 ++-- src/ssl-analyzer.pac | 56 ++++++++++-------- src/ssl-defs.pac | 29 --------- src/ssl-protocol.pac | 23 ------- .../scripts.base.protocols.ssl.basic/ssl.log | 8 +++ .../Traces/tls-conn-with-extensions.trace | Bin 0 -> 24111 bytes .../scripts/base/protocols/ssl/basic.test | 4 ++ 12 files changed, 68 insertions(+), 96 deletions(-) rename src/{SSL-binpac.cc => SSL.cc} (66%) rename src/{SSL-binpac.h => SSL.h} (74%) create mode 100644 testing/btest/Baseline/scripts.base.protocols.ssl.basic/ssl.log create mode 100644 testing/btest/Traces/tls-conn-with-extensions.trace create mode 100644 testing/btest/scripts/base/protocols/ssl/basic.test diff --git a/scripts/base/frameworks/dpd/main.bro b/scripts/base/frameworks/dpd/main.bro index e8488c3ec1..9eb0b467f8 100644 --- a/scripts/base/frameworks/dpd/main.bro +++ b/scripts/base/frameworks/dpd/main.bro @@ -105,5 +105,8 @@ event protocol_violation(c: connection, atype: count, aid: count, reason: string) &priority=-5 { if ( c?$dpd ) + { Log::write(DPD::LOG, c$dpd); + delete c$dpd; + } } diff --git a/scripts/base/protocols/ssl/main.bro b/scripts/base/protocols/ssl/main.bro index 0b280a6bcf..b5f74d5122 100644 --- a/scripts/base/protocols/ssl/main.bro +++ b/scripts/base/protocols/ssl/main.bro @@ -24,6 +24,8 @@ export { session_id: string &log &optional; ## Subject of the X.509 certificate offered by the server. subject: string &log &optional; + ## Subject of the signer of the X.509 certificate offered by the server. + issuer_subject: string &log &optional; ## NotValidBefore field value from the server certificate. not_valid_before: time &log &optional; ## NotValidAfter field value from the serve certificate. @@ -146,6 +148,7 @@ event x509_certificate(c: connection, is_orig: bool, cert: X509, chain_idx: coun # Also save other certificate information about the primary cert. c$ssl$subject = cert$subject; + c$ssl$issuer_subject = cert$issuer; c$ssl$not_valid_before = cert$not_valid_before; c$ssl$not_valid_after = cert$not_valid_after; } diff --git a/src/Analyzer.cc b/src/Analyzer.cc index 92ca3ecc50..a2a35490e8 100644 --- a/src/Analyzer.cc +++ b/src/Analyzer.cc @@ -34,7 +34,7 @@ #include "Portmap.h" #include "POP3.h" #include "SSH.h" -#include "SSL-binpac.h" +#include "SSL.h" #include "Syslog-binpac.h" #include "ConnSizeAnalyzer.h" @@ -121,8 +121,8 @@ const Analyzer::Config Analyzer::analyzer_configs[] = { HTTP_Analyzer_binpac::InstantiateAnalyzer, HTTP_Analyzer_binpac::Available, 0, false }, { AnalyzerTag::SSL, "SSL", - SSL_Analyzer_binpac::InstantiateAnalyzer, - SSL_Analyzer_binpac::Available, 0, false }, + SSL_Analyzer::InstantiateAnalyzer, + SSL_Analyzer::Available, 0, false }, { AnalyzerTag::SYSLOG_BINPAC, "SYSLOG_BINPAC", Syslog_Analyzer_binpac::InstantiateAnalyzer, Syslog_Analyzer_binpac::Available, 0, false }, diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index ce1b25dd42..9f9eb8a60f 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -376,7 +376,7 @@ set(bro_SRCS SMB.cc SMTP.cc SSH.cc - SSL-binpac.cc + SSL.cc Scope.cc SerializationFormat.cc SerialObj.cc diff --git a/src/SSL-binpac.cc b/src/SSL.cc similarity index 66% rename from src/SSL-binpac.cc rename to src/SSL.cc index db9a7004d6..218b17080b 100644 --- a/src/SSL-binpac.cc +++ b/src/SSL.cc @@ -1,21 +1,21 @@ -#include "SSL-binpac.h" +#include "SSL.h" #include "TCP_Reassembler.h" #include "Reporter.h" #include "util.h" -SSL_Analyzer_binpac::SSL_Analyzer_binpac(Connection* c) +SSL_Analyzer::SSL_Analyzer(Connection* c) : TCP_ApplicationAnalyzer(AnalyzerTag::SSL, c) { interp = new binpac::SSL::SSL_Conn(this); had_gap = false; } -SSL_Analyzer_binpac::~SSL_Analyzer_binpac() +SSL_Analyzer::~SSL_Analyzer() { delete interp; } -void SSL_Analyzer_binpac::Done() +void SSL_Analyzer::Done() { TCP_ApplicationAnalyzer::Done(); @@ -23,23 +23,22 @@ void SSL_Analyzer_binpac::Done() interp->FlowEOF(false); } -void SSL_Analyzer_binpac::EndpointEOF(TCP_Reassembler* endp) +void SSL_Analyzer::EndpointEOF(TCP_Reassembler* endp) { TCP_ApplicationAnalyzer::EndpointEOF(endp); interp->FlowEOF(endp->IsOrig()); } -void SSL_Analyzer_binpac::DeliverStream(int len, const u_char* data, bool orig) +void SSL_Analyzer::DeliverStream(int len, const u_char* data, bool orig) { TCP_ApplicationAnalyzer::DeliverStream(len, data, orig); assert(TCP()); - if ( TCP()->IsPartial() ) return; if ( had_gap ) - // XXX: If only one side had a content gap, we could still try to + // If only one side had a content gap, we could still try to // deliver data to the other side if the script layer can handle this. return; @@ -53,7 +52,7 @@ void SSL_Analyzer_binpac::DeliverStream(int len, const u_char* data, bool orig) } } -void SSL_Analyzer_binpac::Undelivered(int seq, int len, bool orig) +void SSL_Analyzer::Undelivered(int seq, int len, bool orig) { TCP_ApplicationAnalyzer::Undelivered(seq, len, orig); had_gap = true; diff --git a/src/SSL-binpac.h b/src/SSL.h similarity index 74% rename from src/SSL-binpac.h rename to src/SSL.h index 8dab19d00c..c9f8d9be91 100644 --- a/src/SSL-binpac.h +++ b/src/SSL.h @@ -1,14 +1,13 @@ -#ifndef ssl_binpac_h -#define ssl_binpac_h +#ifndef ssl_h +#define ssl_h #include "TCP.h" - #include "ssl_pac.h" -class SSL_Analyzer_binpac : public TCP_ApplicationAnalyzer { +class SSL_Analyzer : public TCP_ApplicationAnalyzer { public: - SSL_Analyzer_binpac(Connection* conn); - virtual ~SSL_Analyzer_binpac(); + SSL_Analyzer(Connection* conn); + virtual ~SSL_Analyzer(); // Overriden from Analyzer. virtual void Done(); @@ -19,7 +18,7 @@ public: virtual void EndpointEOF(TCP_Reassembler* endp); static Analyzer* InstantiateAnalyzer(Connection* conn) - { return new SSL_Analyzer_binpac(conn); } + { return new SSL_Analyzer(conn); } static bool Available() { diff --git a/src/ssl-analyzer.pac b/src/ssl-analyzer.pac index f41fb8639b..32f060adf4 100644 --- a/src/ssl-analyzer.pac +++ b/src/ssl-analyzer.pac @@ -25,6 +25,7 @@ string orig_label(bool is_orig); void free_X509(void *); X509* d2i_X509_binpac(X509** px, const uint8** in, int len); + string handshake_type_label(int type); %} %code{ @@ -46,6 +47,27 @@ string orig_label(bool is_orig) return d2i_X509(px, (u_char**) in, len); #endif } + + string handshake_type_label(int type) + { + switch ( type ) { + case HELLO_REQUEST: return string("HELLO_REQUEST"); + case CLIENT_HELLO: return string("CLIENT_HELLO"); + case SERVER_HELLO: return string("SERVER_HELLO"); + case SESSION_TICKET: return string("SESSION_TICKET"); + case CERTIFICATE: return string("CERTIFICATE"); + case SERVER_KEY_EXCHANGE: return string("SERVER_KEY_EXCHANGE"); + case CERTIFICATE_REQUEST: return string("CERTIFICATE_REQUEST"); + case SERVER_HELLO_DONE: return string("SERVER_HELLO_DONE"); + case CERTIFICATE_VERIFY: return string("CERTIFICATE_VERIFY"); + case CLIENT_KEY_EXCHANGE: return string("CLIENT_KEY_EXCHANGE"); + case FINISHED: return string("FINISHED"); + case CERTIFICATE_URL: return string("CERTIFICATE_URL"); + case CERTIFICATE_STATUS: return string("CERTIFICATE_STATUS"); + default: return string(fmt("UNKNOWN (%d)", type)); + } + } + %} @@ -88,15 +110,15 @@ refine connection SSL_Conn += { eof=0; %} - %eof{ - if ( ! eof && - state_ != STATE_CONN_ESTABLISHED && - state_ != STATE_TRACK_LOST && - state_ != STATE_INITIAL ) - bro_analyzer()->ProtocolViolation(fmt("unexpected end of connection in state %s", - state_label(state_).c_str())); - ++eof; - %} + #%eof{ + # if ( ! eof && + # state_ != STATE_CONN_ESTABLISHED && + # state_ != STATE_TRACK_LOST && + # state_ != STATE_INITIAL ) + # bro_analyzer()->ProtocolViolation(fmt("unexpected end of connection in state %s", + # state_label(state_).c_str())); + # ++eof; + #%} %cleanup{ %} @@ -133,11 +155,6 @@ refine connection SSL_Conn += { cipher_suites16 : uint16[], cipher_suites24 : uint24[]) : bool %{ - if ( state_ == STATE_TRACK_LOST ) - bro_analyzer()->ProtocolViolation(fmt("unexpected client hello message from %s in state %s", - orig_label(${rec.is_orig}).c_str(), - state_label(old_state_).c_str())); - if ( ! version_ok(version) ) bro_analyzer()->ProtocolViolation(fmt("unsupported client SSL version 0x%04x", version)); @@ -175,11 +192,6 @@ refine connection SSL_Conn += { cipher_suites24 : uint24[], comp_method : uint8) : bool %{ - if ( state_ == STATE_TRACK_LOST ) - bro_analyzer()->ProtocolViolation(fmt("unexpected server hello message from %s in state %s", - orig_label(${rec.is_orig}).c_str(), - state_label(old_state_).c_str())); - if ( ! version_ok(version) ) bro_analyzer()->ProtocolViolation(fmt("unsupported server SSL version 0x%04x", version)); else @@ -229,11 +241,6 @@ refine connection SSL_Conn += { function proc_certificate(rec: SSLRecord, certificates : bytestring[]) : bool %{ - if ( state_ == STATE_TRACK_LOST ) - bro_analyzer()->ProtocolViolation(fmt("unexpected certificate message from %s in state %s", - orig_label(${rec.is_orig}).c_str(), - state_label(old_state_).c_str())); - if ( certificates->size() == 0 ) return true; @@ -362,6 +369,7 @@ refine connection SSL_Conn += { handshake_type_label(${hs.msg_type}).c_str(), orig_label(is_orig).c_str(), state_label(old_state_).c_str())); + return true; %} diff --git a/src/ssl-defs.pac b/src/ssl-defs.pac index 31d90338f5..b13b7c4881 100644 --- a/src/ssl-defs.pac +++ b/src/ssl-defs.pac @@ -17,35 +17,6 @@ enum ContentType { UNKNOWN_OR_V2_ENCRYPTED = 400 }; -%code{ - string* record_type_label(int type) - { - switch ( type ) { - case CHANGE_CIPHER_SPEC: - return new string("CHANGE_CIPHER_SPEC"); - case ALERT: - return new string("ALERT"); - case HANDSHAKE: - return new string("HANDSHAKE"); - case APPLICATION_DATA: - return new string("APPLICATION_DATA"); - case V2_ERROR: - return new string("V2_ERROR"); - case V2_CLIENT_HELLO: - return new string("V2_CLIENT_HELLO"); - case V2_CLIENT_MASTER_KEY: - return new string("V2_CLIENT_MASTER_KEY"); - case V2_SERVER_HELLO: - return new string("V2_SERVER_HELLO"); - case UNKNOWN_OR_V2_ENCRYPTED: - return new string("UNKNOWN_OR_V2_ENCRYPTED"); - - default: - return new string(fmt("UNEXPECTED (%d)", type)); - } - } -%} - enum SSLVersions { UNKNOWN_VERSION = 0x0000, SSLv20 = 0x0002, diff --git a/src/ssl-protocol.pac b/src/ssl-protocol.pac index 5bfa2c51f1..0019478518 100644 --- a/src/ssl-protocol.pac +++ b/src/ssl-protocol.pac @@ -23,7 +23,6 @@ type uint24 = record { string state_label(int state_nr); double get_time_from_asn1(const ASN1_TIME * atime); - string handshake_type_label(int type); %} extern type to_int; @@ -268,28 +267,6 @@ enum HandshakeType { CERTIFICATE_STATUS = 22, # RFC 3546 }; -%code{ - string handshake_type_label(int type) - { - switch ( type ) { - case HELLO_REQUEST: return string("HELLO_REQUEST"); - case CLIENT_HELLO: return string("CLIENT_HELLO"); - case SERVER_HELLO: return string("SERVER_HELLO"); - case SESSION_TICKET: return string("SESSION_TICKET"); - case CERTIFICATE: return string("CERTIFICATE"); - case SERVER_KEY_EXCHANGE: return string("SERVER_KEY_EXCHANGE"); - case CERTIFICATE_REQUEST: return string("CERTIFICATE_REQUEST"); - case SERVER_HELLO_DONE: return string("SERVER_HELLO_DONE"); - case CERTIFICATE_VERIFY: return string("CERTIFICATE_VERIFY"); - case CLIENT_KEY_EXCHANGE: return string("CLIENT_KEY_EXCHANGE"); - case FINISHED: return string("FINISHED"); - case CERTIFICATE_URL: return string("CERTIFICATE_URL"); - case CERTIFICATE_STATUS: return string("CERTIFICATE_STATUS"); - default: return string(fmt("UNKNOWN (%d)", type)); - } - } -%} - ###################################################################### # V3 Change Cipher Spec Protocol (7.1.) diff --git a/testing/btest/Baseline/scripts.base.protocols.ssl.basic/ssl.log b/testing/btest/Baseline/scripts.base.protocols.ssl.basic/ssl.log new file mode 100644 index 0000000000..74156362e5 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.ssl.basic/ssl.log @@ -0,0 +1,8 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path ssl +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p version cipher server_name session_id subject issuer_subject not_valid_before not_valid_after last_alert +#types time string addr port addr port string string string string string string time time string +1335538392.319381 UWkUyAuUGXf 192.168.1.105 62045 74.125.224.79 443 TLSv10 TLS_ECDHE_RSA_WITH_RC4_128_SHA ssl.gstatic.com - CN=*.gstatic.com,O=Google Inc,L=Mountain View,ST=California,C=US CN=Google Internet Authority,O=Google Inc,C=US 1334102677.000000 1365639277.000000 - diff --git a/testing/btest/Traces/tls-conn-with-extensions.trace b/testing/btest/Traces/tls-conn-with-extensions.trace new file mode 100644 index 0000000000000000000000000000000000000000..a3b724b3a184e320a93fb23db4c361672e96bdc5 GIT binary patch literal 24111 zcmb@NWmH|s^7aqz?iSqL-JPI81A*WY++Bl9g1c*QcXtcH-62>A65M&u$=uBU&g9N~ zdb3uqus7#acRyA2tM1;LnckWlZ~!FW*T3gy000blu~3t$q#g?iPz3%AY5)w>C?W^* zPu92=$gluO06^riNCY4Pt<2W-3Cu#ydqe3=7pzq&;s_D+;VSUw=aeP@02~sk4h#YU z3=9kwUT{@(1@t>e@IS0qu0jIjfY+e*huuH=09q#j2rLi-0Nl_WnIOxc9>7}9bc5wj z%78r}WutQ&=PLZPo(KsJ3(w@ikPWg9>4vYlQxcOB6Hf|)K z^>RPd0Qz7OpaOr4_XK1aWHDhK5^w=D25P@q-1WKzS)AbepB8Zg=yh@aY7rX(3{Vaf zxflXWDYa%{m>YH6E%Ukrd2%%^a(1*|t$68aIF2=CR!nIg0Fdc|@4^Ix0zv@10G=+C zE+{}CfU^sx3$6>T3j^o~34kep9l+Lw*oE8$-USIr1c(CN2?b#8g6%>FU;{9^kh&nA zo&oUSz#h4Q!^Z@m0{|$Fj#f-&j!p(n7Dh})w${&JAg{v%U;)qo8~`o=4}bsweSsVR zV0Ze%Uli<6f2#VMzc?01e)_B6Z~iI=`m56q6>tI_`-cWVMVo=XIsvH~EC2=g37a9OS3-aY3^F{zbLIA+P|1(=uXh%C^cV;$Nb0;S|W>zLvpk-(+1OT)e09pkA zk;D=J5yuh${*Vm;4h9Ym&vm(^3Nodv$ASb6M;9y;e2oMK1_cFRkzz$)frExnhlIue zS65}lU_k?2z+=Em+uE90nUKiZ7_pMEkbrJNVBr0E)5*la#>9z4)Y-}0*1^Kbo#h1% z5-S@E2P-QJ3kwH3w>I#S{f|pl&?Sr6|Lg}A176&~%EHvv!N$UX6`KVU)DH{>l7g+X zjgx_e4T*+@iR=F!)PFt z;c7

0saKRqAiTI=Wo%Ykf}={U(yWo|Tp|$g&0v&kWy*6lU$rB8eUTJfY%Z zgkeBmb?k_voyd0g^4rbmicrN{OnH5rt2~jHbM_^fum~Kk$w9e~w--GFF&e9dx-_wE z!gk!6Hp66fNqb|}6s9=fK=*^?1%R2b1b`W^5CJDkLJv7AO89Y{EuHF zLt;Z>_BeEXSq%7^BA2RGZcjv~miXY`G5_IIS(`t6`ln0(={}Q@gB6SE zuYrPrL29#Tv1t6dW&!{I*pCwnKWGwYkQ^**0e|�K$KfApnz($=bxp0mzB}y8GX8 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 Fe*mm9@-P4Z literal 0 HcmV?d00001 diff --git a/testing/btest/scripts/base/protocols/ssl/basic.test b/testing/btest/scripts/base/protocols/ssl/basic.test new file mode 100644 index 0000000000..94b0e87ec1 --- /dev/null +++ b/testing/btest/scripts/base/protocols/ssl/basic.test @@ -0,0 +1,4 @@ +# This tests a normal SSL connection and the log it outputs. + +# @TEST-EXEC: bro -r $TRACES/tls-conn-with-extensions.trace %INPUT +# @TEST-EXEC: btest-diff ssl.log