diff --git a/CHANGES b/CHANGES index b0c1bac2f9..024276620f 100644 --- a/CHANGES +++ b/CHANGES @@ -1,4 +1,38 @@ +2.1-377 | 2013-03-17 17:36:09 -0700 + + * Fixing potential leak in DNS error case. (Vlad Grigorescu) + +2.1-375 | 2013-03-17 13:14:26 -0700 + + * Add base64 encoding functionality, including new BiFs + encode_base64() and encode_base64_custom(). (Bernhard Amann) + + * Replace call to external "openssl" in extract-certs-pem.bro with + that encode_base64(). (Bernhard Amann) + + * Adding a test for extract-certs-pem.pem. (Robin Sommer) + + * Renaming Base64Decoder to Base64Converter. (Robin Sommer) + +2.1-366 | 2013-03-17 12:35:59 -0700 + + * Correctly handle DNS lookups for software version ranges. (Seth + Hall) + + * Improvements to vulnerable software detection. (Seth Hall) + + - Add a DNS based updating method. This needs to be tested + still. + + - Vulnerable version ranges are used now instead of only single + versions. This can deal with software with multiple stable + major versions. + + * Update software version parsing and comparison to account for a + third numeric subversion. Also, $addl is now compared numerically + if the value is actually numeric. (Seth Hall) + 2.1-361 | 2013-03-13 07:18:22 -0700 * Add check for truncated link frames. Addresses #962. (Jacob diff --git a/VERSION b/VERSION index 9c30e5948f..ccb2f89fe9 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.1-361 +2.1-377 diff --git a/aux/broctl b/aux/broctl index 3d2172a60a..3e3ada3c2e 160000 --- a/aux/broctl +++ b/aux/broctl @@ -1 +1 @@ -Subproject commit 3d2172a60aa503745c92cef8ab3020d1dfc13f0d +Subproject commit 3e3ada3c2efebeda1278b8897859dd7c7d61e671 diff --git a/scripts/base/frameworks/software/main.bro b/scripts/base/frameworks/software/main.bro index 7471076335..fefc465e1a 100644 --- a/scripts/base/frameworks/software/main.bro +++ b/scripts/base/frameworks/software/main.bro @@ -29,6 +29,8 @@ export { minor: count &optional; ## Minor subversion number minor2: count &optional; + ## Minor updates number + minor3: count &optional; ## Additional version string (e.g. "beta42") addl: string &optional; } &log; @@ -146,10 +148,10 @@ function parse(unparsed_version: string): Description if ( /^[\/\-\._v\(]/ in sv ) sv = strip(sub(version_parts[2], /^\(?[\/\-\._v\(]/, "")); local version_numbers = split_n(sv, /[\-\._,\[\(\{ ]/, F, 3); - if ( 4 in version_numbers && version_numbers[4] != "" ) - v$addl = strip(version_numbers[4]); + if ( 5 in version_numbers && version_numbers[5] != "" ) + v$addl = strip(version_numbers[5]); else if ( 3 in version_parts && version_parts[3] != "" && - version_parts[3] != ")" ) + version_parts[3] != ")" ) { if ( /^[[:blank:]]*\([a-zA-Z0-9\-\._[:blank:]]*\)/ in version_parts[3] ) { @@ -177,7 +179,9 @@ function parse(unparsed_version: string): Description } } - + + if ( 4 in version_numbers && version_numbers[4] != "" ) + v$minor3 = extract_count(version_numbers[4]); if ( 3 in version_numbers && version_numbers[3] != "" ) v$minor2 = extract_count(version_numbers[3]); if ( 2 in version_numbers && version_numbers[2] != "" ) @@ -332,8 +336,25 @@ function cmp_versions(v1: Version, v2: Version): int return v1?$minor2 ? 1 : -1; } + if ( v1?$minor3 && v2?$minor3 ) + { + if ( v1$minor3 < v2$minor3 ) + return -1; + if ( v1$minor3 > v2$minor3 ) + return 1; + } + else + { + if ( !v1?$minor3 && !v2?$minor3 ) + { } + else + return v1?$minor3 ? 1 : -1; + } + if ( v1?$addl && v2?$addl ) + { return strcmp(v1$addl, v2$addl); + } else { if ( !v1?$addl && !v2?$addl ) @@ -341,6 +362,9 @@ function cmp_versions(v1: Version, v2: Version): int else return v1?$addl ? 1 : -1; } + + # A catcher return that should never be reached...hopefully + return 0; } function software_endpoint_name(id: conn_id, host: addr): string @@ -351,10 +375,11 @@ function software_endpoint_name(id: conn_id, host: addr): string # Convert a version into a string "a.b.c-x". function software_fmt_version(v: Version): string { - return fmt("%d.%d.%d%s", - v?$major ? v$major : 0, - v?$minor ? v$minor : 0, - v?$minor2 ? v$minor2 : 0, + return fmt("%s%s%s%s%s", + v?$major ? fmt("%d", v$major) : "0", + v?$minor ? fmt(".%d", v$minor) : "", + v?$minor2 ? fmt(".%d", v$minor2) : "", + v?$minor3 ? fmt(".%d", v$minor3) : "", v?$addl ? fmt("-%s", v$addl) : ""); } diff --git a/scripts/base/protocols/ssl/main.bro b/scripts/base/protocols/ssl/main.bro index 2dcbfee5ef..c6c4091a87 100644 --- a/scripts/base/protocols/ssl/main.bro +++ b/scripts/base/protocols/ssl/main.bro @@ -67,11 +67,6 @@ export { ## (especially with large file transfers). const disable_analyzer_after_detection = T &redef; - ## The openssl command line utility. If it's in the path the default - ## value will work, otherwise a full path string can be supplied for the - ## utility. - const openssl_util = "openssl" &redef; - ## The maximum amount of time a script can delay records from being logged. const max_log_delay = 15secs &redef; diff --git a/scripts/policy/frameworks/software/vulnerable.bro b/scripts/policy/frameworks/software/vulnerable.bro index c2c2ba5b32..aedb309dba 100644 --- a/scripts/policy/frameworks/software/vulnerable.bro +++ b/scripts/policy/frameworks/software/vulnerable.bro @@ -1,7 +1,8 @@ -##! 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 +##! a version of that software as old or older than the defined version a ##! notice will be generated. +@load base/frameworks/control @load base/frameworks/notice @load base/frameworks/software @@ -13,17 +14,126 @@ export { Vulnerable_Version, }; - ## This is a table of software versions indexed by the name of the - ## software and yielding the latest version that is vulnerable. - const vulnerable_versions: table[string] of Version &redef; + type VulnerableVersionRange: record { + ## The minimal version of a vulnerable version range. This + ## field can be undefined if all previous versions of a piece + ## of software are vulnerable. + 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 + ## if all future versions of some software are to be considered + ## vulnerable. :) + max: Software::Version; + }; + + ## The DNS zone where runtime vulnerable software updates will + ## be loaded from. + const vulnerable_versions_update_endpoint = "" &redef; + + ## The interval at which vulnerable versions should grab updates + ## over DNS. + const vulnerable_versions_update_interval = 1hr &redef; + + ## This is a table of software versions indexed by the name of the + ## software and a set of version ranges that are declared to be + ## vulnerable for that software. + const vulnerable_versions: table[string] of set[VulnerableVersionRange] = table() &redef; } +global internal_vulnerable_versions: table[string] of set[VulnerableVersionRange] = table(); + +event Control::configuration_update() + { + internal_vulnerable_versions = table(); + + # Copy the const vulnerable versions into the global modifiable one. + for ( sw in vulnerable_versions ) + internal_vulnerable_versions[sw] = vulnerable_versions[sw]; + } + +function decode_vulnerable_version_range(vuln_sw: string): VulnerableVersionRange + { + # Create a max value with a dunce value only because the $max field + # is not optional. + local vvr: Software::VulnerableVersionRange = [$max=[$major=0]]; + + if ( /max=/ !in vuln_sw ) + { + Reporter::warning(fmt("The vulnerable software detection script encountered a version with no max value (which is required). %s", vuln_sw)); + return vvr; + } + + local versions = split1(vuln_sw, /\x09/); + + for ( i in versions ) + { + local field_and_ver = split1(versions[i], /=/); + if ( |field_and_ver| != 2 ) + return vvr; #failure! + + local ver = Software::parse(field_and_ver[2])$version; + if ( field_and_ver[1] == "min" ) + vvr$min = ver; + else if ( field_and_ver[1] == "max" ) + vvr$max = ver; + } + + return vvr; + } + +event grab_vulnerable_versions(i: count) + { + if ( vulnerable_versions_update_endpoint == "" ) + { + # Reschedule this event in case the user updates the setting at runtime. + schedule vulnerable_versions_update_interval { grab_vulnerable_versions(1) }; + return; + } + + when ( local result = lookup_hostname_txt(cat(i,".",vulnerable_versions_update_endpoint)) ) + { + local parts = split1(result, /\x09/); + if ( |parts| != 2 ) #failure or end of list! + { + schedule vulnerable_versions_update_interval { grab_vulnerable_versions(1) }; + return; + } + + local sw = parts[1]; + local vvr = decode_vulnerable_version_range(parts[2]); + if ( sw !in internal_vulnerable_versions ) + internal_vulnerable_versions[sw] = set(); + add internal_vulnerable_versions[sw][vvr]; + + event grab_vulnerable_versions(i+1); + } + timeout 5secs + { + # In case a lookup fails, try starting over in one minute. + schedule 1min { grab_vulnerable_versions(1) }; + } + } + +event bro_init() + { + event grab_vulnerable_versions(1); + } + event log_software(rec: Info) { - if ( rec$name in vulnerable_versions && - cmp_versions(rec$version, vulnerable_versions[rec$name]) <= 0 ) + if ( rec$name !in internal_vulnerable_versions ) + return; + + for ( version_range in internal_vulnerable_versions[rec$name] ) { - NOTICE([$note=Vulnerable_Version, $src=rec$host, - $msg=fmt("A vulnerable version of software was detected: %s", software_fmt(rec))]); + if ( cmp_versions(rec$version, version_range$max) <= 0 && + (!version_range?$min || cmp_versions(rec$version, version_range$min) >= 0) ) + { + # The software is inside a vulnerable version range. + NOTICE([$note=Vulnerable_Version, $src=rec$host, + $msg=fmt("%s is running %s which is vulnerable.", rec$host, software_fmt(rec)), + $sub=software_fmt(rec)]); + } } } diff --git a/scripts/policy/protocols/ssl/extract-certs-pem.bro b/scripts/policy/protocols/ssl/extract-certs-pem.bro index 420c60a4fd..0a412a119d 100644 --- a/scripts/policy/protocols/ssl/extract-certs-pem.bro +++ b/scripts/policy/protocols/ssl/extract-certs-pem.bro @@ -4,14 +4,10 @@ ##! ##! ..note:: ##! -##! - It doesn't work well on a cluster because each worker will write its +##! - It doesn't work well on a cluster because each worker will write its ##! own certificate files and no duplicate checking is done across ##! clusters so each node would log each certificate. ##! -##! - If there is a certificate input based vulnerability found in the -##! openssl command line utility, you could be in trouble because this -##! script uses that utility to convert from DER to PEM certificates. -##! @load base/protocols/ssl @load base/utils/directions-and-hosts @@ -20,7 +16,7 @@ module SSL; export { - ## Control if host certificates offered by the defined hosts + ## Control if host certificates offered by the defined hosts ## will be written to the PEM certificates file. ## Choices are: LOCAL_HOSTS, REMOTE_HOSTS, ALL_HOSTS, NO_HOSTS const extract_certs_pem = LOCAL_HOSTS &redef; @@ -35,15 +31,33 @@ event ssl_established(c: connection) &priority=5 { if ( ! c$ssl?$cert ) return; + if ( ! addr_matches_host(c$id$resp_h, extract_certs_pem) ) return; - + if ( c$ssl$cert_hash in extracted_certs ) # If we already extracted this cert, don't do it again. return; - + add extracted_certs[c$ssl$cert_hash]; - local side = Site::is_local_addr(c$id$resp_h) ? "local" : "remote"; - local cmd = fmt("%s x509 -inform DER -outform PEM >> certs-%s.pem", openssl_util, side); - piped_exec(cmd, c$ssl$cert); + local filename = Site::is_local_addr(c$id$resp_h) ? "certs-local.pem" : "certs-remote.pem"; + local outfile = open_for_append(filename); + + print outfile, "-----BEGIN CERTIFICATE-----"; + + # Encode to base64 and format to fit 50 lines. Otherwise openssl won't like it later. + local lines = split_all(encode_base64(c$ssl$cert), /.{50}/); + local i = 1; + for ( line in lines ) + { + if ( |lines[i]| > 0 ) + { + print outfile, lines[i]; + } + i+=1; + } + + print outfile, "-----END CERTIFICATE-----"; + print outfile, ""; + close(outfile); } diff --git a/scripts/site/local.bro b/scripts/site/local.bro index a080300185..6dff7881f5 100644 --- a/scripts/site/local.bro +++ b/scripts/site/local.bro @@ -14,13 +14,6 @@ # information. @load frameworks/software/vulnerable -# Example vulnerable software. This needs to be updated and maintained over -# time as new vulnerabilities are discovered. -redef Software::vulnerable_versions += { - ["Flash"] = [$major=10,$minor=2,$minor2=153,$addl="1"], - ["Java"] = [$major=1,$minor=6,$minor2=0,$addl="22"], -}; - # Detect software changing (e.g. attacker installing hacked SSHD). @load frameworks/software/version-changes diff --git a/src/Base64.cc b/src/Base64.cc index b0da8ea74c..d953ec3557 100644 --- a/src/Base64.cc +++ b/src/Base64.cc @@ -1,10 +1,48 @@ #include "config.h" #include "Base64.h" +#include -int Base64Decoder::default_base64_table[256]; -const string Base64Decoder::default_alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; +int Base64Converter::default_base64_table[256]; +const string Base64Converter::default_alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; -int* Base64Decoder::InitBase64Table(const string& alphabet) +void Base64Converter::Encode(int len, const unsigned char* data, int* pblen, char** pbuf) + { + int blen; + char *buf; + + if ( ! pbuf ) + reporter->InternalError("nil pointer to encoding result buffer"); + + if ( *pbuf && (*pblen % 4 != 0) ) + reporter->InternalError("Base64 encode buffer not a multiple of 4"); + + if ( *pbuf ) + { + buf = *pbuf; + blen = *pblen; + } + else + { + blen = (int)(4 * ceil((double)len / 3)); + *pbuf = buf = new char[blen]; + *pblen = blen; + } + + for ( int i = 0, j = 0; (i < len) && ( j < blen ); ) + { + uint32_t bit32 = ((i < len ? data[i++] : 0) << 16) + + ((i < len ? data[i++] : 0 & i++) << 8) + + ( i < len ? data[i++] : 0 & i++); + + buf[j++] = alphabet[(bit32 >> 18) & 0x3f]; + buf[j++] = alphabet[(bit32 >> 12) & 0x3f]; + buf[j++] = (i == (len+2)) ? '=' : alphabet[(bit32 >> 6) & 0x3f]; + buf[j++] = (i >= (len+1)) ? '=' : alphabet[bit32 & 0x3f]; + } + } + + +int* Base64Converter::InitBase64Table(const string& alphabet) { assert(alphabet.size() == 64); @@ -44,26 +82,42 @@ int* Base64Decoder::InitBase64Table(const string& alphabet) return base64_table; } -Base64Decoder::Base64Decoder(Analyzer* arg_analyzer, const string& alphabet) + + +Base64Converter::Base64Converter(Analyzer* arg_analyzer, const string& arg_alphabet) { - base64_table = InitBase64Table(alphabet.size() ? alphabet : default_alphabet); + if ( arg_alphabet.size() > 0 ) + { + assert(arg_alphabet.size() == 64); + alphabet = arg_alphabet; + } + else + { + alphabet = default_alphabet; + } + + base64_table = 0; base64_group_next = 0; base64_padding = base64_after_padding = 0; errored = 0; analyzer = arg_analyzer; } -Base64Decoder::~Base64Decoder() +Base64Converter::~Base64Converter() { if ( base64_table != default_base64_table ) delete base64_table; } -int Base64Decoder::Decode(int len, const char* data, int* pblen, char** pbuf) +int Base64Converter::Decode(int len, const char* data, int* pblen, char** pbuf) { int blen; char* buf; + // Initialization of table on first_time call of Decode. + if ( ! base64_table ) + base64_table = InitBase64Table(alphabet); + if ( ! pbuf ) reporter->InternalError("nil pointer to decoding result buffer"); @@ -145,7 +199,7 @@ int Base64Decoder::Decode(int len, const char* data, int* pblen, char** pbuf) return dlen; } -int Base64Decoder::Done(int* pblen, char** pbuf) +int Base64Converter::Done(int* pblen, char** pbuf) { const char* padding = "==="; @@ -177,7 +231,7 @@ BroString* decode_base64(const BroString* s, const BroString* a) int rlen2, rlen = buf_len; char* rbuf2, *rbuf = new char[rlen]; - Base64Decoder dec(0, a ? a->CheckString() : ""); + Base64Converter dec(0, a ? a->CheckString() : ""); if ( dec.Decode(s->Len(), (const char*) s->Bytes(), &rlen, &rbuf) == -1 ) goto err; @@ -195,3 +249,21 @@ err: delete [] rbuf; return 0; } + +BroString* encode_base64(const BroString* s, const BroString* a) + { + if ( a && a->Len() != 64 ) + { + reporter->Error("base64 alphabet is not 64 characters: %s", + a->CheckString()); + return 0; + } + + char* outbuf = 0; + int outlen = 0; + Base64Converter enc(0, a ? a->CheckString() : ""); + enc.Encode(s->Len(), (const unsigned char*) s->Bytes(), &outlen, &outbuf); + + return new BroString(1, (u_char*)outbuf, outlen); + } + diff --git a/src/Base64.h b/src/Base64.h index 0e02c94cf0..8cfeffde74 100644 --- a/src/Base64.h +++ b/src/Base64.h @@ -10,14 +10,13 @@ #include "Analyzer.h" // Maybe we should have a base class for generic decoders? - -class Base64Decoder { +class Base64Converter { public: // is used for error reporting, and it should be zero when - // the decoder is called by the built-in function decode_base64(). + // the decoder is called by the built-in function decode_base64() or encode_base64(). // Empty alphabet indicates the default base64 alphabet. - Base64Decoder(Analyzer* analyzer, const string& alphabet = ""); - ~Base64Decoder(); + Base64Converter(Analyzer* analyzer, const string& alphabet = ""); + ~Base64Converter(); // A note on Decode(): // @@ -30,6 +29,7 @@ public: // is not enough output buffer space. int Decode(int len, const char* data, int* blen, char** buf); + void Encode(int len, const unsigned char* data, int* blen, char** buf); int Done(int* pblen, char** pbuf); int HasData() const { return base64_group_next != 0; } @@ -39,7 +39,7 @@ public: const char* ErrorMsg() const { return error_msg; } void IllegalEncoding(const char* msg) - { + { // strncpy(error_msg, msg, sizeof(error_msg)); if ( analyzer ) analyzer->Weird("base64_illegal_encoding", msg); @@ -51,19 +51,22 @@ protected: char error_msg[256]; protected: + static const string default_alphabet; + string alphabet; + + static int* InitBase64Table(const string& alphabet); + static int default_base64_table[256]; char base64_group[4]; int base64_group_next; int base64_padding; int base64_after_padding; + int* base64_table; int errored; // if true, we encountered an error - skip further processing Analyzer* analyzer; - int* base64_table; - static int* InitBase64Table(const string& alphabet); - static int default_base64_table[256]; - static const string default_alphabet; }; BroString* decode_base64(const BroString* s, const BroString* a = 0); +BroString* encode_base64(const BroString* s, const BroString* a = 0); #endif /* base64_h */ diff --git a/src/MIME.cc b/src/MIME.cc index 4a7c0268b0..ce60e74b89 100644 --- a/src/MIME.cc +++ b/src/MIME.cc @@ -810,7 +810,7 @@ void MIME_Entity::StartDecodeBase64() if ( base64_decoder ) reporter->InternalError("previous Base64 decoder not released!"); - base64_decoder = new Base64Decoder(message->GetAnalyzer()); + base64_decoder = new Base64Converter(message->GetAnalyzer()); } void MIME_Entity::FinishDecodeBase64() diff --git a/src/MIME.h b/src/MIME.h index ffff30e387..17ac7fde9f 100644 --- a/src/MIME.h +++ b/src/MIME.h @@ -163,7 +163,7 @@ protected: MIME_Entity* parent; MIME_Entity* current_child_entity; - Base64Decoder* base64_decoder; + Base64Converter* base64_decoder; int data_buf_length; char* data_buf_data; diff --git a/src/bro.bif b/src/bro.bif index 014c582ec9..ac54da0e75 100644 --- a/src/bro.bif +++ b/src/bro.bif @@ -2829,13 +2829,55 @@ function bytestring_to_hexstr%(bytestring: string%): string return new StringVal(hexstr); %} +## Encodes a Base64-encoded string. +## +## s: The string to encode +## +## Returns: The encoded version of *s*. +## +## .. bro:see:: encode_base64_custom, decode_base64 +function encode_base64%(s: string%): string + %{ + BroString* t = encode_base64(s->AsString()); + if ( t ) + return new StringVal(t); + else + { + reporter->Error("error in encoding string %s", s->CheckString()); + return new StringVal(""); + } + %} + +## Encodes a Base64-encoded string with a custom alphabet. +## +## s: The string to encode +## +## a: The custom alphabet. The empty string indicates the default alphabet. The +## length of *a* must be 64. For example, a custom alphabet could be +## ``"!#$%&/(),-.:;<>@[]^ `_{|}~abcdefghijklmnopqrstuvwxyz0123456789+?"``. +## +## Returns: The encoded version of *s*. +## +## .. bro:see:: encode_base64, decode_base64_custom +function encode_base64_custom%(s: string, a: string%): string + %{ + BroString* t = encode_base64(s->AsString(), a->AsString()); + if ( t ) + return new StringVal(t); + else + { + reporter->Error("error in encoding string %s", s->CheckString()); + return new StringVal(""); + } + %} + ## Decodes a Base64-encoded string. ## ## s: The Base64-encoded string. ## ## Returns: The decoded version of *s*. ## -## .. bro:see:: decode_base64_custom +## .. bro:see:: decode_base64_custom, encode_base64 function decode_base64%(s: string%): string %{ BroString* t = decode_base64(s->AsString()); @@ -2858,7 +2900,7 @@ function decode_base64%(s: string%): string ## ## Returns: The decoded version of *s*. ## -## .. bro:see:: decode_base64 +## .. bro:see:: decode_base64, encode_base64_custom function decode_base64_custom%(s: string, a: string%): string %{ BroString* t = decode_base64(s->AsString(), a->AsString()); diff --git a/src/nb_dns.c b/src/nb_dns.c index e8595e6837..33a00837e4 100644 --- a/src/nb_dns.c +++ b/src/nb_dns.c @@ -265,6 +265,7 @@ _nb_dns_mkquery(register struct nb_dns_info *nd, register const char *name, default: snprintf(errstr, NB_DNS_ERRSIZE, "_nb_dns_mkquery: bad family %d", atype); + free(ne); return (-1); } diff --git a/testing/btest/Baseline/bifs.encode_base64/out b/testing/btest/Baseline/bifs.encode_base64/out new file mode 100644 index 0000000000..84c2c98264 --- /dev/null +++ b/testing/btest/Baseline/bifs.encode_base64/out @@ -0,0 +1,6 @@ +YnJv +YnJv +}n-v +cGFkZGluZw== +cGFkZGluZzE= +cGFkZGluZzEy diff --git a/testing/btest/Baseline/scripts.policy.protocols.ssl.extract-certs-pem/certs-remote.pem b/testing/btest/Baseline/scripts.policy.protocols.ssl.extract-certs-pem/certs-remote.pem new file mode 100644 index 0000000000..1767a32095 --- /dev/null +++ b/testing/btest/Baseline/scripts.policy.protocols.ssl.extract-certs-pem/certs-remote.pem @@ -0,0 +1,34 @@ +-----BEGIN CERTIFICATE----- +MIIEfDCCA+WgAwIBAgIQBKeBFvADKDvaK4RiBJ+eyzANBgkqhk +iG9w0BAQUFADCBujEfMB0GA1UEChMWVmVyaVNpZ24gVHJ1c3Qg +TmV0d29yazEXMBUGA1UECxMOVmVyaVNpZ24sIEluYy4xMzAxBg +NVBAsTKlZlcmlTaWduIEludGVybmF0aW9uYWwgU2VydmVyIENB +IC0gQ2xhc3MgMzFJMEcGA1UECxNAd3d3LnZlcmlzaWduLmNvbS +9DUFMgSW5jb3JwLmJ5IFJlZi4gTElBQklMSVRZIExURC4oYyk5 +NyBWZXJpU2lnbjAeFw0wNjExMTQwMDAwMDBaFw0wNzExMTQyMz +U5NTlaMIHAMQswCQYDVQQGEwJERTEPMA0GA1UECBMGQmF5ZXJu +MREwDwYDVQQHFAhNdWVuY2hlbjE3MDUGA1UEChQuQUdJUyBBbG +xpYW56IERyZXNkbmVyIEluZm9ybWF0aW9uc3N5c3RlbWUgR21i +SDEzMDEGA1UECxQqVGVybXMgb2YgdXNlIGF0IHd3dy52ZXJpc2 +lnbi5jb20vcnBhIChjKTAwMR8wHQYDVQQDFBZ3d3cuZHJlc2Ru +ZXItcHJpdmF0LmRlMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQ +KBgQDrqHR+++O06r6LHD3t6oYEYlHgKlqehm+Yy7zF7cXIylad +TJJY4WsTb7y35S6YQPeP1qPACqtGUhs4/AUg54Duxl3VuwP8xY +O6mmcI/Sy6owiU8LMfFij2BWZbv3+oWfq+mWs2YrhuxoNHU2MP +WrRRwYioVbnUMW09KkqVCtF7hwIDAQABo4IBeTCCAXUwCQYDVR +0TBAIwADALBgNVHQ8EBAMCBaAwRgYDVR0fBD8wPTA7oDmgN4Y1 +aHR0cDovL2NybC52ZXJpc2lnbi5jb20vQ2xhc3MzSW50ZXJuYX +Rpb25hbFNlcnZlci5jcmwwRAYDVR0gBD0wOzA5BgtghkgBhvhF +AQcXAzAqMCgGCCsGAQUFBwIBFhxodHRwczovL3d3dy52ZXJpc2 +lnbi5jb20vcnBhMCgGA1UdJQQhMB8GCWCGSAGG+EIEAQYIKwYB +BQUHAwEGCCsGAQUFBwMCMDQGCCsGAQUFBwEBBCgwJjAkBggrBg +EFBQcwAYYYaHR0cDovL29jc3AudmVyaXNpZ24uY29tMG0GCCsG +AQUFBwEMBGEwX6FdoFswWTBXMFUWCWltYWdlL2dpZjAhMB8wBw +YFKw4DAhoEFI/l0xqGrI2Oa8PPgGrUSBgsexkuMCUWI2h0dHA6 +Ly9sb2dvLnZlcmlzaWduLmNvbS92c2xvZ28uZ2lmMA0GCSqGSI +b3DQEBBQUAA4GBAC9z4m/BniN+WVCJlXhv6QS9mFRTYOwIUtIK +KZKabarVsWfBYt7JGE5XPWmcsgNmkgO76E3FmNQvQtm20uCXEF +h2z+fWp8y72yXuQl3L8HSr0lTl6LpRD6TDPjT6UvKg5nr0j9x2 +Qr09/HjAt+teLR/FoF7foBGH+MNYEMh5KPjk +-----END CERTIFICATE----- + diff --git a/testing/btest/Traces/ssl.v3.trace b/testing/btest/Traces/ssl.v3.trace new file mode 100644 index 0000000000..3bcb9729a2 Binary files /dev/null and b/testing/btest/Traces/ssl.v3.trace differ diff --git a/testing/btest/bifs/encode_base64.bro b/testing/btest/bifs/encode_base64.bro new file mode 100644 index 0000000000..a351392bb5 --- /dev/null +++ b/testing/btest/bifs/encode_base64.bro @@ -0,0 +1,14 @@ +# @TEST-EXEC: bro -b %INPUT >out +# @TEST-EXEC: btest-diff out + +global default_alphabet: string = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + +global my_alphabet: string = "!#$%&/(),-.:;<>@[]^ `_{|}~abcdefghijklmnopqrstuvwxyz0123456789+?"; + +print encode_base64("bro"); +print encode_base64_custom("bro", default_alphabet); +print encode_base64_custom("bro", my_alphabet); + +print encode_base64("padding"); +print encode_base64("padding1"); +print encode_base64("padding12"); diff --git a/testing/btest/scripts/base/frameworks/software/version-parsing.bro b/testing/btest/scripts/base/frameworks/software/version-parsing.bro index 03327a25cd..2b406f22b8 100644 --- a/testing/btest/scripts/base/frameworks/software/version-parsing.bro +++ b/testing/btest/scripts/base/frameworks/software/version-parsing.bro @@ -21,7 +21,7 @@ global matched_software: table[string] of Software::Description = { ["Java1.2.2-JDeveloper"] = [$name="Java", $version=[$major=1,$minor=2,$minor2=2,$addl="JDeveloper"], $unparsed_version=""], ["Java/1.6.0_13"] = - [$name="Java", $version=[$major=1,$minor=6,$minor2=0,$addl="13"], $unparsed_version=""], + [$name="Java", $version=[$major=1,$minor=6,$minor2=0,$minor3=13], $unparsed_version=""], ["Python-urllib/3.1"] = [$name="Python-urllib", $version=[$major=3,$minor=1], $unparsed_version=""], ["libwww-perl/5.820"] = @@ -39,9 +39,9 @@ global matched_software: table[string] of Software::Description = { ["The Bat! (v2.00.9) Personal"] = [$name="The Bat!", $version=[$major=2,$minor=0,$minor2=9,$addl="Personal"], $unparsed_version=""], ["Flash/10,2,153,1"] = - [$name="Flash", $version=[$major=10,$minor=2,$minor2=153,$addl="1"], $unparsed_version=""], + [$name="Flash", $version=[$major=10,$minor=2,$minor2=153,$minor3=1], $unparsed_version=""], ["mt2/1.2.3.967 Oct 13 2010-13:40:24 ord-pixel-x2 pid 0x35a3 13731"] = - [$name="mt2", $version=[$major=1,$minor=2,$minor2=3,$addl="967"], $unparsed_version=""], + [$name="mt2", $version=[$major=1,$minor=2,$minor2=3,$minor3=967,$addl="Oct"], $unparsed_version=""], ["CacheFlyServe v26b"] = [$name="CacheFlyServe", $version=[$major=26,$addl="b"], $unparsed_version=""], ["Apache/2.0.46 (Win32) mod_ssl/2.0.46 OpenSSL/0.9.7b mod_jk2/2.0.4"] = @@ -54,7 +54,7 @@ global matched_software: table[string] of Software::Description = { ["Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_3_2 like Mac OS X; en-us) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8H7 Safari/6533.18.5"] = [$name="Safari", $version=[$major=5,$minor=0,$minor2=2,$addl="Mobile"], $unparsed_version=""], ["Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_7; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Chrome/10.0.648.205 Safari/534.16"] = - [$name="Chrome", $version=[$major=10,$minor=0,$minor2=648,$addl="205"], $unparsed_version=""], + [$name="Chrome", $version=[$major=10,$minor=0,$minor2=648,$minor3=205], $unparsed_version=""], ["Opera/9.80 (Windows NT 6.1; U; sv) Presto/2.7.62 Version/11.01"] = [$name="Opera", $version=[$major=11,$minor=1], $unparsed_version=""], ["Mozilla/5.0 (Windows; U; Windows NT 5.1; de; rv:1.9.2.11) Gecko/20101013 Lightning/1.0b2 Thunderbird/3.1.5"] = @@ -62,7 +62,7 @@ global matched_software: table[string] of Software::Description = { ["iTunes/9.0 (Macintosh; Intel Mac OS X 10.5.8) AppleWebKit/531.9"] = [$name="iTunes", $version=[$major=9,$minor=0,$addl="Macintosh"], $unparsed_version=""], ["Java1.3.1_04"] = - [$name="Java", $version=[$major=1,$minor=3,$minor2=1,$addl="04"], $unparsed_version=""], + [$name="Java", $version=[$major=1,$minor=3,$minor2=1,$minor3=4], $unparsed_version=""], ["Mozilla/5.0 (Linux; U; Android 2.3.3; zh-tw; HTC Pyramid Build/GRI40) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1"] = [$name="Safari", $version=[$major=4,$minor=0,$addl="Mobile"], $unparsed_version=""], ["Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_6; en-us) AppleWebKit/533.20.25 (KHTML, like Gecko) Version/5.0.4 Safari/533.20.27"] = diff --git a/testing/btest/scripts/policy/protocols/ssl/extract-certs-pem.bro b/testing/btest/scripts/policy/protocols/ssl/extract-certs-pem.bro new file mode 100644 index 0000000000..acc414a33c --- /dev/null +++ b/testing/btest/scripts/policy/protocols/ssl/extract-certs-pem.bro @@ -0,0 +1,6 @@ +# @TEST-EXEC: bro -r $TRACES/ssl.v3.trace %INPUT +# @TEST-EXEC: btest-diff certs-remote.pem + +@load protocols/ssl/extract-certs-pem + +redef SSL::extract_certs_pem = ALL_HOSTS;