[Bro] set initializers (Re: Bro scripts)

Matthias Vallentin vallentin at icir.org
Mon Nov 1 14:13:36 PDT 2010


> 	.... $cookies=set("xs", "c_user", "sid")

That works, thanks.

I attached a revamped version of the sidejacking detector which should
exhibit less false positives now (and has slightly improved logging).

   Matthias
-------------- next part --------------
# A simple sidejacking detector. 
#
# The script raises an alarm whenever more than one client makes use of the
# same cookie, where a user is defined a as (IP, user agent) pair.

@load notice
@load http-request
@load http-reply

module HTTP;

export
{
    redef enum Notice += { Sidejacking };

    const cookie_expiration = 1 hr &redef;

    type cookie_info: record
    {
        url: pattern;                # URL pattern matched against Host header.
        keys: set[string] &optional; # Cookie keys that define the user session.
        pat: pattern &optional;      # Cookie keys pattern, instead of a set.
    };

    # List of cookie information per service (taken from Firesheep handlers).
    const cookie_list: table[string] of cookie_info =
    {
        ["Amazon"]       = [$url=/amazon.com/, $keys=set("x-main")],
        ["Basecamp"]     = [$url=/basecamphq.com/, 
                            $keys=set("_basecamp_session", "session_token")],
        ["bit.ly"]       = [$url=/bit.ly/, $keys=set("user")],
        ["Cisco"]        = [$url=/cisco.com/, $keys=set("SMIDENTITY")],
        ["CNET"]         = [$url=/cnet.com/, $keys=set("urs_sessionId")],
        ["Dropbox"]      = [$url=/dropbox.com/, $keys=set("lid")],
        ["Enom"]         = [$url=/enom.com/, 
                            $keys=set("OatmealCookie", "EmailAddress")],
        ["Evernote"]     = [$url=/evernote.com/, $keys=set("auth")],
        ["Facebook"]     = [$url=/facebook.com/, 
                            $keys=set("xs", "c_user", "sid")],
        ["Flickr"]       = [$url=/flickr.com/, $keys=set("cookie_session")],
        ["Foursquare"]   = [$url=/foursquare.com/, 
                            $keys=set("ext_id", "XSESSIONID")],
        ["GitHub"]       = [$url=/github.com/, $keys=set("_github_ses")],
        ["Google"]       = [$url=/google.com/,  
                           $keys=set("NID", "SID", "HSID", "PREF")],
        ["Gowalla"]      = [$url=/gowalla.com/, $keys=set("__utma")],
        ["Hacker News"]  = [$url=/news.ycombinator.com/, $keys=set("user")],
        ["Harvest"]      = [$url=/harvestapp.com/, $keys=set("_enc_sess")],
        ["NY Times"]     = [$url=/nytimes.com/, $keys=set("NYT-s", "nyt-d")],
        ["Pivotal Tracker"] = [$url=/pivotaltracker.com/, 
                            $keys=set("_myapp_session")],
        ["Slicehost"]    = [$url=/manage.slicehost.com/,
                            $keys=set("_coach_session_id")],
        ["tumblr"]       = [$url=/tumblr.com/, $keys=set("pfp")],
        ["Twitter"]      = [$url=/twitter.com/, 
                            $keys=set("_twitter_sess", "auth_token")],
        ["Yahoo"]        = [$url=/yahoo.com/, $keys=set("T", "Y")],
        ["Yelp"]         = [$url=/yelp.com/, $keys=set("__utma")],
        ["Windows Live"] = [$url=/live.com/, 
                            $keys=set("MSPProf", "MSPAuth", "RPSTAuth", "NAP")],
        ["Wordpress"]    = [$url=/wordpress.com/, $pat=/wordpress_[0-9a-fA-F]+/]
    } &redef;
}

# Map cookies to users, who are defined as a (address, user-agent) pair.
type cookie_map: table[string] of set[addr,string] ;
global evict_reported: function(map: cookie_map, cookie: string) : interval;
global cookies: cookie_map
    &write_expire = cookie_expiration &expire_func=evict_reported;

# Hijacked sessions that have already been reported.
global hijacking_reported: set[string];

# Once a cookie entry expires, this function evicts the corresponding entry
# from the set of reported cookies.
function evict_reported(map: cookie_map, cookie: string) : interval
{
    delete hijacking_reported[cookie];

    return 0 secs;
}

# Create a unique user session identifier based on a pattern of cookie keys.
function sessionize(cookie: string, info: cookie_info) : string
{
    local id = "";
    local fields = split(cookie, /; /);

    if (info?$pat)
    {
        for (i in fields)
        {
            local s = split1(fields[i], /=/);
            if (s[1] == info$pat)
                id += s[2];
        }
    }

    if (info?$keys)
    {
        local matches: set[string];
        matches = set();
        for (i in fields)
        {
            s = split1(fields[i], /=/);
            if (s[1] in info$keys)
                add matches[s[2]];
        }

        if (|matches| == |info$keys|)
            for (m in matches)
                id += m;
    }

    return id;
}

event http_all_headers(c: connection, is_orig: bool, hlist: mime_header_list)
{
    if (! is_orig)
        return;

    local cookie = "";
    local ua = "";
    local host = "";
    for (i in hlist)
    {
        local hdr = hlist[i]$name;
        local value = hlist[i]$value;
        if (hdr == "COOKIE")
            cookie = value;
        else if (hdr == "USER-AGENT")
            ua = value;
        else if (hdr == "HOST")
            host = to_lower(value);
    }

    if (cookie == "")
        return;

    local id = "";
    local desc = "";
    if (host != "")
        for (k in cookie_list)
        {
            local info = cookie_list[k];
            if (info$url in host)
            {
                id = sessionize(cookie, info);
                desc = k;
                break;
            }
        }

    if (id == "")
        id = cookie;

    if (id !in cookies)
        cookies[id] = set() &mergeable;

    local client = c$id$orig_h;
    add cookies[id][client, ua];

    if (|cookies[id]| <= 1)
        return;

    if (id !in hijacking_reported)
    {
        local s = lookup_http_request_stream(c);
        desc = (desc == "" ? "" : fmt("%s ", desc));
        NOTICE([$note=Sidejacking, $src=client,
                $msg=fmt("%ssession hijacked by %s (%d users/cookie)", desc, 
                client, |cookies[id]|)]);

        add hijacking_reported[id];
    }
}


More information about the Bro mailing list