Software framework stores ports for server software.

This commit is contained in:
Bernhard Amann 2011-12-07 12:12:46 -08:00
parent f1e132cd1a
commit 707926aaa4
4 changed files with 49 additions and 27 deletions

View file

@ -34,7 +34,11 @@ export {
## The time at which the software was first detected. ## The time at which the software was first detected.
ts: time &log; ts: time &log;
## The IP address detected running the software. ## The IP address detected running the software.
host: addr &log; host_a: addr &log;
## The Port on which the software is running. Only sensible for server software.
host_p: port &log &optional;
## The transport protocol that is being used. Only sensible for server software.
proto: transport_proto &log &optional;
## The type of software detected (e.g. WEB_SERVER) ## The type of software detected (e.g. WEB_SERVER)
software_type: Type &log &default=UNKNOWN; software_type: Type &log &default=UNKNOWN;
## Name of the software (e.g. Apache) ## Name of the software (e.g. Apache)
@ -71,7 +75,13 @@ export {
## still many cases where scripts may have to have their own specific ## still many cases where scripts may have to have their own specific
## version parsing though. ## version parsing though.
global parse: function(unparsed_version: string, global parse: function(unparsed_version: string,
host: addr, host_a: addr,
software_type: Type): Info;
## This function is the equivalent to parse for software that has a specific
## source port (i.e. server software)
global parse_with_port: function(unparsed_version: string,
host_a: addr, host_p: port,
software_type: Type): Info; software_type: Type): Info;
## Compare two versions. ## Compare two versions.
@ -107,7 +117,7 @@ event bro_init()
} }
function parse_mozilla(unparsed_version: string, function parse_mozilla(unparsed_version: string,
host: addr, host_a: addr,
software_type: Type): Info software_type: Type): Info
{ {
local software_name = "<unknown browser>"; local software_name = "<unknown browser>";
@ -119,7 +129,7 @@ function parse_mozilla(unparsed_version: string,
software_name = "Opera"; software_name = "Opera";
parts = split_all(unparsed_version, /Opera [0-9\.]*$/); parts = split_all(unparsed_version, /Opera [0-9\.]*$/);
if ( 2 in parts ) if ( 2 in parts )
v = parse(parts[2], host, software_type)$version; v = parse(parts[2], host_a, software_type)$version;
} }
else if ( / MSIE / in unparsed_version ) else if ( / MSIE / in unparsed_version )
{ {
@ -134,7 +144,7 @@ function parse_mozilla(unparsed_version: string,
{ {
parts = split_all(unparsed_version, /MSIE [0-9]{1,2}\.*[0-9]*b?[0-9]*/); parts = split_all(unparsed_version, /MSIE [0-9]{1,2}\.*[0-9]*b?[0-9]*/);
if ( 2 in parts ) if ( 2 in parts )
v = parse(parts[2], host, software_type)$version; v = parse(parts[2], host_a, software_type)$version;
} }
} }
else if ( /Version\/.*Safari\// in unparsed_version ) else if ( /Version\/.*Safari\// in unparsed_version )
@ -143,7 +153,7 @@ function parse_mozilla(unparsed_version: string,
parts = split_all(unparsed_version, /Version\/[0-9\.]*/); parts = split_all(unparsed_version, /Version\/[0-9\.]*/);
if ( 2 in parts ) if ( 2 in parts )
{ {
v = parse(parts[2], host, software_type)$version; v = parse(parts[2], host_a, software_type)$version;
if ( / Mobile\/?.* Safari/ in unparsed_version ) if ( / Mobile\/?.* Safari/ in unparsed_version )
v$addl = "Mobile"; v$addl = "Mobile";
} }
@ -153,7 +163,7 @@ function parse_mozilla(unparsed_version: string,
parts = split_all(unparsed_version, /(Firefox|Netscape|Thunderbird)\/[0-9\.]*/); parts = split_all(unparsed_version, /(Firefox|Netscape|Thunderbird)\/[0-9\.]*/);
if ( 2 in parts ) if ( 2 in parts )
{ {
local tmp_s = parse(parts[2], host, software_type); local tmp_s = parse(parts[2], host_a, software_type);
software_name = tmp_s$name; software_name = tmp_s$name;
v = tmp_s$version; v = tmp_s$version;
} }
@ -163,7 +173,7 @@ function parse_mozilla(unparsed_version: string,
software_name = "Chrome"; software_name = "Chrome";
parts = split_all(unparsed_version, /Chrome\/[0-9\.]*/); parts = split_all(unparsed_version, /Chrome\/[0-9\.]*/);
if ( 2 in parts ) if ( 2 in parts )
v = parse(parts[2], host, software_type)$version; v = parse(parts[2], host_a, software_type)$version;
} }
else if ( /^Opera\// in unparsed_version ) else if ( /^Opera\// in unparsed_version )
{ {
@ -174,12 +184,12 @@ function parse_mozilla(unparsed_version: string,
software_name = parts[2]; software_name = parts[2];
parts = split_all(unparsed_version, /Version\/[0-9\.]*/); parts = split_all(unparsed_version, /Version\/[0-9\.]*/);
if ( 2 in parts ) if ( 2 in parts )
v = parse(parts[2], host, software_type)$version; v = parse(parts[2], host_a, software_type)$version;
else else
{ {
parts = split_all(unparsed_version, /Opera Mini\/[0-9\.]*/); parts = split_all(unparsed_version, /Opera Mini\/[0-9\.]*/);
if ( 2 in parts ) if ( 2 in parts )
v = parse(parts[2], host, software_type)$version; v = parse(parts[2], host_a, software_type)$version;
} }
} }
else else
@ -187,7 +197,7 @@ function parse_mozilla(unparsed_version: string,
software_name = "Opera"; software_name = "Opera";
parts = split_all(unparsed_version, /Version\/[0-9\.]*/); parts = split_all(unparsed_version, /Version\/[0-9\.]*/);
if ( 2 in parts ) if ( 2 in parts )
v = parse(parts[2], host, software_type)$version; v = parse(parts[2], host_a, software_type)$version;
} }
} }
else if ( /AppleWebKit\/[0-9\.]*/ in unparsed_version ) else if ( /AppleWebKit\/[0-9\.]*/ in unparsed_version )
@ -195,17 +205,17 @@ function parse_mozilla(unparsed_version: string,
software_name = "Unspecified WebKit"; software_name = "Unspecified WebKit";
parts = split_all(unparsed_version, /AppleWebKit\/[0-9\.]*/); parts = split_all(unparsed_version, /AppleWebKit\/[0-9\.]*/);
if ( 2 in parts ) if ( 2 in parts )
v = parse(parts[2], host, software_type)$version; v = parse(parts[2], host_a, software_type)$version;
} }
return [$ts=network_time(), $host=host, $name=software_name, $version=v, return [$ts=network_time(), $host_a=host_a, $name=software_name, $version=v,
$software_type=software_type, $unparsed_version=unparsed_version]; $software_type=software_type, $unparsed_version=unparsed_version];
} }
# Don't even try to understand this now, just make sure the tests are # Don't even try to understand this now, just make sure the tests are
# working. # working.
function parse(unparsed_version: string, function parse(unparsed_version: string,
host: addr, host_a: addr,
software_type: Type): Info software_type: Type): Info
{ {
local software_name = "<parse error>"; local software_name = "<parse error>";
@ -214,7 +224,7 @@ function parse(unparsed_version: string,
# Parse browser-alike versions separately # Parse browser-alike versions separately
if ( /^(Mozilla|Opera)\/[0-9]\./ in unparsed_version ) if ( /^(Mozilla|Opera)\/[0-9]\./ in unparsed_version )
{ {
return parse_mozilla(unparsed_version, host, software_type); return parse_mozilla(unparsed_version, host_a, software_type);
} }
else else
{ {
@ -276,11 +286,23 @@ function parse(unparsed_version: string,
v$major = extract_count(version_numbers[1]); v$major = extract_count(version_numbers[1]);
} }
} }
return [$ts=network_time(), $host=host, $name=software_name, return [$ts=network_time(), $host_a=host_a, $name=software_name,
$version=v, $unparsed_version=unparsed_version, $version=v, $unparsed_version=unparsed_version,
$software_type=software_type]; $software_type=software_type];
} }
function parse_with_port(unparsed_version: string,
host_a: addr, host_p: port,
software_type: Type): Info
{
local i: Info;
i = parse(unparsed_version, host_a, software_type);
i$host_p = host_p;
i$proto = get_port_transport_proto(host_p);
return i;
}
function cmp_versions(v1: Version, v2: Version): int function cmp_versions(v1: Version, v2: Version): int
{ {
@ -340,9 +362,9 @@ function cmp_versions(v1: Version, v2: Version): int
} }
} }
function software_endpoint_name(id: conn_id, host: addr): string function software_endpoint_name(id: conn_id, host_a: addr): string
{ {
return fmt("%s %s", host, (host == id$orig_h ? "client" : "server")); return fmt("%s %s", host_a, (host_a == id$orig_h ? "client" : "server"));
} }
# Convert a version into a string "a.b.c-x". # Convert a version into a string "a.b.c-x".
@ -366,10 +388,10 @@ function software_fmt(i: Info): string
event software_register(id: conn_id, info: Info) event software_register(id: conn_id, info: Info)
{ {
# Host already known? # Host already known?
if ( info$host !in tracked ) if ( info$host_a !in tracked )
tracked[info$host] = table(); tracked[info$host_a] = table();
local ts = tracked[info$host]; local ts = tracked[info$host_a];
# Software already registered for this host? We don't want to endlessly # Software already registered for this host? We don't want to endlessly
# log the same thing. # log the same thing.
if ( info$name in ts ) if ( info$name in ts )
@ -389,7 +411,7 @@ event software_register(id: conn_id, info: Info)
function found(id: conn_id, info: Info): bool function found(id: conn_id, info: Info): bool
{ {
if ( info$force_log || addr_matches_host(info$host, asset_tracking) ) if ( info$force_log || addr_matches_host(info$host_a, asset_tracking) )
{ {
event software_register(id, info); event software_register(id, info);
return T; return T;

View file

@ -23,7 +23,7 @@ event signature_match(state: signature_state, msg: string, data: string) &priori
if ( /^webapp-/ !in state$sig_id ) return; if ( /^webapp-/ !in state$sig_id ) return;
local c = state$conn; local c = state$conn;
local si = Software::parse(msg, c$id$resp_h, WEB_APPLICATION); local si = Software::parse_with_port(msg, c$id$resp_h, c$id$resp_p, WEB_APPLICATION);
si$url = build_url_http(c$http); si$url = build_url_http(c$http);
if ( c$id$resp_h in Software::tracked && if ( c$id$resp_h in Software::tracked &&
si$name in Software::tracked[c$id$resp_h] ) si$name in Software::tracked[c$id$resp_h] )

View file

@ -25,13 +25,13 @@ event http_header(c: connection, is_orig: bool, name: string, value: string) &pr
else else
{ {
if ( name == "SERVER" ) if ( name == "SERVER" )
Software::found(c$id, Software::parse(value, c$id$resp_h, SERVER)); Software::found(c$id, Software::parse_with_port(value, c$id$resp_h, c$id$resp_p, SERVER));
else if ( name == "X-POWERED-BY" ) else if ( name == "X-POWERED-BY" )
Software::found(c$id, Software::parse(value, c$id$resp_h, APPSERVER)); Software::found(c$id, Software::parse_with_port(value, c$id$resp_h, c$id$resp_p, APPSERVER));
else if ( name == "MICROSOFTSHAREPOINTTEAMSERVICES" ) else if ( name == "MICROSOFTSHAREPOINTTEAMSERVICES" )
{ {
value = cat("SharePoint/", value); value = cat("SharePoint/", value);
Software::found(c$id, Software::parse(value, c$id$resp_h, APPSERVER)); Software::found(c$id, Software::parse_with_port(value, c$id$resp_h, c$id$resp_p, APPSERVER));
} }
} }
} }

View file

@ -24,6 +24,6 @@ event ssh_server_version(c: connection, version: string) &priority=4
{ {
# Get rid of the protocol information when passing to the software framework. # Get rid of the protocol information when passing to the software framework.
local cleaned_version = sub(version, /SSH[0-9\.\-]{2,}/, ""); local cleaned_version = sub(version, /SSH[0-9\.\-]{2,}/, "");
local si = Software::parse(cleaned_version, c$id$resp_h, SERVER); local si = Software::parse_with_port(cleaned_version, c$id$resp_h, c$id$resp_p, SERVER);
Software::found(c$id, si); Software::found(c$id, si);
} }