======================== Contributed Bro Scripts ======================== .. contents:: ``roam.bro`` ============ The `roam.bro <http://git.bro-ids.org/bro-scripts.git/blob_plain/HEAD:/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 ``sidejack.bro`` ================ The `sidejack.bro <http://git.bro-ids.org/bro-scripts.git/blob_plain/HEAD:/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 SidejackingBlogPost_. Requires Bro 2.x. .. _SidejackingBlogPost: http://matthias.vallentin.net/blog/2010/10/taming-the-sheep-detecting-sidejacking-with-bro/ .. _Sidejacking: http://en.wikipedia.org/wiki/Session_hijacking .. _Firesheep: http://codebutler.com/firesheep Author: Matthias Vallentin Contributors: Jordi Ros-Giralt (Reservoir Labs) ``mime-attachment.bro`` ======================= 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 via: :: # 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 = /[pP][dD][fF]$/ | /[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 name. Requires Bro 1.5 Author: Matthias Vallentin ``scan.bro`` ============ 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.