[Bro] Sanity check - Grabbing platform tokens from browser user agents (was p0f)

Gary Faulkner gary at doit.wisc.edu
Wed Jan 29 15:35:46 PST 2014

After being asked if Bro could be used to gather passive intelligence on 
OS usage I started investigating places to try to identify OS. I 
initially was looking into p0f and Seth showed me a way to invoke the 
existing p0f fingerprinting functionality within Bro, but also suggested 
a slew of other data sources to look at. I wasn't terribly excited with 
the p0f fingerprint output, and while browser user agents may not be the 
best data source, I decided to start by looking at platform tokens and 
reporting on those instead of the p0f data. This is my first-ish bro 
script and it is by no means a complete script (it only matches a 
handful of Windows OS). I'm wondering if folks see anything in the 
attached that would misbehave badly if used on live traffic instead of 


Gary Faulkner

-------------- next part --------------
module BrowserPlatform;

    redef enum Log::ID += { LOG };

    type Info: record {
        ts:                 time    &log &optional;
        uid:                string  &log &optional;
        host:               addr    &log &optional;
        platform_token:     string  &log &optional;
        unparsed_version:   string  &log &optional;

    # A set of seen IP + OS combinations. Used to prevent logging the same combo repeatedly.   
    global seen_browser_platforms: set[string] &create_expire=1day &synchronized &redef;	

event bro_init() &priority=5

event http_header(c: connection, is_orig: bool, name: string, value: string)
    local platform = "Unknown OS";	
    if ( is_orig )
	if ( name == "USER-AGENT" && /Windows NT 5.1/ in value )
		platform = "Windows XP";
        else if ( name == "USER-AGENT" && /Windows NT 6.0/ in value )
		platform = "Windows Vista";
        else if ( name == "USER-AGENT" && /Windows NT 6.1/ in value )
                platform = "Windows 7";
        else if ( name == "USER-AGENT" && /Windows NT 6.2/ in value )
                platform = "Windows 8";
        else if ( name == "USER-AGENT" && /Windows NT 6.3/ in value )
                platform = "Windows 8.1";
    local saw = cat(c$id$orig_h,platform); #There is probably a less ugly way to do this than cat, but it seems to work
    if ( platform != "Unknown OS" && saw !in seen_browser_platforms )
	local rec: BrowserPlatform::Info = [$ts=network_time(), $uid=c$uid, $host=c$id$orig_h, $platform_token=platform, $unparsed_version=value];
	Log::write(BrowserPlatform::LOG, rec);
	add seen_browser_platforms[saw];
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 6257 bytes
Desc: S/MIME Cryptographic Signature
Url : http://mailman.ICSI.Berkeley.EDU/pipermail/bro/attachments/20140129/6a5b0762/attachment.bin 

More information about the Bro mailing list