diff --git a/src/analyzer/protocol/irc/IRC.cc b/src/analyzer/protocol/irc/IRC.cc index d621ce2cce..2ed04ee6b1 100644 --- a/src/analyzer/protocol/irc/IRC.cc +++ b/src/analyzer/protocol/irc/IRC.cc @@ -2,7 +2,6 @@ #include #include "IRC.h" -#include "analyzer/protocol/tcp/ContentLine.h" #include "NetVar.h" #include "Event.h" #include "analyzer/protocol/zip/ZIP.h" @@ -21,8 +20,11 @@ IRC_Analyzer::IRC_Analyzer(Connection* conn) resp_status = WAIT_FOR_REGISTRATION; orig_zip_status = NO_ZIP; resp_zip_status = NO_ZIP; - AddSupportAnalyzer(new tcp::ContentLine_Analyzer(conn, true)); - AddSupportAnalyzer(new tcp::ContentLine_Analyzer(conn, false)); + starttls = false; + cl_orig = new tcp::ContentLine_Analyzer(conn, true); + AddSupportAnalyzer(cl_orig); + cl_resp = new tcp::ContentLine_Analyzer(conn, false); + AddSupportAnalyzer(cl_resp); } void IRC_Analyzer::Done() @@ -34,6 +36,12 @@ void IRC_Analyzer::DeliverStream(int length, const u_char* line, bool orig) { tcp::TCP_ApplicationAnalyzer::DeliverStream(length, line, orig); + if ( starttls ) + { + ForwardStream(length, line, orig); + return; + } + // check line size if ( length > 512 ) { @@ -98,6 +106,11 @@ void IRC_Analyzer::DeliverStream(int length, const u_char* line, bool orig) } else { // get command + + // special case that has no arguments + if ( myline == "STARTTLS" ) + return; + unsigned int pos = myline.find(' '); if ( pos > (unsigned int) length ) { @@ -556,6 +569,10 @@ void IRC_Analyzer::DeliverStream(int length, const u_char* line, bool orig) } break; + case 670: + // StartTLS success reply to StartTLS + StartTLS(); + // All other server replies. default: val_list* vl = new val_list; @@ -1169,6 +1186,25 @@ void IRC_Analyzer::DeliverStream(int length, const u_char* line, bool orig) return; } +void IRC_Analyzer::StartTLS() + { + // STARTTLS was succesful. Remove support analyzers, add SSL + // analyzer, and throw event signifying the change. + starttls = true; + + RemoveSupportAnalyzer(cl_orig); + RemoveSupportAnalyzer(cl_resp); + + Analyzer* ssl = analyzer_mgr->InstantiateAnalyzer("SSL", Conn()); + if ( ssl ) + AddChildAnalyzer(ssl); + + val_list* vl = new val_list; + vl->append(BuildConnVal()); + + ConnectionEvent(irc_starttls, vl); + } + vector IRC_Analyzer::SplitWords(const string input, const char split) { vector words; diff --git a/src/analyzer/protocol/irc/IRC.h b/src/analyzer/protocol/irc/IRC.h index bce9cdf054..82a97a4d4d 100644 --- a/src/analyzer/protocol/irc/IRC.h +++ b/src/analyzer/protocol/irc/IRC.h @@ -3,6 +3,7 @@ #ifndef ANALYZER_PROTOCOL_IRC_IRC_H #define ANALYZER_PROTOCOL_IRC_IRC_H #include "analyzer/protocol/tcp/TCP.h" +#include "analyzer/protocol/tcp/ContentLine.h" namespace analyzer { namespace irc { @@ -44,6 +45,8 @@ protected: int resp_zip_status; private: + void StartTLS(); + /** \brief counts number of invalid IRC messages */ int invalid_msg_count; @@ -60,6 +63,9 @@ private: */ vector SplitWords(const string input, const char split); + tcp::ContentLine_Analyzer* cl_orig; + tcp::ContentLine_Analyzer* cl_resp; + bool starttls; // if true, connection has been upgraded to tls }; } } // namespace analyzer::* diff --git a/src/analyzer/protocol/irc/events.bif b/src/analyzer/protocol/irc/events.bif index 4e69b9ad33..be425817b2 100644 --- a/src/analyzer/protocol/irc/events.bif +++ b/src/analyzer/protocol/irc/events.bif @@ -797,3 +797,10 @@ event irc_user_message%(c: connection, is_orig: bool, user: string, host: string ## irc_nick_message irc_notice_message irc_oper_message irc_oper_response ## irc_part_message event irc_password_message%(c: connection, is_orig: bool, password: string%); + +## Generated if an IRC connection switched to TLS using STARTTLS. After this +## event no more IRC events will be raised for the connection. See the SSL +## analyzer for related SSL events, which will now be generated. +## +## c: The connection. +event irc_starttls%(c: connection%); diff --git a/testing/btest/Baseline/scripts.base.protocols.irc.starttls/conn.log b/testing/btest/Baseline/scripts.base.protocols.irc.starttls/conn.log new file mode 100644 index 0000000000..a4f9d436d6 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.irc.starttls/conn.log @@ -0,0 +1,10 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path conn +#open 2015-07-29-18-47-29 +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p proto service duration orig_bytes resp_bytes conn_state local_orig local_resp missed_bytes history orig_pkts orig_ip_bytes resp_pkts resp_ip_bytes tunnel_parents +#types time string addr port addr port enum string interval count count string bool bool count string count count count count set[string] +1438145937.325196 CXWv6p3arKYeMETxOg 203.143.168.47 55123 185.18.76.170 6667 tcp irc,ssl 4.923144 913 1903 SF - - 0 ShADadFRf 11 1469 9 2379 (empty) +#close 2015-07-29-18-47-29 diff --git a/testing/btest/Baseline/scripts.base.protocols.irc.starttls/ssl.log b/testing/btest/Baseline/scripts.base.protocols.irc.starttls/ssl.log new file mode 100644 index 0000000000..41a49a16cc --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.irc.starttls/ssl.log @@ -0,0 +1,10 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path ssl +#open 2015-07-29-18-47-29 +#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 +1438145937.994419 CXWv6p3arKYeMETxOg 203.143.168.47 55123 185.18.76.170 6667 TLSv12 TLS_RSA_WITH_AES_256_GCM_SHA384 - - F - - T Fyz2bd3loV0LDM3r95 (empty) CN=irc.joulunet.org,OU=IRCd,O=Multim,L=Pori,ST=Pori,C=FI CN=irc.joulunet.org,OU=IRCd,O=Multim,L=Pori,ST=Pori,C=FI - - +#close 2015-07-29-18-47-29 diff --git a/testing/btest/Baseline/scripts.base.protocols.irc.starttls/x509.log b/testing/btest/Baseline/scripts.base.protocols.irc.starttls/x509.log new file mode 100644 index 0000000000..957d807f9e --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.irc.starttls/x509.log @@ -0,0 +1,10 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path x509 +#open 2015-07-29-18-47-29 +#fields ts id certificate.version certificate.serial certificate.subject certificate.issuer certificate.not_valid_before certificate.not_valid_after certificate.key_alg certificate.sig_alg certificate.key_type certificate.key_length certificate.exponent certificate.curve san.dns san.uri san.email san.ip basic_constraints.ca basic_constraints.path_len +#types time string count string string string time time string string string count string string vector[string] vector[string] vector[string] vector[addr] bool count +1438145938.995683 Fyz2bd3loV0LDM3r95 3 F9435743EF353D9E CN=irc.joulunet.org,OU=IRCd,O=Multim,L=Pori,ST=Pori,C=FI CN=irc.joulunet.org,OU=IRCd,O=Multim,L=Pori,ST=Pori,C=FI 1436555613.000000 1751915613.000000 rsaEncryption sha256WithRSAEncryption rsa 4096 65537 - - - - - T - +#close 2015-07-29-18-47-29 diff --git a/testing/btest/Traces/tls/irc-starttls.pcap b/testing/btest/Traces/tls/irc-starttls.pcap new file mode 100644 index 0000000000..77b244685f Binary files /dev/null and b/testing/btest/Traces/tls/irc-starttls.pcap differ diff --git a/testing/btest/scripts/base/protocols/irc/starttls.test b/testing/btest/scripts/base/protocols/irc/starttls.test new file mode 100644 index 0000000000..c110a77c39 --- /dev/null +++ b/testing/btest/scripts/base/protocols/irc/starttls.test @@ -0,0 +1,9 @@ +# @TEST-EXEC: bro -b -C -r $TRACES/tls/irc-starttls.pcap %INPUT +# @TEST-EXEC: btest-diff conn.log +# @TEST-EXEC: btest-diff ssl.log +# @TEST-EXEC: btest-diff x509.log + +@load base/protocols/conn +@load base/frameworks/dpd +@load base/protocols/ssl +@load base/protocols/irc