diff --git a/scripts/base/protocols/krb/main.bro b/scripts/base/protocols/krb/main.bro index cc133e36d6..8294477671 100644 --- a/scripts/base/protocols/krb/main.bro +++ b/scripts/base/protocols/krb/main.bro @@ -71,12 +71,14 @@ redef record connection += { krb: Info &optional; }; -const ports = { 88/udp }; +const udp_ports = { 88/udp, 750/udp }; +const tcp_ports = { 88/tcp, 750/tcp }; event bro_init() &priority=5 { Log::create_stream(KRB::LOG, [$columns=Info, $ev=log_krb]); - Analyzer::register_for_ports(Analyzer::ANALYZER_KRB, ports); + Analyzer::register_for_ports(Analyzer::ANALYZER_KRB, udp_ports); + Analyzer::register_for_ports(Analyzer::ANALYZER_KRB_TCP, tcp_ports); } event krb_error(c: connection, msg: Error_Msg) diff --git a/src/analyzer/protocol/krb/CMakeLists.txt b/src/analyzer/protocol/krb/CMakeLists.txt index 05b7c575d2..03e10212f8 100644 --- a/src/analyzer/protocol/krb/CMakeLists.txt +++ b/src/analyzer/protocol/krb/CMakeLists.txt @@ -1,4 +1,3 @@ - include(BroPlugin) include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR} @@ -10,3 +9,8 @@ bro_plugin_bif(types.bif) bro_plugin_bif(events.bif) bro_plugin_pac(krb.pac krb-protocol.pac krb-analyzer.pac) bro_plugin_end() + +bro_plugin_begin(Bro KRB_TCP) +bro_plugin_cc(KRB_TCP.cc Plugin_TCP.cc) +bro_plugin_pac(krb_TCP.pac krb-protocol.pac krb-analyzer.pac) +bro_plugin_end() diff --git a/src/analyzer/protocol/krb/KRB_TCP.cc b/src/analyzer/protocol/krb/KRB_TCP.cc new file mode 100644 index 0000000000..229c4c5e8b --- /dev/null +++ b/src/analyzer/protocol/krb/KRB_TCP.cc @@ -0,0 +1,66 @@ +// See the file "COPYING" in the main distribution directory for copyright. + +#include "KRB_TCP.h" +#include "analyzer/protocol/tcp/TCP_Reassembler.h" +#include "types.bif.h" +#include "events.bif.h" + +using namespace analyzer::krb_tcp; + +KRB_Analyzer::KRB_Analyzer(Connection* conn) + : tcp::TCP_ApplicationAnalyzer("KRB_TCP", conn) + { + interp = new binpac::KRB_TCP::KRB_Conn(this); + had_gap = false; + } + +KRB_Analyzer::~KRB_Analyzer() + { + delete interp; + } + +void KRB_Analyzer::Done() + { + tcp::TCP_ApplicationAnalyzer::Done(); + + interp->FlowEOF(true); + interp->FlowEOF(false); + } + +void KRB_Analyzer::EndpointEOF(bool is_orig) + { + tcp::TCP_ApplicationAnalyzer::EndpointEOF(is_orig); + interp->FlowEOF(is_orig); + } + +void KRB_Analyzer::DeliverStream(int len, const u_char* data, bool orig) + { + tcp::TCP_ApplicationAnalyzer::DeliverStream(len, data, orig); + + assert(TCP()); + if ( TCP()->IsPartial() ) + return; + + if ( had_gap ) + // 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; + + try + { + interp->NewData(orig, data, data + len); + } + catch ( const binpac::Exception& e ) + { + printf("BinPAC Exception: %s\n", e.c_msg()); + ProtocolViolation(e.c_msg()); + } + } + +void KRB_Analyzer::Undelivered(uint64 seq, int len, bool orig) + { + tcp::TCP_ApplicationAnalyzer::Undelivered(seq, len, orig); + had_gap = true; + interp->NewGap(orig, len); + } diff --git a/src/analyzer/protocol/krb/KRB_TCP.h b/src/analyzer/protocol/krb/KRB_TCP.h new file mode 100644 index 0000000000..0052c25e8d --- /dev/null +++ b/src/analyzer/protocol/krb/KRB_TCP.h @@ -0,0 +1,37 @@ +// See the file "COPYING" in the main distribution directory for copyright. + +#ifndef ANALYZER_PROTOCOL_KRB_KRB_TCP_H +#define ANALYZER_PROTOCOL_KRB_KRB_TCP_H + +#include "analyzer/protocol/tcp/TCP.h" + +#include "krb_TCP_pac.h" + +namespace analyzer { namespace krb_tcp { + +class KRB_Analyzer : public tcp::TCP_ApplicationAnalyzer { + +public: + + KRB_Analyzer(Connection* conn); + virtual ~KRB_Analyzer(); + + virtual void Done(); + virtual void DeliverStream(int len, const u_char* data, bool orig); + virtual void Undelivered(uint64 seq, int len, bool orig); + + // Overriden from tcp::TCP_ApplicationAnalyzer. + virtual void EndpointEOF(bool is_orig); + + static analyzer::Analyzer* Instantiate(Connection* conn) + { return new KRB_Analyzer(conn); } + +protected: + + binpac::KRB_TCP::KRB_Conn* interp; + bool had_gap; +}; + +} } // namespace analyzer::* + +#endif diff --git a/src/analyzer/protocol/krb/Plugin_TCP.cc b/src/analyzer/protocol/krb/Plugin_TCP.cc new file mode 100644 index 0000000000..de96542088 --- /dev/null +++ b/src/analyzer/protocol/krb/Plugin_TCP.cc @@ -0,0 +1,20 @@ +//See the file in the main distribution directory for copyright. + +#include "plugin/Plugin.h" +#include "KRB_TCP.h" + +namespace plugin { + namespace Bro_KRB_TCP { + class Plugin : public plugin::Plugin { + public: + plugin::Configuration Configure() + { + AddComponent(new ::analyzer::Component("KRB_TCP", ::analyzer::krb_tcp::KRB_Analyzer::Instantiate)); + plugin::Configuration config; + config.name = "Bro::KRB_TCP"; + config.description = "Kerberos analyzer (TCP)"; + return config; + } + } plugin; + } +} diff --git a/src/analyzer/protocol/krb/krb-analyzer.pac b/src/analyzer/protocol/krb/krb-analyzer.pac index 14cbcbe710..3034c4e696 100644 --- a/src/analyzer/protocol/krb/krb-analyzer.pac +++ b/src/analyzer/protocol/krb/krb-analyzer.pac @@ -1,12 +1,3 @@ -connection KRB_Conn(bro_analyzer: BroAnalyzer) { - upflow = KRB_Flow(true); - downflow = KRB_Flow(false); -}; - -flow KRB_Flow(is_orig: bool) { - datagram = KRB_PDU withcontext(connection, this); -}; - %header{ Val* GetTimeFromAsn1(const KRB_Time* atime); Val* GetTimeFromAsn1(StringVal* atime); @@ -111,6 +102,7 @@ refine connection KRB_Conn += { function proc_krb_kdc_req(msg: KRB_KDC_REQ): bool %{ + bro_analyzer()->ProtocolConfirmation(); if ( ( binary_to_int64(${msg.msg_type.data.content}) == 10 ) && ! krb_as_req ) return false; @@ -266,6 +258,7 @@ refine connection KRB_Conn += { function proc_krb_kdc_rep(msg: KRB_KDC_REP): bool %{ + bro_analyzer()->ProtocolConfirmation(); if ( ( binary_to_int64(${msg.msg_type.data.content}) == 11 ) && ! krb_as_rep ) return false; @@ -337,18 +330,21 @@ refine connection KRB_Conn += { function proc_krb_ap_req(msg: KRB_AP_REQ): bool %{ - // Not implemented - return true; + bro_analyzer()->ProtocolConfirmation(); + // Not implemented + return true; %} function proc_krb_ap_rep(msg: KRB_AP_REP): bool %{ - // Not implemented - return true; + bro_analyzer()->ProtocolConfirmation(); + // Not implemented + return true; %} function proc_krb_error_msg(msg: KRB_ERROR_MSG): bool %{ + bro_analyzer()->ProtocolConfirmation(); if ( krb_error ) { RecordVal* rv = new RecordVal(BifType::Record::KRB::Error_Msg); @@ -431,20 +427,23 @@ refine connection KRB_Conn += { function proc_krb_safe_msg(msg: KRB_SAFE_MSG): bool %{ - // Not implemented - return true; + bro_analyzer()->ProtocolConfirmation(); + // Not implemented + return true; %} function proc_krb_priv_msg(msg: KRB_PRIV_MSG): bool - %{ - // Not implemented - return true; + %{ + bro_analyzer()->ProtocolConfirmation(); + // Not implemented + return true; %} function proc_krb_cred_msg(msg: KRB_CRED_MSG): bool %{ - // Not implemented - return true; + bro_analyzer()->ProtocolConfirmation(); + // Not implemented + return true; %} function debug_req_arg(msg: KRB_REQ_Arg_Data): bool diff --git a/src/analyzer/protocol/krb/krb-protocol.pac b/src/analyzer/protocol/krb/krb-protocol.pac index 2ba591168b..212342e423 100644 --- a/src/analyzer/protocol/krb/krb-protocol.pac +++ b/src/analyzer/protocol/krb/krb-protocol.pac @@ -13,6 +13,11 @@ enum KRBMessageTypes { KRB_ERROR = 30, }; +type KRB_PDU_TCP = record { + size: uint32; + pdu : KRB_PDU; +} &length=size+4 &byteorder=bigendian; + type KRB_PDU = record { app_meta : ASN1EncodingMeta; msg_type : case (app_meta.tag - 96) of { diff --git a/src/analyzer/protocol/krb/krb.pac b/src/analyzer/protocol/krb/krb.pac index c2e83be19b..2092877d5d 100644 --- a/src/analyzer/protocol/krb/krb.pac +++ b/src/analyzer/protocol/krb/krb.pac @@ -11,5 +11,15 @@ analyzer KRB withcontext { flow: KRB_Flow; }; +connection KRB_Conn(bro_analyzer: BroAnalyzer) { + upflow = KRB_Flow(true); + downflow = KRB_Flow(false); +}; + %include krb-protocol.pac + +flow KRB_Flow(is_orig: bool) { + datagram = KRB_PDU withcontext(connection, this); +}; + %include krb-analyzer.pac diff --git a/src/analyzer/protocol/krb/krb_TCP.pac b/src/analyzer/protocol/krb/krb_TCP.pac new file mode 100644 index 0000000000..d2efd628e4 --- /dev/null +++ b/src/analyzer/protocol/krb/krb_TCP.pac @@ -0,0 +1,25 @@ +%include binpac.pac +%include bro.pac + +%extern{ +#include "types.bif.h" +#include "events.bif.h" +%} + +analyzer KRB_TCP withcontext { + connection: KRB_Conn; + flow: KRB_Flow; +}; + +connection KRB_Conn(bro_analyzer: BroAnalyzer) { + upflow = KRB_Flow(true); + downflow = KRB_Flow(false); +}; + +%include krb-protocol.pac + +flow KRB_Flow(is_orig: bool) { + flowunit = KRB_PDU_TCP withcontext(connection, this); +}; + +%include krb-analyzer.pac