mirror of
https://github.com/zeek/zeek.git
synced 2025-10-05 16:18:19 +00:00
Merge branch 'topic/script-reference' of ssh://git.bro-ids.org/bro into topic/script-reference
Conflicts: scripts/base/frameworks/notice/actions/pp-alarms.bro scripts/base/frameworks/notice/main.bro src/bro.bif src/const.bif src/event.bif src/strings.bif src/types.bif
This commit is contained in:
commit
e5a42e8a85
56 changed files with 691 additions and 368 deletions
|
@ -1,43 +1,30 @@
|
|||
##! This is a utility script that sends the current values of all &redef'able
|
||||
##! consts to a remote Bro then sends the
|
||||
##! :bro:id:`Control::configuration_update` event and terminates processing.
|
||||
##!
|
||||
##! 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>]
|
||||
##!
|
||||
##! A controllee only needs to load the controllee script in addition
|
||||
##! to the specific analysis scripts desired. It may also need a node
|
||||
##! 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
|
||||
##! 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
|
||||
##! using the "control" class.
|
||||
##! The control framework provides the foundation for providing "commands"
|
||||
##! that can be taken remotely at runtime to modify a running Bro instance
|
||||
##! or collect information from the running instance.
|
||||
|
||||
module Control;
|
||||
|
||||
export {
|
||||
## This is the address of the host that will be controlled.
|
||||
## The address of the host that will be controlled.
|
||||
const host = 0.0.0.0 &redef;
|
||||
|
||||
## This is the port of the host that will be controlled.
|
||||
## The port of the host that will be controlled.
|
||||
const host_port = 0/tcp &redef;
|
||||
|
||||
## 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
|
||||
## controller or controllee.
|
||||
## The command that is being done. It's typically set on the
|
||||
## command line.
|
||||
const cmd = "" &redef;
|
||||
|
||||
## This can be used by commands that take an argument.
|
||||
const arg = "" &redef;
|
||||
|
||||
## Events that need to be handled by controllers.
|
||||
const controller_events = /Control::.*_request/ &redef;
|
||||
|
||||
## Events that need to be handled by controllees.
|
||||
const controllee_events = /Control::.*_response/ &redef;
|
||||
|
||||
## These are the commands that can be given on the command line for
|
||||
## The commands that can currently be given on the command line for
|
||||
## remote control.
|
||||
const commands: set[string] = {
|
||||
"id_value",
|
||||
|
@ -45,11 +32,10 @@ export {
|
|||
"net_stats",
|
||||
"configuration_update",
|
||||
"shutdown",
|
||||
};
|
||||
} &redef;
|
||||
|
||||
## Variable IDs that are to be ignored by the update process.
|
||||
const ignore_ids: set[string] = {
|
||||
};
|
||||
const ignore_ids: set[string] = { };
|
||||
|
||||
## Event for requesting the value of an ID (a variable).
|
||||
global id_value_request: event(id: string);
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
# user_name
|
||||
# file_name
|
||||
# file_md5
|
||||
# x509_cert - DER encoded, not PEM (ascii armored)
|
||||
# x509_md5
|
||||
|
||||
# Example tags:
|
||||
# infrastructure
|
||||
|
@ -25,6 +25,7 @@
|
|||
module Intel;
|
||||
|
||||
export {
|
||||
## The intel logging stream identifier.
|
||||
redef enum Log::ID += { LOG };
|
||||
|
||||
redef enum Notice::Type += {
|
||||
|
@ -33,72 +34,117 @@ export {
|
|||
Detection,
|
||||
};
|
||||
|
||||
## Record type used for logging information from the intelligence framework.
|
||||
## Primarily for problems or oddities with inserting and querying data.
|
||||
## This is important since the content of the intelligence framework can
|
||||
## change quite dramatically during runtime and problems may be introduced
|
||||
## into the data.
|
||||
type Info: record {
|
||||
## The current network time.
|
||||
ts: time &log;
|
||||
## Represents the severity of the message.
|
||||
## This value should be one of: "info", "warn", "error"
|
||||
level: string &log;
|
||||
## The message.
|
||||
message: string &log;
|
||||
};
|
||||
|
||||
## Record to represent metadata associated with a single piece of
|
||||
## intelligence.
|
||||
type MetaData: record {
|
||||
## A description for the data.
|
||||
desc: string &optional;
|
||||
## A URL where more information may be found about the intelligence.
|
||||
url: string &optional;
|
||||
## The time at which the data was first declared to be intelligence.
|
||||
first_seen: time &optional;
|
||||
## When this data was most recent inserted into the framework.
|
||||
latest_seen: time &optional;
|
||||
## Arbitrary text tags for the data.
|
||||
tags: set[string];
|
||||
};
|
||||
|
||||
## Record to represent a singular piece of intelligence.
|
||||
type Item: record {
|
||||
## If the data is an IP address, this hold the address.
|
||||
ip: addr &optional;
|
||||
## If the data is textual, this holds the text.
|
||||
str: string &optional;
|
||||
## If the data is numeric, this holds the number.
|
||||
num: int &optional;
|
||||
## The subtype of the data for when either the $str or $num fields are
|
||||
## given. If one of those fields are given, this field must be present.
|
||||
subtype: string &optional;
|
||||
|
||||
## The next five fields are temporary until a better model for
|
||||
## attaching metadata to an intelligence item is created.
|
||||
desc: string &optional;
|
||||
url: string &optional;
|
||||
first_seen: time &optional;
|
||||
latest_seen: time &optional;
|
||||
tags: set[string];
|
||||
|
||||
## These single string tags are throw away until pybroccoli supports sets
|
||||
## These single string tags are throw away until pybroccoli supports sets.
|
||||
tag1: string &optional;
|
||||
tag2: string &optional;
|
||||
tag3: string &optional;
|
||||
};
|
||||
|
||||
## Record model used for constructing queries against the intelligence
|
||||
## framework.
|
||||
type QueryItem: record {
|
||||
ip: addr &optional;
|
||||
str: string &optional;
|
||||
num: int &optional;
|
||||
subtype: string &optional;
|
||||
## If an IP address is being queried for, this field should be given.
|
||||
ip: addr &optional;
|
||||
## If a string is being queried for, this field should be given.
|
||||
str: string &optional;
|
||||
## If numeric data is being queried for, this field should be given.
|
||||
num: int &optional;
|
||||
## If either a string or number is being queried for, this field should
|
||||
## indicate the subtype of the data.
|
||||
subtype: string &optional;
|
||||
|
||||
or_tags: set[string] &optional;
|
||||
and_tags: set[string] &optional;
|
||||
## A set of tags where if a single metadata record attached to an item
|
||||
## has any one of the tags defined in this field, it will match.
|
||||
or_tags: set[string] &optional;
|
||||
## A set of tags where a single metadata record attached to an item
|
||||
## must have all of the tags defined in this field.
|
||||
and_tags: set[string] &optional;
|
||||
|
||||
## The predicate can be given when searching for a match. It will
|
||||
## be tested against every :bro:type:`Intel::MetaData` item associated
|
||||
## with the data being matched on. If it returns T a single time, the
|
||||
## matcher will consider that the item has matched.
|
||||
pred: function(meta: Intel::MetaData): bool &optional;
|
||||
## matcher will consider that the item has matched. This field can
|
||||
## be used for constructing arbitrarily complex queries that may not
|
||||
## be possible with the $or_tags or $and_tags fields.
|
||||
pred: function(meta: Intel::MetaData): bool &optional;
|
||||
};
|
||||
|
||||
|
||||
## Function to insert data into the intelligence framework.
|
||||
##
|
||||
## item: The data item.
|
||||
##
|
||||
## Returns: T if the data was successfully inserted into the framework,
|
||||
## otherwise it returns F.
|
||||
global insert: function(item: Item): bool;
|
||||
|
||||
## A wrapper for the :bro:id:`Intel::insert` function. This is primarily
|
||||
## used as the external API for inserting data into the intelligence
|
||||
## using Broccoli.
|
||||
global insert_event: event(item: Item);
|
||||
|
||||
## Function for matching data within the intelligence framework.
|
||||
global matcher: function(item: QueryItem): bool;
|
||||
|
||||
type MetaDataStore: table[count] of MetaData;
|
||||
type DataStore: record {
|
||||
ip_data: table[addr] of MetaDataStore;
|
||||
## The first string is the actual value and the second string is the subtype.
|
||||
string_data: table[string, string] of MetaDataStore;
|
||||
int_data: table[int, string] of MetaDataStore;
|
||||
};
|
||||
global data_store: DataStore;
|
||||
|
||||
|
||||
}
|
||||
|
||||
type MetaDataStore: table[count] of MetaData;
|
||||
type DataStore: record {
|
||||
ip_data: table[addr] of MetaDataStore;
|
||||
# The first string is the actual value and the second string is the subtype.
|
||||
string_data: table[string, string] of MetaDataStore;
|
||||
int_data: table[int, string] of MetaDataStore;
|
||||
};
|
||||
global data_store: DataStore;
|
||||
|
||||
event bro_init()
|
||||
{
|
||||
Log::create_stream(Intel::LOG, [$columns=Info]);
|
||||
|
|
|
@ -13,11 +13,11 @@
|
|||
module Metrics;
|
||||
|
||||
export {
|
||||
## This value allows a user to decide how large of result groups the
|
||||
## workers should transmit values.
|
||||
## Allows a user to decide how large of result groups the
|
||||
## workers should transmit values for cluster metric aggregation.
|
||||
const cluster_send_in_groups_of = 50 &redef;
|
||||
|
||||
## This is the percent of the full threshold value that needs to be met
|
||||
## The percent of the full threshold value that needs to be met
|
||||
## on a single worker for that worker to send the value to its manager in
|
||||
## order for it to request a global view for that value. There is no
|
||||
## requirement that the manager requests a global view for the index
|
||||
|
@ -25,11 +25,11 @@ export {
|
|||
## recently.
|
||||
const cluster_request_global_view_percent = 0.1 &redef;
|
||||
|
||||
## This event is sent by the manager in a cluster to initiate the
|
||||
## Event sent by the manager in a cluster to initiate the
|
||||
## collection of metrics values for a filter.
|
||||
global cluster_filter_request: event(uid: string, id: ID, filter_name: string);
|
||||
|
||||
## This event is sent by nodes that are collecting metrics after receiving
|
||||
## Event sent by nodes that are collecting metrics after receiving
|
||||
## a request for the metric filter from the manager.
|
||||
global cluster_filter_response: event(uid: string, id: ID, filter_name: string, data: MetricTable, done: bool);
|
||||
|
||||
|
|
|
@ -1,13 +1,16 @@
|
|||
##! This is the implementation of the metrics framework.
|
||||
##! The metrics framework provides a way to count and measure data.
|
||||
|
||||
@load base/frameworks/notice
|
||||
|
||||
module Metrics;
|
||||
|
||||
export {
|
||||
## The metrics logging stream identifier.
|
||||
redef enum Log::ID += { LOG };
|
||||
|
||||
## Identifiers for metrics to collect.
|
||||
type ID: enum {
|
||||
## Blank placeholder value.
|
||||
NOTHING,
|
||||
};
|
||||
|
||||
|
@ -15,10 +18,13 @@ export {
|
|||
## current value to the logging stream.
|
||||
const default_break_interval = 15mins &redef;
|
||||
|
||||
## This is the interval for how often notices will happen after they have
|
||||
## already fired.
|
||||
## This is the interval for how often threshold based notices will happen
|
||||
## after they have already fired.
|
||||
const renotice_interval = 1hr &redef;
|
||||
|
||||
## Represents a thing which is having metrics collected for it. An instance
|
||||
## of this record type and a :bro:type:`Metrics::ID` together represent a
|
||||
## single measurement.
|
||||
type Index: record {
|
||||
## Host is the value to which this metric applies.
|
||||
host: addr &optional;
|
||||
|
@ -37,17 +43,30 @@ export {
|
|||
network: subnet &optional;
|
||||
} &log;
|
||||
|
||||
## The record type that is used for logging metrics.
|
||||
type Info: record {
|
||||
## Timestamp at which the metric was "broken".
|
||||
ts: time &log;
|
||||
## What measurement the metric represents.
|
||||
metric_id: ID &log;
|
||||
## The name of the filter being logged. :bro:type:`Metrics::ID` values
|
||||
## can have multiple filters which represent different perspectives on
|
||||
## the data so this is necessary to understand the value.
|
||||
filter_name: string &log;
|
||||
## What the metric value applies to.
|
||||
index: Index &log;
|
||||
## The simple numeric value of the metric.
|
||||
value: count &log;
|
||||
};
|
||||
|
||||
# TODO: configure a metrics filter logging stream to log the current
|
||||
# TODO: configure a metrics filter logging stream to log the current
|
||||
# metrics configuration in case someone is looking through
|
||||
# old logs and the configuration has changed since then.
|
||||
|
||||
## Filters define how the data from a metric is aggregated and handled.
|
||||
## Filters can be used to set how often the measurements are cut or "broken"
|
||||
## and logged or how the data within them is aggregated. It's also
|
||||
## possible to disable logging and use filters for thresholding.
|
||||
type Filter: record {
|
||||
## The :bro:type:`Metrics::ID` that this filter applies to.
|
||||
id: ID &optional;
|
||||
|
@ -62,7 +81,7 @@ export {
|
|||
aggregation_mask: count &optional;
|
||||
## This is essentially a mapping table between addresses and subnets.
|
||||
aggregation_table: table[subnet] of subnet &optional;
|
||||
## The interval at which the metric should be "broken" and written
|
||||
## The interval at which this filter should be "broken" and written
|
||||
## to the logging stream. The counters are also reset to zero at
|
||||
## this time so any threshold based detection needs to be set to a
|
||||
## number that should be expected to happen within this period.
|
||||
|
@ -79,25 +98,51 @@ export {
|
|||
notice_threshold: count &optional;
|
||||
## A series of thresholds at which to generate notices.
|
||||
notice_thresholds: vector of count &optional;
|
||||
## How often this notice should be raised for this metric index. It
|
||||
## How often this notice should be raised for this filter. It
|
||||
## will be generated everytime it crosses a threshold, but if the
|
||||
## $break_interval is set to 5mins and this is set to 1hr the notice
|
||||
## only be generated once per hour even if something crosses the
|
||||
## threshold in every break interval.
|
||||
notice_freq: interval &optional;
|
||||
};
|
||||
|
||||
type MetricTable: table[Index] of count &default=0;
|
||||
|
||||
## Function to associate a metric filter with a metric ID.
|
||||
##
|
||||
## id: The metric ID that the filter should be associated with.
|
||||
##
|
||||
## filter: The record representing the filter configuration.
|
||||
global add_filter: function(id: ID, filter: Filter);
|
||||
|
||||
## Add data into a :bro:type:`Metrics::ID`. This should be called when
|
||||
## a script has measured some point value and is ready to increment the
|
||||
## counters.
|
||||
##
|
||||
## id: The metric ID that the data represents.
|
||||
##
|
||||
## index: The metric index that the value is to be added to.
|
||||
##
|
||||
## increment: How much to increment the counter by.
|
||||
global add_data: function(id: ID, index: Index, increment: count);
|
||||
|
||||
## Helper function to represent a :bro:type:`Metrics::Index` value as
|
||||
## a simple string
|
||||
##
|
||||
## index: The metric index that is to be converted into a string.
|
||||
##
|
||||
## Returns: A string reprentation of the metric index.
|
||||
global index2str: function(index: Index): string;
|
||||
|
||||
# This is the event that is used to "finish" metrics and adapt the metrics
|
||||
# framework for clustered or non-clustered usage.
|
||||
## Event that is used to "finish" metrics and adapt the metrics
|
||||
## framework for clustered or non-clustered usage.
|
||||
##
|
||||
## ..note: This is primarily intended for internal use.
|
||||
global log_it: event(filter: Filter);
|
||||
|
||||
## Event to access metrics records as they are passed to the logging framework.
|
||||
global log_metrics: event(rec: Info);
|
||||
|
||||
## Type to store a table of metrics values. Interal use only!
|
||||
type MetricTable: table[Index] of count &default=0;
|
||||
}
|
||||
|
||||
redef record Notice::Info += {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
##! This script provides the framework for software version detection and
|
||||
##! parsing, but doesn't actually do any detection on it's own. It relys on
|
||||
##! parsing but doesn't actually do any detection on it's own. It relys on
|
||||
##! other protocol specific scripts to parse out software from the protocols
|
||||
##! that they analyze. The entry point for providing new software detections
|
||||
##! to this framework is through the :bro:id:`Software::found` function.
|
||||
|
@ -10,39 +10,44 @@
|
|||
module Software;
|
||||
|
||||
export {
|
||||
|
||||
## The software logging stream identifier.
|
||||
redef enum Log::ID += { LOG };
|
||||
|
||||
|
||||
## Scripts detecting new types of software need to redef this enum to add
|
||||
## their own specific software types which would then be used when they
|
||||
## create :bro:type:`Software::Info` records.
|
||||
type Type: enum {
|
||||
## A placeholder type for when the type of software is not known.
|
||||
UNKNOWN,
|
||||
OPERATING_SYSTEM,
|
||||
DATABASE_SERVER,
|
||||
# There are a number of ways to detect printers on the
|
||||
# network, we just need to codify them in a script and move
|
||||
# this out of here. It isn't currently used for anything.
|
||||
PRINTER,
|
||||
};
|
||||
|
||||
|
||||
## A structure to represent the numeric version of software.
|
||||
type Version: record {
|
||||
major: count &optional; ##< Major version number
|
||||
minor: count &optional; ##< Minor version number
|
||||
minor2: count &optional; ##< Minor subversion number
|
||||
addl: string &optional; ##< Additional version string (e.g. "beta42")
|
||||
## Major version number
|
||||
major: count &optional;
|
||||
## Minor version number
|
||||
minor: count &optional;
|
||||
## Minor subversion number
|
||||
minor2: count &optional;
|
||||
## Additional version string (e.g. "beta42")
|
||||
addl: string &optional;
|
||||
} &log;
|
||||
|
||||
|
||||
## The record type that is used for representing and logging software.
|
||||
type Info: record {
|
||||
## The time at which the software was first detected.
|
||||
## The time at which the software was detected.
|
||||
ts: time &log;
|
||||
## The IP address detected running the software.
|
||||
host: addr &log;
|
||||
## The type of software detected (e.g. WEB_SERVER)
|
||||
## The type of software detected (e.g. :bro:enum:`HTTP::SERVER`).
|
||||
software_type: Type &log &default=UNKNOWN;
|
||||
## Name of the software (e.g. Apache)
|
||||
## Name of the software (e.g. Apache).
|
||||
name: string &log;
|
||||
## Version of the software
|
||||
## Version of the software.
|
||||
version: Version &log;
|
||||
## The full unparsed version string found because the version parsing
|
||||
## doesn't work 100% reliably and this acts as a fall back in the logs.
|
||||
## doesn't always work reliably in all cases and this acts as a
|
||||
## fallback in the logs.
|
||||
unparsed_version: string &log &optional;
|
||||
|
||||
## This can indicate that this software being detected should
|
||||
|
@ -55,37 +60,48 @@ export {
|
|||
force_log: bool &default=F;
|
||||
};
|
||||
|
||||
## The hosts whose software should be detected and tracked.
|
||||
## Hosts whose software should be detected and tracked.
|
||||
## Choices are: LOCAL_HOSTS, REMOTE_HOSTS, ALL_HOSTS, NO_HOSTS
|
||||
const asset_tracking = LOCAL_HOSTS &redef;
|
||||
|
||||
|
||||
## Other scripts should call this function when they detect software.
|
||||
## unparsed_version: This is the full string from which the
|
||||
## :bro:type:`Software::Info` was extracted.
|
||||
##
|
||||
## id: The connection id where the software was discovered.
|
||||
##
|
||||
## info: A record representing the software discovered.
|
||||
##
|
||||
## Returns: T if the software was logged, F otherwise.
|
||||
global found: function(id: conn_id, info: Software::Info): bool;
|
||||
|
||||
## This function can take many software version strings and parse them
|
||||
## Take many common software version strings and parse them
|
||||
## into a sensible :bro:type:`Software::Version` record. There are
|
||||
## still many cases where scripts may have to have their own specific
|
||||
## version parsing though.
|
||||
##
|
||||
## unparsed_version: The raw version string.
|
||||
##
|
||||
## host: The host where the software was discovered.
|
||||
##
|
||||
## software_type: The type of software.
|
||||
##
|
||||
## Returns: A complete record ready for the :bro:id:`Software::found` function.
|
||||
global parse: function(unparsed_version: string,
|
||||
host: addr,
|
||||
software_type: Type): Info;
|
||||
|
||||
## Compare two versions.
|
||||
## Compare two version records.
|
||||
##
|
||||
## Returns: -1 for v1 < v2, 0 for v1 == v2, 1 for v1 > v2.
|
||||
## If the numerical version numbers match, the addl string
|
||||
## is compared lexicographically.
|
||||
global cmp_versions: function(v1: Version, v2: Version): int;
|
||||
|
||||
## This type represents a set of software. It's used by the
|
||||
## :bro:id:`Software::tracked` variable to store all known pieces of
|
||||
## software for a particular host. It's indexed with the name of a piece
|
||||
## of software such as "Firefox" and it yields a
|
||||
## :bro:type:`Software::Info` record with more information about the
|
||||
## software.
|
||||
## Type to represent a collection of :bro:type:`Software::Info` records.
|
||||
## It's indexed with the name of a piece of software such as "Firefox"
|
||||
## and it yields a :bro:type:`Software::Info` record with more information
|
||||
## about the software.
|
||||
type SoftwareSet: table[string] of Info;
|
||||
|
||||
## The set of software associated with an address. Data expires from
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue