From febfd4cf04f58bd20dae10fcaa72929b7b191b46 Mon Sep 17 00:00:00 2001 From: Seth Hall Date: Mon, 14 Mar 2011 15:41:45 -0400 Subject: [PATCH] Better software version parsing. * $addl field now parsed out in many cases. * A few new tests for web browser versions. * Browers user-agents need preprocessed though. * All tests pass. --- policy/software.bro | 33 ++++++++++++++----- .../software/default-version-parsing.bro | 21 +++++++++--- 2 files changed, 40 insertions(+), 14 deletions(-) diff --git a/policy/software.bro b/policy/software.bro index f64a313de3..4f01026dc0 100644 --- a/policy/software.bro +++ b/policy/software.bro @@ -28,9 +28,6 @@ export { type Type: enum { UNKNOWN, OPERATING_SYSTEM, - WEB_SERVER, - WEB_BROWSER, - WEB_BROWSER_PLUGIN, WEB_APPLICATION, MAIL_SERVER, MAIL_CLIENT, @@ -104,6 +101,8 @@ event bro_init() Log::add_default_filter("SOFTWARE"); } +# Don't even try to understand this now, just make sure the tests are +# working. function default_parse(unparsed_version: string, host: addr, software_type: Type): Info @@ -113,16 +112,32 @@ function default_parse(unparsed_version: string, # The regular expression should match the complete version number # and software name. - local version_parts = split_all(unparsed_version, /[0-9\/\-\._ ]{2,}/); + local version_parts = split_n(unparsed_version, /[0-9\/\-\._ ]{2,}/, T, 1); if ( |version_parts| >= 2 ) { software_name = version_parts[1]; - # Remove the name/version separator because it's left at the begging + # Remove the name/version separator because it's left at the begining # of the version number from the previous split_all. - local sv = sub(version_parts[2], /^./, ""); - local version_numbers = split_n(sv, /[\-\._, \[\(]/, F, 4); - if ( |version_numbers| > 3 ) - v$addl = version_numbers[4]; + local sv = version_parts[2]; + if ( /^[\/\-\._ ]/ in sv ) + sv = sub(version_parts[2], /^[\/\-\._ ]/, ""); + local version_numbers = split_n(sv, /[\-\._,\[\(\{ ]/, F, 4); + local addl = ""; + if ( 4 in version_numbers && version_numbers[4] != "" ) + addl = version_numbers[4]; + else if ( 3 in version_parts && version_parts[3] != "" ) + { + # TODO: there's a bug with do_split! + local vp = split_n(version_parts[3], /[\-\._,\[\]\(\)\{\} ]/, F, 2); + if ( |vp| >= 1 && vp[1] != "" ) + addl = vp[1]; + else if ( |vp| >= 2 ) + addl = vp[2]; + else + addl = version_parts[3]; + } + v$addl = addl; + if ( |version_numbers| >= 3 ) v$minor2 = to_count(version_numbers[3]); if ( |version_numbers| >= 2 ) diff --git a/testing/btest/software/default-version-parsing.bro b/testing/btest/software/default-version-parsing.bro index 9555314ba7..882d0301b6 100644 --- a/testing/btest/software/default-version-parsing.bro +++ b/testing/btest/software/default-version-parsing.bro @@ -10,15 +10,26 @@ global matched_software: table[string] of Software::Info = { ["OpenSSH_5.2"] = [$name="OpenSSH", $version=[$major=5,$minor=2,$minor2=0], $ts=ts], ["Apache/2.0.63 (Unix) mod_auth_kerb/5.3 mod_ssl/2.0.63 OpenSSL/0.9.7a mod_fastcgi/2.4.2"] = - [$name="Apache", $version=[$major=2,$minor=0,$minor2=63], $ts=ts], + [$name="Apache", $version=[$major=2,$minor=0,$minor2=63,$addl="Unix"], $ts=ts], ["Apache/1.3.19 (Unix)"] = - [$name="Apache", $version=[$major=1,$minor=3,$minor2=19], $ts=ts], + [$name="Apache", $version=[$major=1,$minor=3,$minor2=19,$addl="Unix"], $ts=ts], + # $addl is not quite right here, but it's close enough. ["ProFTPD 1.2.5rc1 Server (Debian)"] = - [$name="ProFTPD", $version=[$major=1,$minor=2,$minor2=5], $ts=ts], + [$name="ProFTPD", $version=[$major=1,$minor=2,$minor2=5,$addl="rc"], $ts=ts], ["wu-2.4.2-academ[BETA-18-VR14](1)"] = - [$name="wu", $version=[$major=2,$minor=4,$minor2=2], $ts=ts], + [$name="wu", $version=[$major=2,$minor=4,$minor2=2,$addl="academ"], $ts=ts], ["wu-2.6.2(1)"] = - [$name="wu", $version=[$major=2,$minor=6,$minor2=2], $ts=ts], + [$name="wu", $version=[$major=2,$minor=6,$minor2=2,$addl="1"], $ts=ts], + ["Java1.2.2-JDeveloper"] = + [$name="Java", $version=[$major=1,$minor=2,$minor2=2,$addl="JDeveloper"], $ts=ts], + ["Java/1.6.0_13"] = + [$name="Java", $version=[$major=1,$minor=6,$minor2=0,$addl="13"], $ts=ts], + # Web Browers are going to have to be pre processed before sending here. + # They can't be handled generically by the software framework. + ["Firefox/3.6.7"] = + [$name="Firefox", $version=[$major=3,$minor=6,$minor2=7], $ts=ts], + ["Firefox/4.0b9pre"] = + [$name="Firefox", $version=[$major=4,$minor=0,$minor2=0,$addl="b9pre"], $ts=ts], }; event bro_init()