Add @load-sigs directive for loading signature files (addresses #551).

This commit is contained in:
Jon Siwek 2012-06-01 14:10:23 -05:00
parent c5ae071500
commit dd4dd0ca6e
12 changed files with 67 additions and 13 deletions

View file

@ -51,13 +51,18 @@ This script contains a default event handler that raises
:bro:enum:`Signatures::Sensitive_Signature` :doc:`Notices <notice>`
(as well as others; see the beginning of the script).
As signatures are independent of Bro's policy scripts, they are put
into their own file(s). There are two ways to specify which files
contain signatures: By using the ``-s`` flag when you invoke Bro, or
by extending the Bro variable :bro:id:`signature_files` using the ``+=``
operator. If a signature file is given without a path, it is searched
along the normal ``BROPATH``. The default extension of the file name
is ``.sig``, and Bro appends that automatically when necessary.
As signatures are independent of Bro's policy scripts, they are put into
their own file(s). There are three ways to specify which files contain
signatures: By using the ``-s`` flag when you invoke Bro, or by
extending the Bro variable :bro:id:`signature_files` using the ``+=``
operator, or by using the ``@load-sigs`` directive inside a Bro script.
If a signature file is given without a full path, it is searched for
along the normal ``BROPATH``. Additionally, the ``@load-sigs``
directive can be used to load signature files in a path relative to the
Bro script in which it's placed, e.g. ``@load-sigs ./mysigs.sig`` will
expect that signature file in the same directory as the Bro script. The
default extension of the file name is ``.sig``, and Bro appends that
automatically when necessary.
Signature language
==================

View file

@ -3,8 +3,7 @@
module DPD;
## Add the DPD signatures to the signature framework.
redef signature_files += "base/frameworks/dpd/dpd.sig";
@load-sigs ./dpd.sig
export {
## Add the DPD logging stream identifier.

View file

@ -615,7 +615,9 @@ function add_signature_file(sold: string, snew: string): string
}
## Signature files to read. Use ``redef signature_files += "foo.sig"`` to
## extend. Signature files will be searched relative to ``BROPATH``.
## extend. Signature files added this way will be searched relative to
## ``BROPATH``. Using the ``@load-sigs`` directive instead is preferred
## since that can search paths relative to the current script.
global signature_files = "" &add_func = add_signature_file;
## ``p0f`` fingerprint file to use. Will be searched relative to ``BROPATH``.

View file

@ -6,7 +6,8 @@
@load ./utils
# Add the magic number signatures to the core signature set.
redef signature_files += "base/protocols/http/file-ident.sig";
@load-sigs ./file-ident.sig
# Ignore the signatures used to match files
redef Signatures::ignored_ids += /^matchfile-/;

View file

@ -4,9 +4,10 @@
@load base/frameworks/software
@load base/protocols/http
@load-sigs ./detect-webapps.sig
module HTTP;
redef signature_files += "protocols/http/detect-webapps.sig";
# Ignore the signatures used to match webapps
redef Signatures::ignored_ids += /^webapp-/;

View file

@ -25,7 +25,7 @@ redef Software::vulnerable_versions += {
@load frameworks/software/version-changes
# This adds signatures to detect cleartext forward and reverse windows shells.
redef signature_files += "frameworks/signatures/detect-windows-shells.sig";
@load-sigs frameworks/signatures/detect-windows-shells
# Uncomment the following line to begin receiving (by default hourly) emails
# containing all of your notices.

View file

@ -69,6 +69,7 @@ PktSrc* current_pktsrc = 0;
IOSource* current_iosrc;
std::list<ScannedFile> files_scanned;
std::vector<string> sig_files;
RETSIGTYPE watchdog(int /* signo */)
{

View file

@ -111,5 +111,6 @@ struct ScannedFile {
};
extern std::list<ScannedFile> files_scanned;
extern std::vector<string> sig_files;
#endif

View file

@ -838,6 +838,10 @@ int main(int argc, char** argv)
if ( *s )
rule_files.append(s);
// Append signature files defined in @load-sigs
for ( size_t i = 0; i < sig_files.size(); ++i )
rule_files.append(copy_string(sig_files[i].c_str()));
if ( rule_files.length() > 0 )
{
rule_matcher = new RuleMatcher(RE_level);

View file

@ -358,6 +358,22 @@ when return TOK_WHEN;
(void) load_files(new_file);
}
@load-sigs{WS}{FILE} {
const char* new_sig_file = skip_whitespace(yytext + 10);
const char* full_filename = 0;
FILE* f = search_for_file(new_sig_file, "sig", &full_filename, false, 0);
if ( f )
{
sig_files.push_back(full_filename);
fclose(f);
delete [] full_filename;
}
else
reporter->Error("failed to find file associated with @load-sigs %s",
new_sig_file);
}
@unload{WS}{FILE} {
// Skip "@unload".
const char* new_file = skip_whitespace(yytext + 7);

View file

@ -0,0 +1,3 @@
[orig_h=141.142.220.118, orig_p=35642/tcp, resp_h=208.80.152.2, resp_p=80/tcp]
works
GET /images/wikimedia-button.png HTTP/1.1^M^JHost: meta.wikimedia.org^M^JUser-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.15) Geck...

View file

@ -0,0 +1,21 @@
# A test of signature loading using @load-sigs.
# @TEST-EXEC: bro -C -r $TRACES/wikipedia.trace %INPUT >output
# @TEST-EXEC: btest-diff output
@load-sigs ./subdir/mysigs.sig
event signature_match(state: signature_state, msg: string, data: string)
{
print state$conn$id;
print msg;
print data;
}
@TEST-START-FILE subdir/mysigs.sig
signature my-sig {
ip-proto == tcp
payload /GET \/images/
event "works"
}
@TEST-END-FILE