Merge remote-tracking branch 'origin/master' into topic/seth/file-entropy

This commit is contained in:
Seth Hall 2015-01-30 00:52:41 -05:00
commit 8e53e719f3
1894 changed files with 189157 additions and 279280 deletions

View file

@ -1,8 +1,9 @@
##! This is a utility script that implements the controller interface for the
##! control framework. It's intended to be run to control a remote Bro
##! control framework. It's intended to be run to control a remote Bro
##! and then shutdown.
##!
##! It's intended to be used from the command line like this::
##!
##! bro <scripts> frameworks/control/controller Control::host=<host_addr> Control::port=<host_port> Control::cmd=<command> [Control::arg=<arg>]
@load base/frameworks/control

View file

@ -1,6 +1,6 @@
##! This script enables logging of packet segment data when a protocol
##! parsing violation is encountered. The amount of
##! data from the packet logged is set by the packet_segment_size variable.
##! This script enables logging of packet segment data when a protocol
##! parsing violation is encountered. The amount of data from the
##! packet logged is set by the :bro:see:`DPD::packet_segment_size` variable.
##! A caveat to logging packet data is that in some cases, the packet may
##! not be the packet that actually caused the protocol violation.
@ -10,8 +10,8 @@ module DPD;
export {
redef record Info += {
## A chunk of the payload the most likely resulted in the protocol
## violation.
## A chunk of the payload that most likely resulted in the
## protocol violation.
packet_segment: string &optional &log;
};

View file

@ -23,35 +23,50 @@ export {
/application\/jar/ |
/video\/mp4/ &redef;
## The malware hash registry runs each malware sample through several A/V engines.
## Team Cymru returns a percentage to indicate how many A/V engines flagged the
## sample as malicious. This threshold allows you to require a minimum detection
## rate.
## The Match notice has a sub message with a URL where you can get more
## information about the file. The %s will be replaced with the SHA-1
## hash of the file.
const match_sub_url = "https://www.virustotal.com/en/search/?query=%s" &redef;
## The malware hash registry runs each malware sample through several
## A/V engines. Team Cymru returns a percentage to indicate how
## many A/V engines flagged the sample as malicious. This threshold
## allows you to require a minimum detection rate.
const notice_threshold = 10 &redef;
}
event file_hash(f: fa_file, kind: string, hash: string)
function do_mhr_lookup(hash: string, fi: Notice::FileInfo)
{
if ( kind=="sha1" && match_file_types in f$mime_type )
local hash_domain = fmt("%s.malware.hash.cymru.com", hash);
when ( local MHR_result = lookup_hostname_txt(hash_domain) )
{
local hash_domain = fmt("%s.malware.hash.cymru.com", hash);
when ( local MHR_result = lookup_hostname_txt(hash_domain) )
# Data is returned as "<dateFirstDetected> <detectionRate>"
local MHR_answer = split1(MHR_result, / /);
if ( |MHR_answer| == 2 )
{
# Data is returned as "<dateFirstDetected> <detectionRate>"
local MHR_answer = split1(MHR_result, / /);
if ( |MHR_answer| == 2 )
local mhr_detect_rate = to_count(MHR_answer[2]);
if ( mhr_detect_rate >= notice_threshold )
{
local mhr_first_detected = double_to_time(to_double(MHR_answer[1]));
local mhr_detect_rate = to_count(MHR_answer[2]);
local readable_first_detected = strftime("%Y-%m-%d %H:%M:%S", mhr_first_detected);
if ( mhr_detect_rate >= notice_threshold )
{
local message = fmt("Malware Hash Registry Detection rate: %d%% Last seen: %s", mhr_detect_rate, readable_first_detected);
local virustotal_url = fmt("https://www.virustotal.com/en/file/%s/analysis/", hash);
NOTICE([$note=Match, $msg=message, $sub=virustotal_url, $f=f]);
}
local message = fmt("Malware Hash Registry Detection rate: %d%% Last seen: %s", mhr_detect_rate, readable_first_detected);
local virustotal_url = fmt(match_sub_url, hash);
# We don't have the full fa_file record here in order to
# avoid the "when" statement cloning it (expensive!).
local n: Notice::Info = Notice::Info($note=Match, $msg=message, $sub=virustotal_url);
Notice::populate_file_info2(fi, n);
NOTICE(n);
}
}
}
}
event file_hash(f: fa_file, kind: string, hash: string)
{
if ( kind == "sha1" && f?$info && f$info?$mime_type &&
match_file_types in f$info$mime_type )
do_mhr_lookup(hash, Notice::create_file_info(f));
}

View file

@ -1,4 +1,4 @@
# Perform MD5 and SHA1 hashing on all files.
##! Perform MD5 and SHA1 hashing on all files.
event file_new(f: fa_file)
{

View file

@ -18,7 +18,7 @@ export {
do_notice: bool &default=F;
## Restrictions on when notices are created to only create
## them if the do_notice field is T and the notice was
## them if the *do_notice* field is T and the notice was
## seen in the indicated location.
if_in: Intel::Where &optional;
};

View file

@ -0,0 +1 @@
Scripts that send data to the intelligence framework.

View file

@ -1,8 +1,10 @@
@load ./conn-established
@load ./dns
@load ./http-host-header
@load ./file-hashes
@load ./file-names
@load ./http-headers
@load ./http-url
@load ./http-user-agents
@load ./ssl
@load ./smtp
@load ./smtp-url-extraction
@load ./smtp-url-extraction
@load ./x509

View file

@ -0,0 +1,12 @@
@load base/frameworks/intel
@load ./where-locations
event file_hash(f: fa_file, kind: string, hash: string)
{
local seen = Intel::Seen($indicator=hash,
$indicator_type=Intel::FILE_HASH,
$f=f,
$where=Files::IN_HASH);
Intel::seen(seen);
}

View file

@ -0,0 +1,11 @@
@load base/frameworks/intel
@load ./where-locations
event file_new(f: fa_file)
{
if ( f?$info && f$info?$filename )
Intel::seen([$indicator=f$info$filename,
$indicator_type=Intel::FILE_NAME,
$f=f,
$where=Files::IN_NAME]);
}

View file

@ -0,0 +1,53 @@
@load base/frameworks/intel
@load ./where-locations
@load base/utils/addrs
event http_header(c: connection, is_orig: bool, name: string, value: string)
{
if ( is_orig )
{
switch ( name )
{
case "HOST":
if ( is_valid_ip(value) )
Intel::seen([$host=to_addr(value),
$indicator_type=Intel::ADDR,
$conn=c,
$where=HTTP::IN_HOST_HEADER]);
else
Intel::seen([$indicator=value,
$indicator_type=Intel::DOMAIN,
$conn=c,
$where=HTTP::IN_HOST_HEADER]);
break;
case "REFERER":
Intel::seen([$indicator=sub(value, /^.*:\/\//, ""),
$indicator_type=Intel::URL,
$conn=c,
$where=HTTP::IN_REFERRER_HEADER]);
break;
case "X-FORWARDED-FOR":
if ( is_valid_ip(value) )
{
local addrs = find_ip_addresses(value);
for ( i in addrs )
{
Intel::seen([$host=to_addr(addrs[i]),
$indicator_type=Intel::ADDR,
$conn=c,
$where=HTTP::IN_X_FORWARDED_FOR_HEADER]);
}
}
break;
case "USER-AGENT":
Intel::seen([$indicator=value,
$indicator_type=Intel::SOFTWARE,
$conn=c,
$where=HTTP::IN_USER_AGENT_HEADER]);
break;
}
}
}

View file

@ -1,11 +0,0 @@
@load base/frameworks/intel
@load ./where-locations
event http_header(c: connection, is_orig: bool, name: string, value: string)
{
if ( is_orig && name == "HOST" )
Intel::seen([$indicator=value,
$indicator_type=Intel::DOMAIN,
$conn=c,
$where=HTTP::IN_HOST_HEADER]);
}

View file

@ -1,12 +0,0 @@
@load base/frameworks/intel
@load ./where-locations
event http_header(c: connection, is_orig: bool, name: string, value: string)
{
if ( is_orig && name == "USER-AGENT" )
Intel::seen([$indicator=value,
$indicator_type=Intel::SOFTWARE,
$conn=c,
$where=HTTP::IN_USER_AGENT_HEADER]);
}

View file

@ -2,31 +2,9 @@
@load base/protocols/ssl
@load ./where-locations
event x509_certificate(c: connection, is_orig: bool, cert: X509, chain_idx: count, chain_len: count, der_cert: string)
event ssl_extension_server_name(c: connection, is_orig: bool, names: string_vec)
{
if ( chain_idx == 0 )
{
if ( /emailAddress=/ in cert$subject )
{
local email = sub(cert$subject, /^.*emailAddress=/, "");
email = sub(email, /,.*$/, "");
Intel::seen([$indicator=email,
$indicator_type=Intel::EMAIL,
$conn=c,
$where=(is_orig ? SSL::IN_CLIENT_CERT : SSL::IN_SERVER_CERT)]);
}
Intel::seen([$indicator=sha1_hash(der_cert),
$indicator_type=Intel::CERT_HASH,
$conn=c,
$where=(is_orig ? SSL::IN_CLIENT_CERT : SSL::IN_SERVER_CERT)]);
}
}
event ssl_extension(c: connection, is_orig: bool, code: count, val: string)
{
if ( is_orig && SSL::extensions[code] == "server_name" &&
c?$ssl && c$ssl?$server_name )
if ( is_orig && c?$ssl && c$ssl?$server_name )
Intel::seen([$indicator=c$ssl$server_name,
$indicator_type=Intel::DOMAIN,
$conn=c,

View file

@ -4,10 +4,14 @@ export {
redef enum Intel::Where += {
Conn::IN_ORIG,
Conn::IN_RESP,
Files::IN_HASH,
Files::IN_NAME,
DNS::IN_REQUEST,
DNS::IN_RESPONSE,
HTTP::IN_HOST_HEADER,
HTTP::IN_REFERRER_HEADER,
HTTP::IN_USER_AGENT_HEADER,
HTTP::IN_X_FORWARDED_FOR_HEADER,
HTTP::IN_URL,
SMTP::IN_MAIL_FROM,
SMTP::IN_RCPT_TO,
@ -17,9 +21,8 @@ export {
SMTP::IN_REPLY_TO,
SMTP::IN_X_ORIGINATING_IP_HEADER,
SMTP::IN_MESSAGE,
SSL::IN_SERVER_CERT,
SSL::IN_CLIENT_CERT,
SSL::IN_SERVER_NAME,
SMTP::IN_HEADER,
X509::IN_CERT,
};
}

View file

@ -0,0 +1,16 @@
@load base/frameworks/intel
@load base/files/x509
@load ./where-locations
event x509_certificate(f: fa_file, cert_ref: opaque of x509, cert: X509::Certificate)
{
if ( /emailAddress=/ in cert$subject )
{
local email = sub(cert$subject, /^.*emailAddress=/, "");
email = sub(email, /,.*$/, "");
Intel::seen([$indicator=email,
$indicator_type=Intel::EMAIL,
$f=f,
$where=X509::IN_CERT]);
}
}

View file

@ -8,23 +8,23 @@ export {
const max_bpf_shunts = 100 &redef;
## Call this function to use BPF to shunt a connection (to prevent the
## data packets from reaching Bro). For TCP connections, control packets
## are still allowed through so that Bro can continue logging the connection
## and it can stop shunting once the connection ends.
## data packets from reaching Bro). For TCP connections, control
## packets are still allowed through so that Bro can continue logging
## the connection and it can stop shunting once the connection ends.
global shunt_conn: function(id: conn_id): bool;
## This function will use a BPF expresssion to shunt traffic between
## This function will use a BPF expression to shunt traffic between
## the two hosts given in the `conn_id` so that the traffic is never
## exposed to Bro's traffic processing.
global shunt_host_pair: function(id: conn_id): bool;
## Remove shunting for a host pair given as a `conn_id`. The filter
## is not immediately removed. It waits for the occassional filter
## is not immediately removed. It waits for the occasional filter
## update done by the `PacketFilter` framework.
global unshunt_host_pair: function(id: conn_id): bool;
## Performs the same function as the `unshunt_host_pair` function, but
## it forces an immediate filter update.
## Performs the same function as the :bro:id:`PacketFilter::unshunt_host_pair`
## function, but it forces an immediate filter update.
global force_unshunt_host_pair: function(id: conn_id): bool;
## Retrieve the currently shunted connections.
@ -34,12 +34,13 @@ export {
global current_shunted_host_pairs: function(): set[conn_id];
redef enum Notice::Type += {
## Indicative that :bro:id:`PacketFilter::max_bpf_shunts` connections
## are already being shunted with BPF filters and no more are allowed.
## Indicative that :bro:id:`PacketFilter::max_bpf_shunts`
## connections are already being shunted with BPF filters and
## no more are allowed.
No_More_Conn_Shunts_Available,
## Limitations in BPF make shunting some connections with BPF impossible.
## This notice encompasses those various cases.
## Limitations in BPF make shunting some connections with BPF
## impossible. This notice encompasses those various cases.
Cannot_BPF_Shunt_Conn,
};
}

View file

@ -1,4 +1,4 @@
##! Provides the possibly to define software names that are interesting to
##! Provides the possibility to define software names that are interesting to
##! watch for changes. A notice is generated if software versions change on a
##! host.
@ -9,15 +9,15 @@ module Software;
export {
redef enum Notice::Type += {
## For certain software, a version changing may matter. In that case,
## this notice will be generated. Software that matters if the version
## changes can be configured with the
## For certain software, a version changing may matter. In that
## case, this notice will be generated. Software that matters
## if the version changes can be configured with the
## :bro:id:`Software::interesting_version_changes` variable.
Software_Version_Change,
};
## Some software is more interesting when the version changes and this is
## a set of all software that should raise a notice when a different
## Some software is more interesting when the version changes and this
## is a set of all software that should raise a notice when a different
## version is seen on a host.
const interesting_version_changes: set[string] = { } &redef;
}

View file

@ -1,5 +1,5 @@
##! Provides a variable to define vulnerable versions of software and if a
##! a version of that software as old or older than the defined version a
##! Provides a variable to define vulnerable versions of software and if
##! a version of that software is as old or older than the defined version a
##! notice will be generated.
@load base/frameworks/control
@ -21,7 +21,7 @@ export {
min: Software::Version &optional;
## The maximum vulnerable version. This field is deliberately
## not optional because a maximum vulnerable version must
## always be defined. This assumption may become incorrent
## always be defined. This assumption may become incorrect
## if all future versions of some software are to be considered
## vulnerable. :)
max: Software::Version;

View file

@ -0,0 +1,69 @@
##! Windows systems access a Microsoft Certificate Revocation List (CRL) periodically. The
##! user agent for these requests reveals which version of Crypt32.dll installed on the system,
##! which can uniquely identify the version of Windows that's running.
##!
##! This script will log the version of Windows that was identified to the Software framework.
@load base/protocols/http
@load base/frameworks/software
module OS;
export {
redef enum Software::Type += {
## Identifier for Windows operating system versions
WINDOWS,
};
type Software::name_and_version: record {
name : string;
version: Software::Version;
};
const crypto_api_mapping: table[string] of Software::name_and_version = {
["Microsoft-CryptoAPI/5.131.2195.6661"] = [$name="Windows", $version=[$major=5, $minor=131, $minor2=2195, $minor3=6661, $addl="2000 SP4"]],
["Microsoft-CryptoAPI/5.131.2195.6824"] = [$name="Windows", $version=[$major=5, $minor=131, $minor2=2195, $minor3=6824, $addl="2000 with MS04-11"]],
["Microsoft-CryptoAPI/5.131.2195.6926"] = [$name="Windows", $version=[$major=5, $minor=131, $minor2=2195, $minor3=6926, $addl="2000 with Hotfix 98830"]],
["Microsoft-CryptoAPI/5.131.2600.0"] = [$name="Windows", $version=[$major=5, $minor=131, $minor2=2600, $minor3=0, $addl="XP SP0"]],
["Microsoft-CryptoAPI/5.131.2600.1106"] = [$name="Windows", $version=[$major=5, $minor=131, $minor2=2600, $minor3=1106, $addl="XP SP1"]],
["Microsoft-CryptoAPI/5.131.2600.2180"] = [$name="Windows", $version=[$major=5, $minor=131, $minor2=2600, $minor3=2180, $addl="XP SP2"]],
["Microsoft-CryptoAPI/5.131.2600.3180"] = [$name="Windows", $version=[$major=5, $minor=131, $minor2=2600, $minor3=3180, $addl="XP SP3 Beta 1"]],
["Microsoft-CryptoAPI/5.131.2600.3205"] = [$name="Windows", $version=[$major=5, $minor=131, $minor2=2600, $minor3=3205, $addl="XP SP3 Beta 2"]],
["Microsoft-CryptoAPI/5.131.2600.3249"] = [$name="Windows", $version=[$major=5, $minor=131, $minor2=2600, $minor3=3249, $addl="XP SP3 RC Beta"]],
["Microsoft-CryptoAPI/5.131.2600.3264"] = [$name="Windows", $version=[$major=5, $minor=131, $minor2=2600, $minor3=3264, $addl="XP SP3 RC1"]],
["Microsoft-CryptoAPI/5.131.2600.3282"] = [$name="Windows", $version=[$major=5, $minor=131, $minor2=2600, $minor3=3282, $addl="XP SP3 RC1 Update"]],
["Microsoft-CryptoAPI/5.131.2600.3300"] = [$name="Windows", $version=[$major=5, $minor=131, $minor2=2600, $minor3=3300, $addl="XP SP3 RC2"]],
["Microsoft-CryptoAPI/5.131.2600.3311"] = [$name="Windows", $version=[$major=5, $minor=131, $minor2=2600, $minor3=3311, $addl="XP SP3 RC2 Update"]],
["Microsoft-CryptoAPI/5.131.2600.5508"] = [$name="Windows", $version=[$major=5, $minor=131, $minor2=2600, $minor3=5508, $addl="XP SP3 RC2 Update 2"]],
["Microsoft-CryptoAPI/5.131.2600.5512"] = [$name="Windows", $version=[$major=5, $minor=131, $minor2=2600, $minor3=5512, $addl="XP SP3"]],
["Microsoft-CryptoAPI/5.131.3790.0"] = [$name="Windows", $version=[$major=5, $minor=131, $minor2=3790, $minor3=0, $addl="XP x64 or Server 2003 SP0"]],
["Microsoft-CryptoAPI/5.131.3790.1830"] = [$name="Windows", $version=[$major=5, $minor=131, $minor2=3790, $minor3=1830, $addl="XP x64 or Server 2003 SP1"]],
["Microsoft-CryptoAPI/5.131.3790.3959"] = [$name="Windows", $version=[$major=5, $minor=131, $minor2=3790, $minor3=3959, $addl="XP x64 or Server 2003 SP2"]],
["Microsoft-CryptoAPI/5.131.3790.5235"] = [$name="Windows", $version=[$major=5, $minor=131, $minor2=3790, $minor3=5235, $addl="XP x64 or Server 2003 with MS13-095"]],
["Microsoft-CryptoAPI/6.0"] = [$name="Windows", $version=[$major=6, $minor=0, $addl="Vista or Server 2008"]],
["Microsoft-CryptoAPI/6.1"] = [$name="Windows", $version=[$major=6, $minor=1, $addl="7 or Server 2008 R2"]],
["Microsoft-CryptoAPI/6.2"] = [$name="Windows", $version=[$major=6, $minor=2, $addl="8 or Server 2012"]],
["Microsoft-CryptoAPI/6.3"] = [$name="Windows", $version=[$major=6, $minor=3, $addl="8.1 or Server 2012 R2"]],
["Microsoft-CryptoAPI/6.4"] = [$name="Windows", $version=[$major=6, $minor=4, $addl="10 Technical Preview"]],
} &redef;
}
event HTTP::log_http(rec: HTTP::Info) &priority=5
{
if ( rec?$host && rec?$user_agent && rec$host == "crl.microsoft.com" &&
/Microsoft-CryptoAPI\// in rec$user_agent )
{
if ( rec$user_agent !in crypto_api_mapping )
{
Software::found(rec$id, [$unparsed_version=sub(rec$user_agent, /Microsoft-CryptoAPI/, "Unknown CryptoAPI Version"), $host=rec$id$orig_h, $software_type=WINDOWS]);
}
else
{
local result = crypto_api_mapping[rec$user_agent];
Software::found(rec$id, [$version=result$version, $name=result$name, $host=rec$id$orig_h, $software_type=WINDOWS]);
}
}
}