Hello,
I am trying to add BRO the ability to ignore traffic from certain IP ranges
dynamically.
I have a DB with IP addresses (that chances once in a while) and I would
like to write a BRO script that will query the DB once in a while, grab
those IP addresses and drop new connections with these IP's.
Question:
1. Is it possible to query a DB from BRO scripts? is there any examples?
2. Assuming yes, should i implement this logic at the 'new_connection'
event? (I would like to drop connections from these IP's as soon as
possible).
Thank You
Dave
I like that broctl will roll logs over every hour. My default
broctl.cfg file includes:
# Rotation interval in seconds for log files on manager/standalone node.
LogRotationInterval = 3600
I don't like getting an email from broctl every hour, though. Is
there a way to get a daily report, instead of an hourly report?
Related --
The Bro README [1] claims:
"BroControl sends four types of mails to the address given in MailTo:
1. When logs are rotated (per default once a day), a list of all
alarms during the last rotation interval is sent. This can be disabled
by setting MailAlarms=0."
But elsewhere in the README:
"LogRotationInterval (int, default 3600)
The frequency of log rotation in seconds for the manager/standalone node."
This is confusing to me -- maybe someone can help me understand. Are
they talking about two different things?
[1] http://www.bro-ids.org/documentation/components/broctl/README.html
Before I go dive into source I thought I'd throw a quick question to the group.
Can you use the entire BPF syntax (things other than just "host") when building a Bro filter?
For example, I've got something like this in my local.bro:
redef PacketFilter::all_packets = F;
redef capture_filters = [[ "all"] = "ip or not ip"];
redef restrict_filters += [ ["not-one-host"] = "not host 10.10.1.1"];
redef restrict_filters += [ ["not-two-hosts"] = "not host 10.20.1.1 and not host 10.30.1.1"];
redef restrict_filters += [ ["not-one-net"] = "not net 10.40.1.192/26"];
redef restrict_filters += [ ["not-two-nets"] = "not net 10.50.1.0/20 and not net 10.60.1.0/22"];
But it seems that the "10.50.1.0/20" network is still leaking in traffic?
Ultimately I'd like to eliminate the traffic at my upstream device, but in the mean time, does anyone see something I'm doing obviously wrong?
Thanks,
Corey
I spent quite a bit of time and effort trying to figure out. Dropping
a note out to the community to hopefully help the next guy.
Over in this thread
http://mailman.icsi.berkeley.edu/pipermail/bro/2012-August/005811.html
I couldn't figure out why this script
http://mailman.icsi.berkeley.edu/pipermail/bro/2012-August/005812.html
would not send an email alert via the Notice framework.
I was testing the script on a small pcap file. I thought that
debugging approach would enable me to quickly, easily, and reliably
check to see if my new bro script was working as intended.
Here's the problem with that development/debugging approach. The
first few lines in the function email_notice_to (found in
frameworks/notice/main.bro specifically) check to see if you are
reading traffic from a trace file, and then silently disable email
alerting if you are. This turned out to be very frustrating to debug.
To confirm that my script was working as expected, I had to change the
following lines in frameworks/notice/main.bro:
function email_notice_to(n: Notice::Info, dest: string, extend: bool)
{
if ( reading_traces() || dest == "" )
return;
to the following:
function email_notice_to(n: Notice::Info, dest: string, extend: bool)
{
# if ( reading_traces() || dest == "" )
# return;
If you plan to test a new script where you expect it to send an email
via the Notice framework, I recommend that you send traffic that ought
to should trigger an email alert over the wire.
That's not a viable option for me, so commenting out the lines above
is a better approach.
Would also recommend that either the bro documentation make note of
this "feature" or that the resulting notice.log print a message to
indicate that email alerting was disabled because it isn't reading
traffic from a live network capture.
-Chris
I have a short bro script that I wrote that hooks the DNS log
(http://www.bro-ids.org/documentation/logging.html#hooking-into-the-logging).
Each time a DNS::log_dns event fires, if a specific IP is in
rec$answers, the script prints out rec$ts, rec$uid, rec$id$orig_h, and
rec$query.
I want the entries from the script to go to their own log, though. I
am struggling to figure out how to make that work. Based on the
documentation for logging, it looks like I'd need to define a new
Stream to create a new log file.
(http://www.bro-ids.org/documentation/logging.html#adding-streams)
Here's my original script that hooks the DNS logs:
event DNS::log_dns(rec: DNS::Info)
{
for( i in rec$answers )
if( "1.2.3.4" in rec$answers[i] )
print fmt("%s %s %s %s", rec$ts, rec$uid,
rec$id$orig_h, rec$query);
}
To make this go to its own log, I tried this:
module Foo;
export {
# Create an ID for the our new stream. By convention, this is
# called "LOG".
redef enum Log::ID += { LOG };
# Define the fields. By convention, the type is called "Info".
type Info: record {
ts: time &log;
uid: string &log;
orig_ip: string &log;
query: string &log;
};
# Define a hook event. By convention, this is called
# "log_<stream>".
global log_foo: event(rec: Info);
}
redef record rec += {
foo: Info &optional;
};
# This event should be handled at a higher priority so that when
# users modify your stream later and they do it at priority 0,
# their code runs after this.
event bro_init() &priority=5
{
# Create the stream. This also adds a default filter automatically.
Log::create_stream(Foo::LOG, [$columns=Info]);
}
event DNS::log_dns(rec: DNS::Info)
{
for( i in rec$answers )
if( "1.2.3.4" in rec$answers[i] )
local rec: Foo::Info = [ $ts=rec$ts,
$uid=rec$uid, $orig_h=rec$id$orig_h, $query=rec$query];
rec$foo = rec;
Log::write(Foo::LOG, rec);
}
I get the errors:
error in ./test.bro, line 22: unknown identifier (Foo::rec)
error in ./test.bro, line 35 and ./test.bro, line 39: already defined (Foo::rec)
I am new to writing Bro scripts. Any pointers on what I'm doing wrong?
-Chris
Has anybody created or thought of creating a REST shim for Time
Machine? I was going to create something pretty basic, but enough to
send HTTP commands to pull back pcaps from Time Machine w/o having to
SSH to the box. If nobody has done it, that's ok I'll be sure to post
mine when I'm finished with it.
-=Mike
--
cat ~/.bash_history > documentation.txt
Hiya,
while I'm at sharing bro related stuff, I've got a setup here
that parses bro's DNS log in real time and updates the database
of a local DNS server (powerdns with mysql backend) so as to
provide with more useful PTR records.
$ tail -1 dns.log
1345732627.030897 jUJU3ZwGOv4 x.x.x.x 54866 x.x.x.x 53 udp 44687 static.ak.facebook.com 1 C_INTERNET 1 A 0 NOERROR F F
F T T 0 static.ak.facebook.com.edgesuite.net,a749.dsw4.akamai.net,84.53.132.80,84.53.132.88 3364.000000,348.000000,15.000000,15.000000
$ dig -x 84.53.132.88 +short
static.ak.facebook.com.C-EU.120823T143707.
For many "cloud" IP addresses, it won't necessarily be useful,
but in many case, it gives more useful information than the
real PTR record.
Above, it tells us that 84.53.132.88 was last the result of a
query for an A record for static.ak.facebook.com (at 14:37:07),
and it gives you the result of the geoiplookup.
It can be generalised for other things (like for internal IP
addresses, I use other sources of information to feed the
powerdns database).
If anybody is interested, I can post the intructions on how to
set it up along with the small perl script that parses the bro
dns logs here or on github.
--
Stephane
Hiya,
I thought I'd share a way to mark the fake HTTPS connections
done by skype as such in conn.log. We've been seeing connections
to various IP addresses around the world sending hundreds of
megabytes of data and wanted to make sure it wasn't any
information leak. Most of the time, it is skype traffic but we
wanted a way to automatically determine it was the case.
Here is a simple way. It just uses the "service" flag of a bro
"connection" to mark the fact it is skype traffic.
It detects skype traffic by looking at the fake SSL
"ServerHello" that skype responders send. (basically, they send
a fixed "random data" with a date in 2004 where a normal SSL
server would send the current date and a truly random data, I
suspect it is designed that way to help recognise skype traffic
easily).
I've got in my local.bro:
function mark_conn_as_skype(state: signature_state): bool
{
add state$conn$service["skype"];
return T;
}
redef signature_files += "skype-detect.sig";
(change to "return F" to avoid the alarm in notice.log)
And in skype-detect.sig
signature skype_fake_https {
ip-proto == tcp
tcp-state established,responder
event "Skype fake HTTPS connection"
src-port == 443
payload /\x16\x03\x01\x00\x4a\x02\x00\x00\x46\x03\x01\x40\x1b\xe4\x86\x02\xad\xe0\x29\xe1\x77\x74\xe5\x44\xb9\xc9\x9c\xb4\x31\x31\x5e\x02\xdd\x77\x9d\x15\x4a\x96\x09\xba\x5d\xa8\x70/
eval mark_conn_as_skype
}
Then you'll see "skype" in the "service" column for those
connections and need worry less when you see 200MB of data being
sent to Ukraine or any country you usually don't do business
with.
--
Stephane