mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 14:48:21 +00:00
Adding some of the initial scripts that are going to be merged from
my script repository.
This commit is contained in:
parent
5bf18fdb7f
commit
340805fe00
4 changed files with 596 additions and 0 deletions
213
policy/dns-ext.bro
Normal file
213
policy/dns-ext.bro
Normal file
|
@ -0,0 +1,213 @@
|
||||||
|
@load global-ext
|
||||||
|
@load dns
|
||||||
|
|
||||||
|
type dns_ext_session_info: record {
|
||||||
|
id: conn_id;
|
||||||
|
ts: time;
|
||||||
|
trans_id: count;
|
||||||
|
query: string;
|
||||||
|
qtype: count;
|
||||||
|
qclass: count;
|
||||||
|
total_answers: count &default=0;
|
||||||
|
rcode: count &default = 65536;
|
||||||
|
QR: bool &default=F;
|
||||||
|
Z: bool &default=F;
|
||||||
|
AA: bool &default=F;
|
||||||
|
RD: bool &default=F;
|
||||||
|
RA: bool &default=F;
|
||||||
|
TC: bool &default=F;
|
||||||
|
TTL: interval &default=0secs;
|
||||||
|
replies: set[string];
|
||||||
|
};
|
||||||
|
|
||||||
|
# Define the generic dns-ext event that can be handled from other scripts
|
||||||
|
global dns_ext: event(id: conn_id, di: dns_ext_session_info);
|
||||||
|
|
||||||
|
module DNS;
|
||||||
|
|
||||||
|
export {
|
||||||
|
# Follow this example to define domains that you would consider "local".
|
||||||
|
# This is primarily useful if you are monitoring authoritative nameservers,
|
||||||
|
# but also useful for any zones that *should* be pointing at your
|
||||||
|
# network.
|
||||||
|
# e.g.
|
||||||
|
#const local_domains = /(^|\.)(osu|ohio-state)\.edu$/ |
|
||||||
|
# /(^|\.)akamai(tech)?\.net$/ &redef;
|
||||||
|
const local_domains = /(^|\.)akamai(tech)?\.net$/ &redef;
|
||||||
|
|
||||||
|
redef enum Notice += {
|
||||||
|
# Raised when a non-local name is found to be pointing at a local host.
|
||||||
|
# This only works appropriately when all of your authoritative DNS
|
||||||
|
# servers are located in your "local_nets".
|
||||||
|
DNSExternalName,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
global dns_sessions_ext: table[addr, addr, count] of dns_ext_session_info;
|
||||||
|
|
||||||
|
# This doesn't work with live traffic yet.
|
||||||
|
# It's waiting for support to dynamically construct pattern variables at init time.
|
||||||
|
#global dns_suffix_regex = build_regex(local_domains, "(^|\.)~~$");
|
||||||
|
#event bro_init()
|
||||||
|
# {
|
||||||
|
# local i: count = 0;
|
||||||
|
# local tmp_pattern: pattern;
|
||||||
|
# for ( d in local_domains )
|
||||||
|
# {
|
||||||
|
# tmp_pattern = string_to_pattern( fmt("=%s@", d), T );
|
||||||
|
#
|
||||||
|
# if ( i == 0 )
|
||||||
|
# pat = tmp_pattern;
|
||||||
|
# else
|
||||||
|
# pat = merge_pattern(tmp_pattern, pat);
|
||||||
|
# ++i;
|
||||||
|
# }
|
||||||
|
# }
|
||||||
|
|
||||||
|
event expire_DNS_session_ext(orig: addr, resp: addr, trans_id: count)
|
||||||
|
{
|
||||||
|
if ( [orig, resp, trans_id] in dns_sessions_ext )
|
||||||
|
{
|
||||||
|
local session = dns_sessions[orig, resp, trans_id];
|
||||||
|
local session_ext = dns_sessions_ext[orig, resp, trans_id];
|
||||||
|
|
||||||
|
event dns_ext(session_ext$id, session_ext);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
event dns_request(c: connection, msg: dns_msg, query: string, qtype: count, qclass: count)
|
||||||
|
{
|
||||||
|
local id = c$id;
|
||||||
|
local orig = id$orig_h;
|
||||||
|
local resp = id$resp_h;
|
||||||
|
local session = lookup_DNS_session(c, msg$id);
|
||||||
|
local session_ext: dns_ext_session_info;
|
||||||
|
if ( [orig, resp, msg$id] !in dns_sessions_ext )
|
||||||
|
{
|
||||||
|
session_ext$id = c$id;
|
||||||
|
session_ext$trans_id = msg$id;
|
||||||
|
session_ext$ts = network_time();
|
||||||
|
session_ext$RD = msg$RD;
|
||||||
|
session_ext$TC = msg$TC;
|
||||||
|
session_ext$qtype = qtype;
|
||||||
|
session_ext$qclass = qclass;
|
||||||
|
session_ext$query = query;
|
||||||
|
local strings: set[string] = set();
|
||||||
|
session_ext$replies = strings;
|
||||||
|
dns_sessions_ext[orig, resp, msg$id] = session_ext;
|
||||||
|
|
||||||
|
# This needs to expire before the original dns.bro script expires the
|
||||||
|
# the data from the dns_session variable.
|
||||||
|
schedule 14secs { expire_DNS_session_ext(orig, resp, msg$id) };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
event dns_A_reply(c: connection, msg: dns_msg, ans: dns_answer, a: addr)
|
||||||
|
{
|
||||||
|
local id = c$id;
|
||||||
|
local orig = id$orig_h;
|
||||||
|
local resp = id$resp_h;
|
||||||
|
local session = lookup_DNS_session(c, msg$id);
|
||||||
|
local session_ext: dns_ext_session_info;
|
||||||
|
|
||||||
|
if ( [orig, resp, msg$id] in dns_sessions_ext )
|
||||||
|
{
|
||||||
|
session_ext = dns_sessions_ext[orig, resp, msg$id];
|
||||||
|
add session_ext$replies[fmt("%s",a)];
|
||||||
|
session_ext$RA = msg$RA;
|
||||||
|
session_ext$TTL = ans$TTL;
|
||||||
|
session_ext$rcode = msg$rcode;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Check for out of place domain names
|
||||||
|
if ( is_local_addr(a) && # referring to a local host
|
||||||
|
!is_local_addr(c$id$resp_h) && # response from a remote host
|
||||||
|
local_domains !in ans$query ) # drop known names
|
||||||
|
{
|
||||||
|
NOTICE([$note=DNSExternalName,
|
||||||
|
$msg=fmt("%s is pointing to a local host - %s.", ans$query, a),
|
||||||
|
$conn=c]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
event dns_TXT_reply(c: connection, msg: dns_msg, ans: dns_answer, str: string)
|
||||||
|
{
|
||||||
|
local id = c$id;
|
||||||
|
local orig = id$orig_h;
|
||||||
|
local resp = id$resp_h;
|
||||||
|
local session = lookup_DNS_session(c, msg$id);
|
||||||
|
local session_ext: dns_ext_session_info;
|
||||||
|
|
||||||
|
if ( [orig, resp, msg$id] in dns_sessions_ext )
|
||||||
|
{
|
||||||
|
session_ext = dns_sessions_ext[orig, resp, msg$id];
|
||||||
|
session_ext$rcode = msg$rcode;
|
||||||
|
add session_ext$replies[str];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
event dns_AAAA_reply(c: connection, msg: dns_msg, ans: dns_answer, a: addr,
|
||||||
|
astr: string)
|
||||||
|
{
|
||||||
|
local id = c$id;
|
||||||
|
local orig = id$orig_h;
|
||||||
|
local resp = id$resp_h;
|
||||||
|
local session = lookup_DNS_session(c, msg$id);
|
||||||
|
local session_ext: dns_ext_session_info;
|
||||||
|
|
||||||
|
if ( [orig, resp, msg$id] in dns_sessions_ext )
|
||||||
|
{
|
||||||
|
session_ext = dns_sessions_ext[orig, resp, msg$id];
|
||||||
|
session_ext$rcode = msg$rcode;
|
||||||
|
add session_ext$replies[fmt("%s", a)];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
event dns_MX_reply(c: connection, msg: dns_msg, ans: dns_answer, name: string,
|
||||||
|
preference: count)
|
||||||
|
{
|
||||||
|
local id=c$id;
|
||||||
|
local session = lookup_DNS_session(c, msg$id);
|
||||||
|
local session_ext: dns_ext_session_info;
|
||||||
|
|
||||||
|
if ( [id$orig_h, id$resp_h, msg$id] in dns_sessions_ext )
|
||||||
|
{
|
||||||
|
session_ext = dns_sessions_ext[id$orig_h, id$resp_h, msg$id];
|
||||||
|
session_ext$rcode = msg$rcode;
|
||||||
|
add session_ext$replies[name];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
event dns_PTR_reply(c: connection, msg: dns_msg, ans: dns_answer, name: string)
|
||||||
|
{
|
||||||
|
local id = c$id;
|
||||||
|
local orig = id$orig_h;
|
||||||
|
local resp = id$resp_h;
|
||||||
|
local session = lookup_DNS_session(c, msg$id);
|
||||||
|
local session_ext: dns_ext_session_info;
|
||||||
|
|
||||||
|
if ( [orig, resp, msg$id] in dns_sessions_ext )
|
||||||
|
{
|
||||||
|
session_ext = dns_sessions_ext[orig, resp, msg$id];
|
||||||
|
session_ext$rcode = msg$rcode;
|
||||||
|
add session_ext$replies[name];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
event dns_end(c: connection, msg: dns_msg)
|
||||||
|
{
|
||||||
|
local id = c$id;
|
||||||
|
local orig = id$orig_h;
|
||||||
|
local resp = id$resp_h;
|
||||||
|
local session = lookup_DNS_session(c, msg$id);
|
||||||
|
local session_ext: dns_ext_session_info;
|
||||||
|
|
||||||
|
if ( [orig, resp, msg$id] in dns_sessions_ext )
|
||||||
|
{
|
||||||
|
session_ext = dns_sessions_ext[orig, resp, msg$id];
|
||||||
|
session_ext$rcode = msg$rcode;
|
||||||
|
}
|
||||||
|
}
|
268
policy/functions.bro
Normal file
268
policy/functions.bro
Normal file
|
@ -0,0 +1,268 @@
|
||||||
|
function numeric_id_string(id: conn_id): string
|
||||||
|
{
|
||||||
|
return fmt("%s:%d > %s:%d",
|
||||||
|
id$orig_h, id$orig_p,
|
||||||
|
id$resp_h, id$resp_p);
|
||||||
|
}
|
||||||
|
|
||||||
|
function fmt_addr_set(input: addr_set): string
|
||||||
|
{
|
||||||
|
local output = "";
|
||||||
|
local tmp = "";
|
||||||
|
local len = length(input);
|
||||||
|
local i = 1;
|
||||||
|
|
||||||
|
for ( item in input )
|
||||||
|
{
|
||||||
|
tmp = fmt("%s", item);
|
||||||
|
if ( len != i )
|
||||||
|
tmp = fmt("%s ", tmp);
|
||||||
|
i = i+1;
|
||||||
|
output = fmt("%s%s", output, tmp);
|
||||||
|
}
|
||||||
|
return fmt("%s", output);
|
||||||
|
}
|
||||||
|
|
||||||
|
function fmt_str_set(input: string_set, strip: pattern): string
|
||||||
|
{
|
||||||
|
local len = length(input);
|
||||||
|
if ( len == 0 )
|
||||||
|
return "{}";
|
||||||
|
|
||||||
|
local output = "{";
|
||||||
|
local tmp = "";
|
||||||
|
local i = 1;
|
||||||
|
|
||||||
|
for ( item in input )
|
||||||
|
{
|
||||||
|
tmp = fmt("%s", gsub(item, strip, ""));
|
||||||
|
if ( len != i )
|
||||||
|
tmp = fmt("%s, ", tmp);
|
||||||
|
i = i+1;
|
||||||
|
output = fmt("%s%s", output, tmp);
|
||||||
|
}
|
||||||
|
return fmt("%s}", output);
|
||||||
|
}
|
||||||
|
|
||||||
|
# Regular expressions for matching IP addresses in strings.
|
||||||
|
const ipv4_addr_regex = /[[:digit:]]{1,3}\.[[:digit:]]{1,3}\.[[:digit:]]{1,3}\.[[:digit:]]{1,3}/;
|
||||||
|
const ipv6_8hex_regex = /([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4}/;
|
||||||
|
const ipv6_compressed_hex_regex = /(([0-9A-Fa-f]{1,4}(:[0-9A-Fa-f]{1,4})*)?)::(([0-9A-Fa-f]{1,4}(:[0-9A-Fa-f]{1,4})*)?)/;
|
||||||
|
const ipv6_hex4dec_regex = /(([0-9A-Fa-f]{1,4}:){6,6})([0-9]+)\.([0-9]+)\.([0-9]+)\.([0-9]+)/;
|
||||||
|
const ipv6_compressed_hex4dec_regex = /(([0-9A-Fa-f]{1,4}(:[0-9A-Fa-f]{1,4})*)?)::(([0-9A-Fa-f]{1,4}:)*)([0-9]+)\.([0-9]+)\.([0-9]+)\.([0-9]+)/;
|
||||||
|
|
||||||
|
# These are only commented out until this bug is fixed:
|
||||||
|
# http://www.bro-ids.org/wiki/index.php/Known_Issues#Bug_with_OR-ing_together_pattern_variables
|
||||||
|
#const ipv6_addr_regex = ipv6_8hex_regex |
|
||||||
|
# ipv6_compressed_hex_regex |
|
||||||
|
# ipv6_hex4dec_regex |
|
||||||
|
# ipv6_compressed_hex4dec_regex;
|
||||||
|
#const ip_addr_regex = ipv4_addr_regex | ipv6_addr_regex;
|
||||||
|
|
||||||
|
const ipv6_addr_regex =
|
||||||
|
/([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4}/ |
|
||||||
|
/(([0-9A-Fa-f]{1,4}(:[0-9A-Fa-f]{1,4})*)?)::(([0-9A-Fa-f]{1,4}(:[0-9A-Fa-f]{1,4})*)?)/ | # IPv6 Compressed Hex
|
||||||
|
/(([0-9A-Fa-f]{1,4}:){6,6})([0-9]+)\.([0-9]+)\.([0-9]+)\.([0-9]+)/ | # 6Hex4Dec
|
||||||
|
/(([0-9A-Fa-f]{1,4}(:[0-9A-Fa-f]{1,4})*)?)::(([0-9A-Fa-f]{1,4}:)*)([0-9]+)\.([0-9]+)\.([0-9]+)\.([0-9]+)/; # CompressedHex4Dec
|
||||||
|
|
||||||
|
const ip_addr_regex =
|
||||||
|
/[[:digit:]]{1,3}\.[[:digit:]]{1,3}\.[[:digit:]]{1,3}\.[[:digit:]]{1,3}/ |
|
||||||
|
/([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4}/ |
|
||||||
|
/(([0-9A-Fa-f]{1,4}(:[0-9A-Fa-f]{1,4})*)?)::(([0-9A-Fa-f]{1,4}(:[0-9A-Fa-f]{1,4})*)?)/ | # IPv6 Compressed Hex
|
||||||
|
/(([0-9A-Fa-f]{1,4}:){6,6})([0-9]+)\.([0-9]+)\.([0-9]+)\.([0-9]+)/ | # 6Hex4Dec
|
||||||
|
/(([0-9A-Fa-f]{1,4}(:[0-9A-Fa-f]{1,4})*)?)::(([0-9A-Fa-f]{1,4}:)*)([0-9]+)\.([0-9]+)\.([0-9]+)\.([0-9]+)/; # CompressedHex4Dec
|
||||||
|
|
||||||
|
function is_valid_ip(ip_str: string): bool
|
||||||
|
{
|
||||||
|
if ( ip_str == ipv4_addr_regex )
|
||||||
|
{
|
||||||
|
local octets = split(ip_str, /\./);
|
||||||
|
if ( |octets| != 4 )
|
||||||
|
return F;
|
||||||
|
|
||||||
|
local num=0;
|
||||||
|
for ( i in octets )
|
||||||
|
{
|
||||||
|
num = to_count(octets[i]);
|
||||||
|
if ( num < 0 || 255 < num )
|
||||||
|
return F;
|
||||||
|
}
|
||||||
|
return T;
|
||||||
|
}
|
||||||
|
else if ( ip_str == ipv6_addr_regex )
|
||||||
|
{
|
||||||
|
# TODO: make this work correctly.
|
||||||
|
return T;
|
||||||
|
}
|
||||||
|
return F;
|
||||||
|
}
|
||||||
|
|
||||||
|
# This outputs a string_array of ip addresses extracted from a string.
|
||||||
|
# given: "this is 1.1.1.1 a test 2.2.2.2 string with ip addresses 3.3.3.3"
|
||||||
|
# outputs: { [1] = 1.1.1.1, [2] = 2.2.2.2, [3] = 3.3.3.3 }
|
||||||
|
function find_ip_addresses(input: string): string_array
|
||||||
|
{
|
||||||
|
local parts = split_all(input, ip_addr_regex);
|
||||||
|
local output: string_array;
|
||||||
|
|
||||||
|
for ( i in parts )
|
||||||
|
{
|
||||||
|
if ( i % 2 == 0 && is_valid_ip(parts[i]) )
|
||||||
|
output[|output|+1] = parts[i];
|
||||||
|
}
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
########################################
|
||||||
|
# The following functions are for getting contact information (email) for an
|
||||||
|
# IP address in your organization. It will return data from nested subnets
|
||||||
|
# as well.
|
||||||
|
# Below is an example for using it:
|
||||||
|
#
|
||||||
|
# redef subnet_to_admin_table += {
|
||||||
|
# [146.128.0.0/16] = "security@yourorg.com",
|
||||||
|
# [146.128.94.0/24] = "someone@yourorg.com",
|
||||||
|
# };
|
||||||
|
#
|
||||||
|
# event bro_init()
|
||||||
|
# {
|
||||||
|
# print fmt_email_string(find_all_emails(146.128.94.3));
|
||||||
|
# => "security@yourorg.com, someone@yourorg.com"
|
||||||
|
# print fmt_email_string(find_all_emails(146.128.3.3));
|
||||||
|
# => "security@yourorg.com"
|
||||||
|
# }
|
||||||
|
########################################
|
||||||
|
# TODO: make this work with IPv6
|
||||||
|
function find_all_emails(ip: addr): set[string]
|
||||||
|
{
|
||||||
|
if ( ip !in subnet_to_admin_table ) return set();
|
||||||
|
|
||||||
|
local output_values: set[string] = set();
|
||||||
|
local tmp_ip: addr;
|
||||||
|
local i: count;
|
||||||
|
local emails: string;
|
||||||
|
for ( i in one_to_32 )
|
||||||
|
{
|
||||||
|
tmp_ip = mask_addr(ip, one_to_32[i]);
|
||||||
|
emails = subnet_to_admin_table[tmp_ip];
|
||||||
|
if ( emails != "" )
|
||||||
|
add output_values[emails];
|
||||||
|
}
|
||||||
|
return output_values;
|
||||||
|
}
|
||||||
|
|
||||||
|
function fmt_email_string(emails: set[string]): string
|
||||||
|
{
|
||||||
|
local output="";
|
||||||
|
for( email in emails )
|
||||||
|
{
|
||||||
|
if ( output == "" )
|
||||||
|
output = email;
|
||||||
|
else
|
||||||
|
output = fmt("%s, %s", output, email);
|
||||||
|
}
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
########################################
|
||||||
|
|
||||||
|
# Get a software version instance full of zeros.
|
||||||
|
function get_default_software_version(): software_version
|
||||||
|
{
|
||||||
|
local tmp_int: int = 0;
|
||||||
|
local tmp_v: software_version = [$major=tmp_int,
|
||||||
|
$minor=tmp_int,
|
||||||
|
$minor2=tmp_int,
|
||||||
|
$addl=""];
|
||||||
|
return tmp_v;
|
||||||
|
}
|
||||||
|
|
||||||
|
function default_software_parsing(sw: string): software
|
||||||
|
{
|
||||||
|
local software_name = "";
|
||||||
|
local v = get_default_software_version();
|
||||||
|
|
||||||
|
# The regular expression should match the complete version number
|
||||||
|
local version_parts = split_all(sw, /[0-9\-\._]{2,}/);
|
||||||
|
if ( |version_parts| >= 2 )
|
||||||
|
{
|
||||||
|
# Remove the name/version separator
|
||||||
|
software_name = sub(version_parts[1], /.$/, "");
|
||||||
|
local version_numbers = split_n(version_parts[2], /[\-\._[:blank:]]/, F, 4);
|
||||||
|
if ( |version_numbers| >= 4 )
|
||||||
|
v$addl = version_numbers[4];
|
||||||
|
if ( |version_numbers| >= 3 )
|
||||||
|
v$minor2 = to_int(version_numbers[3]);
|
||||||
|
if ( |version_numbers| >= 2 )
|
||||||
|
v$minor = to_int(version_numbers[2]);
|
||||||
|
if ( |version_numbers| >= 1 )
|
||||||
|
v$major = to_int(version_numbers[1]);
|
||||||
|
}
|
||||||
|
local this_software: software = [$name=software_name, $version=v];
|
||||||
|
return this_software;
|
||||||
|
}
|
||||||
|
|
||||||
|
type track_count: record {
|
||||||
|
n: count &default=0;
|
||||||
|
index: count &default=0;
|
||||||
|
};
|
||||||
|
|
||||||
|
function default_track_count(a: addr): track_count
|
||||||
|
{
|
||||||
|
local x: track_count;
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
const default_notice_thresholds: vector of count = {
|
||||||
|
30, 100, 1000, 10000, 100000, 1000000, 10000000,
|
||||||
|
} &redef;
|
||||||
|
|
||||||
|
# This is total rip off from scan.bro, but placed in the global namespace
|
||||||
|
# and slightly reworked to be easier to work with and more general.
|
||||||
|
function check_threshold(v: vector of count, tracker: track_count): bool
|
||||||
|
{
|
||||||
|
if ( tracker$index <= |v| && tracker$n >= v[tracker$index] )
|
||||||
|
{
|
||||||
|
++tracker$index;
|
||||||
|
return T;
|
||||||
|
}
|
||||||
|
return F;
|
||||||
|
}
|
||||||
|
|
||||||
|
function default_check_threshold(tracker: track_count): bool
|
||||||
|
{
|
||||||
|
return check_threshold(default_notice_thresholds, tracker);
|
||||||
|
}
|
||||||
|
|
||||||
|
# This can be used for &default values on tables when the index is an addr.
|
||||||
|
function addr_empty_string_set(a: addr): set[string]
|
||||||
|
{
|
||||||
|
return set();
|
||||||
|
}
|
||||||
|
|
||||||
|
# Some enums for deciding what and when to log.
|
||||||
|
type Directions_and_Hosts: enum {
|
||||||
|
Inbound, Outbound,
|
||||||
|
LocalHosts, RemoteHosts,
|
||||||
|
Enabled, Disabled
|
||||||
|
};
|
||||||
|
const DIRECTIONS = set(Inbound, Outbound, Enabled, Disabled);
|
||||||
|
const HOSTS = set(LocalHosts, RemoteHosts, Enabled, Disabled);
|
||||||
|
|
||||||
|
function id_matches_directions(id: conn_id, d: Directions_and_Hosts): bool
|
||||||
|
{
|
||||||
|
if ( d == Disabled ) return F;
|
||||||
|
|
||||||
|
return ( d == Enabled ||
|
||||||
|
(d == Outbound && is_local_addr(id$orig_h)) ||
|
||||||
|
(d == Inbound && is_local_addr(id$resp_h)) );
|
||||||
|
}
|
||||||
|
|
||||||
|
function addr_matches_hosts(ip: addr, h: Directions_and_Hosts): bool
|
||||||
|
{
|
||||||
|
if ( h == Disabled ) return F;
|
||||||
|
|
||||||
|
return ( h == Enabled ||
|
||||||
|
(h == LocalHosts && is_local_addr(ip)) ||
|
||||||
|
(h == RemoteHosts && !is_local_addr(ip)) );
|
||||||
|
}
|
33
policy/global.bro
Normal file
33
policy/global.bro
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
@load site
|
||||||
|
@load signatures
|
||||||
|
|
||||||
|
const private_address_space: set[subnet] = {10.0.0.0/8, 192.168.0.0/16, 127.0.0.0/8, 172.16.0.0/12};
|
||||||
|
|
||||||
|
# These go along with the functions in functions-ext.bro for mapping IP
|
||||||
|
# addresses to email contact information for IP addresses and subnets.
|
||||||
|
const one_to_32: vector of count = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32};
|
||||||
|
const subnet_to_admin_table: table[subnet] of string = {
|
||||||
|
[0.0.0.0/0] = "",
|
||||||
|
} &redef;
|
||||||
|
|
||||||
|
###############################################################
|
||||||
|
# Make the default signature action ignore certain signatures
|
||||||
|
###############################################################
|
||||||
|
const ignored_signatures = /INTENTIONALLY_BLANK/ &redef;
|
||||||
|
function default_signature_action(sig: string): SigAction
|
||||||
|
{
|
||||||
|
if ( ignored_signatures in sig )
|
||||||
|
return SIG_IGNORE;
|
||||||
|
else
|
||||||
|
return SIG_ALARM;
|
||||||
|
}
|
||||||
|
redef signature_actions &default=default_signature_action;
|
||||||
|
###############################################################
|
||||||
|
|
||||||
|
# This defines the event that is used by the bro-dblogger application
|
||||||
|
# to push data from Bro directly into a database.
|
||||||
|
# see: http://github.com/sethhall/bro-dblogger
|
||||||
|
global db_log: event(db_table: string, data: any);
|
||||||
|
|
||||||
|
@load functions-ext
|
||||||
|
@load logging-ext
|
82
policy/logging.dns-ext.bro
Normal file
82
policy/logging.dns-ext.bro
Normal file
|
@ -0,0 +1,82 @@
|
||||||
|
@load global-ext
|
||||||
|
@load dns-ext
|
||||||
|
|
||||||
|
module DNS;
|
||||||
|
|
||||||
|
export {
|
||||||
|
# Which DNS queries to record.
|
||||||
|
# Choices are: Inbound, Outbound, Enabled, Disabled
|
||||||
|
const query_logging = Enabled &redef;
|
||||||
|
|
||||||
|
# If set to T, this will split inbound and outbound requests
|
||||||
|
# into separate files. F merges everything into a single file.
|
||||||
|
const split_log_file = F &redef;
|
||||||
|
|
||||||
|
# Make this value true to reduce the logs to only what's being
|
||||||
|
# queried for
|
||||||
|
const minimal_logging = F &redef;
|
||||||
|
}
|
||||||
|
|
||||||
|
event bro_init()
|
||||||
|
{
|
||||||
|
LOG::create_logs("dns-ext", query_logging, split_log_file, T);
|
||||||
|
|
||||||
|
if ( minimal_logging )
|
||||||
|
LOG::define_header("dns-ext", cat_sep("\t", "\\N",
|
||||||
|
"ts", "orig_h",
|
||||||
|
"query_type", "query"));
|
||||||
|
else
|
||||||
|
LOG::define_header("dns-ext", cat_sep("\t", "",
|
||||||
|
"ts",
|
||||||
|
"orig_h", "orig_p",
|
||||||
|
"resp_h", "resp_p",
|
||||||
|
"proto", "query_type", "query_class",
|
||||||
|
"query", "transaction_id",
|
||||||
|
"ttl", "flags", "error", "replies"));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
event dns_ext(id: conn_id, di: dns_ext_session_info) &priority=-10
|
||||||
|
{
|
||||||
|
local log = LOG::get_file_by_id("dns-ext", id, F);
|
||||||
|
|
||||||
|
if ( minimal_logging )
|
||||||
|
{
|
||||||
|
print log, cat_sep("\t", "\\N",
|
||||||
|
di$ts,
|
||||||
|
id$orig_h,
|
||||||
|
query_types[di$qtype],
|
||||||
|
di$query);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
local flags: set[string];
|
||||||
|
if ( di$RD )
|
||||||
|
add flags["RD"];
|
||||||
|
if ( di$RA )
|
||||||
|
add flags["RA"];
|
||||||
|
if ( di$TC )
|
||||||
|
add flags["TC"];
|
||||||
|
if ( di$QR )
|
||||||
|
add flags["QR"];
|
||||||
|
if ( di$Z )
|
||||||
|
add flags["Z"];
|
||||||
|
if ( di$AA )
|
||||||
|
add flags["AA"];
|
||||||
|
|
||||||
|
print log, cat_sep("\t", "\\N",
|
||||||
|
di$ts,
|
||||||
|
id$orig_h, port_to_count(id$orig_p),
|
||||||
|
id$resp_h, port_to_count(id$resp_p),
|
||||||
|
get_port_transport_proto(id$resp_p),
|
||||||
|
query_types[di$qtype],
|
||||||
|
dns_class[di$qclass],
|
||||||
|
di$query,
|
||||||
|
fmt("%04x", di$trans_id),
|
||||||
|
fmt("%.0f", interval_to_double(di$TTL)),
|
||||||
|
fmt_str_set(flags, /!!!!/),
|
||||||
|
base_error[di$rcode],
|
||||||
|
fmt_str_set(di$replies, /!!!!/)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue