diff --git a/src/Analyzer.cc b/src/Analyzer.cc index 81f3b6575c..ace543544f 100644 --- a/src/Analyzer.cc +++ b/src/Analyzer.cc @@ -36,6 +36,7 @@ #include "SSH.h" #include "SSLProxy.h" #include "SSL-binpac.h" +#include "Syslog-binpac.h" #include "ConnSizeAnalyzer.h" // Keep same order here as in AnalyzerTag definition! @@ -140,6 +141,9 @@ const Analyzer::Config Analyzer::analyzer_configs[] = { { AnalyzerTag::SSL_BINPAC, "SSL_BINPAC", SSL_Analyzer_binpac::InstantiateAnalyzer, SSL_Analyzer_binpac::Available, 0, false }, + { AnalyzerTag::SYSLOG_BINPAC, "SYSLOG_BINPAC", + Syslog_Analyzer_binpac::InstantiateAnalyzer, + Syslog_Analyzer_binpac::Available, 0, false }, { AnalyzerTag::File, "FILE", File_Analyzer::InstantiateAnalyzer, File_Analyzer::Available, 0, false }, diff --git a/src/AnalyzerTags.h b/src/AnalyzerTags.h index 00ff481413..2ea752036e 100644 --- a/src/AnalyzerTags.h +++ b/src/AnalyzerTags.h @@ -36,7 +36,7 @@ namespace AnalyzerTag { // Application-layer analyzers, binpac-generated. DHCP_BINPAC, DNS_TCP_BINPAC, DNS_UDP_BINPAC, - HTTP_BINPAC, RPC_UDP_BINPAC, SSL_BINPAC, + HTTP_BINPAC, RPC_UDP_BINPAC, SSL_BINPAC, SYSLOG_BINPAC, // Other File, Backdoor, InterConn, SteppingStone, TCPStats, diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index bcf15db597..24b359a4a6 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -201,6 +201,8 @@ binpac_target(ssl.pac ssl-defs.pac ssl-protocol.pac ssl-analyzer.pac) binpac_target(ssl-record-layer.pac ssl-defs.pac ssl.pac) +binpac_target(syslog.pac + syslog-protocol.pac syslog-analyzer.pac) ######################################################################## ## bro target @@ -391,6 +393,7 @@ set(bro_SRCS Stats.cc SteppingStone.cc Stmt.cc + Syslog-binpac.cc TCP.cc TCP_Endpoint.cc TCP_Reassembler.cc diff --git a/src/Syslog-binpac.cc b/src/Syslog-binpac.cc new file mode 100644 index 0000000000..c8697d0f3f --- /dev/null +++ b/src/Syslog-binpac.cc @@ -0,0 +1,90 @@ +#include "Syslog-binpac.h" +#include "TCP_Reassembler.h" + +Syslog_Analyzer_binpac::Syslog_Analyzer_binpac(Connection* conn) +: Analyzer(AnalyzerTag::SYSLOG_BINPAC, conn) + { + interp = new binpac::Syslog::Syslog_Conn(this); + did_session_done = 0; + //ADD_ANALYZER_TIMER(&Syslog_Analyzer_binpac::ExpireTimer, + // network_time + Syslog_session_timeout, 1, TIMER_Syslog_EXPIRE); + } + +Syslog_Analyzer_binpac::~Syslog_Analyzer_binpac() + { + delete interp; + } + +void Syslog_Analyzer_binpac::Done() + { + Analyzer::Done(); + + if ( ! did_session_done ) + Event(udp_session_done); + } + +void Syslog_Analyzer_binpac::DeliverPacket(int len, const u_char* data, bool orig, int seq, const IP_Hdr* ip, int caplen) + { + Analyzer::DeliverPacket(len, data, orig, seq, ip, caplen); + interp->NewData(orig, data, data + len); + } + +//void Syslog_Analyzer_binpac::ExpireTimer(double t) +// { +// // The - 1.0 in the following is to allow 1 second for the +// // common case of a single request followed by a single reply, +// // so we don't needlessly set the timer twice in that case. +// if ( t - Conn()->LastTime() >= Syslog_session_timeout - 1.0 || terminating ) +// { +// Event(connection_timeout); +// sessions->Remove(Conn()); +// } +// else +// ADD_ANALYZER_TIMER(&Syslog_Analyzer_binpac::ExpireTimer, +// t + Syslog_session_timeout, 1, TIMER_Syslog_EXPIRE); +// } + +//Syslog_TCP_Analyzer_binpac::Syslog_TCP_Analyzer_binpac(Connection* conn) +//: TCP_ApplicationAnalyzer(AnalyzerTag::Syslog_TCP_BINPAC, conn) +// { +// interp = new binpac::Syslog_on_TCP::Syslog_TCP_Conn(this); +// } + +//Syslog_TCP_Analyzer_binpac::~Syslog_TCP_Analyzer_binpac() +// { +// delete interp; +// } + +//void Syslog_TCP_Analyzer_binpac::Done() +// { +// TCP_ApplicationAnalyzer::Done(); +// +// interp->FlowEOF(true); +// interp->FlowEOF(false); +// } + +//void Syslog_TCP_Analyzer_binpac::EndpointEOF(TCP_Reassembler* endp) +// { +// TCP_ApplicationAnalyzer::EndpointEOF(endp); +// interp->FlowEOF(endp->IsOrig()); +// } + +//void Syslog_TCP_Analyzer_binpac::DeliverStream(int len, const u_char* data, +// bool orig) +// { +// TCP_ApplicationAnalyzer::DeliverStream(len, data, orig); +// +// assert(TCP()); +// +// if ( TCP()->IsPartial() || TCP()->HadGap(orig) ) +// // punt-on-partial or stop-on-gap. +// return; +// +// interp->NewData(orig, data, data + len); +// } + +//void Syslog_TCP_Analyzer_binpac::Undelivered(int seq, int len, bool orig) +// { +// TCP_ApplicationAnalyzer::Undelivered(seq, len, orig); +// interp->NewGap(orig, len); +// } diff --git a/src/Syslog-binpac.h b/src/Syslog-binpac.h new file mode 100644 index 0000000000..fcd75edf0e --- /dev/null +++ b/src/Syslog-binpac.h @@ -0,0 +1,55 @@ +#ifndef Syslog_binpac_h +#define Syslog_binpac_h + +#include "UDP.h" +#include "TCP.h" + +#include "syslog_pac.h" + +class Syslog_Analyzer_binpac : public Analyzer { +public: + Syslog_Analyzer_binpac(Connection* conn); + virtual ~Syslog_Analyzer_binpac(); + + virtual void Done(); + virtual void DeliverPacket(int len, const u_char* data, bool orig, + int seq, const IP_Hdr* ip, int caplen); + + static Analyzer* InstantiateAnalyzer(Connection* conn) + { return new Syslog_Analyzer_binpac(conn); } + + static bool Available() + { return syslog_message; } + +protected: + friend class AnalyzerTimer; + void ExpireTimer(double t); + + int did_session_done; + + binpac::Syslog::Syslog_Conn* interp; +}; + +// #include "Syslog_tcp_pac.h" +// +//class Syslog_TCP_Analyzer_binpac : public TCP_ApplicationAnalyzer { +//public: +// Syslog_TCP_Analyzer_binpac(Connection* conn); +// virtual ~Syslog_TCP_Analyzer_binpac(); +// +// virtual void Done(); +// virtual void DeliverStream(int len, const u_char* data, bool orig); +// virtual void Undelivered(int seq, int len, bool orig); +// virtual void EndpointEOF(TCP_Reassembler* endp); +// +// static Analyzer* InstantiateAnalyzer(Connection* conn) +// { return new Syslog_TCP_Analyzer_binpac(conn); } +// +// static bool Available() +// { return (Syslog_request || Syslog_full_request) && FLAGS_use_binpac; } +// +//protected: +// binpac::Syslog_on_TCP::Syslog_TCP_Conn* interp; +//}; +// +#endif diff --git a/src/event.bif b/src/event.bif index 74bfaa3e03..d38963d8d1 100644 --- a/src/event.bif +++ b/src/event.bif @@ -388,6 +388,8 @@ event irc_password_message%(c: connection, password: string%); event file_transferred%(c: connection, prefix: string, descr: string, mime_type: string%); event file_virus%(c: connection, virname: string%); +event syslog_message%(c: connection, facility: count, severity: count, msg: string%); + event signature_match%(state: signature_state, msg: string, data: string%); # Generated if a handler finds an identification of the software diff --git a/src/syslog-analyzer.pac b/src/syslog-analyzer.pac new file mode 100644 index 0000000000..6657a63699 --- /dev/null +++ b/src/syslog-analyzer.pac @@ -0,0 +1,27 @@ + +connection Syslog_Conn(bro_analyzer: BroAnalyzer) +{ + upflow = Syslog_Flow; + downflow = Syslog_Flow; +}; + +flow Syslog_Flow +{ + datagram = Syslog_Message withcontext(connection, this); + + function process_syslog_message(m: Syslog_Message): bool + %{ + BifEvent::generate_syslog_message(connection()->bro_analyzer(), + connection()->bro_analyzer()->Conn(), + ${m.PRI.facility}, + ${m.PRI.severity}, + new StringVal(${m.msg}.length(), (const char*) ${m.msg}.begin()) + ); + return true; + %} + +}; + +refine typeattr Syslog_Message += &let { + proc_syslog_message = $context.flow.process_syslog_message(this); +}; diff --git a/src/syslog-protocol.pac b/src/syslog-protocol.pac new file mode 100644 index 0000000000..a2bf8a31da --- /dev/null +++ b/src/syslog-protocol.pac @@ -0,0 +1,15 @@ +type Syslog_Message = record { + PRI: Syslog_Priority; + msg: bytestring &restofdata; +} &byteorder = littleendian; + +type Syslog_Priority = record { + lt : uint8 &check(lt == "<"); + val : RE/[[:digit:]]+/; + gt : uint8 &check(gt == ">"); +} &let { + val_length: int = sizeof(val) - 1; + int_val: int = bytestring_to_int(val, 10); + severity: int = (int_val & 0x07); + facility: int = (int_val & 0x03f8) >> 3; +}; diff --git a/src/syslog.pac b/src/syslog.pac new file mode 100644 index 0000000000..3c0ecfb10d --- /dev/null +++ b/src/syslog.pac @@ -0,0 +1,10 @@ +%include binpac.pac +%include bro.pac + +analyzer Syslog withcontext { + connection: Syslog_Conn; + flow: Syslog_Flow; +}; + +%include syslog-protocol.pac +%include syslog-analyzer.pac