I was asked recently if Bro could do passive OS fingerprinting (in relation to keeping tabs on XP usage on our networks), and it seems that there was a dedicated mechanism for this using p0f, but that the Bro tie-ins may be deprecated per BIT 323 or at least very out of date due to a 6 year p0f development hiatus. With p0f having been rewritten in 2012 are there there any plans for updating Bro to support the newer version? The user agent strings in software.log are useful, but it seems like there were even more fine grained events and records that came with the p0f tie-ins in regards to parsing out the OS.
at least very out of date due to a 6 year p0f development hiatus.
Yep. It's in Bro still though. If you write a script that handles this event:
event OS_version_found(c: connection, host: addr, OS: OS_version)
print cat("p0f reported - ", OS);
you will be getting the output from p0f.
With p0f having been rewritten in 2012 are there there any plans for updating Bro to support the newer version?
Nope, I don't think anyone plans on updating it. The author of p0f stopped trying to fingerprint TCP stacks (mostly) and started using other deeper packet sniffing. Basically the new version of p0f is something you could implement as a Bro script because he's just grabbing user-agent strings and stuff. The problem is that it's really hard to blindly trust user-agent strings because of NAT'ed addressed and people giving fake user-agent strings.
I'm hoping eventually in Bro to write a script that takes lots of measurements (p0f, user-agents, software update mechanisms touches, exposed services) to get a profile for a machine to decide if it's a particular type of host. For instance, imagine that one of your windows xp machines gets identified as such by p0f (in Bro), then identifies that it's windows xp in a browser user-agent, then reaches out for windows updates and identifies that it's version of windows is some version of XP (i can't remember if this is visible for Windows system updates or not).
Anyway, this approach is replicable for many other operating systems too, it just takes time and the Bro scripts to support it.
Basically the new version of p0f is something you could implement as a Bro script because he's just grabbing user-agent strings and stuff.
I've never really written a Bro script outside of some of the examples from Bro Exchange, but would something like the below event be a valid starting point? For reference I started by looking at /bro/share/bro/policy/protocols/http/software.bro which already appeared to be looking at browser user agents and just started experimenting. Also, for learning purposes I'm OK with this not being the most reliable data. I also tried the p0f example on some pcaps to see what it could find after updating to a more recent fingerprint file. My next steps might be to try figuring out how to send the output to a custom log file, say "alleged_os.log".
event http_header(c: connection, is_orig: bool, name: string, value: string) &priority=2
if ( is_orig )
if ( name == "USER-AGENT" && /Windows NT 6.1/ in value )
print cat("Windows 7 detected on - ", $host=c$id$orig_h);
else if ( name == "USER-AGENT" && /Windows NT 6.0/ in value )
print cat("Windows Vista detected on - ", $host=c$id$orig_h);
else if ( name == "USER-AGENT" && /Windows NT 5.1/ in value )
print cat("Windows XP detected on - ", $host=c$id$orig_h);
You can disregard my last post. After re-reading some of the examples on the ryesecurity blog, stepping through some of the pre-packaged bro scripts, and lots of experimentation I'm most of the way to finishing my first bro script and logging the results where I want. Thanks again for the help.