Skip to content


Subversion checkout URL

You can clone with
Download ZIP
Official mirror of


Contributed Bro Scripts

.. contents::


The `roam.bro
<>`_ script
collects IP-to-MAC mappings (and vice versa) of machines that may have more
than one IP address over time due to a DHCP server in the network.

When keeping per-IP-address state, it could well be that the address becomes
invalid because the client's DHCP lease expired or because it received a new IP
address after rejoining the network. Ideally, this state would roam with the
user. But many Bro script data structures use per-address indices and would
mechanistically instantiate state for a new client even though it merely
reappeared under a new IP address. To incorporate the notion of roaming,
``roam.bro`` makes available two data structures that script writers can use:

    global ip_to_mac: table[addr] of string
        &read_expire = alias_expiration &synchronized;

    global mac_to_ip: table[string] of set[addr]
        &read_expire = alias_expiration &synchronized;

Event handlers for the ``dhcp_ack`` and ``arp_reply`` events populate these
tables. For example, the sidejacking script (see below) makes use of
``roam.bro`` to test whether a certain client IP address is an alias of another
IP address:

    function is_aliased(client: addr, ctx: cookie_context) : bool
        if (client in Roam::ip_to_mac)
            local mac = Roam::ip_to_mac[client];
            if (mac == ctx$mac && mac in Roam::mac_to_ip
                && client in Roam::mac_to_ip[mac])
                return T;

        return F;

If the two tables are not accessed for more than the ``alias_expiration``, the
entry will expire. It is possible to redefine the expiration interval:

    redef Roam::alias_expiration = 7 days;

Requires Bro 1.5

Author: Matthias Vallentin


The `sidejack.bro
script detects the reuse of session cookies in different contexts.
Sidejacking_ is also known as cookie hijacking and means that an
attacker captured a session cookie of a victim to reuse that session.
Off-the-shelf tools like Firesheep_ implement this attack as a Firefox
extension, which makes this attack accessible to the masses.

In its default settings, the script raises a ``SessionCookieReuse`` notice when
the same session cookie is seen from different user agents. If in addition the
IP addresses do not match, a Sidejack notice is being triggered.

There exist various options to tweak the behavior of the script. First, the
notion of a user can be changed. In flat IP address space, it makes sense to
identify a user by its IP address, but this would fail in a NAT environment
where a single IP accommodates several users. For NAT scenarios, one could
define a user as a pair of IP address and USER-AGENT header. For large NATs or
NATs with identically configured machines, this latter notion of user could be
prone to false positives. The user can change the definition of a user via


    redef HTTP::user_is_ip = F;

Another issue poses the presence of absence of link-layer context. Consider a
hotspot or coffeeshop network operator with a private IP space. If Bro can see
DHCP or ARP traffic, we can crisply identify a user by its MAC address and do
not have to resort to high-level notions, such as provided by HTTP headers. In
a static setup, however, this context will likely not be available. At the same
time, if a different address reuses a session cookie in a static IP topology,
we probably observed a sidejacking attack. Furthermore, if the same address
uses the same session cookie from a different user agent, we report such
activity.  By setting


    redef HTTP::use_aliasing = T;

one tells Bro to use keep track of multiple IP addresses for the same host via
``roam.bro``. It makes only sense to set this flag when Bro actually sees DHCP
or ARP traffic.

There is another subtlety: the cookie header consists of a list of key-value
pairs, yet only a subset of those represent a user session while the others
could be random. Simply comparing the entire cookie string against a value seen
in the past would thus be prone to false negatives. Hence we have to restrict
ourselves to the relevant session-identifying subset. In fact, this is how
Firesheep works: it ships with site-specific handlers that define the cookie
keys to extract and then sets only those to impersonate a user. This motivates
the following design: if a specification for a particular service is available,
restrict the cookie to the relevant fields, and otherwise use the cookie as a
whole. The default set of known services that ships with the detector is based
on all handlers Firesheep currently implements. To extend the detection to all
cookies, one can set


    redef HTTP::known_services_only = F;

Finally, the timeout for cookie expiration can be adjusted, e.g.,


    redef HTTP::cookie_expiration = 1 day;

If a cookie is not seen after the ``cookie_expiration``, the associated state
is removed. More information about the script can be found at

Requires Bro 2.x.

.. _SidejackingBlogPost:
.. _Sidejacking:
.. _Firesheep:

Author: Matthias Vallentin

Contributors: Jordi Ros-Giralt (Reservoir Labs)


The `mime-attachment.bro <mime-attachment.bro>`_ script extracts MIME entities
from a STMP session and reports suspicious email attachments, and optionally
saves them to disk. Storing attachment on disk allows for powerful
out-of-the-loop post-processing, such as scanning office documents for
malicious JavaScript or executables for viruses.

The script works by registering a callback handler for the CONTENT-TYPE header
in an SMTP session. Then both MIME type and the name of the attachment is
examined. If either looks suspicious, Bro generates a ``SensitiveMIMEType`` or
``SensitiveExtension`` notice. The user can customize the the analyzer behavior
in many ways. To change the directory where the attachments are stored on disk,
one can redefine the ``attachment_dir`` variable:


    redef Email::attachment_dir = "foo";

The script stores attachments by default, but this behavior can easily changed


    # Whether attachments with sensitive MIME types should be stored.
    redef Email::store_sensitive_mime_types = F;

    # Whether attachments with sensitive file extensions should be stored.
    redef Email::store_sensitive_extensions = F;

It is also possible to restrict or extend the regular expression used to
determine whether an attachment is sensitive or not:


    # Deem only application\/octet-stream as suspicious.
    redef Email::sensitive_mime_types = /application\/octet-stream;

    # Restrict sensitive extensions to office documents and executables.
    redef Email::sensitive_extensions =
      | /[dD][oO][cC][xX]?$/
      | /[xX][lL][sS]$/
      | /[pP][pP][sStT]$/
      | /[eE][xX][eE]$/
      | /[cC][oO][mM]$/
      | /[bB][aA][tT]$/;

The script generates a file of the form ``<ID>-<filename>`` where ``ID`` is a
unique attachment ID that is monotonically increasing and ``filename`` is the
name of the attachment or just the MIME type if the attachment does not have a

Requires Bro 1.5

Author: Matthias Vallentin


This script is the Bro 1.5 scan detector ported to Bro 2.0.

The script has evolved over many years and is quite a mess right now.
We have adapted it to work with Bro 2.x, but eventually Bro 2.x will
get its own rewritten and generalized scan detector.

In addition, there's `scan.cluster.bro` that adapts `scan.bro` to work
in cluster settings. It mimics the default 1.5 configuration as
installed by BroControl.

Requires Bro 2.0

Author: Many over many years.

Something went wrong with that request. Please try again.