new bro "CURRENT" release - 0.8a37
Vern Paxson
vern at icir.org
Thu Sep 4 16:38:20 PDT 2003
[Normally I'd only send this announcement to bro-devel at lbl.gov, but folks
still do nearly all of the discussion on bro at lbl.gov, and this version
includes a number of fixes for bugs that have been discussed there.]
An updated "CURRENT" version of Bro is now available from
ftp://ftp.ee.lbl.gov/bro-pub-0.8-current.tar.gz
I've appended the changes between it and the last "CURRENT" version (0.8a34).
Vern
-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
0.8a37 Wed Sep 3 23:20:21 PDT 2003
- A new attribute, "&persistent", indicates that a global variable's
state should persist on disk (Robin Sommer). Currently, they
reside in the file "state.bst".
For example, given the following script:
global a = 0 &persistent;
event bro_init()
{
print ++a;
}
then every time you run it, a increases by one.
You can dump the state file using "bro -x state.bst <scriptname>".
(There's also a partially-implemented XML dumper which you invoke via
"bro -X state.bst <scriptname>".)
If you send Bro a HUP signal, then it will synchronize all persistent
state to disk (checkpoint) at that point. More generally, the policy
script can do so at any time by calling the new built-in checkpoint_state().
By including the new policy script "checkpoint", you can have Bro
automatically checkpoint every time checkpoint_interval elapses
(default 15 minutes).
- You can also record events to disk by loading the "capture-events"
policy script, or calling the new capture_events() built-in (Robin Sommer).
The events are written to the file events.bst. You can dump these
using bro -x (or -X), as above. You can also replay them using
"bro -R <file>". By replaying them using the same policy script as
generated them, you should get the same output. For example:
bro -r tracefile myscript capture-events
...
bro -R events.log myscript
- An experimental module facility has been added (Umesh Shankar).
The module facility implements namespaces. Everything is in some namespace
or other. The default namespace is called "GLOBAL" and is searched by
default when doing name resolution. The scoping operator is "::" as in
C++. You can only access things in the current namespace, things in the
GLOBAL namespace, or things that have been explicitly exported from a
different namespace. Exported variables and functions still require
fully-qualified names. The syntax is as follows:
module foo; # Sets the current namespace to "foo"
export {
int i;
int j;
}
int k;
module bar;
int i;
foo::i = 1;
bar::i = 2;
print i; # bar::i (since we're currently in module bar)
j = 3; # ERROR: j is exported, but the fully qualified name
# foo::j is required
foo::k = 4; # ERROR: k is not exported
The same goes for calling functions.
One restriction currently in place is that variables not in the "GLOBAL"
namespace can't shadow those in GLOBAL, so you can't have
module GLOBAL;
global i: int;
module other_module;
global i: int;
It is a little confusing that the "global" declaration really only means
that the variable i is global to the current module, not that it is truly
global and thus visible everywhere (that would require that it be in
GLOBAL, or if using the full name is ok, that it be exported). Perhaps
there will be a change to the syntax in the future to address this.
The "module" statement cuts across @load commands, so that if you say:
module foo;
@load other_script;
then other_script will be in module foo. Likewise if other_script changes
to module bar, then the current module will be module bar even after
other_script is done. However, this functionality may change in the future
if it proves problematic.
The policy scripts in the Bro distribution have not yet been updated to
use it, but there is a backward-compatibility feature so that existing
scripts should work without modification. In particular, everything is
put in GLOBAL by default.
- The hooks are now in place for communicating events between running
Bro's. An experimental implementation of doing so (written by Robin
Sommer) will be integrated shortly.
- A side-effect of getting those hooks in place is that event handlers must
now be directly specified (by naming them) rather than indirectly
(for example, by indexing a table whose value yields an event handler).
This may be fixed soon.
- An experimental "match" expression scans a list of predicates to find
the first one that's both true and has the highest priority (Umesh Shankar).
The general form is:
match some_record on {
[ priority, class_name, predicate ],
...
}
where "predicate" is evaluated in the context of the value (and type) of
some_record. For example, if some_record has a field "num_alerts"
then predicate could be "$num_alerts > 5".
"priority" is a non-negative integer (i.e., of type "count"), and,
for now, "class_name" is a string.
For example,
global c: conn_id;
c = [ $orig_h = 0.0.0.0, $orig_p = 0/tcp,
$resp_h = 1.1.1.1, $resp_p = 1/tcp ];
print match c on {
[ 2, "emptyweb", $orig_h == 0.0.0.0 && $resp_p == 80/tcp ],
[ 1, "emptyhost", $orig_h == 0.0.0.0 ],
[ 0, "should not match", 1 == 0 ]
};
will print "emptyhost".
The initial intent behind this is to eventually provide more flexible
customization of alert processing, though it clearly has broader
applicable. *It is very likely that the semantics and perhaps the syntax
of "match" will change in the near future.*
- Bro's packet filter is now computed via pcap.bro (which is automatically
included via bro.init). It uses two new built-ins:
precompile_pcap_filter(id: PcapFilterID, s: string): bool
install_pcap_filter(id: PcapFilterID): bool
The first is for precompiling a pcap filter so it can be installed
or turned off dynamically. Associating an ID with the filter, you can
then activate the filter by calling the second function (installing a
new filter replaces the current one). (Robin Sommer)
Be default, pcap.bro is responsible for building a pcap string based on
the capture/restrict_filters defined by the various analyzers. It compiles
and installs this filter, so there is no observable difference in usage
to the old implementation, except capture/restrict_filter are now *tables*
rather than strings, and are written as plural rather than singular.
So the analyzers need to define something like this:
[finger.bro]
redef capture_filters += { ["finger"] = "port finger" };
This then allows "finger" to be used as the name for the corresponding
filter element (see the next item).
- load-level.bro is an experimental policy script for allowing Bro to
shed or add on load (in terms of which protocols it analyzes). It
provides three interface functions for setting the current loadlevel:
# level is LoadLevel1, ..., LoadLevel10
function set_load_level(level: PcapFilterID): bool
function increase_load_level()
function decrease_load_level()
load-levels.bro defines ten different load levels (from 1 to 10, with 10
being the one with the most load imposed on the system), which are
configured by defining capture_load_level/restrict_load_levels: Example:
redef capture_load_levels += {
["dns"] = LoadLevel1,
["smtp"] = LoadLevel2,
["http-reply"] = LoadLevel3,
["http-request"] = LoadLevel8,
};
This means for example: "include the capture_filter associated with
'http-reply' if the current load level is 3 or below". There's a similar
mechanism for restrict_filters:
redef restrict_filters += {
["cs-only"] = "net 131.159.0.0/16",
};
redef restrict_load_levels += {
["cs-only"] = LoadLevel7,
};
This applies the given restrict_filter if the current load level is 7
or *above*.
The pcap filters belonging to the ten load levels are built and pre-compiled
on startup. The three functions shown above just call install_pcap_filter()
then. (Robin Sommer)
- drop-adapt.bro tries to adjust the load level based on the current
packet drop rate (Robin Sommer).
- synflood.bro is an experimental policy script for detecting SYN floods.
It is not yet documented, other than brief comments in the script.
(Robin Sommer)
- Subnet lookups now use Patricia trees instead of brute-force, which should
make them significantly more efficient for large lists, e.g., local nets.
(Robin Sommer)
- Due to the addition of modules, which use a C++-style "::" scope
designator, you now need to use "0x" to introduce IPv6 address constants
that use "::" to specify a series of empty octets. For example, you
used to be able to specify "deadbeef::cafe", but now this needs to be
"0xdeadbeef::cafe". Note that "1::2" can still be written without needing
a "0x" prefix; it's just hex constants that start with letters that need
the prefix.
- A new built-in, escape_string(), takes a string and returns a copy of
it that uses escape sequences for any problematic characters (Robin Sommer).
- A number of low-level bug fixes and portability tweaks (Robin Sommer,
Ruoming Pang, Christian Kreibich, Chema Gonzalez).
- A new timer, status_update_timer, fires for each ongoing connection
every connection_status_update_interval seconds (default = 0 seconds,
which means "don't fire). (Robin Sommer)
- An additional Bro-level packet filter can filter/sample packets
based on their src/dest ip/subnet (using a Patricia tree for
efficiency; Robin Sommer). install_src_addr_filter(ip, flags, p) drops
packets originating from ip with probability p (0..100) if none of the
given TCP flags is set. install_src_net_filter, install_dst_addr_filter
and install_dst_net_filter" work similarly. The corresponding "uninstall_*"
functions remove the filters again.
- The @if/@else/@endif mechanisms have been made more powerful (Robin Sommer).
- New configure option --enable-debug to compile without optimization
(Robin Sommer).
- Small tweaks to the mpatrol support (Robin Sommer).
- SMTP is now one of the services which can use a small inactivity timeout
in inactivity.bro (Robin Sommer).
- Alerts for signatures which are triggered by worms may be suppressed if
we already know that the triggering host is indeed infected by a worm
(Robin Sommer).
- Matches of a signature can now be counted per destination host
(Robin Sommer).
- snort2bro now ignores sid-526 ("BAD TRAFFIC data in TCP SYN packet";
Robin Sommer). Due to different semantics of Bro (matching stream-wise)
and Snort (matching packet-wise) this signature generates a lot of
false positives.
More information about the Bro
mailing list