diff --git a/doc/signatures.rst b/doc/signatures.rst index 7a1b164dbb..f65215eceb 100644 --- a/doc/signatures.rst +++ b/doc/signatures.rst @@ -51,13 +51,18 @@ This script contains a default event handler that raises :bro:enum:`Signatures::Sensitive_Signature` :doc:`Notices ` (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 ================== diff --git a/scripts/base/frameworks/dpd/main.bro b/scripts/base/frameworks/dpd/main.bro index 9eb0b467f8..a5349b6cfb 100644 --- a/scripts/base/frameworks/dpd/main.bro +++ b/scripts/base/frameworks/dpd/main.bro @@ -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. diff --git a/scripts/base/init-bare.bro b/scripts/base/init-bare.bro index da2b742725..c35acd525d 100644 --- a/scripts/base/init-bare.bro +++ b/scripts/base/init-bare.bro @@ -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``. diff --git a/scripts/base/protocols/http/file-ident.bro b/scripts/base/protocols/http/file-ident.bro index f2cb9d19ac..b493f02bf0 100644 --- a/scripts/base/protocols/http/file-ident.bro +++ b/scripts/base/protocols/http/file-ident.bro @@ -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-/; diff --git a/scripts/policy/protocols/http/detect-webapps.bro b/scripts/policy/protocols/http/detect-webapps.bro index 796da5c29a..fb805bfd33 100644 --- a/scripts/policy/protocols/http/detect-webapps.bro +++ b/scripts/policy/protocols/http/detect-webapps.bro @@ -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-/; diff --git a/scripts/site/local.bro b/scripts/site/local.bro index 9681f7a75c..db1a786839 100644 --- a/scripts/site/local.bro +++ b/scripts/site/local.bro @@ -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. diff --git a/src/Net.cc b/src/Net.cc index 5bfae2275b..328998b011 100644 --- a/src/Net.cc +++ b/src/Net.cc @@ -69,6 +69,7 @@ PktSrc* current_pktsrc = 0; IOSource* current_iosrc; std::list files_scanned; +std::vector sig_files; RETSIGTYPE watchdog(int /* signo */) { diff --git a/src/Net.h b/src/Net.h index 9e68cc025b..5b959d1688 100644 --- a/src/Net.h +++ b/src/Net.h @@ -111,5 +111,6 @@ struct ScannedFile { }; extern std::list files_scanned; +extern std::vector sig_files; #endif diff --git a/src/main.cc b/src/main.cc index 9e9c867714..b1d0a4d723 100644 --- a/src/main.cc +++ b/src/main.cc @@ -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); diff --git a/src/scan.l b/src/scan.l index 30d521c6bd..645ce659cd 100644 --- a/src/scan.l +++ b/src/scan.l @@ -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); diff --git a/testing/btest/Baseline/core.load-sigs/output b/testing/btest/Baseline/core.load-sigs/output new file mode 100644 index 0000000000..2a22b47ad4 --- /dev/null +++ b/testing/btest/Baseline/core.load-sigs/output @@ -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... diff --git a/testing/btest/core/load-sigs.bro b/testing/btest/core/load-sigs.bro new file mode 100644 index 0000000000..3e08338f2c --- /dev/null +++ b/testing/btest/core/load-sigs.bro @@ -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