Bro is an open-source network security platform that incoming packet streams into high-level events. Bro allows you to configure an array of real-time alerts, execute arbitrary programs on demand, and log data for later use.[1]
Bro began within a research project at the Lawrence Berkeley National Laboratory in 1995 and moved onto an operational deployment there a year later. [1]
Bro has been compared to tcpdump, wireshark, Snort, netflow, and Perl (or any other scripting language) all in one. [2]
Events
event http_header(c: connection, is_orig: bool, name: string, value: string)
Logs
1428008490.419994 CiMFm14le11UPtJhkl 10.1.1.34 57913 38.102.137.159 80 1 GET stationdata.wunderground.com /cgi-bin/stationlookup?format=json&maxage=10&station=KNYNEWYO118&units=english&v=2.0&callback=jQuery17203764660065062344_1428008136674&_=1428008438624 http://www.wunderground.com/cgi-bin/findweather/hdfForecast?query=10010&MR=1 Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.101 Safari/537.36 0 310 200OK - - - (empty) - - - - - Fx8RKotcNrCGtMpG3 text/plain
A network tap is a hardware device which provides a way to access the data flowing across a computer network [3]. Taps are the preferred method for acquiring network data, especially in cases when physical networks are the data source.
The SPAN feature, which is sometimes called port mirroring or port monitoring, selects network traffic for analysis by a network analyzer from a network switch [4]
The SPAN feature was introduced on switches because of a fundamental difference that switches have with hubs. When a hub receives a packet on one port, the hub sends out a copy of that packet on all ports except on the one where the hub received the packet. After a switch boots, it starts to build up a Layer 2 forwarding table on the basis of the source MAC address of the different packets that the switch receives. After this forwarding table is built, the switch forwards traffic that is destined for a MAC address directly to the corresponding port. [4]
For example, if you want to capture Ethernet traffic that is sent by host A to host B, and both are connected to a hub, just attach a sniffer to this hub. All other ports see the traffic between hosts A and B. [4]
conf t
monitor session 1 source [interface | vlan] [ interface | vlan #]
monitor session 1 destination [interface | vlan]
Bro is considered to be in "cluster" mode when Bro is configured to use multiple processes. * Bro clusters can only be used on real-time data acquired from a network interface * Bro clusters are most useful for flow level traffic analysis
Bro is considered to be in "stand-alone" mode when it is configured to use only one process. * "Stand-alone" Bro can be used on real-time data acquired from a network interface or PCAP data * When used as a standalone tool Bro can be used for flow and packet level traffic analysis
Bro clusters consist of three components:
The configuration file that specifies the layout of your cluster is located in: * $BRO_HOME/etc/node.cfg
At a high level, Bro's core consists of four parts:
The "Bro" scripting language is a domain-specific languge designed specifically to be useful in the analysis of network data.
Data gets delivered to Bro's scripting engine in "events". Events are like functions that are called each time Bro's parsers conclude a phase of parsing from a file or network protocol.
"Events" most often coincide with important protocol phases such as the arrival of a DNS query (dns_query) or the establishment of a TCP session (connection_established).
For instance, if I was interested in saving all DNS queries seen by Bro in a data structure, I would add a script containg a "dns_query" event. Within the dns_query event, there would be code for extracting data from the event, and loading that data into a data structure.
A list of all Events generated by protocol parsers is located at: http://www.bro.org/sphinx/scripts/base/event.bif.html
Bro is a strongly typed programming language, all data in the Bro programming language must be dealt with explicitly according to its type. Being a domain specific programming language, Bro has a number of data types that are not common in general programming language. Below is a list of the most common data types in the Bro language.
addr - An “addr” is a type representing IPv4 and IPv6 addresses.
event connection_established(c: connection) {
local a: addr;
a = 10.1.1.1
}
string - A "string" is used to hold character‐strings.
event connection_established(c: connection) {
local s: string;
s = "I'm a string";
}
table - A “table” is an associative array that maps one value (the index) to another value (the yield). ``` global TrackedSessions: table[addr] of string;
event connection_established(c: connection) { TrackedSessions[cidorig_h] = c$uid }
* **record** - A “record” is a collection of values (much like a struct in other well‐known languages such as C++), each value has a field and a data type. Records can hold fields of any data type, regardless of the data type of the other fields.
export { type conn_id: record { orig_h: addr &log orig_p: port &log resp_h: addr &log resp_p: port &log }; }
* **subnet** - A type representing a block of IP addresses in CIDR notation. A subnet constant is written as an addr followed by a slash (/) and then the network prefix size specified as a decimal number. For example, 192.168.0.0/16 or [fe80::]/64.
Subnets can be compared for equality (==, !=). An addr can be checked for inclusion in a subnet using the “in” or ”!in” operators.
## Attributes
Attributes occur at the end of type/event declarations and change their behavior. The syntax is &key or &key=val, e.g., type T: set[count] &read_expire=5min or event foo() &priority=-3. The Bro scripting language supports the following built-in attributes.
* **&redef** Allows for redefinition of initial object values. This is typically used with constants, for example, const clever = T &redef; would allow the constant to be redefined at some later point during script execution.
## Conditionals
* **If** - If statements look like this:
if (condition) { print "code!"; }
## Loops
* Bro supports "For" loops
local t: table[count] of string; for ( n in t ) ...
local services: table[addr, port] of string; for ( [a, p] in services ) ...
## The Anatomy of an Event
In this example we will be analyzing the **connection_established** event. The connection established event is, "Generated when [Bro sees] a SYN-ACK packet from the responder in a TCP handshake." [7]
event connection_established (c: connection) { ... }
There are four parts to an event call:
1. "event" - This tells Bro that event name will follow
2. "connection_established" - This tells Bro which event you would like to "hook"
3. "(c: connection)" - This illustrates that the event will be loaded with a variable named "c" and it will be of type "connection"
4. "{ ... }" - The code for your Bro script should go between the two curly braces. It is represented by elipsis in this example.
## The Connection Record
A "connection" is a very common data type in Bro. If you understand how it works, you will be well on your way to understanding most data loaded in Bro events.
A "connection" is not a primitive data type in Bro. Instead, it is a construct created in Bro script to deliver data for TCP connections in Bro. A "connection" is created with the primitive datatype "record".
Below is a sample of the information contained in a "connection" from Bro's documentation (https://www.bro.org/sphinx/scripts/base/init-bare.bro.html#type-connection).
id: conn_id The connection’s identifying 4-tuple. orig: endpoint Statistics about originator side. resp: endpoint Statistics about responder side. start_time: time The timestamp of the connection’s first packet. duration: interval The duration of the conversation. Roughly speaking, this is the interval between first and last data packet (low-level TCP details may adjust it somewhat in ambiguous cases). service: set [string] The set of services the connection is using as determined by Bro’s dynamic protocol detection. Each entry is the label of an analyzer that confirmed that it could parse the connection payload. While typically, there will be at most one entry for each connection, in principle it is possible that more than one protocol analyzer is able to parse the same data. If so, all will be recorded. Also note that the recorded services are independent of any transport-level protocols. ```
Now that we understand more about the connection_established event, lets write a simple Bro script that extracts the source and destination addresses from network traffic and print them out.
event connection_established (c: connection) {
}
Access to a record field uses the dollar sign ($) operator:
global r: MyRecordType;
r$c = 13;
event connection_established (c: connection) {
print c$id;
}
Change the print statement again so that you only print connection records for responders in the subnet 192.168.1.0/24.
https://www.bro.org/sphinx-git/scripts/base/bif/plugins/Bro_TCP.events.bif.bro.html