Merge branch 'master' into fastpath

This commit is contained in:
Jon Siwek 2011-07-23 13:21:14 -05:00
commit d8cbccd0eb
24 changed files with 326 additions and 202 deletions

View file

@ -1,10 +1,19 @@
include(InstallPackageConfigFile)
install(DIRECTORY ./ DESTINATION ${POLICYDIR} FILES_MATCHING install(DIRECTORY ./ DESTINATION ${POLICYDIR} FILES_MATCHING
PATTERN "summaries" EXCLUDE PATTERN "summaries" EXCLUDE
PATTERN "all.bro" EXCLUDE PATTERN "all.bro" EXCLUDE
PATTERN "site/local.bro" EXCLUDE
PATTERN "bro.init" PATTERN "bro.init"
PATTERN "*.bro" PATTERN "*.bro"
PATTERN "*.sig" PATTERN "*.sig"
PATTERN "*.osf" PATTERN "*.osf"
) )
install(DIRECTORY DESTINATION ${POLICYDIR}/site) # Install as a config file since the local.bro script is meant to be
# user modify-able.
InstallPackageConfigFile(
${CMAKE_CURRENT_SOURCE_DIR}/site/local.bro
${POLICYDIR}/site
local.bro)

View file

@ -1275,7 +1275,7 @@ const log_rotate_interval = 0 sec &redef;
# If set, rotate logs at given time + i * log_rotate_interval. # If set, rotate logs at given time + i * log_rotate_interval.
# (string is time in 24h format, e.g., "18:00"). # (string is time in 24h format, e.g., "18:00").
const log_rotate_base_time = "" &redef; const log_rotate_base_time = "0:00" &redef;
# Rotate logs when they reach this size (in bytes). Note, the # Rotate logs when they reach this size (in bytes). Note, the
# parameter is a double rather than a count to enable easy expression # parameter is a double rather than a count to enable easy expression

View file

@ -33,10 +33,6 @@ export {
## connecting to a running instance to update settings or request data. ## connecting to a running instance to update settings or request data.
const control_events = Control::controller_events &redef; const control_events = Control::controller_events &redef;
## Directory where the cluster is archiving logs.
## TODO: we need a sane default here.
const log_dir = "/not/set" &redef;
## Record type to indicate a node in a cluster. ## Record type to indicate a node in a cluster.
type Node: record { type Node: record {
node_type: NodeType; node_type: NodeType;

View file

@ -22,6 +22,5 @@ redef max_remote_events_processed = 10000;
event Notice::notice(n: Notice::Info) event Notice::notice(n: Notice::Info)
{ {
if ( is_remote_event() ) if ( is_remote_event() )
#if ( FilterDuplicates::is_new(n) )
NOTICE(n); NOTICE(n);
} }

View file

@ -14,5 +14,9 @@ redef Log::default_rotation_postprocessor = "delete-log";
# TODO: should we really be setting this to T? # TODO: should we really be setting this to T?
redef record_all_packets = T; redef record_all_packets = T;
# TODO: Workers need to have a filter for the notice log which doesn't # Workers need to have a filter for the notice log which doesn't
# do remote logging since we forward the notice event directly. # do remote logging since we forward the notice event directly.
event bro_init()
{
Log::add_filter(Notice::NOTICE, [$pred(n: Notice::Info) = { return F; }]);
}

View file

@ -5,6 +5,11 @@
##! Intended to be used from the command line like this when starting a controller: ##! Intended to be used from the command line like this when starting a controller:
##! bro <scripts> frameworks/control/controller Control::host=<host_addr> Control::port=<host_port> Control::cmd=<command> [Control::arg=<arg>] ##! bro <scripts> frameworks/control/controller Control::host=<host_addr> Control::port=<host_port> Control::cmd=<command> [Control::arg=<arg>]
##! ##!
##! A controllee only needs to load the controllee script in addition
##! to the specific analysis scripts desired. It may also need a noded
##! configured as a controller node in the communications nodes configuration.
##! bro <scripts> frameworks/control/controllee
##!
##! To use the framework as a controllee, it only needs to be loaded and ##! To use the framework as a controllee, it only needs to be loaded and
##! the controlled node need to accept all events in the "Control::" namespace ##! the controlled node need to accept all events in the "Control::" namespace
##! from the host where the control actions will be performed from along with ##! from the host where the control actions will be performed from along with
@ -21,8 +26,7 @@ export {
## This is the command that is being done. It's typically set on the ## This is the command that is being done. It's typically set on the
## command line and influences whether this instance starts up as a ## command line and influences whether this instance starts up as a
## controller or controllee. If left blank this node will start as a ## controller or controllee.
## controllee and a controller if there is a given command.
const cmd = "" &redef; const cmd = "" &redef;
## This can be used by commands that take an argument. ## This can be used by commands that take an argument.

View file

@ -22,8 +22,12 @@ event Control::peer_status_request()
if ( ! peer$connected ) if ( ! peer$connected )
next; next;
status += fmt("peer=%s host=%s events_in=? events_out=? ops_in=? ops_out=? bytes_in=? bytes_out=?\n", local res = resource_usage();
peer$peer$descr, peer$host); status += fmt("%.6f peer=%s host=%s events_in=%s events_out=%s ops_in=%s ops_out=%s bytes_in=? bytes_out=?\n",
network_time(),
peer$peer$descr, peer$host,
res$num_events_queued, res$num_events_dispatched,
res$blocking_input, res$blocking_output);
} }
event Control::peer_status_response(status); event Control::peer_status_response(status);

View file

@ -1,2 +1,4 @@
@load frameworks/notice/base @load ./base
@load frameworks/notice/weird
# Load the script to add hostnames to emails by default.
@load ./extend-email/hostnames

View file

@ -0,0 +1,9 @@
@load ./main
@load ./weird
# There should be no overhead imposed by loading notice actions so we
# load them all.
@load ./actions/drop
@load ./actions/email_admin
@load ./actions/page

View file

@ -0,0 +1,34 @@
##! This script extends the built in notice code to implement the IP address
##! dropping functionality.
module Notice;
export {
redef enum Action += {
## Drops the address via Drop::drop_address, and generates an alarm.
ACTION_DROP
};
redef record Info += {
## Indicate if the $src IP address was dropped and denied network access.
dropped: bool &log &default=F;
};
}
# This is a little awkward because we want to inject drop along with the
# synchronous functions.
event bro_init()
{
local drop_func = function(n: Notice::Info)
{
if ( ACTION_DROP in n$actions )
{
#local drop = React::drop_address(n$src, "");
#local addl = drop?$sub ? fmt(" %s", drop$sub) : "";
#n$dropped = drop$note != Drop::AddressDropIgnored;
#n$msg += fmt(" [%s%s]", drop$note, addl);
}
};
add Notice::sync_functions[drop_func];
}

View file

@ -0,0 +1,28 @@
module Notice;
export {
redef enum Action += {
## Indicate that the generated email should be addressed to the
## appropriate email addresses as found in the
## :bro:id:`Site::addr_to_emails` variable based on the relevant
## address or addresses indicated in the notice.
ACTION_EMAIL_ADMIN
};
}
event notice(n: Notice::Info) &priority=-5
{
if ( |Site::local_admins| > 0 &&
ACTION_EMAIL_ADMIN in n$actions )
{
local email = "";
if ( n?$src && |Site::get_emails(n$src)| > 0 )
email = fmt("%s, %s", email, Site::get_emails(n$src));
if ( n?$dst && |Site::get_emails(n$dst)| > 0 )
email = fmt("%s, %s", email, Site::get_emails(n$dst));
if ( email != "" )
email_notice_to(n, email, T);
}
}

View file

@ -0,0 +1,19 @@
module Notice;
export {
redef enum Action += {
## Indicates that the notice should be sent to the pager email address
## configured in the :bro:id:`mail_page_dest` variable.
ACTION_PAGE
};
## Email address to send notices with the :bro:enum:`Notice::ACTION_PAGE` action.
const mail_page_dest = "" &redef;
}
event notice(n: Notice::Info) &priority=-5
{
if ( ACTION_PAGE in n$actions )
email_notice_to(n, mail_page_dest, F);
}

View file

@ -16,6 +16,8 @@ export {
## This is the notice policy auditing log. It records what the current ## This is the notice policy auditing log. It records what the current
## notice policy is at Bro init time. ## notice policy is at Bro init time.
NOTICE_POLICY, NOTICE_POLICY,
## This is the alarm stream.
ALARM,
}; };
## Scripts creating new notices need to redef this enum to add their own ## Scripts creating new notices need to redef this enum to add their own
@ -34,26 +36,13 @@ export {
type Action: enum { type Action: enum {
## Indicates that there is no action to be taken. ## Indicates that there is no action to be taken.
ACTION_NONE, ACTION_NONE,
## Indicates that the notice should be sent to the notice file. ## Indicates that the notice should be sent to the notice logging stream.
ACTION_FILE, ACTION_LOG,
## Indicates that the notice should be alarmed on.
ACTION_ALARM,
## Indicates that the notice should be sent to the email address(es) ## Indicates that the notice should be sent to the email address(es)
## configured in the :bro:id:`mail_dest` variable. ## configured in the :bro:id:`Notice::mail_dest` variable.
ACTION_EMAIL, ACTION_EMAIL,
## Indicate that the generated email should be addressed to the ## Indicates that the notice should be alarmed.
## appropriate email addresses as found in the ACTION_ALARM,
## :bro:id:`Site::addr_to_emails` variable based on the originator
## of the connection or the $src field.
ACTION_EMAIL_ADMIN_ORIG,
## Indicate that the generated email should be addressed to the
## appropriate email addresses as found in the
## :bro:id:`Site::addr_to_emails` variable based on the responder
## of the connection or the $dst field.
ACTION_EMAIL_ADMIN_RESP,
## Indicates that the notice should be sent to the pager email address
## configured in the :bro:id:`mail_page_dest` variable.
ACTION_PAGE,
}; };
type Info: record { type Info: record {
@ -61,44 +50,45 @@ export {
uid: string &log &optional; uid: string &log &optional;
id: conn_id &log &optional; id: conn_id &log &optional;
## The victim of the notice. This can be used in cases where there ## These are shorthand ways of giving the uid and id to a notice. The
## is a definite loser for a notice. In cases where there isn't a ## reference to the actual connection will be deleted after applying
## victim, this field should be left empty. ## the notice policy.
victim: addr &log &optional; conn: connection &optional;
iconn: icmp_conn &optional;
## The :bro:enum:`Notice::Type` of the notice. ## The :bro:enum:`Notice::Type` of the notice.
note: Type &log; note: Type &log;
## The human readable message for the notice. ## The human readable message for the notice.
msg: string &log &optional; msg: string &log &optional;
## Sub-message. ## The human readable sub-message.
sub: string &log &optional; sub: string &log &optional;
## Source address, if we don't have a connection. ## Source address, if we don't have a :bro:type:`conn_id`.
src: addr &log &optional; src: addr &log &optional;
## Destination address. ## Destination address.
dst: addr &log &optional; dst: addr &log &optional;
## Associated port, if we don't have a connection. ## Associated port, if we don't have a :bro:type:`conn_id`.
p: port &log &optional; p: port &log &optional;
## Associated count, or perhaps a status code. ## Associated count, or perhaps a status code.
n: count &log &optional; n: count &log &optional;
## Connection associated with the notice.
conn: connection &optional;
## Associated ICMP "connection".
iconn: icmp_conn &optional;
## Peer that raised this notice. ## Peer that raised this notice.
src_peer: event_peer &log &optional; src_peer: event_peer &optional;
## Uniquely identifying tag associated with this notice. ## Textual description for the peer that raised this notice.
tag: string &log &optional; peer_descr: string &log &optional;
## The set of actions that are to be applied to this notice. ## The actions that are to be applied to this notice. The set[count]
## TODO: there is a problem setting a &default=set() attribute ## is to indicate which :bro:id:`Notice::policy` items
## for sets containing enum values. ## triggered the action being added to the notice.
actions: set[Notice::Action] &log &optional; actions: set[Notice::Action] &log &optional;
## These are policy items that returned T and applied their action
## to the notice.
## TODO: this can't take set() as a default. (bug)
policy_items: set[count] &log &optional;
## By adding chunks of text into this element, other scripts can ## By adding chunks of text into this element, other scripts can
## expand on notices that being emailed. The normal way to add text ## expand on notices that are being emailed. The normal way to add text
## is to extend the vector by handling the :bro:id:`Notice::notice` ## is to extend the vector by handling the :bro:id:`Notice::notice`
## event and modifying the notice in place. ## event and modifying the notice in place.
email_body_sections: vector of string &default=vector(); email_body_sections: vector of string &default=vector();
@ -108,9 +98,14 @@ export {
const ignored_types: set[Notice::Type] = {} &redef; const ignored_types: set[Notice::Type] = {} &redef;
## Emailed notice types. ## Emailed notice types.
const emailed_types: set[Notice::Type] = {} &redef; const emailed_types: set[Notice::Type] = {} &redef;
## Alarmed notice types.
const alarmed_types: set[Notice::Type] = {} &redef;
## This is the record that defines the items that make up the notice policy. ## This is the record that defines the items that make up the notice policy.
type PolicyItem: record { type PolicyItem: record {
## This is the exact positional order in which the :id:type:`PolicyItem`
## records are checked. This is set internally by the notice framework.
position: count &log &optional;
## Define the priority for this check. Items are checked in ordered ## Define the priority for this check. Items are checked in ordered
## from highest value (10) to lowest value (0). ## from highest value (10) to lowest value (0).
priority: count &log &default=5; priority: count &log &default=5;
@ -126,31 +121,38 @@ export {
halt: bool &log &default=F; halt: bool &log &default=F;
}; };
# This is the :bro:id:`Notice::policy` where the local notice conversion ## This is the where the :bro:id:`Notice::policy` is defined. All notice
# policy is set. ## processing is done through this variable.
const policy: set[Notice::PolicyItem] = { const policy: set[PolicyItem] = {
[$pred(n: Notice::Info) = { return (n$note in Notice::ignored_types); }, [$pred(n: Notice::Info) = { return (n$note in Notice::ignored_types); },
$halt=T, $priority = 10], $halt=T, $priority = 9],
[$pred(n: Notice::Info) = { return (n$note in Notice::alarmed_types); },
$priority = 8],
[$pred(n: Notice::Info) = { return (n$note in Notice::emailed_types); }, [$pred(n: Notice::Info) = { return (n$note in Notice::emailed_types); },
$result = ACTION_EMAIL, $result = ACTION_EMAIL,
$priority = 9], $priority = 8],
[$pred(n: Notice::Info) = { return T; }, [$pred(n: Notice::Info) = { return T; },
$result = ACTION_FILE, $result = ACTION_LOG,
$priority = 0], $priority = 0],
} &redef; } &redef;
## Local system mail program. ## Local system sendmail program.
const mail_script = "/bin/mail" &redef; const sendmail = "/usr/sbin/sendmail" &redef;
## Email address to send notices with the :bro:enum:`ACTION_EMAIL` action. ## Email address to send notices with the :bro:enum:`ACTION_EMAIL` action.
const mail_dest = "" &redef; const mail_dest = "" &redef;
## Email address to send notices with the :bro:enum:`ACTION_PAGE` action.
const mail_page_dest = "" &redef; ## Address that emails will be from.
const mail_from = "Big Brother <bro@localhost>" &redef;
## Reply-to address used in outbound email.
const reply_to = "" &redef;
## Text string prefixed to the subject of all emails sent out.
const mail_subject_prefix = "[Bro]" &redef;
## This is the event that is called as the entry point to the ## This is the event that is called as the entry point to the
## notice framework by the global :bro:id:`NOTICE` function. By the time ## notice framework by the global :bro:id:`NOTICE` function. By the time
## this event is generated, default values have already been filled out in ## this event is generated, default values have already been filled out in
## the :bro:type:`Notice::Info` record and synchronous functions in the ## the :bro:type:`Notice::Info` record and synchronous functions in the
## :bro:id:`Notice:notice_functions` have already been called. The notice ## :bro:id:`Notice:sync_functions` have already been called. The notice
## policy has also been applied. ## policy has also been applied.
global notice: event(n: Info); global notice: event(n: Info);
@ -165,7 +167,7 @@ export {
## Normally the event based extension model using the ## Normally the event based extension model using the
## :bro:id:`Notice::notice` event will work fine if there aren't harder ## :bro:id:`Notice::notice` event will work fine if there aren't harder
## real time constraints. ## real time constraints.
const notice_functions: set[function(n: Notice::Info)] = set() &redef; const sync_functions: set[function(n: Notice::Info)] = set() &redef;
## Call this function to send a notice in an email. It is already used ## Call this function to send a notice in an email. It is already used
## by default with the built in :bro:enum:`ACTION_EMAIL` and ## by default with the built in :bro:enum:`ACTION_EMAIL` and
@ -189,14 +191,18 @@ global ordered_policy: vector of PolicyItem = vector();
event bro_init() event bro_init()
{ {
Log::create_stream(NOTICE_POLICY, [$columns=PolicyItem]); Log::create_stream(NOTICE_POLICY, [$columns=PolicyItem]);
Log::create_stream(Notice::NOTICE, [$columns=Info, $ev=log_notice]); Log::create_stream(Notice::NOTICE, [$columns=Info, $ev=log_notice]);
# Add a filter to create the alarm log. Log::create_stream(ALARM, [$columns=Notice::Info]);
Log::add_filter(Notice::NOTICE, [$name = "alarm", $path = "alarm", # Make sure that this log is output as text so that it can be packaged
$pred(rec: Notice::Info) = { return (ACTION_ALARM in rec$actions); }]); # up and emailed later.
Log::add_filter(ALARM, [$name="default", $writer=Log::WRITER_ASCII]);
} }
# TODO: need a way to call a Bro script level callback during file rotation.
# we need more than a just $postprocessor.
#redef Log::rotation_control += {
# [Log::WRITER_ASCII, "alarm"] = [$postprocessor="mail-alarms"];
#};
# TODO: fix this. # TODO: fix this.
#function notice_tags(n: Notice::Info) : table[string] of string #function notice_tags(n: Notice::Info) : table[string] of string
@ -221,24 +227,47 @@ function email_notice_to(n: Notice::Info, dest: string, extend: bool)
if ( reading_traces() || dest == "" ) if ( reading_traces() || dest == "" )
return; return;
local email_text = cat(
"From: ", mail_from, "\n",
"Subject: ", mail_subject_prefix, " ", n$note, "\n",
"To: ", dest, "\n",
# TODO: BiF to get version (the resource_usage Bif seems like overkill).
"User-Agent: Bro-IDS/?.?.?\n");
if ( reply_to != "" )
email_text = cat(email_text, "Reply-To: ", reply_to, "\n");
# The notice emails always start off with the human readable message. # The notice emails always start off with the human readable message.
local email_text = n$msg; email_text = cat(email_text, "\n", n$msg, "\n");
# Add the extended information if it's requested.
if ( extend ) if ( extend )
{ {
email_text = cat(email_text, "\n\n------------------\n");
for ( i in n$email_body_sections ) for ( i in n$email_body_sections )
email_text = cat(email_text, n$email_body_sections[i]); {
email_text = cat(email_text, "******************\n");
email_text = cat(email_text, n$email_body_sections[i], "\n");
}
} }
# The contortions here ensure that the arguments to the mail email_text = cat(email_text, "\n\n--\n[Automatically generated]\n\n");
# script will not be confused. Re-evaluate if 'system' is reworked.
local mail_cmd =
fmt("echo \"%s\" | %s -s \"[Bro Alarm] %s\" %s",
str_shell_escape(email_text), mail_script, n$note, dest);
local mail_cmd =
fmt("echo \"%s\" | %s -t -oi %s",
str_shell_escape(email_text), sendmail);
system(mail_cmd); system(mail_cmd);
} }
event notice(n: Notice::Info) &priority=-5
{
if ( ACTION_EMAIL in n$actions )
email_notice_to(n, mail_dest, T);
if ( ACTION_LOG in n$actions )
Log::write(Notice::NOTICE, n);
if ( ACTION_ALARM in n$actions )
Log::write(ALARM, n);
}
# Executes a script with all of the notice fields put into the # Executes a script with all of the notice fields put into the
# new process' environment as "BRO_ARG_<field>" variables. # new process' environment as "BRO_ARG_<field>" variables.
function execute_with_notice(cmd: string, n: Notice::Info) function execute_with_notice(cmd: string, n: Notice::Info)
@ -254,81 +283,65 @@ function execute_with_notice(cmd: string, n: Notice::Info)
function apply_policy(n: Notice::Info) function apply_policy(n: Notice::Info)
{ {
# Fill in some defaults. # Fill in some defaults.
if ( ! n?$ts )
n$ts = network_time(); n$ts = network_time();
if ( n?$conn ) if ( n?$conn )
{ {
if ( ! n?$uid )
n$uid = n$conn$uid;
if ( ! n?$id ) if ( ! n?$id )
n$id = n$conn$id; n$id = n$conn$id;
if ( ! n?$uid )
n$uid = n$conn$uid;
} }
if ( ! n?$src && n?$id ) if ( n?$id )
{
if ( ! n?$src )
n$src = n$id$orig_h; n$src = n$id$orig_h;
if ( ! n?$dst && n?$id ) if ( ! n?$dst )
n$dst = n$id$resp_h; n$dst = n$id$resp_h;
if ( ! n?$p )
if ( ! n?$p && n?$id )
n$p = n$id$resp_p; n$p = n$id$resp_p;
}
if ( ! n?$src && n?$iconn ) if ( n?$iconn )
{
if ( ! n?$src )
n$src = n$iconn$orig_h; n$src = n$iconn$orig_h;
if ( ! n?$dst && n?$iconn ) if ( ! n?$dst )
n$dst = n$iconn$resp_h; n$dst = n$iconn$resp_h;
}
if ( ! n?$src_peer ) if ( ! n?$src_peer )
n$src_peer = get_event_peer(); n$src_peer = get_event_peer();
n$peer_descr = n$src_peer?$descr ? n$src_peer$descr : fmt("%s", n$src_peer$host);
if ( ! n?$actions ) if ( ! n?$actions )
n$actions = set(); n$actions = set();
# Generate a unique ID for this notice. if ( ! n?$policy_items )
n$tag = unique_id("@"); n$policy_items = set();
for ( i in ordered_policy ) for ( i in ordered_policy )
{ {
if ( ordered_policy[i]$pred(n) ) if ( ordered_policy[i]$pred(n) )
{ {
# If the predicate matched, the result of the PolicyItem is added
# to the notices actions.
add n$actions[ordered_policy[i]$result]; add n$actions[ordered_policy[i]$result];
add n$policy_items[int_to_count(i)];
# If the policy item wants to halt policy processing, do it now! # If the policy item wants to halt policy processing, do it now!
if ( ordered_policy[i]$halt ) if ( ordered_policy[i]$halt )
break; break;
} }
} }
}
event notice(n: Notice::Info) &priority=-5 # Delete the connection record if it's there so we aren't sending that
{ # to remote machines. It can cause problems due to the size of the
if ( ACTION_EMAIL in n$actions ) # connection record.
email_notice_to(n, mail_dest, T); if ( n?$conn )
delete n$conn;
if ( ACTION_PAGE in n$actions ) if ( n?$iconn )
email_notice_to(n, mail_page_dest, F); delete n$iconn;
if ( |Site::local_admins| > 0 )
{
local email = "";
if ( n?$src && ACTION_EMAIL_ADMIN_ORIG in n$actions )
{
email = Site::get_emails(n$src);
if ( email != "" )
email_notice_to(n, email, T);
}
if ( n?$dst && ACTION_EMAIL_ADMIN_RESP in n$actions )
{
email = Site::get_emails(n$dst);
if ( email != "" )
email_notice_to(n, email, T);
}
}
if ( ACTION_FILE in n$actions )
Log::write(Notice::NOTICE, n);
} }
# Create the ordered notice policy automatically which will be used at runtime # Create the ordered notice policy automatically which will be used at runtime
@ -357,6 +370,7 @@ event bro_init()
{ {
for ( pi in tmp[j] ) for ( pi in tmp[j] )
{ {
pi$position = |ordered_policy|;
ordered_policy[|ordered_policy|] = pi; ordered_policy[|ordered_policy|] = pi;
Log::write(NOTICE_POLICY, pi); Log::write(NOTICE_POLICY, pi);
} }
@ -373,7 +387,7 @@ function NOTICE(n: Notice::Info)
Notice::apply_policy(n); Notice::apply_policy(n);
# Run the synchronous functions with the notice. # Run the synchronous functions with the notice.
for ( func in Notice::notice_functions ) for ( func in Notice::sync_functions )
func(n); func(n);
# Generate the notice event with the notice. # Generate the notice event with the notice.

View file

@ -1,9 +1,11 @@
@load frameworks/notice/base @load frameworks/notice
@load utils/conn-ids @load utils/conn-ids
module Weird; module Weird;
export { export {
redef enum Log::ID += { WEIRD };
redef enum Notice::Type += { redef enum Notice::Type += {
## Generic unusual but alarm-worthy activity. ## Generic unusual but alarm-worthy activity.
WeirdActivity, WeirdActivity,
@ -15,8 +17,6 @@ export {
ContentGap, ContentGap,
}; };
redef enum Log::ID += { WEIRD };
type Info: record { type Info: record {
ts: time &log; ts: time &log;
uid: string &log &optional; uid: string &log &optional;
@ -59,7 +59,7 @@ export {
["baroque_SYN"] = WEIRD_FILE, ["baroque_SYN"] = WEIRD_FILE,
["base64_illegal_encoding"] = WEIRD_FILE, ["base64_illegal_encoding"] = WEIRD_FILE,
["connection_originator_SYN_ack"] = WEIRD_FILE, ["connection_originator_SYN_ack"] = WEIRD_FILE,
["corrupt_tcp_options"] = WEIRD_FILE, ["corrupt_tcp_options"] = WEIRD_NOTICE_PER_ORIG,
["crud_trailing_HTTP_request"] = WEIRD_FILE, ["crud_trailing_HTTP_request"] = WEIRD_FILE,
["data_after_reset"] = WEIRD_FILE, ["data_after_reset"] = WEIRD_FILE,
["data_before_established"] = WEIRD_FILE, ["data_before_established"] = WEIRD_FILE,
@ -200,10 +200,10 @@ export {
# Code Red generates slews ... # Code Red generates slews ...
["excessively_small_fragment"] = WEIRD_NOTICE_PER_ORIG, ["excessively_small_fragment"] = WEIRD_NOTICE_PER_ORIG,
["fragment_inconsistency"] = WEIRD_NOTICE_ALWAYS, ["fragment_inconsistency"] = WEIRD_NOTICE_PER_ORIG,
["fragment_overlap"] = WEIRD_NOTICE_ALWAYS, ["fragment_overlap"] = WEIRD_NOTICE_PER_ORIG,
["fragment_protocol_inconsistency"] = WEIRD_NOTICE_ALWAYS, ["fragment_protocol_inconsistency"] = WEIRD_NOTICE_ALWAYS,
["fragment_size_inconsistency"] = WEIRD_NOTICE_ALWAYS, ["fragment_size_inconsistency"] = WEIRD_NOTICE_PER_ORIG,
["fragment_with_DF"] = WEIRD_FILE, # these do indeed happen! ["fragment_with_DF"] = WEIRD_FILE, # these do indeed happen!
["incompletely_captured_fragment"] = WEIRD_NOTICE_ALWAYS, ["incompletely_captured_fragment"] = WEIRD_NOTICE_ALWAYS,
@ -217,6 +217,9 @@ export {
# generated by policy script # generated by policy script
["Land_attack"] = WEIRD_NOTICE_PER_ORIG, ["Land_attack"] = WEIRD_NOTICE_PER_ORIG,
["bad_pm_port"] = WEIRD_NOTICE_PER_ORIG, ["bad_pm_port"] = WEIRD_NOTICE_PER_ORIG,
["ICMP-unreachable for wrong state"] = WEIRD_NOTICE_PER_ORIG,
} &redef; } &redef;
# table that maps weird types into a function that should be called # table that maps weird types into a function that should be called

View file

@ -0,0 +1,36 @@
module Notice;
# This probably doesn't actually work due to the async lookup_addr.
event Notice::notice(n: Notice::Info) &priority=10
{
if ( ! n?$src && ! n?$dst )
return;
local output = "";
if ( n?$src )
{
when ( local src_name = lookup_addr(n$src) )
{
output = cat(output, "orig_h/src: ", src_name, "\n");
}
timeout 5secs
{
output = cat(output, "orig_h/src: <timeout>\n");
}
}
if ( n?$dst )
{
when ( local dst_name = lookup_addr(n$dst) )
{
output = cat(output, "resp_h/dst: ", dst_name, "\n");
}
timeout 5secs
{
output = cat(output, "resp_h/dst: <timeout>\n");
}
}
if ( output != "" )
n$email_body_sections[|n$email_body_sections|] = output;
}

View file

@ -44,11 +44,11 @@ export {
## changed however to enable port-independent protocol analysis. ## changed however to enable port-independent protocol analysis.
const all_packets = T &redef; const all_packets = T &redef;
## Filter string which is unconditionally or'ed to every dynamically ## Filter string which is unconditionally or'ed to the beginning of every
## built filter. ## dynamically built filter.
const unrestricted_filter = "" &redef; const unrestricted_filter = "" &redef;
## Call this function to build and install a new dynamically build ## Call this function to build and install a new dynamically built
## packet filter. ## packet filter.
global install: function(); global install: function();

View file

@ -24,8 +24,8 @@ event Control::configuration_update()
if ( g !in disabled ) if ( g !in disabled )
enable_event_group(g); enable_event_group(g);
# Disable those which are not already. # Disable those which are not already disabled.
for ( g in disable_event_group ) for ( g in disabled )
if ( g !in currently_disabled ) if ( g !in currently_disabled )
disable_event_group(g); disable_event_group(g);

View file

@ -5,7 +5,7 @@ module TrimTraceFile;
export { export {
## The interval between times that the output tracefile is rotated. ## The interval between times that the output tracefile is rotated.
const trim_interval = 5 secs &redef; const trim_interval = 10 mins &redef;
## This event can be generated externally to this script if on-demand ## This event can be generated externally to this script if on-demand
## tracefile rotation is required with the caveat that the script doesn't ## tracefile rotation is required with the caveat that the script doesn't

View file

@ -1,4 +1,3 @@
@load protocols/dns/base/consts
module DNS; module DNS;

View file

@ -32,6 +32,11 @@ export {
const root_certs: table[string] of string = {} &redef; const root_certs: table[string] of string = {} &redef;
global log_ssl: event(rec: Info); global log_ssl: event(rec: Info);
const ports = {
443/tcp, 563/tcp, 585/tcp, 614/tcp, 636/tcp,
989/tcp, 990/tcp, 992/tcp, 993/tcp, 995/tcp, 5223/tcp
} &redef;
} }
redef record connection += { redef record connection += {
@ -57,13 +62,8 @@ redef capture_filters += {
["pop3s"] = "tcp port 995" ["pop3s"] = "tcp port 995"
}; };
global ssl_ports = {
443/tcp, 563/tcp, 585/tcp, 614/tcp, 636/tcp,
989/tcp, 990/tcp, 992/tcp, 993/tcp, 995/tcp, 5223/tcp
} &redef;
redef dpd_config += { redef dpd_config += {
[[ANALYZER_SSL]] = [$ports = ssl_ports] [[ANALYZER_SSL]] = [$ports = ports]
}; };
function set_session(c: connection) function set_session(c: connection)

View file

@ -1,8 +1,10 @@
##! Template for local site policy. Customize as appropriate. ##! Local site policy. Customize as appropriate.
# DPD should typically be loaded for detecting protocols on any port. # DPD should typically be loaded. It enables the subsystem for detecting
# protocols on non-standard ports and attaching the appropriate analyzer.
@load frameworks/dpd @load frameworks/dpd
# Load some of the commonly used frameworks.
@load frameworks/notice @load frameworks/notice
@load frameworks/signatures @load frameworks/signatures
@load frameworks/metrics @load frameworks/metrics
@ -14,7 +16,7 @@
@load frameworks/packet-filter/netstats @load frameworks/packet-filter/netstats
@load misc/loaded-scripts @load misc/loaded-scripts
# Load most of the protocol analysis scripts.
@load protocols/conn @load protocols/conn
@load protocols/dns @load protocols/dns
@load protocols/ftp @load protocols/ftp
@ -26,44 +28,5 @@
@load protocols/ssl @load protocols/ssl
@load protocols/syslog @load protocols/syslog
# Apply the default tuning scripts for common tuning settings.
@load tuning/defaults @load tuning/defaults
# Sample notice policy which you will almost certainly want
# to adapt to your environment.
#redef notice_action_filters +=
# {
# # These are all very common.
# #[Weird::ContentGap] = tally_notice_type_and_ignore,
# #[Weird::AckAboveHole] = tally_notice_type_and_ignore,
# #[Weird::RetransmissionInconsistency] = tally_notice_type_and_ignore,
# #[Drop::AddressDropIgnored] = ignore_notice,
# #[Drop::AddressDropped] = ignore_notice,
# #[Weird::WeirdActivity] = file_local_bro_notices,
# #[PacketFilter::DroppedPackets] = file_notice,
# #[TerminateConnection::TerminatingConnectionIgnored] = notice_alarm_per_orig,
# #[ProtocolDetector::ProtocolFound] = file_notice,
# #[ProtocolDetector::ServerFound] = file_if_remote,
# #[DynDisable::ProtocolViolation] = file_notice,
# };
redef Weird::weird_action += {
["window_recision"] = Weird::WEIRD_FILE,
["RST_with_data"] = Weird::WEIRD_FILE,
["line_terminated_with_single_CR"] = Weird::WEIRD_FILE,
["line_terminated_with_single_LF"] = Weird::WEIRD_FILE,
["spontaneous_RST"] = Weird::WEIRD_FILE,
["spontaneous_FIN"] = Weird::WEIRD_FILE,
["data_before_established"] = Weird::WEIRD_FILE,
["unsolicited_SYN_response"] = Weird::WEIRD_FILE,
["inappropriate_FIN"] = Weird::WEIRD_FILE,
["possible_split_routing"] = Weird::WEIRD_FILE,
["connection_originator_SYN_ack"] = Weird::WEIRD_FILE,
["fragment_inconsistency"] = Weird::WEIRD_NOTICE_PER_ORIG,
["fragment_size_inconsistency"] = Weird::WEIRD_NOTICE_PER_ORIG,
["fragment_overlap"] = Weird::WEIRD_NOTICE_PER_ORIG,
["ICMP-unreachable for wrong state"] = Weird::WEIRD_NOTICE_PER_ORIG,
["corrupt_tcp_options"] = Weird::WEIRD_NOTICE_PER_ORIG,
};

View file

@ -1,2 +1,2 @@
@load tuning/defaults/remove-high-volume-notices @load ./remove-high-volume-notices
@load tuning/defaults/packet-fragments @load ./packet-fragments

View file

@ -1,12 +1,13 @@
##! This strives to tune out high volume and less useful data ##! This strives to tune out high volume and less useful data
##! from the notice log. ##! from the notice log.
@load frameworks/notice
# Remove these notices from logging since they can be too noisy. # Remove these notices from logging since they can be too noisy.
redef Notice::ignored_types += { redef Notice::ignored_types += {
Weird::ContentGap, Weird::ContentGap,
Weird::AckAboveHole, Weird::AckAboveHole,
Weird::RetransmissionInconsistency, Weird::RetransmissionInconsistency,
Weird::WeirdActivity, # Only allow these to go in the weird log. ## Only allow these to go in the weird log.
Weird::WeirdActivity,
#DynDisable::ProtocolViolation,
}; };