Last updated at Wed, 13 Dec 2017 21:19:55 GMT
Synopsis:
Bro is a network security monitoring platform. The reason for calling it a platform is due to the fact that Bro is a domain specific programming language and a collection of tools and APIs. Together, they comprise a platform for network monitoring. In this article, we will attempt to solidify the fact that Bro is a language by using it as such.
Data Types
The Bro scripting language supports the following built-in types:
Name | Description |
---|---|
[bool](https://www.bro.org/sphinx/script-reference/types.html#type-bool "bool type") | Boolean |
[count](https://www.bro.org/sphinx/script-reference/types.html#type-count "count type"), [int](https://www.bro.org/sphinx/script-reference/types.html#type-int "int type"), [double](https://www.bro.org/sphinx/script-reference/types.html#type-double "double type") | Numeric types |
[time](https://www.bro.org/sphinx/script-reference/types.html#type-time "time type"), [interval](https://www.bro.org/sphinx/script-reference/types.html#type-interval "interval type") | Time types |
[string](https://www.bro.org/sphinx/script-reference/types.html#type-string "string type") | String |
[pattern](https://www.bro.org/sphinx/script-reference/types.html#type-pattern "pattern type") | Regular expression |
[port](https://www.bro.org/sphinx/script-reference/types.html#type-port "port type"), [addr](https://www.bro.org/sphinx/script-reference/types.html#type-addr "addr type"), [subnet](https://www.bro.org/sphinx/script-reference/types.html#type-subnet "subnet type") | Network types |
[enum](https://www.bro.org/sphinx/script-reference/types.html#type-enum "enum type") | Enumeration (user-defined type) |
[table](https://www.bro.org/sphinx/script-reference/types.html#type-table "table type"), [set](https://www.bro.org/sphinx/script-reference/types.html#type-set "set type"), [vector](https://www.bro.org/sphinx/script-reference/types.html#type-vector "vector type"), [record](https://www.bro.org/sphinx/script-reference/types.html#type-record "record type") | Container types |
[function](https://www.bro.org/sphinx/script-reference/types.html#type-function "function type"), [event](https://www.bro.org/sphinx/script-reference/types.html#type-event "event type"), [hook](https://www.bro.org/sphinx/script-reference/types.html#type-hook "hook type") | Executable types |
[file](https://www.bro.org/sphinx/script-reference/types.html#type-file "file type") | File type (only for writing) |
[opaque](https://www.bro.org/sphinx/script-reference/types.html#type-opaque "opaque type") | Opaque type (for some built-in functions) |
[any](https://www.bro.org/sphinx/script-reference/types.html#type-any "any type") | Any type (for functions or containers) |
Execution
Most people run Bro by reading a PCAP but Bro is an interpreter, we only need to supply a Bro script for it to begin interpreting.
$ bro blah.bro
We can also use the shebang to call the interpreter. This way we can just execute the script by its filename. We’ll use the conventional first programming example.
#!/usr/local/bin/bro
print "Hello World!";
Make it executable and then execute it.
$ chmod 755 blah.bro
$ ./blah.bro
Hello World!
In addition, Bro accepts instructions on standard in:
$ echo 'print "Hello World!";' | bro
Hello World!
Examples
Examples of using some of the data types are listed below. Variable declarations take the form of
scope varname: type;
where scope can be global or local, varname can be any alphanumeric and underscore combination, and type is one of the aforementioned data types. Note that some data structure types require more parameters such as an index type.
Here, we declare and add two numeric data types.
# Numbers
local t: int;
local s: count;
s = 5;
t = 1 + 1;
print fmt("Numbers: %d, %d", t, s);
$ bro num.bro
Numbers: 2, 5
A simple string declaration
# Strings
local a: string = "abc";
print fmt("String: %s", a);
$ bro string.bro
String: abc
Setting and testing Boolean values.
# Boolean
local val: bool = T;
if (val)
print fmt("Bool: %s", val);
$ bro bool.bro
Bool: T
Sets are a data structure that maintain uniqueness i.e. there cannot be elements of the same value.
local uniq_addr: set[addr];
uniq_addr = set( 192.168.1.1, 10.0.0.1 ); # Initialize set
add uniq_addr[172.16.32.1]; # Add another element to set
add uniq_addr[10.0.0.1]; # Add another element to set
print fmt("Set has %d elements:", |uniq_addr|);
print uniq_addr;
$ bro set.bro
Set has 3 elements:
{
172.16.32.1,
192.168.1.1,
10.0.0.1
}
Tables are similar to dictionaries in Python where the table is indexed by a key. The keys are used as a reference to obtain the values they point to.
# Tables
local things: table[string] of string;
things = table(); # Initialize table
things["food"] = "hot";
things["animal"] = "dog";
print fmt("Table: %s, has %d elements", things, |things|);
print fmt("Who doesn't like a salty %s %s?", things["food"], things["animal"]);
$ bro table.bro
Table has 2 elements
{
[animal] = dog,
[food] = hot
}
Who doesn't like a salty hot dog?
A vector is a data structure that is indexed by a count. It’s similar to an one-dimensional array in other languages and is efficient at iterations.
# Vector
local array: vector of string;
array = vector();
array[0] = "first element";
array[1] = "second element";
print fmt("Vector: %s, has %d elements", array, |array|);
$ bro vector.bro
Vector: [first element, second element], has 2 elements
Try to play around with a few more data types and you’ll be comfortable with the language in little time.