[Bro] Bro scripts

Matthias Vallentin vallentin at icir.org
Thu Oct 28 23:56:15 PDT 2010

> On Oct 28, 2010, at 9:48 PM, Martin Holste wrote:
> > Instead of tracking by IP, how about one cookie per user agent?
> Good point!


> global cookies: table[string] of set[addr]
> to...
> global cookies: table[string] of set[addr, string]

That will almost do it, except that I now need to write a handler for
http_all_headers instead of http_header to obviate the need for some
global glue code. 

Furthermore, the Cookie header often bundles a bunch of cookie key-value
pairs of which only a few define the actual user session. The others can
vary and thus cause false negatives. Firesheep fortunately ships with a
bunch of handlers for major sites which I will use a baseline to
define user session for specific sites, i.e.,

    # Distills relevant cookies that define a user session.
    type user_session: record
        url: pattern;       # URL
        cookies: pattern;   # Cookie keys that define the user session.

    const session_info: table[string] of user_session =
        ["Amazon"]       = [$url=/amazon.com/, $cookies=/x-main/],
        ["Dropbox"]      = [$url=/dropbox.com/, $cookies=/lid/],
        ["Facebook"]     = [$url=/facebook.com/, $cookies=/xs|c_user|sid/],
        ["Flickr"]       = [$url=/flickr.com/, $cookies=/cookie_session/],
        ["Google"]       = [$url=/google.com/, $cookies=/NID|SID|HSID|PREF/],
        ["NY Times"]     = [$url=/nytimes.com/, $cookies=/NYT-s|nyt-d/],
        ["Twitter"]      = [$url=/twitter.com/, $cookies=/_twitter_sess/],
        ["Yelp"]         = [$url=/yelp.com/, $cookies=/__utma/],
        ["Windows Live"] = [$url=/live.com/,
        ["Wordpress"]    = [$url=/yelp.com/,
    } &redef;

What remains todo is to split the Cookie string into its key-value pairs
and then match the keys against user_session$cookies. Instead of regular
expression, I'd preferably have a set[string], but this cannot be
statically defined in a record, i.e.,

    ["Facebook"]     = [$url=/facebook.com/, $cookies={"xs", "c_user", "sid"}],
appears not to be correct Bro syntax, because I think variable-size
types inside records cannot be initialized statically. Is that correct?
If so, I'd probably change to simple table[string] of set[string] to
represent user sessions.

In any case, the downside is that this would only detect sidejacking for
known sites. I think it would make sense to do the following. If a
profile for a user_session for a particular site (as defined above)
exists, use it, and otherwise use the entire cookie value.

> I think your point about NAT gets to a more general point of what
> techniques could we use to detect NAT?  

This is truly an important issue to tackle. I wonder if it is possible
to have better abstractions in Bro to support user-based analysis. For
example, it would be neat to augment several events with a "user"
argument which is a essentially a record filled by many other events. In
HTTP for example, some code would parse the User-Agent and fill this
record, so that the script writer could simply refer to user$os or


More information about the Bro mailing list