Added the initial syslog analyzer and policy script.

This commit is contained in:
Seth Hall 2010-10-27 15:37:00 -04:00
parent 340805fe00
commit cc7c3776cc
11 changed files with 313 additions and 5 deletions

38
policy/logging.syslog.bro Normal file
View file

@ -0,0 +1,38 @@
@load syslog
module Syslog;
export {
# If set to T, this will split inbound and outbound transactions
# into separate files. F merges everything into a single file.
const split_log_file = F &redef;
# Which SSH logins to record.
# Choices are: Inbound, Outbound, Enabled, Disabled
const logging = Enabled &redef;
}
event bro_init()
{
LOG::create_logs("syslog", logging, split_log_file, T);
LOG::define_header("syslog", cat_sep("\t", "",
"ts",
"orig_h", "orig_p",
"resp_h", "resp_p",
"facility", "severity",
"msg"));
}
event syslog_message(c: connection, facility: count, severity: count, msg: string)
{
local log = LOG::get_file_by_id("syslog", c$id, F);
local id = c$id;
print log, cat_sep("\t", "\\N",
network_time(),
id$orig_h, port_to_count(id$orig_p),
id$resp_h, port_to_count(id$resp_p),
facility_codes[facility], severity_codes[severity],
msg);
}

57
policy/syslog.bro Normal file
View file

@ -0,0 +1,57 @@
redef capture_filters += { ["syslog"] = "port 514" };
global syslog_ports = { 514/udp } &redef;
redef dpd_config += { [ANALYZER_SYSLOG_BINPAC] = [$ports = syslog_ports] };
module Syslog;
export {
redef enum Notice += {
Syslog_New_Source,
Syslog_New_Destination,
};
const facility_codes: table[count] of string = {
[0] = "KERN",
[1] = "USER",
[2] = "MAIL",
[3] = "DAEMON",
[4] = "AUTH",
[5] = "SYSLOG",
[6] = "LPR",
[7] = "NEWS",
[8] = "UUCP",
[9] = "CRON",
[10] = "AUTHPRIV",
[11] = "FTP",
[12] = "NTP",
[13] = "AUDIT",
[14] = "ALERT",
[15] = "CLOCK",
[16] = "LOCAL0",
[17] = "LOCAL1",
[18] = "LOCAL2",
[19] = "LOCAL3",
[20] = "LOCAL4",
[21] = "LOCAL5",
[22] = "LOCAL6",
[23] = "LOCAL7",
};
const severity_codes: table[count] of string = {
[0] = "EMERG",
[1] = "ALERT",
[2] = "CRIT",
[3] = "ERR",
[4] = "WARNING",
[5] = "NOTICE",
[6] = "INFO",
[7] = "DEBUG",
};
}
event syslog_message(c: connection, facility: count, severity: count, msg: string)
{
}

View file

@ -36,6 +36,7 @@
#include "SSH.h"
#include "SSLProxy.h"
#include "SSL-binpac.h"
#include "Syslog-binpac.h"
// Keep same order here as in AnalyzerTag definition!
const Analyzer::Config Analyzer::analyzer_configs[] = {
@ -138,6 +139,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 },

View file

@ -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,

View file

@ -31,7 +31,7 @@ bifcl_SOURCES = bif_lex.cc bif_parse.cc bif_arg.cc
BINPAC_SRC = binpac-lib.pac binpac_bro-lib.pac bittorrent.pac \
dce_rpc.pac dce_rpc_simple.pac dhcp.pac dns.pac \
dns_tcp.pac http.pac ncp.pac netflow.pac rpc.pac smb.pac \
ssl.pac ssl-record-layer.pac
ssl.pac ssl-record-layer.pac syslog.pac
BINPAC_H = $(BINPAC_SRC:.pac=_pac.h)
BINPAC_CC = $(BINPAC_SRC:.pac=_pac.cc)
@ -49,7 +49,8 @@ BINPAC_RPC_AUXSRC = \
rpc-protocol.pac rpc-analyzer.pac \
smb-protocol.pac smb-mailslot.pac smb-pipe.pac \
ssl.pac ssl-analyzer.pac ssl-defs.pac \
ssl-protocol.pac ssl-record-layer.pac
ssl-protocol.pac ssl-record-layer.pac \
syslog.pac syslog-protocol.pac syslog-analyzer.pac
BINPAC = @BINPAC@
BINPAC_FLAGS = -d $(top_builddir)/src -I $(srcdir)
@ -129,7 +130,7 @@ bro_SOURCES = \
Queue.cc RE.cc RPC.cc Reassem.cc RemoteSerializer.cc Rlogin.cc RSH.cc \
Rule.cc RuleAction.cc RuleCondition.cc RuleMatcher.cc \
ScriptAnaly.cc SmithWaterman.cc SMB.cc SMTP.cc \
SSH.cc SSL-binpac.cc \
SSH.cc SSL-binpac.cc Syslog-binpac.cc \
Scope.cc SerializationFormat.cc SerialObj.cc Serializer.cc \
Sessions.cc StateAccess.cc Stats.cc SteppingStone.cc Stmt.cc \
TCP.cc TCP_Endpoint.cc TCP_Reassembler.cc TCP_Rewriter.cc \
@ -165,7 +166,7 @@ noinst_HEADERS = Active.h Analyzer.h AnalyzerTags.h Anon.h ARP.h Attr.h \
SSLInterpreter.h SSLProxy.h SSLv2.h SSLv3.h SSLv3Automaton.h Scope.h \
SerialInfo.h SerialObj.h SerialTypes.h \
SerializationFormat.h Serializer.h Sessions.h StateAccess.h \
Stats.h SteppingStone.h Stmt.h StmtEnums.h \
Stats.h SteppingStone.h Stmt.h StmtEnums.h Syslog-binpac.h \
TCP.h TCP_Endpoint.h TCP_Reassembler.h TCP_Rewriter.h Telnet.h Timer.h \
Traverse.h TraverseTypes.h Trigger.h TwoWise.h Type.h UDP.h \
Val.h Var.h X509.h XDR.h ZIP.h \
@ -331,6 +332,10 @@ ssl_pac.h ssl_pac.cc: ssl.pac $(BINPAC) $(BINPAC_AUXSRC) $(BINPAC_AUXHDR) ssl-pr
ssl-record-layer_pac.h ssl-record-layer_pac.cc: ssl-record-layer.pac $(BINPAC) $(BINPAC_AUXSRC) $(BINPAC_AUXHDR)
$(BINPAC) $(BINPAC_FLAGS) $(srcdir)/ssl-record-layer.pac
syslog_pac.h syslog_pac.cc: syslog.pac $(BINPAC) $(BINPAC_AUXSRC) $(BINPAC_AUXHDR) syslog-protocol.pac syslog-analyzer.pac
$(BINPAC) $(BINPAC_FLAGS) $(srcdir)/syslog.pac
patricia.o: patricia.c patricia.h
$(CC) $(CFLAGS) -c $(srcdir)/patricia.c

92
src/Syslog-binpac.cc Normal file
View file

@ -0,0 +1,92 @@
// $Id:$
#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);
// }

58
src/Syslog-binpac.h Normal file
View file

@ -0,0 +1,58 @@
// $Id:$
#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 true; }
//{ return (Syslog_request || Syslog_full_request) && FLAGS_use_binpac; }
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

View file

@ -392,6 +392,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

27
src/syslog-analyzer.pac Normal file
View file

@ -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
%{
bro_event_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);
};

15
src/syslog-protocol.pac Normal file
View file

@ -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;
};

10
src/syslog.pac Normal file
View file

@ -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