mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 06:38:20 +00:00
Use sourcecode Sphinx directive more widely
It looks better by default with the RTD theme, Bro syntax highlighting is supported well enough, and I think will be more more consistent with the literalinclude usages, so being able to drop the extra Sphinx extension seems good.
This commit is contained in:
parent
9f642bfe5b
commit
a80d7ead6c
24 changed files with 209 additions and 476 deletions
|
@ -24,7 +24,7 @@ rejected usernames and passwords occurring from a single address. We
|
||||||
start by defining a threshold for the number of attempts, a monitoring
|
start by defining a threshold for the number of attempts, a monitoring
|
||||||
interval (in minutes), and a new notice type.
|
interval (in minutes), and a new notice type.
|
||||||
|
|
||||||
.. code:: bro
|
.. sourcecode:: bro
|
||||||
:caption: detect-bruteforcing.bro
|
:caption: detect-bruteforcing.bro
|
||||||
|
|
||||||
module FTP;
|
module FTP;
|
||||||
|
@ -53,7 +53,7 @@ function to break down the reply code and check if the first digit is a
|
||||||
"5" or not. If true, we then use the :ref:`Summary Statistics Framework
|
"5" or not. If true, we then use the :ref:`Summary Statistics Framework
|
||||||
<sumstats-framework>` to keep track of the number of failed attempts.
|
<sumstats-framework>` to keep track of the number of failed attempts.
|
||||||
|
|
||||||
.. code:: bro
|
.. sourcecode:: bro
|
||||||
:caption: detect-bruteforcing.bro
|
:caption: detect-bruteforcing.bro
|
||||||
|
|
||||||
event ftp_reply(c: connection, code: count, msg: string, cont_resp: bool)
|
event ftp_reply(c: connection, code: count, msg: string, cont_resp: bool)
|
||||||
|
@ -70,7 +70,7 @@ Next, we use the SumStats framework to raise a notice of the attack when
|
||||||
the number of failed attempts exceeds the specified threshold during the
|
the number of failed attempts exceeds the specified threshold during the
|
||||||
measuring interval.
|
measuring interval.
|
||||||
|
|
||||||
.. code:: bro
|
.. sourcecode:: bro
|
||||||
:caption: detect-bruteforcing.bro
|
:caption: detect-bruteforcing.bro
|
||||||
|
|
||||||
event bro_init()
|
event bro_init()
|
||||||
|
@ -99,7 +99,7 @@ measuring interval.
|
||||||
|
|
||||||
Below is the final code for our script.
|
Below is the final code for our script.
|
||||||
|
|
||||||
.. code:: bro
|
.. sourcecode:: bro
|
||||||
:caption: detect-bruteforcing.bro
|
:caption: detect-bruteforcing.bro
|
||||||
|
|
||||||
##! FTP brute-forcing detector, triggering when too many rejected usernames or
|
##! FTP brute-forcing detector, triggering when too many rejected usernames or
|
||||||
|
@ -163,7 +163,7 @@ Below is the final code for our script.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.. console::
|
.. sourcecode:: console
|
||||||
|
|
||||||
$ bro -r ftp/bruteforce.pcap protocols/ftp/detect-bruteforcing.bro
|
$ bro -r ftp/bruteforce.pcap protocols/ftp/detect-bruteforcing.bro
|
||||||
$ cat notice.log
|
$ cat notice.log
|
||||||
|
|
|
@ -26,7 +26,7 @@ sys.path.insert(0, os.path.abspath('ext'))
|
||||||
|
|
||||||
# Add any Sphinx extension module names here, as strings. They can be extensions
|
# Add any Sphinx extension module names here, as strings. They can be extensions
|
||||||
# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
|
# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
|
||||||
extensions += ['bro', 'rst_directive', 'sphinx.ext.todo']
|
extensions += ['bro', 'sphinx.ext.todo']
|
||||||
|
|
||||||
# Add any paths that contain templates here, relative to this directory.
|
# Add any paths that contain templates here, relative to this directory.
|
||||||
templates_path = ['_templates']
|
templates_path = ['_templates']
|
||||||
|
|
|
@ -1,76 +0,0 @@
|
||||||
from pygments.lexer import RegexLexer, bygroups, include
|
|
||||||
from pygments.token import *
|
|
||||||
|
|
||||||
__all__ = ["BroLexer"]
|
|
||||||
|
|
||||||
class BroLexer(RegexLexer):
|
|
||||||
name = 'Bro'
|
|
||||||
aliases = ['bro']
|
|
||||||
filenames = ['*.bro']
|
|
||||||
|
|
||||||
_hex = r'[0-9a-fA-F_]+'
|
|
||||||
_float = r'((\d*\.?\d+)|(\d+\.?\d*))([eE][-+]?\d+)?'
|
|
||||||
_h = r'[A-Za-z0-9][-A-Za-z0-9]*'
|
|
||||||
|
|
||||||
tokens = {
|
|
||||||
'root': [
|
|
||||||
# Whitespace
|
|
||||||
('^@.*?\n', Comment.Preproc),
|
|
||||||
(r'#.*?\n', Comment.Single),
|
|
||||||
(r'\n', Text),
|
|
||||||
(r'\s+', Text),
|
|
||||||
(r'\\\n', Text),
|
|
||||||
# Keywords
|
|
||||||
(r'(add|alarm|break|case|const|continue|delete|do|else|enum|event'
|
|
||||||
r'|export|for|function|if|global|local|module|next'
|
|
||||||
r'|of|print|redef|return|schedule|when|while)\b', Keyword),
|
|
||||||
(r'(addr|any|bool|count|counter|double|file|int|interval|net'
|
|
||||||
r'|pattern|port|record|set|string|subnet|table|time|timer'
|
|
||||||
r'|vector)\b', Keyword.Type),
|
|
||||||
(r'(T|F)\b', Keyword.Constant),
|
|
||||||
(r'(&)((?:add|delete|expire)_func|attr|(create|read|write)_expire'
|
|
||||||
r'|default|raw_output|encrypt|group|log'
|
|
||||||
r'|mergeable|optional|persistent|priority|redef'
|
|
||||||
r'|rotate_(?:interval|size)|synchronized)\b', bygroups(Punctuation,
|
|
||||||
Keyword)),
|
|
||||||
(r'\s+module\b', Keyword.Namespace),
|
|
||||||
# Addresses, ports and networks
|
|
||||||
(r'\d+/(tcp|udp|icmp|unknown)\b', Number),
|
|
||||||
(r'(\d+\.){3}\d+', Number),
|
|
||||||
(r'(' + _hex + r'){7}' + _hex, Number),
|
|
||||||
(r'0x' + _hex + r'(' + _hex + r'|:)*::(' + _hex + r'|:)*', Number),
|
|
||||||
(r'((\d+|:)(' + _hex + r'|:)*)?::(' + _hex + r'|:)*', Number),
|
|
||||||
(r'(\d+\.\d+\.|(\d+\.){2}\d+)', Number),
|
|
||||||
# Hostnames
|
|
||||||
(_h + r'(\.' + _h + r')+', String),
|
|
||||||
# Numeric
|
|
||||||
(_float + r'\s+(day|hr|min|sec|msec|usec)s?\b', Literal.Date),
|
|
||||||
(r'0[xX]' + _hex, Number.Hex),
|
|
||||||
(_float, Number.Float),
|
|
||||||
(r'\d+', Number.Integer),
|
|
||||||
(r'/', String.Regex, 'regex'),
|
|
||||||
(r'"', String, 'string'),
|
|
||||||
# Operators
|
|
||||||
(r'[!%*/+-:<=>?~|]', Operator),
|
|
||||||
(r'([-+=&|]{2}|[+-=!><]=)', Operator),
|
|
||||||
(r'(in|match)\b', Operator.Word),
|
|
||||||
(r'[{}()\[\]$.,;]', Punctuation),
|
|
||||||
# Identfier
|
|
||||||
(r'([_a-zA-Z]\w*)(::)', bygroups(Name, Name.Namespace)),
|
|
||||||
(r'[a-zA-Z_][a-zA-Z_0-9]*', Name)
|
|
||||||
],
|
|
||||||
'string': [
|
|
||||||
(r'"', String, '#pop'),
|
|
||||||
(r'\\([\\abfnrtv"\']|x[a-fA-F0-9]{2,4}|[0-7]{1,3})', String.Escape),
|
|
||||||
(r'[^\\"\n]+', String),
|
|
||||||
(r'\\\n', String),
|
|
||||||
(r'\\', String)
|
|
||||||
],
|
|
||||||
'regex': [
|
|
||||||
(r'/', String.Regex, '#pop'),
|
|
||||||
(r'\\[\\nt/]', String.Regex), # String.Escape is too intense.
|
|
||||||
(r'[^\\/\n]+', String.Regex),
|
|
||||||
(r'\\\n', String.Regex),
|
|
||||||
(r'\\', String.Regex)
|
|
||||||
]
|
|
||||||
}
|
|
|
@ -1,183 +0,0 @@
|
||||||
def setup(app):
|
|
||||||
pass
|
|
||||||
|
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
"""
|
|
||||||
|
|
||||||
Modified version of the the Pygments reStructuredText directive. -Robin
|
|
||||||
|
|
||||||
This provides two new directives:
|
|
||||||
|
|
||||||
- .. code:: [<format>]
|
|
||||||
|
|
||||||
Highlights the following code block according to <format> if
|
|
||||||
given (e.g., "c", "python", etc.).
|
|
||||||
|
|
||||||
- .. console::
|
|
||||||
|
|
||||||
Highlits the following code block as a shell session.
|
|
||||||
|
|
||||||
For compatibility with the original version, "sourcecode" is
|
|
||||||
equivalent to "code".
|
|
||||||
|
|
||||||
Original comment:
|
|
||||||
|
|
||||||
The Pygments reStructuredText directive
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
This fragment is a Docutils_ 0.5 directive that renders source code
|
|
||||||
(to HTML only, currently) via Pygments.
|
|
||||||
|
|
||||||
To use it, adjust the options below and copy the code into a module
|
|
||||||
that you import on initialization. The code then automatically
|
|
||||||
registers a ``sourcecode`` directive that you can use instead of
|
|
||||||
normal code blocks like this::
|
|
||||||
|
|
||||||
.. sourcecode:: python
|
|
||||||
|
|
||||||
My code goes here.
|
|
||||||
|
|
||||||
If you want to have different code styles, e.g. one with line numbers
|
|
||||||
and one without, add formatters with their names in the VARIANTS dict
|
|
||||||
below. You can invoke them instead of the DEFAULT one by using a
|
|
||||||
directive option::
|
|
||||||
|
|
||||||
.. sourcecode:: python
|
|
||||||
:linenos:
|
|
||||||
|
|
||||||
My code goes here.
|
|
||||||
|
|
||||||
Look at the `directive documentation`_ to get all the gory details.
|
|
||||||
|
|
||||||
.. _Docutils: http://docutils.sf.net/
|
|
||||||
.. _directive documentation:
|
|
||||||
http://docutils.sourceforge.net/docs/howto/rst-directives.html
|
|
||||||
|
|
||||||
:copyright: Copyright 2006-2010 by the Pygments team, see AUTHORS.
|
|
||||||
:license: BSD, see LICENSE for details.
|
|
||||||
"""
|
|
||||||
|
|
||||||
# Options
|
|
||||||
# ~~~~~~~
|
|
||||||
|
|
||||||
# Set to True if you want inline CSS styles instead of classes
|
|
||||||
INLINESTYLES = False
|
|
||||||
|
|
||||||
from pygments.formatters import HtmlFormatter
|
|
||||||
|
|
||||||
class MyHtmlFormatter(HtmlFormatter):
|
|
||||||
def format_unencoded(self, tokensource, outfile):
|
|
||||||
|
|
||||||
# A NOP currently.
|
|
||||||
new_tokens = []
|
|
||||||
for (i, piece) in tokensource:
|
|
||||||
new_tokens += [(i, piece)]
|
|
||||||
|
|
||||||
return super(MyHtmlFormatter, self).format_unencoded(new_tokens, outfile)
|
|
||||||
|
|
||||||
# The default formatter
|
|
||||||
DEFAULT = MyHtmlFormatter(noclasses=INLINESTYLES, cssclass="pygments")
|
|
||||||
|
|
||||||
# Add name -> formatter pairs for every variant you want to use
|
|
||||||
VARIANTS = {
|
|
||||||
# 'linenos': HtmlFormatter(noclasses=INLINESTYLES, linenos=True),
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
import textwrap
|
|
||||||
|
|
||||||
from docutils import nodes
|
|
||||||
from docutils.parsers.rst import directives, Directive
|
|
||||||
|
|
||||||
from pygments import highlight
|
|
||||||
from pygments.lexers import get_lexer_by_name, guess_lexer, TextLexer
|
|
||||||
from pygments.token import Text, Keyword, Error, Operator, Name
|
|
||||||
from pygments.filter import Filter
|
|
||||||
|
|
||||||
# Ugly hack to register the Bro lexer. I'm sure there's a better way to do it,
|
|
||||||
# but it's not obvious ...
|
|
||||||
from bro_lexer.bro import BroLexer
|
|
||||||
from pygments.lexers._mapping import LEXERS
|
|
||||||
LEXERS['BroLexer'] = ('bro_lexer.bro', BroLexer.name, BroLexer.aliases, BroLexer.filenames, ())
|
|
||||||
|
|
||||||
class Pygments(Directive):
|
|
||||||
""" Source code syntax hightlighting.
|
|
||||||
"""
|
|
||||||
#max_line_length = 68
|
|
||||||
max_line_length = 0
|
|
||||||
|
|
||||||
required_arguments = 0
|
|
||||||
optional_arguments = 1
|
|
||||||
final_argument_whitespace = True
|
|
||||||
option_spec = dict([(key, directives.flag) for key in VARIANTS])
|
|
||||||
has_content = True
|
|
||||||
|
|
||||||
def wrapped_content(self):
|
|
||||||
content = []
|
|
||||||
|
|
||||||
if Console.max_line_length:
|
|
||||||
for line in self.content:
|
|
||||||
content += textwrap.wrap(line, Console.max_line_length, subsequent_indent=" ")
|
|
||||||
else:
|
|
||||||
content = self.content
|
|
||||||
|
|
||||||
return u'\n'.join(content)
|
|
||||||
|
|
||||||
def run(self):
|
|
||||||
self.assert_has_content()
|
|
||||||
|
|
||||||
content = self.wrapped_content()
|
|
||||||
|
|
||||||
if len(self.arguments) > 0:
|
|
||||||
try:
|
|
||||||
lexer = get_lexer_by_name(self.arguments[0])
|
|
||||||
except (ValueError, IndexError):
|
|
||||||
# lexer not found, use default.
|
|
||||||
lexer = TextLexer()
|
|
||||||
else:
|
|
||||||
try:
|
|
||||||
lexer = guess_lexer(content)
|
|
||||||
except:
|
|
||||||
lexer = TextLexer()
|
|
||||||
|
|
||||||
# import sys
|
|
||||||
# print >>sys.stderr, self.arguments, lexer.__class__
|
|
||||||
|
|
||||||
# take an arbitrary option if more than one is given
|
|
||||||
formatter = self.options and VARIANTS[self.options.keys()[0]] or DEFAULT
|
|
||||||
parsed = highlight(content, lexer, formatter)
|
|
||||||
return [nodes.raw('', parsed, format='html')]
|
|
||||||
|
|
||||||
class MyFilter(Filter):
|
|
||||||
def filter(self, lexer, stream):
|
|
||||||
|
|
||||||
bol = True
|
|
||||||
|
|
||||||
for (ttype, value) in stream:
|
|
||||||
# Color the '>' prompt sign.
|
|
||||||
if bol and ttype is Text and value == ">":
|
|
||||||
ttype = Name.Variable.Class # This gives us a nice red.
|
|
||||||
|
|
||||||
# Discolor builtin, that can look funny.
|
|
||||||
if ttype is Name.Builtin:
|
|
||||||
ttype = Text
|
|
||||||
|
|
||||||
bol = value.endswith("\n")
|
|
||||||
|
|
||||||
yield (ttype, value)
|
|
||||||
|
|
||||||
class Console(Pygments):
|
|
||||||
required_arguments = 0
|
|
||||||
optional_arguments = 0
|
|
||||||
|
|
||||||
def run(self):
|
|
||||||
self.assert_has_content()
|
|
||||||
content = self.wrapped_content()
|
|
||||||
lexer = get_lexer_by_name("sh")
|
|
||||||
lexer.add_filter(MyFilter())
|
|
||||||
parsed = highlight(content, lexer, DEFAULT)
|
|
||||||
return [nodes.raw('', parsed, format='html')]
|
|
||||||
|
|
||||||
directives.register_directive('sourcecode', Pygments)
|
|
||||||
directives.register_directive('code', Pygments)
|
|
||||||
directives.register_directive('console', Console)
|
|
|
@ -430,7 +430,7 @@ should always use the fully-qualified event name.
|
||||||
|
|
||||||
For example, this will likely not work as expected:
|
For example, this will likely not work as expected:
|
||||||
|
|
||||||
.. code:: bro
|
.. sourcecode:: bro
|
||||||
|
|
||||||
module MyModule;
|
module MyModule;
|
||||||
|
|
||||||
|
@ -454,7 +454,7 @@ will never be called and also not any remote handlers either, even if
|
||||||
:bro:see:`Broker::auto_publish` was used elsewhere for it. Instead, at
|
:bro:see:`Broker::auto_publish` was used elsewhere for it. Instead, at
|
||||||
minimum you would need change the ``bro_init()`` handler:
|
minimum you would need change the ``bro_init()`` handler:
|
||||||
|
|
||||||
.. code:: bro
|
.. sourcecode:: bro
|
||||||
|
|
||||||
event bro_init()
|
event bro_init()
|
||||||
{
|
{
|
||||||
|
@ -465,7 +465,7 @@ minimum you would need change the ``bro_init()`` handler:
|
||||||
Though, an easy rule of thumb to remember would be to always use the
|
Though, an easy rule of thumb to remember would be to always use the
|
||||||
explicit module namespace scoping and you can't go wrong:
|
explicit module namespace scoping and you can't go wrong:
|
||||||
|
|
||||||
.. code:: bro
|
.. sourcecode:: bro
|
||||||
|
|
||||||
module MyModule;
|
module MyModule;
|
||||||
|
|
||||||
|
@ -494,7 +494,7 @@ Manager Sending Events To Workers
|
||||||
This is fairly straightforward, we just need a topic name which we know
|
This is fairly straightforward, we just need a topic name which we know
|
||||||
all workers are subscribed combined with the event we want to send them.
|
all workers are subscribed combined with the event we want to send them.
|
||||||
|
|
||||||
.. code:: bro
|
.. sourcecode:: bro
|
||||||
|
|
||||||
event manager_to_workers(s: string)
|
event manager_to_workers(s: string)
|
||||||
{
|
{
|
||||||
|
@ -524,10 +524,10 @@ all workers are subscribed combined with the event we want to send them.
|
||||||
# eliminated by using the following conditional directives.
|
# eliminated by using the following conditional directives.
|
||||||
# It's evaluated once per node at parse-time and, if false,
|
# It's evaluated once per node at parse-time and, if false,
|
||||||
# any code within is just ignored / treated as not existing at all.
|
# any code within is just ignored / treated as not existing at all.
|
||||||
@if ( Cluster::local_node_type() == Cluster::MANAGER )
|
@if ( Cluster::local_node_type() == Cluster::MANAGER )
|
||||||
Broker::publish(Cluster::worker_topic, manager_to_workers,
|
Broker::publish(Cluster::worker_topic, manager_to_workers,
|
||||||
"hello v3");
|
"hello v3");
|
||||||
@endif
|
@endif
|
||||||
}
|
}
|
||||||
|
|
||||||
Worker Sending Events To Manager
|
Worker Sending Events To Manager
|
||||||
|
@ -537,7 +537,7 @@ This should look almost identical to the previous case of sending an event
|
||||||
from the manager to workers, except it simply changes the topic name to
|
from the manager to workers, except it simply changes the topic name to
|
||||||
one which the manager is subscribed.
|
one which the manager is subscribed.
|
||||||
|
|
||||||
.. code:: bro
|
.. sourcecode:: bro
|
||||||
|
|
||||||
event worker_to_manager(worker_name: string)
|
event worker_to_manager(worker_name: string)
|
||||||
{
|
{
|
||||||
|
@ -558,17 +558,17 @@ topology, this type of communication is a bit different than what we
|
||||||
did before since we have to manually relay the event via some node that *is*
|
did before since we have to manually relay the event via some node that *is*
|
||||||
connected to all workers. The manager or a proxy satisfies that requirement:
|
connected to all workers. The manager or a proxy satisfies that requirement:
|
||||||
|
|
||||||
.. code:: bro
|
.. sourcecode:: bro
|
||||||
|
|
||||||
event worker_to_workers(worker_name: string)
|
event worker_to_workers(worker_name: string)
|
||||||
{
|
{
|
||||||
@if ( Cluster::local_node_type() == Cluster::MANAGER ||
|
@if ( Cluster::local_node_type() == Cluster::MANAGER ||
|
||||||
Cluster::local_node_type() == Cluster::PROXY )
|
Cluster::local_node_type() == Cluster::PROXY )
|
||||||
Broker::publish(Cluster::worker_topic, worker_to_workers,
|
Broker::publish(Cluster::worker_topic, worker_to_workers,
|
||||||
worker_name)
|
worker_name)
|
||||||
@else
|
@else
|
||||||
print "got event from worker", worker_name;
|
print "got event from worker", worker_name;
|
||||||
@endif
|
@endif
|
||||||
}
|
}
|
||||||
|
|
||||||
event some_event_handled_on_worker()
|
event some_event_handled_on_worker()
|
||||||
|
@ -597,7 +597,7 @@ we can make use of a `Highest Random Weight (HRW) hashing
|
||||||
<https://en.wikipedia.org/wiki/Rendezvous_hashing>`_ distribution strategy
|
<https://en.wikipedia.org/wiki/Rendezvous_hashing>`_ distribution strategy
|
||||||
to uniformly map an arbitrary key space across all available proxies.
|
to uniformly map an arbitrary key space across all available proxies.
|
||||||
|
|
||||||
.. code:: bro
|
.. sourcecode:: bro
|
||||||
|
|
||||||
event worker_to_proxies(worker_name: string)
|
event worker_to_proxies(worker_name: string)
|
||||||
{
|
{
|
||||||
|
|
|
@ -42,7 +42,7 @@ Declaring options
|
||||||
|
|
||||||
The "option" keyword allows variables to be declared as configuration options.
|
The "option" keyword allows variables to be declared as configuration options.
|
||||||
|
|
||||||
.. code:: bro
|
.. sourcecode:: bro
|
||||||
|
|
||||||
module TestModule;
|
module TestModule;
|
||||||
|
|
||||||
|
@ -67,7 +67,7 @@ being that there is no need to specify the :bro:attr:`&redef` attribute in
|
||||||
the declaration of an option. For example, given the above option
|
the declaration of an option. For example, given the above option
|
||||||
declarations, here are some possible redefs:
|
declarations, here are some possible redefs:
|
||||||
|
|
||||||
.. code:: bro
|
.. sourcecode:: bro
|
||||||
|
|
||||||
redef TestModule::enable_feature = T;
|
redef TestModule::enable_feature = T;
|
||||||
redef TestModule::my_networks += { 10.1.0.0/16, 10.2.0.0/16 };
|
redef TestModule::my_networks += { 10.1.0.0/16, 10.2.0.0/16 };
|
||||||
|
@ -90,7 +90,7 @@ only the manager node attempts to read the specified configuration files.
|
||||||
|
|
||||||
For example, simply add something like this to local.bro:
|
For example, simply add something like this to local.bro:
|
||||||
|
|
||||||
.. code:: bro
|
.. sourcecode:: bro
|
||||||
|
|
||||||
redef Config::config_files += { "/path/to/config.dat" };
|
redef Config::config_files += { "/path/to/config.dat" };
|
||||||
|
|
||||||
|
@ -131,7 +131,7 @@ supported by the config input reader. In that case you would need to use
|
||||||
the Config::set_value function to change the value of such an option as
|
the Config::set_value function to change the value of such an option as
|
||||||
shown in the following example.
|
shown in the following example.
|
||||||
|
|
||||||
.. code:: bro
|
.. sourcecode:: bro
|
||||||
|
|
||||||
module TestModule;
|
module TestModule;
|
||||||
|
|
||||||
|
@ -158,7 +158,7 @@ change handler for an option that has a data type of "addr" (for other
|
||||||
data types, the return type and 2nd parameter data type must be adjusted
|
data types, the return type and 2nd parameter data type must be adjusted
|
||||||
accordingly):
|
accordingly):
|
||||||
|
|
||||||
.. code:: bro
|
.. sourcecode:: bro
|
||||||
|
|
||||||
module TestModule;
|
module TestModule;
|
||||||
|
|
||||||
|
|
|
@ -41,7 +41,7 @@ Here's a simple example:
|
||||||
:language: bro
|
:language: bro
|
||||||
:linenos:
|
:linenos:
|
||||||
|
|
||||||
.. console::
|
.. sourcecode:: console
|
||||||
|
|
||||||
$ bro -r http/get.trace file_analysis_01.bro
|
$ bro -r http/get.trace file_analysis_01.bro
|
||||||
file_state_remove
|
file_state_remove
|
||||||
|
@ -88,7 +88,7 @@ calculate the MD5 of plain text files:
|
||||||
:language: bro
|
:language: bro
|
||||||
:linenos:
|
:linenos:
|
||||||
|
|
||||||
.. console::
|
.. sourcecode:: console
|
||||||
|
|
||||||
$ bro -r http/get.trace file_analysis_02.bro
|
$ bro -r http/get.trace file_analysis_02.bro
|
||||||
new file, FakNcS1Jfe01uljb3
|
new file, FakNcS1Jfe01uljb3
|
||||||
|
@ -97,7 +97,7 @@ calculate the MD5 of plain text files:
|
||||||
Some file analyzers might have tunable parameters that need to be
|
Some file analyzers might have tunable parameters that need to be
|
||||||
specified in the call to :bro:see:`Files::add_analyzer`:
|
specified in the call to :bro:see:`Files::add_analyzer`:
|
||||||
|
|
||||||
.. code:: bro
|
.. sourcecode:: bro
|
||||||
|
|
||||||
event file_new(f: fa_file)
|
event file_new(f: fa_file)
|
||||||
{
|
{
|
||||||
|
@ -137,7 +137,7 @@ the input framework uses to uniquely identify an input stream.
|
||||||
|
|
||||||
Example output of the above script may be:
|
Example output of the above script may be:
|
||||||
|
|
||||||
.. console::
|
.. sourcecode:: console
|
||||||
|
|
||||||
$ echo "Hello world" > myfile
|
$ echo "Hello world" > myfile
|
||||||
$ bro file_analysis_03.bro
|
$ bro file_analysis_03.bro
|
||||||
|
|
|
@ -26,19 +26,19 @@ Before building Bro, you need to install libmaxminddb.
|
||||||
|
|
||||||
* RPM/RedHat-based Linux:
|
* RPM/RedHat-based Linux:
|
||||||
|
|
||||||
.. console::
|
.. sourcecode:: console
|
||||||
|
|
||||||
sudo yum install libmaxminddb-devel
|
sudo yum install libmaxminddb-devel
|
||||||
|
|
||||||
* DEB/Debian-based Linux:
|
* DEB/Debian-based Linux:
|
||||||
|
|
||||||
.. console::
|
.. sourcecode:: console
|
||||||
|
|
||||||
sudo apt-get install libmaxminddb-dev
|
sudo apt-get install libmaxminddb-dev
|
||||||
|
|
||||||
* FreeBSD:
|
* FreeBSD:
|
||||||
|
|
||||||
.. console::
|
.. sourcecode:: console
|
||||||
|
|
||||||
sudo pkg install libmaxminddb
|
sudo pkg install libmaxminddb
|
||||||
|
|
||||||
|
@ -58,7 +58,7 @@ and regions in addition to countries.
|
||||||
`Download <http://geolite.maxmind.com/download/geoip/database/GeoLite2-City.tar.gz>`__
|
`Download <http://geolite.maxmind.com/download/geoip/database/GeoLite2-City.tar.gz>`__
|
||||||
the GeoLite2 city binary database:
|
the GeoLite2 city binary database:
|
||||||
|
|
||||||
.. console::
|
.. sourcecode:: console
|
||||||
|
|
||||||
wget http://geolite.maxmind.com/download/geoip/database/GeoLite2-City.tar.gz
|
wget http://geolite.maxmind.com/download/geoip/database/GeoLite2-City.tar.gz
|
||||||
tar zxf GeoLite2-City.tar.gz
|
tar zxf GeoLite2-City.tar.gz
|
||||||
|
@ -69,7 +69,7 @@ and will vary depending on which platform and package you are using. For
|
||||||
FreeBSD, use ``/usr/local/share/GeoIP``. For Linux, use ``/usr/share/GeoIP``
|
FreeBSD, use ``/usr/local/share/GeoIP``. For Linux, use ``/usr/share/GeoIP``
|
||||||
or ``/var/lib/GeoIP`` (choose whichever one already exists).
|
or ``/var/lib/GeoIP`` (choose whichever one already exists).
|
||||||
|
|
||||||
.. console::
|
.. sourcecode:: console
|
||||||
|
|
||||||
mv <extracted subdir>/GeoLite2-City.mmdb <path_to_database_dir>/GeoLite2-City.mmdb
|
mv <extracted subdir>/GeoLite2-City.mmdb <path_to_database_dir>/GeoLite2-City.mmdb
|
||||||
|
|
||||||
|
@ -81,7 +81,7 @@ everything is setup correctly. After installing libmaxminddb and the GeoIP
|
||||||
city database, and building Bro, you can quickly check if the GeoIP
|
city database, and building Bro, you can quickly check if the GeoIP
|
||||||
functionality works by running a command like this:
|
functionality works by running a command like this:
|
||||||
|
|
||||||
.. console::
|
.. sourcecode:: console
|
||||||
|
|
||||||
bro -e "print lookup_location(8.8.8.8);"
|
bro -e "print lookup_location(8.8.8.8);"
|
||||||
|
|
||||||
|
@ -113,7 +113,7 @@ Usage
|
||||||
|
|
||||||
There is a built-in function that provides the GeoIP functionality:
|
There is a built-in function that provides the GeoIP functionality:
|
||||||
|
|
||||||
.. code:: bro
|
.. sourcecode:: bro
|
||||||
|
|
||||||
function lookup_location(a:addr): geo_location
|
function lookup_location(a:addr): geo_location
|
||||||
|
|
||||||
|
@ -130,7 +130,7 @@ Example
|
||||||
|
|
||||||
To show every ftp connection from hosts in Ohio, this is now very easy:
|
To show every ftp connection from hosts in Ohio, this is now very easy:
|
||||||
|
|
||||||
.. code:: bro
|
.. sourcecode:: bro
|
||||||
|
|
||||||
event ftp_reply(c: connection, code: count, msg: string, cont_resp: bool)
|
event ftp_reply(c: connection, code: count, msg: string, cont_resp: bool)
|
||||||
{
|
{
|
||||||
|
|
|
@ -53,7 +53,7 @@ the table content.
|
||||||
|
|
||||||
The two records are defined as:
|
The two records are defined as:
|
||||||
|
|
||||||
.. code:: bro
|
.. sourcecode:: bro
|
||||||
|
|
||||||
type Idx: record {
|
type Idx: record {
|
||||||
ip: addr;
|
ip: addr;
|
||||||
|
@ -72,7 +72,7 @@ columns does not matter, because each column is identified by name.
|
||||||
The log file is read into the table with a simple call of the
|
The log file is read into the table with a simple call of the
|
||||||
:bro:id:`Input::add_table` function:
|
:bro:id:`Input::add_table` function:
|
||||||
|
|
||||||
.. code:: bro
|
.. sourcecode:: bro
|
||||||
|
|
||||||
global blacklist: table[addr] of Val = table();
|
global blacklist: table[addr] of Val = table();
|
||||||
|
|
||||||
|
@ -109,7 +109,7 @@ Once the input framework finishes reading from a data source, it fires
|
||||||
the :bro:id:`Input::end_of_data` event. Once this event has been received all
|
the :bro:id:`Input::end_of_data` event. Once this event has been received all
|
||||||
data from the input file is available in the table.
|
data from the input file is available in the table.
|
||||||
|
|
||||||
.. code:: bro
|
.. sourcecode:: bro
|
||||||
|
|
||||||
event Input::end_of_data(name: string, source: string) {
|
event Input::end_of_data(name: string, source: string) {
|
||||||
# now all data is in the table
|
# now all data is in the table
|
||||||
|
@ -121,7 +121,7 @@ just might not contain all lines from the input file before the event has
|
||||||
fired. After the table has been populated it can be used like any other Bro
|
fired. After the table has been populated it can be used like any other Bro
|
||||||
table and blacklist entries can easily be tested:
|
table and blacklist entries can easily be tested:
|
||||||
|
|
||||||
.. code:: bro
|
.. sourcecode:: bro
|
||||||
|
|
||||||
if ( 192.168.18.12 in blacklist )
|
if ( 192.168.18.12 in blacklist )
|
||||||
# take action
|
# take action
|
||||||
|
@ -143,7 +143,7 @@ elements from the file will be updated. After the update is finished the
|
||||||
|
|
||||||
In our example the call would look like:
|
In our example the call would look like:
|
||||||
|
|
||||||
.. code:: bro
|
.. sourcecode:: bro
|
||||||
|
|
||||||
Input::force_update("blacklist");
|
Input::force_update("blacklist");
|
||||||
|
|
||||||
|
@ -155,7 +155,7 @@ of the :bro:id:`Input::add_table` call. Valid values are ``Input::MANUAL``
|
||||||
setting the value of the ``mode`` option in the previous example
|
setting the value of the ``mode`` option in the previous example
|
||||||
would look like this:
|
would look like this:
|
||||||
|
|
||||||
.. code:: bro
|
.. sourcecode:: bro
|
||||||
|
|
||||||
Input::add_table([$source="blacklist.file", $name="blacklist",
|
Input::add_table([$source="blacklist.file", $name="blacklist",
|
||||||
$idx=Idx, $val=Val, $destination=blacklist,
|
$idx=Idx, $val=Val, $destination=blacklist,
|
||||||
|
@ -189,7 +189,7 @@ item is added to, removed from, or changed in a table.
|
||||||
The event definition looks like this (note that you can change the name of
|
The event definition looks like this (note that you can change the name of
|
||||||
this event in your own Bro script):
|
this event in your own Bro script):
|
||||||
|
|
||||||
.. code:: bro
|
.. sourcecode:: bro
|
||||||
|
|
||||||
event entry(description: Input::TableDescription, tpe: Input::Event,
|
event entry(description: Input::TableDescription, tpe: Input::Event,
|
||||||
left: Idx, right: Val) {
|
left: Idx, right: Val) {
|
||||||
|
@ -199,7 +199,7 @@ this event in your own Bro script):
|
||||||
|
|
||||||
The event must be specified in ``$ev`` in the ``add_table`` call:
|
The event must be specified in ``$ev`` in the ``add_table`` call:
|
||||||
|
|
||||||
.. code:: bro
|
.. sourcecode:: bro
|
||||||
|
|
||||||
Input::add_table([$source="blacklist.file", $name="blacklist",
|
Input::add_table([$source="blacklist.file", $name="blacklist",
|
||||||
$idx=Idx, $val=Val, $destination=blacklist,
|
$idx=Idx, $val=Val, $destination=blacklist,
|
||||||
|
@ -244,7 +244,7 @@ The following example filter will reject adding entries to the table when
|
||||||
they were generated over a month ago. It will accept all changes and all
|
they were generated over a month ago. It will accept all changes and all
|
||||||
removals of values that are already present in the table.
|
removals of values that are already present in the table.
|
||||||
|
|
||||||
.. code:: bro
|
.. sourcecode:: bro
|
||||||
|
|
||||||
Input::add_table([$source="blacklist.file", $name="blacklist",
|
Input::add_table([$source="blacklist.file", $name="blacklist",
|
||||||
$idx=Idx, $val=Val, $destination=blacklist,
|
$idx=Idx, $val=Val, $destination=blacklist,
|
||||||
|
@ -307,7 +307,7 @@ discussed in much detail. To read the blacklist of the previous example
|
||||||
into an event stream, the :bro:id:`Input::add_event` function is used.
|
into an event stream, the :bro:id:`Input::add_event` function is used.
|
||||||
For example:
|
For example:
|
||||||
|
|
||||||
.. code:: bro
|
.. sourcecode:: bro
|
||||||
|
|
||||||
type Val: record {
|
type Val: record {
|
||||||
ip: addr;
|
ip: addr;
|
||||||
|
|
|
@ -69,7 +69,7 @@ same fields that are present in the ASCII log files::
|
||||||
Note that the ASCII ``conn.log`` will still be created. To prevent this file
|
Note that the ASCII ``conn.log`` will still be created. To prevent this file
|
||||||
from being created, you can remove the default filter:
|
from being created, you can remove the default filter:
|
||||||
|
|
||||||
.. code:: bro
|
.. sourcecode:: bro
|
||||||
|
|
||||||
Log::remove_filter(Conn::LOG, "default");
|
Log::remove_filter(Conn::LOG, "default");
|
||||||
|
|
||||||
|
|
|
@ -65,7 +65,7 @@ done:
|
||||||
In the following example, we create a new module "Foo" which creates
|
In the following example, we create a new module "Foo" which creates
|
||||||
a new log stream.
|
a new log stream.
|
||||||
|
|
||||||
.. code:: bro
|
.. sourcecode:: bro
|
||||||
|
|
||||||
module Foo;
|
module Foo;
|
||||||
|
|
||||||
|
@ -115,7 +115,7 @@ In this example, the :bro:id:`connection_established` event provides our data,
|
||||||
and we also store a copy of the data being logged into the
|
and we also store a copy of the data being logged into the
|
||||||
:bro:type:`connection` record:
|
:bro:type:`connection` record:
|
||||||
|
|
||||||
.. code:: bro
|
.. sourcecode:: bro
|
||||||
|
|
||||||
event connection_established(c: connection)
|
event connection_established(c: connection)
|
||||||
{
|
{
|
||||||
|
@ -158,7 +158,7 @@ Let's say we want to add a boolean field ``is_private`` to
|
||||||
:bro:type:`Conn::Info` that indicates whether the originator IP address
|
:bro:type:`Conn::Info` that indicates whether the originator IP address
|
||||||
is part of the :rfc:`1918` space:
|
is part of the :rfc:`1918` space:
|
||||||
|
|
||||||
.. code:: bro
|
.. sourcecode:: bro
|
||||||
|
|
||||||
# Add a field to the connection log record.
|
# Add a field to the connection log record.
|
||||||
redef record Conn::Info += {
|
redef record Conn::Info += {
|
||||||
|
@ -184,7 +184,7 @@ In this example, since a connection's summary is generated at
|
||||||
the time its state is removed from memory, we can add another handler
|
the time its state is removed from memory, we can add another handler
|
||||||
at that time that sets our field correctly:
|
at that time that sets our field correctly:
|
||||||
|
|
||||||
.. code:: bro
|
.. sourcecode:: bro
|
||||||
|
|
||||||
event connection_state_remove(c: connection)
|
event connection_state_remove(c: connection)
|
||||||
{
|
{
|
||||||
|
@ -217,7 +217,7 @@ being logged. For these cases, a stream can specify an event that will
|
||||||
be generated every time a log record is written to it. To do this, we
|
be generated every time a log record is written to it. To do this, we
|
||||||
need to modify the example module shown above to look something like this:
|
need to modify the example module shown above to look something like this:
|
||||||
|
|
||||||
.. code:: bro
|
.. sourcecode:: bro
|
||||||
|
|
||||||
module Foo;
|
module Foo;
|
||||||
|
|
||||||
|
@ -248,7 +248,7 @@ connection log stream raises the event :bro:id:`Conn::log_conn`. You
|
||||||
could use that for example for flagging when a connection to a
|
could use that for example for flagging when a connection to a
|
||||||
specific destination exceeds a certain duration:
|
specific destination exceeds a certain duration:
|
||||||
|
|
||||||
.. code:: bro
|
.. sourcecode:: bro
|
||||||
|
|
||||||
redef enum Notice::Type += {
|
redef enum Notice::Type += {
|
||||||
## Indicates that a connection remained established longer
|
## Indicates that a connection remained established longer
|
||||||
|
@ -275,7 +275,7 @@ Disable a Stream
|
||||||
One way to "turn off" a log is to completely disable the stream. For
|
One way to "turn off" a log is to completely disable the stream. For
|
||||||
example, the following example will prevent the conn.log from being written:
|
example, the following example will prevent the conn.log from being written:
|
||||||
|
|
||||||
.. code:: bro
|
.. sourcecode:: bro
|
||||||
|
|
||||||
event bro_init()
|
event bro_init()
|
||||||
{
|
{
|
||||||
|
@ -310,7 +310,7 @@ The easiest way to change a log filename is to simply replace the
|
||||||
default log filter with a new filter that specifies a value for the "path"
|
default log filter with a new filter that specifies a value for the "path"
|
||||||
field. In this example, "conn.log" will be changed to "myconn.log":
|
field. In this example, "conn.log" will be changed to "myconn.log":
|
||||||
|
|
||||||
.. code:: bro
|
.. sourcecode:: bro
|
||||||
|
|
||||||
event bro_init()
|
event bro_init()
|
||||||
{
|
{
|
||||||
|
@ -335,7 +335,7 @@ if you want to restrict the set of fields being logged to the new file.
|
||||||
In this example, a new filter is added to the Conn::LOG stream that writes
|
In this example, a new filter is added to the Conn::LOG stream that writes
|
||||||
two fields to a new log file:
|
two fields to a new log file:
|
||||||
|
|
||||||
.. code:: bro
|
.. sourcecode:: bro
|
||||||
|
|
||||||
event bro_init()
|
event bro_init()
|
||||||
{
|
{
|
||||||
|
@ -366,7 +366,7 @@ corresponding ``exclude`` filter attribute that you can use instead of
|
||||||
If you want to make this the only log file for the stream, you can
|
If you want to make this the only log file for the stream, you can
|
||||||
remove the default filter:
|
remove the default filter:
|
||||||
|
|
||||||
.. code:: bro
|
.. sourcecode:: bro
|
||||||
|
|
||||||
event bro_init()
|
event bro_init()
|
||||||
{
|
{
|
||||||
|
@ -383,7 +383,7 @@ allows, e.g., to record local and remote connections into separate
|
||||||
files. To do this, you define a function that returns the desired path,
|
files. To do this, you define a function that returns the desired path,
|
||||||
and use the "path_func" filter attribute:
|
and use the "path_func" filter attribute:
|
||||||
|
|
||||||
.. code:: bro
|
.. sourcecode:: bro
|
||||||
|
|
||||||
# Note: if using BroControl then you don't need to redef local_nets.
|
# Note: if using BroControl then you don't need to redef local_nets.
|
||||||
redef Site::local_nets = { 192.168.0.0/16 };
|
redef Site::local_nets = { 192.168.0.0/16 };
|
||||||
|
@ -415,7 +415,7 @@ only with the :bro:enum:`Conn::LOG` stream as the record type is hardcoded
|
||||||
into its argument list. However, Bro allows to do a more generic
|
into its argument list. However, Bro allows to do a more generic
|
||||||
variant:
|
variant:
|
||||||
|
|
||||||
.. code:: bro
|
.. sourcecode:: bro
|
||||||
|
|
||||||
function myfunc(id: Log::ID, path: string,
|
function myfunc(id: Log::ID, path: string,
|
||||||
rec: record { id: conn_id; } ) : string
|
rec: record { id: conn_id; } ) : string
|
||||||
|
@ -434,7 +434,7 @@ We have seen how to customize the columns being logged, but
|
||||||
you can also control which records are written out by providing a
|
you can also control which records are written out by providing a
|
||||||
predicate that will be called for each log record:
|
predicate that will be called for each log record:
|
||||||
|
|
||||||
.. code:: bro
|
.. sourcecode:: bro
|
||||||
|
|
||||||
function http_only(rec: Conn::Info) : bool
|
function http_only(rec: Conn::Info) : bool
|
||||||
{
|
{
|
||||||
|
@ -464,7 +464,7 @@ Or specifically for certain :bro:type:`Log::Filter` instances by setting
|
||||||
their ``interv`` field. Here's an example of changing just the
|
their ``interv`` field. Here's an example of changing just the
|
||||||
:bro:enum:`Conn::LOG` stream's default filter rotation.
|
:bro:enum:`Conn::LOG` stream's default filter rotation.
|
||||||
|
|
||||||
.. code:: bro
|
.. sourcecode:: bro
|
||||||
|
|
||||||
event bro_init()
|
event bro_init()
|
||||||
{
|
{
|
||||||
|
@ -503,7 +503,7 @@ Some writer options are global (i.e., they affect all log filters using
|
||||||
that log writer). For example, to change the output format of all ASCII
|
that log writer). For example, to change the output format of all ASCII
|
||||||
logs to JSON format:
|
logs to JSON format:
|
||||||
|
|
||||||
.. code:: bro
|
.. sourcecode:: bro
|
||||||
|
|
||||||
redef LogAscii::use_json = T;
|
redef LogAscii::use_json = T;
|
||||||
|
|
||||||
|
@ -511,7 +511,7 @@ Some writer options are filter-specific (i.e., they affect only the filters
|
||||||
that explicitly specify the option). For example, to change the output
|
that explicitly specify the option). For example, to change the output
|
||||||
format of the ``conn.log`` only:
|
format of the ``conn.log`` only:
|
||||||
|
|
||||||
.. code:: bro
|
.. sourcecode:: bro
|
||||||
|
|
||||||
event bro_init()
|
event bro_init()
|
||||||
{
|
{
|
||||||
|
|
|
@ -65,7 +65,7 @@ Backends should be initialized in the :bro:see:`NetControl::init` event, calling
|
||||||
the :bro:see:`NetControl::activate` function after the plugin instance has been
|
the :bro:see:`NetControl::activate` function after the plugin instance has been
|
||||||
initialized. The debug plugin can be initialized as follows:
|
initialized. The debug plugin can be initialized as follows:
|
||||||
|
|
||||||
.. code:: bro
|
.. sourcecode:: bro
|
||||||
|
|
||||||
event NetControl::init()
|
event NetControl::init()
|
||||||
{
|
{
|
||||||
|
@ -143,7 +143,7 @@ plugin to print one line to the standard output, which contains information
|
||||||
about the rule that was added. It will also cause creation of `netcontrol.log`,
|
about the rule that was added. It will also cause creation of `netcontrol.log`,
|
||||||
which contains information about all actions that are taken by NetControl:
|
which contains information about all actions that are taken by NetControl:
|
||||||
|
|
||||||
.. console::
|
.. sourcecode:: console
|
||||||
|
|
||||||
$ bro -C -r tls/ecdhe.pcap netcontrol-1-drop-with-debug.bro
|
$ bro -C -r tls/ecdhe.pcap netcontrol-1-drop-with-debug.bro
|
||||||
netcontrol debug (Debug-All): init
|
netcontrol debug (Debug-All): init
|
||||||
|
@ -179,7 +179,7 @@ additional log called `netcontrol_drop.log`. This log file is much more succinct
|
||||||
only contains information that is specific to drops that are enacted by
|
only contains information that is specific to drops that are enacted by
|
||||||
NetControl:
|
NetControl:
|
||||||
|
|
||||||
.. console::
|
.. sourcecode:: console
|
||||||
|
|
||||||
$ cat netcontrol_drop.log
|
$ cat netcontrol_drop.log
|
||||||
#separator \x09
|
#separator \x09
|
||||||
|
@ -203,7 +203,7 @@ following code automatically blocks a recognized SSH guesser:
|
||||||
:language: bro
|
:language: bro
|
||||||
:linenos:
|
:linenos:
|
||||||
|
|
||||||
.. console::
|
.. sourcecode:: console
|
||||||
|
|
||||||
$ bro -C -r ssh/sshguess.pcap netcontrol-2-ssh-guesser.bro
|
$ bro -C -r ssh/sshguess.pcap netcontrol-2-ssh-guesser.bro
|
||||||
netcontrol debug (Debug-All): init
|
netcontrol debug (Debug-All): init
|
||||||
|
@ -233,7 +233,7 @@ the :bro:see:`Notice::ACTION_DROP` action of the notice framework:
|
||||||
:language: bro
|
:language: bro
|
||||||
:linenos:
|
:linenos:
|
||||||
|
|
||||||
.. console::
|
.. sourcecode:: console
|
||||||
|
|
||||||
$ bro -C -r ssh/sshguess.pcap netcontrol-3-ssh-guesser.bro
|
$ bro -C -r ssh/sshguess.pcap netcontrol-3-ssh-guesser.bro
|
||||||
netcontrol debug (Debug-All): init
|
netcontrol debug (Debug-All): init
|
||||||
|
@ -259,7 +259,7 @@ Using the :bro:see:`Notice::ACTION_DROP` action of the notice framework also
|
||||||
will cause the `dropped` column in `notice.log` to be set to true each time that
|
will cause the `dropped` column in `notice.log` to be set to true each time that
|
||||||
the NetControl framework enacts a block:
|
the NetControl framework enacts a block:
|
||||||
|
|
||||||
.. console::
|
.. sourcecode:: console
|
||||||
|
|
||||||
$ cat notice.log
|
$ cat notice.log
|
||||||
#separator \x09
|
#separator \x09
|
||||||
|
@ -326,7 +326,7 @@ drops all connections on the network:
|
||||||
:language: bro
|
:language: bro
|
||||||
:linenos:
|
:linenos:
|
||||||
|
|
||||||
.. console::
|
.. sourcecode:: console
|
||||||
|
|
||||||
$ bro -C -r tls/ecdhe.pcap netcontrol-4-drop.bro
|
$ bro -C -r tls/ecdhe.pcap netcontrol-4-drop.bro
|
||||||
netcontrol debug (Debug-All): init
|
netcontrol debug (Debug-All): init
|
||||||
|
@ -386,7 +386,7 @@ originating from the 192.168.* network:
|
||||||
:language: bro
|
:language: bro
|
||||||
:linenos:
|
:linenos:
|
||||||
|
|
||||||
.. console::
|
.. sourcecode:: console
|
||||||
|
|
||||||
$ bro -C -r tls/ecdhe.pcap netcontrol-5-hook.bro
|
$ bro -C -r tls/ecdhe.pcap netcontrol-5-hook.bro
|
||||||
netcontrol debug (Debug-All): init
|
netcontrol debug (Debug-All): init
|
||||||
|
@ -465,7 +465,7 @@ address is already blocked in the second connection.
|
||||||
:language: bro
|
:language: bro
|
||||||
:linenos:
|
:linenos:
|
||||||
|
|
||||||
.. console::
|
.. sourcecode:: console
|
||||||
|
|
||||||
$ bro -C -r tls/google-duplicate.trace netcontrol-6-find.bro
|
$ bro -C -r tls/google-duplicate.trace netcontrol-6-find.bro
|
||||||
netcontrol debug (Debug-All): init
|
netcontrol debug (Debug-All): init
|
||||||
|
@ -519,7 +519,7 @@ Using catch and release in your scripts is easy; just use
|
||||||
:language: bro
|
:language: bro
|
||||||
:linenos:
|
:linenos:
|
||||||
|
|
||||||
.. console::
|
.. sourcecode:: console
|
||||||
|
|
||||||
$ bro -C -r tls/ecdhe.pcap netcontrol-7-catch-release.bro
|
$ bro -C -r tls/ecdhe.pcap netcontrol-7-catch-release.bro
|
||||||
netcontrol debug (Debug-All): init
|
netcontrol debug (Debug-All): init
|
||||||
|
@ -535,7 +535,7 @@ first 10 minutes, it is blocked for 1 hour and then monitored for 24 hours, etc.
|
||||||
Catch and release adds its own new logfile in addition to the already existing
|
Catch and release adds its own new logfile in addition to the already existing
|
||||||
ones (netcontrol_catch_release.log):
|
ones (netcontrol_catch_release.log):
|
||||||
|
|
||||||
.. console::
|
.. sourcecode:: console
|
||||||
|
|
||||||
$ cat netcontrol_catch_release.log
|
$ cat netcontrol_catch_release.log
|
||||||
#separator \x09
|
#separator \x09
|
||||||
|
@ -664,7 +664,7 @@ plugin. We manually block a few addresses in the
|
||||||
:language: bro
|
:language: bro
|
||||||
:linenos:
|
:linenos:
|
||||||
|
|
||||||
.. console::
|
.. sourcecode:: console
|
||||||
|
|
||||||
$ bro netcontrol-8-multiple.bro
|
$ bro netcontrol-8-multiple.bro
|
||||||
netcontrol debug (Debug-All): init
|
netcontrol debug (Debug-All): init
|
||||||
|
@ -675,7 +675,7 @@ output to the command line. The other two lines are handled by the OpenFlow
|
||||||
plugin. We can verify this by looking at netcontrol.log. The plugin column shows
|
plugin. We can verify this by looking at netcontrol.log. The plugin column shows
|
||||||
which plugin handled a rule and reveals that two rules were handled by OpenFlow:
|
which plugin handled a rule and reveals that two rules were handled by OpenFlow:
|
||||||
|
|
||||||
.. console::
|
.. sourcecode:: console
|
||||||
|
|
||||||
$ cat netcontrol.log
|
$ cat netcontrol.log
|
||||||
#separator \x09
|
#separator \x09
|
||||||
|
@ -702,7 +702,7 @@ which plugin handled a rule and reveals that two rules were handled by OpenFlow:
|
||||||
Furthermore, openflow.log also shows the two added rules, converted to OpenFlow
|
Furthermore, openflow.log also shows the two added rules, converted to OpenFlow
|
||||||
flow mods:
|
flow mods:
|
||||||
|
|
||||||
.. console::
|
.. sourcecode:: console
|
||||||
|
|
||||||
$ cat openflow.log
|
$ cat openflow.log
|
||||||
#separator \x09
|
#separator \x09
|
||||||
|
@ -792,7 +792,7 @@ to our very first example:
|
||||||
:language: bro
|
:language: bro
|
||||||
:linenos:
|
:linenos:
|
||||||
|
|
||||||
.. console::
|
.. sourcecode:: console
|
||||||
|
|
||||||
$ bro -C -r tls/ecdhe.pcap netcontrol-10-use-skeleton.bro
|
$ bro -C -r tls/ecdhe.pcap netcontrol-10-use-skeleton.bro
|
||||||
add, [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[ty=NetControl::CONNECTION, conn=[orig_h=192.168.18.50, orig_p=56981/tcp, resp_h=74.125.239.97, resp_p=443/tcp], flow=<uninitialized>, ip=<uninitialized>, mac=<uninitialized>], expire=20.0 secs, priority=0, location=, out_port=<uninitialized>, mod=<uninitialized>, id=2, cid=2, _plugin_ids={
|
add, [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[ty=NetControl::CONNECTION, conn=[orig_h=192.168.18.50, orig_p=56981/tcp, resp_h=74.125.239.97, resp_p=443/tcp], flow=<uninitialized>, ip=<uninitialized>, mac=<uninitialized>], expire=20.0 secs, priority=0, location=, out_port=<uninitialized>, mod=<uninitialized>, id=2, cid=2, _plugin_ids={
|
||||||
|
|
|
@ -96,7 +96,7 @@ the server at 192.168.56.103:
|
||||||
:language: bro
|
:language: bro
|
||||||
:linenos:
|
:linenos:
|
||||||
|
|
||||||
.. console::
|
.. sourcecode:: console
|
||||||
|
|
||||||
$ bro -C -r ssh/sshguess.pcap notice_ssh_guesser.bro
|
$ bro -C -r ssh/sshguess.pcap notice_ssh_guesser.bro
|
||||||
$ cat notice.log
|
$ cat notice.log
|
||||||
|
@ -121,7 +121,7 @@ Hooks can also have priorities applied to order their execution like events
|
||||||
with a default priority of 0. Greater values are executed first. Setting
|
with a default priority of 0. Greater values are executed first. Setting
|
||||||
a hook body to run before default hook bodies might look like this:
|
a hook body to run before default hook bodies might look like this:
|
||||||
|
|
||||||
.. code:: bro
|
.. sourcecode:: bro
|
||||||
|
|
||||||
hook Notice::policy(n: Notice::Info) &priority=5
|
hook Notice::policy(n: Notice::Info) &priority=5
|
||||||
{
|
{
|
||||||
|
@ -191,7 +191,7 @@ SSH analysis scripts sees enough failed logins to a given host, it
|
||||||
raises a notice of the type :bro:see:`SSH::Password_Guessing`. The code
|
raises a notice of the type :bro:see:`SSH::Password_Guessing`. The code
|
||||||
in the base SSH analysis script which raises the notice looks like this:
|
in the base SSH analysis script which raises the notice looks like this:
|
||||||
|
|
||||||
.. code:: bro
|
.. sourcecode:: bro
|
||||||
|
|
||||||
NOTICE([$note=Password_Guessing,
|
NOTICE([$note=Password_Guessing,
|
||||||
$msg=fmt("%s appears to be guessing SSH passwords (seen in %d connections).", key$host, r$num),
|
$msg=fmt("%s appears to be guessing SSH passwords (seen in %d connections).", key$host, r$num),
|
||||||
|
@ -302,7 +302,7 @@ for session negotiations where the certificate or certificate chain did
|
||||||
not validate successfully against the available certificate authority
|
not validate successfully against the available certificate authority
|
||||||
certificates.
|
certificates.
|
||||||
|
|
||||||
.. code:: bro
|
.. sourcecode:: bro
|
||||||
|
|
||||||
NOTICE([$note=SSL::Invalid_Server_Cert,
|
NOTICE([$note=SSL::Invalid_Server_Cert,
|
||||||
$msg=fmt("SSL certificate validation failed with (%s)", c$ssl$validation_status),
|
$msg=fmt("SSL certificate validation failed with (%s)", c$ssl$validation_status),
|
||||||
|
@ -348,7 +348,7 @@ There is a field in the :bro:see:`Notice::Info` record named
|
||||||
sent. An example of including some information from an HTTP request is
|
sent. An example of including some information from an HTTP request is
|
||||||
included below.
|
included below.
|
||||||
|
|
||||||
.. code:: bro
|
.. sourcecode:: bro
|
||||||
|
|
||||||
hook Notice::policy(n: Notice::Info)
|
hook Notice::policy(n: Notice::Info)
|
||||||
{
|
{
|
||||||
|
|
|
@ -20,9 +20,7 @@ Signature Framework
|
||||||
Basics
|
Basics
|
||||||
======
|
======
|
||||||
|
|
||||||
Let's look at an example signature first:
|
Let's look at an example signature first::
|
||||||
|
|
||||||
.. code:: bro-sig
|
|
||||||
|
|
||||||
signature my-first-sig {
|
signature my-first-sig {
|
||||||
ip-proto == tcp
|
ip-proto == tcp
|
||||||
|
@ -36,7 +34,7 @@ This signature asks Bro to match the regular expression ``.*root`` on
|
||||||
all TCP connections going to port 80. When the signature triggers, Bro
|
all TCP connections going to port 80. When the signature triggers, Bro
|
||||||
will raise an event :bro:id:`signature_match` of the form:
|
will raise an event :bro:id:`signature_match` of the form:
|
||||||
|
|
||||||
.. code:: bro
|
.. sourcecode:: bro
|
||||||
|
|
||||||
event signature_match(state: signature_state, msg: string, data: string)
|
event signature_match(state: signature_state, msg: string, data: string)
|
||||||
|
|
||||||
|
@ -117,9 +115,7 @@ evaluates to true, the whole header condition matches (exception: with
|
||||||
``!=``, the header condition only matches if all values differ).
|
``!=``, the header condition only matches if all values differ).
|
||||||
|
|
||||||
In addition to these pre-defined header keywords, a general header
|
In addition to these pre-defined header keywords, a general header
|
||||||
condition can be defined either as
|
condition can be defined either as::
|
||||||
|
|
||||||
.. code:: bro-sig
|
|
||||||
|
|
||||||
header <proto>[<offset>:<size>] [& <integer>] <cmp> <value-list>
|
header <proto>[<offset>:<size>] [& <integer>] <cmp> <value-list>
|
||||||
|
|
||||||
|
@ -141,9 +137,7 @@ are not allowed in the value-list, though you can still inspect any 1,
|
||||||
2, or 4 byte section of an IPv6 header using this keyword.
|
2, or 4 byte section of an IPv6 header using this keyword.
|
||||||
|
|
||||||
Putting it all together, this is an example condition that is
|
Putting it all together, this is an example condition that is
|
||||||
equivalent to ``dst-ip == 1.2.3.4/16, 5.6.7.8/24``:
|
equivalent to ``dst-ip == 1.2.3.4/16, 5.6.7.8/24``::
|
||||||
|
|
||||||
.. code:: bro-sig
|
|
||||||
|
|
||||||
header ip[16:4] == 1.2.3.4/16, 5.6.7.8/24
|
header ip[16:4] == 1.2.3.4/16, 5.6.7.8/24
|
||||||
|
|
||||||
|
@ -162,9 +156,7 @@ Second, it may be prefixed with an analyzer-specific label, in which
|
||||||
case the expression is matched against the data as extracted by the
|
case the expression is matched against the data as extracted by the
|
||||||
corresponding analyzer.
|
corresponding analyzer.
|
||||||
|
|
||||||
A ``payload`` condition has the form:
|
A ``payload`` condition has the form::
|
||||||
|
|
||||||
.. code:: bro-sig
|
|
||||||
|
|
||||||
payload /<regular expression>/
|
payload /<regular expression>/
|
||||||
|
|
||||||
|
@ -272,7 +264,7 @@ two actions defined:
|
||||||
Raises a :bro:id:`signature_match` event. The event handler has the
|
Raises a :bro:id:`signature_match` event. The event handler has the
|
||||||
following type:
|
following type:
|
||||||
|
|
||||||
.. code:: bro
|
.. sourcecode:: bro
|
||||||
|
|
||||||
event signature_match(state: signature_state, msg: string, data: string)
|
event signature_match(state: signature_state, msg: string, data: string)
|
||||||
|
|
||||||
|
|
|
@ -81,7 +81,7 @@ inline documentation that does this with the Sumstats framework:
|
||||||
When run on a sample PCAP file from the Bro test suite, the following output
|
When run on a sample PCAP file from the Bro test suite, the following output
|
||||||
is created:
|
is created:
|
||||||
|
|
||||||
.. console::
|
.. sourcecode:: console
|
||||||
|
|
||||||
$ bro -r workshop_2011_browse.trace sumstats-countconns.bro
|
$ bro -r workshop_2011_browse.trace sumstats-countconns.bro
|
||||||
Number of connections established: 6
|
Number of connections established: 6
|
||||||
|
@ -103,7 +103,7 @@ real-world functional example, that is left to the
|
||||||
Let's see if there are any hosts that crossed the threshold in a PCAP file
|
Let's see if there are any hosts that crossed the threshold in a PCAP file
|
||||||
containing a host running nmap:
|
containing a host running nmap:
|
||||||
|
|
||||||
.. console::
|
.. sourcecode:: console
|
||||||
|
|
||||||
$ bro -r nmap-vsn.trace sumstats-toy-scan.bro
|
$ bro -r nmap-vsn.trace sumstats-toy-scan.bro
|
||||||
192.168.1.71 attempted 5 or more connections
|
192.168.1.71 attempted 5 or more connections
|
||||||
|
|
|
@ -89,7 +89,7 @@ detect a reply for a ``GET http://`` request.
|
||||||
:language: bro
|
:language: bro
|
||||||
:linenos:
|
:linenos:
|
||||||
|
|
||||||
.. console::
|
.. sourcecode:: console
|
||||||
|
|
||||||
$ bro -r http/proxy.pcap http_proxy_01.bro
|
$ bro -r http/proxy.pcap http_proxy_01.bro
|
||||||
A local server is acting as an open proxy: 192.168.56.101
|
A local server is acting as an open proxy: 192.168.56.101
|
||||||
|
@ -104,7 +104,7 @@ will extend our basic script to also consider the additional codes.
|
||||||
:language: bro
|
:language: bro
|
||||||
:linenos:
|
:linenos:
|
||||||
|
|
||||||
.. console::
|
.. sourcecode:: console
|
||||||
|
|
||||||
$ bro -r http/proxy.pcap http_proxy_02.bro
|
$ bro -r http/proxy.pcap http_proxy_02.bro
|
||||||
A local server is acting as an open proxy: 192.168.56.101
|
A local server is acting as an open proxy: 192.168.56.101
|
||||||
|
@ -117,7 +117,7 @@ network.
|
||||||
:language: bro
|
:language: bro
|
||||||
:linenos:
|
:linenos:
|
||||||
|
|
||||||
.. console::
|
.. sourcecode:: console
|
||||||
|
|
||||||
$ bro -r http/proxy.pcap http_proxy_03.bro
|
$ bro -r http/proxy.pcap http_proxy_03.bro
|
||||||
A local server is acting as an open proxy: 192.168.56.101
|
A local server is acting as an open proxy: 192.168.56.101
|
||||||
|
@ -140,7 +140,7 @@ Below is the complete script.
|
||||||
:language: bro
|
:language: bro
|
||||||
:linenos:
|
:linenos:
|
||||||
|
|
||||||
.. console::
|
.. sourcecode:: console
|
||||||
|
|
||||||
$ bro -r http/proxy.pcap http_proxy_04.bro
|
$ bro -r http/proxy.pcap http_proxy_04.bro
|
||||||
$ cat notice.log
|
$ cat notice.log
|
||||||
|
@ -178,7 +178,7 @@ using the :ref:`File Analysis Framework <file-analysis-framework>`
|
||||||
:language: bro
|
:language: bro
|
||||||
:linenos:
|
:linenos:
|
||||||
|
|
||||||
.. console::
|
.. sourcecode:: console
|
||||||
|
|
||||||
$ bro -r bro.org.pcap file_extraction.bro
|
$ bro -r bro.org.pcap file_extraction.bro
|
||||||
Extracting file HTTP-FiIpIB2hRQSDBOSJRg.html
|
Extracting file HTTP-FiIpIB2hRQSDBOSJRg.html
|
||||||
|
|
|
@ -25,14 +25,14 @@ You first need to compile a few build tools native to the host system
|
||||||
for use during the later cross-compile build. In the root of your
|
for use during the later cross-compile build. In the root of your
|
||||||
Bro source tree:
|
Bro source tree:
|
||||||
|
|
||||||
.. console::
|
.. sourcecode:: console
|
||||||
|
|
||||||
./configure --builddir=../bro-buildtools
|
./configure --builddir=../bro-buildtools
|
||||||
( cd ../bro-buildtools && make binpac bifcl )
|
( cd ../bro-buildtools && make binpac bifcl )
|
||||||
|
|
||||||
Next configure Bro to use your cross-compilation toolchain:
|
Next configure Bro to use your cross-compilation toolchain:
|
||||||
|
|
||||||
.. console::
|
.. sourcecode:: console
|
||||||
|
|
||||||
./configure --toolchain=/home/jon/x-tools/RaspberryPi-toolchain.cmake --with-binpac=$(pwd)/../bro-buildtools/aux/binpac/src/binpac --with-bifcl=$(pwd)/../bro-buildtools/src/bifcl
|
./configure --toolchain=/home/jon/x-tools/RaspberryPi-toolchain.cmake --with-binpac=$(pwd)/../bro-buildtools/aux/binpac/src/binpac --with-bifcl=$(pwd)/../bro-buildtools/src/bifcl
|
||||||
|
|
||||||
|
@ -71,13 +71,13 @@ something the following (using a Raspberry Pi as target system)::
|
||||||
|
|
||||||
If that configuration succeeds you are ready to build:
|
If that configuration succeeds you are ready to build:
|
||||||
|
|
||||||
.. console::
|
.. sourcecode:: console
|
||||||
|
|
||||||
make
|
make
|
||||||
|
|
||||||
And if that works, install on your host system:
|
And if that works, install on your host system:
|
||||||
|
|
||||||
.. console::
|
.. sourcecode:: console
|
||||||
|
|
||||||
make install
|
make install
|
||||||
|
|
||||||
|
|
|
@ -50,13 +50,13 @@ To install the required dependencies, you can use:
|
||||||
|
|
||||||
* RPM/RedHat-based Linux:
|
* RPM/RedHat-based Linux:
|
||||||
|
|
||||||
.. console::
|
.. sourcecode:: console
|
||||||
|
|
||||||
sudo yum install cmake make gcc gcc-c++ flex bison libpcap-devel openssl-devel python-devel swig zlib-devel
|
sudo yum install cmake make gcc gcc-c++ flex bison libpcap-devel openssl-devel python-devel swig zlib-devel
|
||||||
|
|
||||||
* DEB/Debian-based Linux:
|
* DEB/Debian-based Linux:
|
||||||
|
|
||||||
.. console::
|
.. sourcecode:: console
|
||||||
|
|
||||||
sudo apt-get install cmake make gcc g++ flex bison libpcap-dev libssl-dev python-dev swig zlib1g-dev
|
sudo apt-get install cmake make gcc g++ flex bison libpcap-dev libssl-dev python-dev swig zlib1g-dev
|
||||||
|
|
||||||
|
@ -68,7 +68,7 @@ To install the required dependencies, you can use:
|
||||||
Most required dependencies should come with a minimal FreeBSD install
|
Most required dependencies should come with a minimal FreeBSD install
|
||||||
except for the following.
|
except for the following.
|
||||||
|
|
||||||
.. console::
|
.. sourcecode:: console
|
||||||
|
|
||||||
sudo pkg install bash cmake swig30 bison python py27-sqlite3 py27-ipaddress
|
sudo pkg install bash cmake swig30 bison python py27-sqlite3 py27-ipaddress
|
||||||
|
|
||||||
|
@ -152,7 +152,7 @@ hosted at https://github.com/zeek. See our `git development documentation
|
||||||
information on Bro's use of git revision control, but the short story
|
information on Bro's use of git revision control, but the short story
|
||||||
for downloading the full source code experience for Bro via git is:
|
for downloading the full source code experience for Bro via git is:
|
||||||
|
|
||||||
.. console::
|
.. sourcecode:: console
|
||||||
|
|
||||||
git clone --recursive https://github.com/zeek/zeek
|
git clone --recursive https://github.com/zeek/zeek
|
||||||
|
|
||||||
|
@ -163,7 +163,7 @@ for downloading the full source code experience for Bro via git is:
|
||||||
The typical way to build and install from source is (for more options,
|
The typical way to build and install from source is (for more options,
|
||||||
run ``./configure --help``):
|
run ``./configure --help``):
|
||||||
|
|
||||||
.. console::
|
.. sourcecode:: console
|
||||||
|
|
||||||
./configure
|
./configure
|
||||||
make
|
make
|
||||||
|
@ -214,13 +214,13 @@ according to the platform/shell/package you're using. For example:
|
||||||
|
|
||||||
Bourne-Shell Syntax:
|
Bourne-Shell Syntax:
|
||||||
|
|
||||||
.. console::
|
.. sourcecode:: console
|
||||||
|
|
||||||
export PATH=/usr/local/bro/bin:$PATH
|
export PATH=/usr/local/bro/bin:$PATH
|
||||||
|
|
||||||
C-Shell Syntax:
|
C-Shell Syntax:
|
||||||
|
|
||||||
.. console::
|
.. sourcecode:: console
|
||||||
|
|
||||||
setenv PATH /usr/local/bro/bin:$PATH
|
setenv PATH /usr/local/bro/bin:$PATH
|
||||||
|
|
||||||
|
|
|
@ -41,7 +41,7 @@ As the fields of the log entries can be further customized by the
|
||||||
user, the Logging Framework makes use of a header block to ensure that
|
user, the Logging Framework makes use of a header block to ensure that
|
||||||
it remains self-describing. Here's the first few lines of a ``conn.log``.
|
it remains self-describing. Here's the first few lines of a ``conn.log``.
|
||||||
|
|
||||||
.. console::
|
.. sourcecode:: console
|
||||||
|
|
||||||
$ cat conn.log
|
$ cat conn.log
|
||||||
#separator \x09
|
#separator \x09
|
||||||
|
@ -139,7 +139,7 @@ require the user to refer to fields referenced by their position).
|
||||||
For example, the following command extracts just the given columns
|
For example, the following command extracts just the given columns
|
||||||
from a ``conn.log``:
|
from a ``conn.log``:
|
||||||
|
|
||||||
.. console::
|
.. sourcecode:: console
|
||||||
|
|
||||||
$ cat conn.log | bro-cut id.orig_h id.orig_p id.resp_h duration
|
$ cat conn.log | bro-cut id.orig_h id.orig_p id.resp_h duration
|
||||||
141.142.220.202 5353 224.0.0.251 -
|
141.142.220.202 5353 224.0.0.251 -
|
||||||
|
@ -156,7 +156,7 @@ from a ``conn.log``:
|
||||||
|
|
||||||
The corresponding ``awk`` command will look like this:
|
The corresponding ``awk`` command will look like this:
|
||||||
|
|
||||||
.. console::
|
.. sourcecode:: console
|
||||||
|
|
||||||
$ awk '/^[^#]/ {print $3, $4, $5, $6, $9}' conn.log
|
$ awk '/^[^#]/ {print $3, $4, $5, $6, $9}' conn.log
|
||||||
141.142.220.202 5353 224.0.0.251 5353 -
|
141.142.220.202 5353 224.0.0.251 5353 -
|
||||||
|
@ -223,7 +223,7 @@ includes the human readable time stamp, the unique identifier, the
|
||||||
HTTP ``Host``, and HTTP ``URI`` as extracted from the ``http.log``
|
HTTP ``Host``, and HTTP ``URI`` as extracted from the ``http.log``
|
||||||
file:
|
file:
|
||||||
|
|
||||||
.. console::
|
.. sourcecode:: console
|
||||||
|
|
||||||
$ bro-cut -d ts uid host uri < http.log
|
$ bro-cut -d ts uid host uri < http.log
|
||||||
2011-03-18T19:06:08+0000 CUM0KZ3MLUfNB0cl11 bits.wikimedia.org /skins-1.5/monobook/main.css
|
2011-03-18T19:06:08+0000 CUM0KZ3MLUfNB0cl11 bits.wikimedia.org /skins-1.5/monobook/main.css
|
||||||
|
@ -237,7 +237,7 @@ Often times log files from multiple sources are stored in UTC time to
|
||||||
allow easy correlation. Converting the timestamp from a log file to
|
allow easy correlation. Converting the timestamp from a log file to
|
||||||
UTC can be accomplished with the ``-u`` option:
|
UTC can be accomplished with the ``-u`` option:
|
||||||
|
|
||||||
.. console::
|
.. sourcecode:: console
|
||||||
|
|
||||||
$ bro-cut -u ts uid host uri < http.log
|
$ bro-cut -u ts uid host uri < http.log
|
||||||
2011-03-18T19:06:08+0000 CUM0KZ3MLUfNB0cl11 bits.wikimedia.org /skins-1.5/monobook/main.css
|
2011-03-18T19:06:08+0000 CUM0KZ3MLUfNB0cl11 bits.wikimedia.org /skins-1.5/monobook/main.css
|
||||||
|
@ -255,7 +255,7 @@ using the ``-D`` and ``-U`` flags, using the standard ``strftime``
|
||||||
syntax. For example, to format the timestamp in the US-typical "Middle
|
syntax. For example, to format the timestamp in the US-typical "Middle
|
||||||
Endian" you could use a format string of: ``%d-%m-%YT%H:%M:%S%z``
|
Endian" you could use a format string of: ``%d-%m-%YT%H:%M:%S%z``
|
||||||
|
|
||||||
.. console::
|
.. sourcecode:: console
|
||||||
|
|
||||||
$ bro-cut -D %d-%m-%YT%H:%M:%S%z ts uid host uri < http.log
|
$ bro-cut -D %d-%m-%YT%H:%M:%S%z ts uid host uri < http.log
|
||||||
18-03-2011T19:06:08+0000 CUM0KZ3MLUfNB0cl11 bits.wikimedia.org /skins-1.5/monobook/main.css
|
18-03-2011T19:06:08+0000 CUM0KZ3MLUfNB0cl11 bits.wikimedia.org /skins-1.5/monobook/main.css
|
||||||
|
@ -285,7 +285,7 @@ largest number of bytes from the responder by redirecting the output
|
||||||
for ``cat conn.log`` into bro-cut to extract the UID and the
|
for ``cat conn.log`` into bro-cut to extract the UID and the
|
||||||
resp_bytes, then sorting that output by the resp_bytes field.
|
resp_bytes, then sorting that output by the resp_bytes field.
|
||||||
|
|
||||||
.. console::
|
.. sourcecode:: console
|
||||||
|
|
||||||
$ cat conn.log | bro-cut uid resp_bytes | sort -nrk2 | head -5
|
$ cat conn.log | bro-cut uid resp_bytes | sort -nrk2 | head -5
|
||||||
CwjjYJ2WqgTbAqiHl6 734
|
CwjjYJ2WqgTbAqiHl6 734
|
||||||
|
@ -297,7 +297,7 @@ resp_bytes, then sorting that output by the resp_bytes field.
|
||||||
Taking the UID of the first of the top responses, we can now
|
Taking the UID of the first of the top responses, we can now
|
||||||
crossreference that with the UIDs in the ``http.log`` file.
|
crossreference that with the UIDs in the ``http.log`` file.
|
||||||
|
|
||||||
.. console::
|
.. sourcecode:: console
|
||||||
|
|
||||||
$ cat http.log | bro-cut uid id.resp_h method status_code host uri | grep UM0KZ3MLUfNB0cl11
|
$ cat http.log | bro-cut uid id.resp_h method status_code host uri | grep UM0KZ3MLUfNB0cl11
|
||||||
CUM0KZ3MLUfNB0cl11 208.80.152.118 GET 304 bits.wikimedia.org /skins-1.5/monobook/main.css
|
CUM0KZ3MLUfNB0cl11 208.80.152.118 GET 304 bits.wikimedia.org /skins-1.5/monobook/main.css
|
||||||
|
|
|
@ -81,7 +81,7 @@ final code for our script.
|
||||||
:language: bro
|
:language: bro
|
||||||
:linenos:
|
:linenos:
|
||||||
|
|
||||||
.. console::
|
.. sourcecode:: console
|
||||||
|
|
||||||
$ bro -r http/bro.org.pcap mimestats.bro
|
$ bro -r http/bro.org.pcap mimestats.bro
|
||||||
#separator \x09
|
#separator \x09
|
||||||
|
|
|
@ -44,20 +44,20 @@ installation that will manage a single Bro instance on the ``localhost``:
|
||||||
|
|
||||||
Now start the BroControl shell like:
|
Now start the BroControl shell like:
|
||||||
|
|
||||||
.. console::
|
.. sourcecode:: console
|
||||||
|
|
||||||
broctl
|
broctl
|
||||||
|
|
||||||
Since this is the first-time use of the shell, perform an initial installation
|
Since this is the first-time use of the shell, perform an initial installation
|
||||||
of the BroControl configuration:
|
of the BroControl configuration:
|
||||||
|
|
||||||
.. console::
|
.. sourcecode:: console
|
||||||
|
|
||||||
[BroControl] > install
|
[BroControl] > install
|
||||||
|
|
||||||
Then start up a Bro instance:
|
Then start up a Bro instance:
|
||||||
|
|
||||||
.. console::
|
.. sourcecode:: console
|
||||||
|
|
||||||
[BroControl] > start
|
[BroControl] > start
|
||||||
|
|
||||||
|
@ -74,7 +74,7 @@ policy and output the results in ``$PREFIX/logs``.
|
||||||
|
|
||||||
You can leave it running for now, but to stop this Bro instance you would do:
|
You can leave it running for now, but to stop this Bro instance you would do:
|
||||||
|
|
||||||
.. console::
|
.. sourcecode:: console
|
||||||
|
|
||||||
[BroControl] > stop
|
[BroControl] > stop
|
||||||
|
|
||||||
|
@ -200,7 +200,7 @@ Let's continue on our path to modify the behavior for the two SSL
|
||||||
notices. Looking at :doc:`/scripts/base/frameworks/notice/main.bro`,
|
notices. Looking at :doc:`/scripts/base/frameworks/notice/main.bro`,
|
||||||
we see that it advertises:
|
we see that it advertises:
|
||||||
|
|
||||||
.. code:: bro
|
.. sourcecode:: bro
|
||||||
|
|
||||||
module Notice;
|
module Notice;
|
||||||
|
|
||||||
|
@ -212,7 +212,7 @@ we see that it advertises:
|
||||||
|
|
||||||
That's exactly what we want to do for the first notice. Add to ``local.bro``:
|
That's exactly what we want to do for the first notice. Add to ``local.bro``:
|
||||||
|
|
||||||
.. code:: bro
|
.. sourcecode:: bro
|
||||||
|
|
||||||
redef Notice::ignored_types += { SSL::Invalid_Server_Cert };
|
redef Notice::ignored_types += { SSL::Invalid_Server_Cert };
|
||||||
|
|
||||||
|
@ -226,7 +226,7 @@ Then go into the BroControl shell to check whether the configuration change
|
||||||
is valid before installing it and then restarting the Bro instance. The
|
is valid before installing it and then restarting the Bro instance. The
|
||||||
"deploy" command does all of this automatically:
|
"deploy" command does all of this automatically:
|
||||||
|
|
||||||
.. console::
|
.. sourcecode:: console
|
||||||
|
|
||||||
[BroControl] > deploy
|
[BroControl] > deploy
|
||||||
checking configurations ...
|
checking configurations ...
|
||||||
|
@ -260,7 +260,7 @@ In ``local.bro``, let's define a new ``policy`` hook handler body:
|
||||||
:language: bro
|
:language: bro
|
||||||
:linenos:
|
:linenos:
|
||||||
|
|
||||||
.. console::
|
.. sourcecode:: console
|
||||||
|
|
||||||
$ bro -r tls/tls-expired-cert.trace conditional-notice.bro
|
$ bro -r tls/tls-expired-cert.trace conditional-notice.bro
|
||||||
$ cat notice.log
|
$ cat notice.log
|
||||||
|
@ -325,7 +325,7 @@ Monitoring Live Traffic
|
||||||
|
|
||||||
Analyzing live traffic from an interface is simple:
|
Analyzing live traffic from an interface is simple:
|
||||||
|
|
||||||
.. console::
|
.. sourcecode:: console
|
||||||
|
|
||||||
bro -i en0 <list of scripts to load>
|
bro -i en0 <list of scripts to load>
|
||||||
|
|
||||||
|
@ -345,7 +345,7 @@ Reading Packet Capture (pcap) Files
|
||||||
Capturing packets from an interface and writing them to a file can be done
|
Capturing packets from an interface and writing them to a file can be done
|
||||||
like this:
|
like this:
|
||||||
|
|
||||||
.. console::
|
.. sourcecode:: console
|
||||||
|
|
||||||
sudo tcpdump -i en0 -s 0 -w mypackets.trace
|
sudo tcpdump -i en0 -s 0 -w mypackets.trace
|
||||||
|
|
||||||
|
@ -356,7 +356,7 @@ whole packets; in cases where it's not supported use ``-s 65535`` instead).
|
||||||
After a while of capturing traffic, kill the ``tcpdump`` (with ctrl-c),
|
After a while of capturing traffic, kill the ``tcpdump`` (with ctrl-c),
|
||||||
and tell Bro to perform all the default analysis on the capture which primarily includes :
|
and tell Bro to perform all the default analysis on the capture which primarily includes :
|
||||||
|
|
||||||
.. console::
|
.. sourcecode:: console
|
||||||
|
|
||||||
bro -r mypackets.trace
|
bro -r mypackets.trace
|
||||||
|
|
||||||
|
@ -365,7 +365,7 @@ Bro will output log files into the working directory.
|
||||||
If you are interested in more detection, you can again load the ``local``
|
If you are interested in more detection, you can again load the ``local``
|
||||||
script that we include as a suggested configuration:
|
script that we include as a suggested configuration:
|
||||||
|
|
||||||
.. console::
|
.. sourcecode:: console
|
||||||
|
|
||||||
bro -r mypackets.trace local
|
bro -r mypackets.trace local
|
||||||
|
|
||||||
|
@ -374,7 +374,7 @@ Telling Bro Which Scripts to Load
|
||||||
|
|
||||||
A command-line invocation of Bro typically looks like:
|
A command-line invocation of Bro typically looks like:
|
||||||
|
|
||||||
.. console::
|
.. sourcecode:: console
|
||||||
|
|
||||||
bro <options> <scripts...>
|
bro <options> <scripts...>
|
||||||
|
|
||||||
|
@ -391,7 +391,7 @@ directories are included in the default search path for Bro scripts::
|
||||||
|
|
||||||
These prefix paths can be used to load scripts like this:
|
These prefix paths can be used to load scripts like this:
|
||||||
|
|
||||||
.. console::
|
.. sourcecode:: console
|
||||||
|
|
||||||
bro -r mypackets.trace frameworks/files/extract-all
|
bro -r mypackets.trace frameworks/files/extract-all
|
||||||
|
|
||||||
|
@ -420,7 +420,7 @@ customization" and is not overwritten when upgrades take place. To use
|
||||||
the site-specific ``local.bro`` script, just add it to the command-line (can
|
the site-specific ``local.bro`` script, just add it to the command-line (can
|
||||||
also be loaded through scripts with @load):
|
also be loaded through scripts with @load):
|
||||||
|
|
||||||
.. console::
|
.. sourcecode:: console
|
||||||
|
|
||||||
bro -i en0 local
|
bro -i en0 local
|
||||||
|
|
||||||
|
@ -429,7 +429,7 @@ This causes Bro to load a script that prints a warning about lacking the
|
||||||
information at the command line like this (supply your "local" subnets
|
information at the command line like this (supply your "local" subnets
|
||||||
in place of the example subnets):
|
in place of the example subnets):
|
||||||
|
|
||||||
.. console::
|
.. sourcecode:: console
|
||||||
|
|
||||||
bro -r mypackets.trace local "Site::local_nets += { 1.2.3.0/24, 5.6.7.0/24 }"
|
bro -r mypackets.trace local "Site::local_nets += { 1.2.3.0/24, 5.6.7.0/24 }"
|
||||||
|
|
||||||
|
|
|
@ -305,7 +305,7 @@ Here is a more detailed description of each type:
|
||||||
of an address gives the size in bits (32 for IPv4, and 128 for IPv6).
|
of an address gives the size in bits (32 for IPv4, and 128 for IPv6).
|
||||||
Addresses can also be masked with ``/`` to produce a :bro:type:`subnet`:
|
Addresses can also be masked with ``/`` to produce a :bro:type:`subnet`:
|
||||||
|
|
||||||
.. code:: bro
|
.. sourcecode:: bro
|
||||||
|
|
||||||
local a: addr = 192.168.1.100;
|
local a: addr = 192.168.1.100;
|
||||||
local s: subnet = 192.168.0.0/16;
|
local s: subnet = 192.168.0.0/16;
|
||||||
|
@ -315,7 +315,7 @@ Here is a more detailed description of each type:
|
||||||
And checked for inclusion within a :bro:type:`subnet` using ``in``
|
And checked for inclusion within a :bro:type:`subnet` using ``in``
|
||||||
or ``!in``:
|
or ``!in``:
|
||||||
|
|
||||||
.. code:: bro
|
.. sourcecode:: bro
|
||||||
|
|
||||||
local a: addr = 192.168.1.100;
|
local a: addr = 192.168.1.100;
|
||||||
local s: subnet = 192.168.0.0/16;
|
local s: subnet = 192.168.0.0/16;
|
||||||
|
@ -329,7 +329,7 @@ Here is a more detailed description of each type:
|
||||||
correspond to multiple IP addresses, the type of such a variable is
|
correspond to multiple IP addresses, the type of such a variable is
|
||||||
"set[addr]". For example:
|
"set[addr]". For example:
|
||||||
|
|
||||||
.. code:: bro
|
.. sourcecode:: bro
|
||||||
|
|
||||||
local a = www.google.com;
|
local a = www.google.com;
|
||||||
|
|
||||||
|
@ -349,7 +349,7 @@ Here is a more detailed description of each type:
|
||||||
A type allowing the specification of a set of related values that
|
A type allowing the specification of a set of related values that
|
||||||
have no further structure. An example declaration:
|
have no further structure. An example declaration:
|
||||||
|
|
||||||
.. code:: bro
|
.. sourcecode:: bro
|
||||||
|
|
||||||
type color: enum { Red, White, Blue, };
|
type color: enum { Red, White, Blue, };
|
||||||
|
|
||||||
|
@ -379,13 +379,13 @@ Here is a more detailed description of each type:
|
||||||
Here is an example of declaring a table indexed by "count" values
|
Here is an example of declaring a table indexed by "count" values
|
||||||
and yielding "string" values:
|
and yielding "string" values:
|
||||||
|
|
||||||
.. code:: bro
|
.. sourcecode:: bro
|
||||||
|
|
||||||
global a: table[count] of string;
|
global a: table[count] of string;
|
||||||
|
|
||||||
The yield type can also be more complex:
|
The yield type can also be more complex:
|
||||||
|
|
||||||
.. code:: bro
|
.. sourcecode:: bro
|
||||||
|
|
||||||
global a: table[count] of table[addr, port] of string;
|
global a: table[count] of table[addr, port] of string;
|
||||||
|
|
||||||
|
@ -396,7 +396,7 @@ Here is a more detailed description of each type:
|
||||||
One way to initialize a table is by enclosing a set of initializers within
|
One way to initialize a table is by enclosing a set of initializers within
|
||||||
braces, for example:
|
braces, for example:
|
||||||
|
|
||||||
.. code:: bro
|
.. sourcecode:: bro
|
||||||
|
|
||||||
global t: table[count] of string = {
|
global t: table[count] of string = {
|
||||||
[11] = "eleven",
|
[11] = "eleven",
|
||||||
|
@ -405,7 +405,7 @@ Here is a more detailed description of each type:
|
||||||
|
|
||||||
A table constructor can also be used to create a table:
|
A table constructor can also be used to create a table:
|
||||||
|
|
||||||
.. code:: bro
|
.. sourcecode:: bro
|
||||||
|
|
||||||
global t2 = table(
|
global t2 = table(
|
||||||
[192.168.0.2, 22/tcp] = "ssh",
|
[192.168.0.2, 22/tcp] = "ssh",
|
||||||
|
@ -416,7 +416,7 @@ Here is a more detailed description of each type:
|
||||||
useful when a more complex index type could otherwise be
|
useful when a more complex index type could otherwise be
|
||||||
ambiguous:
|
ambiguous:
|
||||||
|
|
||||||
.. code:: bro
|
.. sourcecode:: bro
|
||||||
|
|
||||||
type MyRec: record {
|
type MyRec: record {
|
||||||
a: count &optional;
|
a: count &optional;
|
||||||
|
@ -430,13 +430,13 @@ Here is a more detailed description of each type:
|
||||||
Accessing table elements is provided by enclosing index values within
|
Accessing table elements is provided by enclosing index values within
|
||||||
square brackets (``[]``), for example:
|
square brackets (``[]``), for example:
|
||||||
|
|
||||||
.. code:: bro
|
.. sourcecode:: bro
|
||||||
|
|
||||||
print t[11];
|
print t[11];
|
||||||
|
|
||||||
And membership can be tested with ``in`` or ``!in``:
|
And membership can be tested with ``in`` or ``!in``:
|
||||||
|
|
||||||
.. code:: bro
|
.. sourcecode:: bro
|
||||||
|
|
||||||
if ( 13 in t )
|
if ( 13 in t )
|
||||||
...
|
...
|
||||||
|
@ -445,13 +445,13 @@ Here is a more detailed description of each type:
|
||||||
|
|
||||||
Add or overwrite individual table elements by assignment:
|
Add or overwrite individual table elements by assignment:
|
||||||
|
|
||||||
.. code:: bro
|
.. sourcecode:: bro
|
||||||
|
|
||||||
t[13] = "thirteen";
|
t[13] = "thirteen";
|
||||||
|
|
||||||
Remove individual table elements with :bro:keyword:`delete`:
|
Remove individual table elements with :bro:keyword:`delete`:
|
||||||
|
|
||||||
.. code:: bro
|
.. sourcecode:: bro
|
||||||
|
|
||||||
delete t[13];
|
delete t[13];
|
||||||
|
|
||||||
|
@ -461,7 +461,7 @@ Here is a more detailed description of each type:
|
||||||
The number of elements in a table can be obtained by placing the table
|
The number of elements in a table can be obtained by placing the table
|
||||||
identifier between vertical pipe characters:
|
identifier between vertical pipe characters:
|
||||||
|
|
||||||
.. code:: bro
|
.. sourcecode:: bro
|
||||||
|
|
||||||
|t|
|
|t|
|
||||||
|
|
||||||
|
@ -482,7 +482,7 @@ Here is a more detailed description of each type:
|
||||||
|
|
||||||
Sets can be initialized by listing elements enclosed by curly braces:
|
Sets can be initialized by listing elements enclosed by curly braces:
|
||||||
|
|
||||||
.. code:: bro
|
.. sourcecode:: bro
|
||||||
|
|
||||||
global s: set[port] = { 21/tcp, 23/tcp, 80/tcp, 443/tcp };
|
global s: set[port] = { 21/tcp, 23/tcp, 80/tcp, 443/tcp };
|
||||||
global s2: set[port, string] = { [21/tcp, "ftp"], [23/tcp, "telnet"] };
|
global s2: set[port, string] = { [21/tcp, "ftp"], [23/tcp, "telnet"] };
|
||||||
|
@ -490,7 +490,7 @@ Here is a more detailed description of each type:
|
||||||
A set constructor (equivalent to above example) can also be used to
|
A set constructor (equivalent to above example) can also be used to
|
||||||
create a set:
|
create a set:
|
||||||
|
|
||||||
.. code:: bro
|
.. sourcecode:: bro
|
||||||
|
|
||||||
global s3 = set(21/tcp, 23/tcp, 80/tcp, 443/tcp);
|
global s3 = set(21/tcp, 23/tcp, 80/tcp, 443/tcp);
|
||||||
|
|
||||||
|
@ -498,7 +498,7 @@ Here is a more detailed description of each type:
|
||||||
useful when a more complex index type could otherwise be
|
useful when a more complex index type could otherwise be
|
||||||
ambiguous:
|
ambiguous:
|
||||||
|
|
||||||
.. code:: bro
|
.. sourcecode:: bro
|
||||||
|
|
||||||
type MyRec: record {
|
type MyRec: record {
|
||||||
a: count &optional;
|
a: count &optional;
|
||||||
|
@ -511,7 +511,7 @@ Here is a more detailed description of each type:
|
||||||
|
|
||||||
Set membership is tested with ``in`` or ``!in``:
|
Set membership is tested with ``in`` or ``!in``:
|
||||||
|
|
||||||
.. code:: bro
|
.. sourcecode:: bro
|
||||||
|
|
||||||
if ( 21/tcp in s )
|
if ( 21/tcp in s )
|
||||||
...
|
...
|
||||||
|
@ -521,7 +521,7 @@ Here is a more detailed description of each type:
|
||||||
|
|
||||||
Elements are added with :bro:keyword:`add`:
|
Elements are added with :bro:keyword:`add`:
|
||||||
|
|
||||||
.. code:: bro
|
.. sourcecode:: bro
|
||||||
|
|
||||||
add s[22/tcp];
|
add s[22/tcp];
|
||||||
|
|
||||||
|
@ -530,7 +530,7 @@ Here is a more detailed description of each type:
|
||||||
|
|
||||||
And removed with :bro:keyword:`delete`:
|
And removed with :bro:keyword:`delete`:
|
||||||
|
|
||||||
.. code:: bro
|
.. sourcecode:: bro
|
||||||
|
|
||||||
delete s[21/tcp];
|
delete s[21/tcp];
|
||||||
|
|
||||||
|
@ -540,7 +540,7 @@ Here is a more detailed description of each type:
|
||||||
The number of elements in a set can be obtained by placing the set
|
The number of elements in a set can be obtained by placing the set
|
||||||
identifier between vertical pipe characters:
|
identifier between vertical pipe characters:
|
||||||
|
|
||||||
.. code:: bro
|
.. sourcecode:: bro
|
||||||
|
|
||||||
|s|
|
|s|
|
||||||
|
|
||||||
|
@ -563,13 +563,13 @@ Here is a more detailed description of each type:
|
||||||
:bro:type:`count` (and vector indexing is always zero-based). A vector
|
:bro:type:`count` (and vector indexing is always zero-based). A vector
|
||||||
is declared like:
|
is declared like:
|
||||||
|
|
||||||
.. code:: bro
|
.. sourcecode:: bro
|
||||||
|
|
||||||
global v: vector of string;
|
global v: vector of string;
|
||||||
|
|
||||||
And can be initialized with the vector constructor:
|
And can be initialized with the vector constructor:
|
||||||
|
|
||||||
.. code:: bro
|
.. sourcecode:: bro
|
||||||
|
|
||||||
local v = vector("one", "two", "three");
|
local v = vector("one", "two", "three");
|
||||||
|
|
||||||
|
@ -577,7 +577,7 @@ Here is a more detailed description of each type:
|
||||||
is useful for when a more complex yield type could otherwise be
|
is useful for when a more complex yield type could otherwise be
|
||||||
ambiguous.
|
ambiguous.
|
||||||
|
|
||||||
.. code:: bro
|
.. sourcecode:: bro
|
||||||
|
|
||||||
type MyRec: record {
|
type MyRec: record {
|
||||||
a: count &optional;
|
a: count &optional;
|
||||||
|
@ -591,14 +591,14 @@ Here is a more detailed description of each type:
|
||||||
Accessing vector elements is provided by enclosing index values within
|
Accessing vector elements is provided by enclosing index values within
|
||||||
square brackets (``[]``), for example:
|
square brackets (``[]``), for example:
|
||||||
|
|
||||||
.. code:: bro
|
.. sourcecode:: bro
|
||||||
|
|
||||||
print v[2];
|
print v[2];
|
||||||
|
|
||||||
An element can be added to a vector by assigning the value (a value
|
An element can be added to a vector by assigning the value (a value
|
||||||
that already exists at that index will be overwritten):
|
that already exists at that index will be overwritten):
|
||||||
|
|
||||||
.. code:: bro
|
.. sourcecode:: bro
|
||||||
|
|
||||||
v[3] = "four";
|
v[3] = "four";
|
||||||
|
|
||||||
|
@ -606,21 +606,21 @@ Here is a more detailed description of each type:
|
||||||
is normally equal to the number of elements in the vector) can be obtained
|
is normally equal to the number of elements in the vector) can be obtained
|
||||||
by placing the vector identifier between vertical pipe characters:
|
by placing the vector identifier between vertical pipe characters:
|
||||||
|
|
||||||
.. code:: bro
|
.. sourcecode:: bro
|
||||||
|
|
||||||
|v|
|
|v|
|
||||||
|
|
||||||
A particularly common operation on a vector is to append an element
|
A particularly common operation on a vector is to append an element
|
||||||
to its end. You can do so using:
|
to its end. You can do so using:
|
||||||
|
|
||||||
.. code:: bro
|
.. sourcecode:: bro
|
||||||
|
|
||||||
v += e;
|
v += e;
|
||||||
|
|
||||||
where if e's type is ``X``, v's type is ``vector of X``. Note that
|
where if e's type is ``X``, v's type is ``vector of X``. Note that
|
||||||
this expression is equivalent to:
|
this expression is equivalent to:
|
||||||
|
|
||||||
.. code:: bro
|
.. sourcecode:: bro
|
||||||
|
|
||||||
v[|v|] = e;
|
v[|v|] = e;
|
||||||
|
|
||||||
|
@ -660,7 +660,7 @@ Here is a more detailed description of each type:
|
||||||
same as local or global variables). An example record type
|
same as local or global variables). An example record type
|
||||||
definition:
|
definition:
|
||||||
|
|
||||||
.. code:: bro
|
.. sourcecode:: bro
|
||||||
|
|
||||||
type MyRecordType: record {
|
type MyRecordType: record {
|
||||||
c: count;
|
c: count;
|
||||||
|
@ -672,27 +672,27 @@ Here is a more detailed description of each type:
|
||||||
:bro:attr:`&optional` or have a :bro:attr:`&default` attribute must
|
:bro:attr:`&optional` or have a :bro:attr:`&default` attribute must
|
||||||
be specified. First, there's a constructor syntax:
|
be specified. First, there's a constructor syntax:
|
||||||
|
|
||||||
.. code:: bro
|
.. sourcecode:: bro
|
||||||
|
|
||||||
local r: MyRecordType = record($c = 7);
|
local r: MyRecordType = record($c = 7);
|
||||||
|
|
||||||
And the constructor can be explicitly named by type, too, which
|
And the constructor can be explicitly named by type, too, which
|
||||||
is arguably more readable:
|
is arguably more readable:
|
||||||
|
|
||||||
.. code:: bro
|
.. sourcecode:: bro
|
||||||
|
|
||||||
local r = MyRecordType($c = 42);
|
local r = MyRecordType($c = 42);
|
||||||
|
|
||||||
And the third way is like this:
|
And the third way is like this:
|
||||||
|
|
||||||
.. code:: bro
|
.. sourcecode:: bro
|
||||||
|
|
||||||
local r: MyRecordType = [$c = 13, $s = "thirteen"];
|
local r: MyRecordType = [$c = 13, $s = "thirteen"];
|
||||||
|
|
||||||
Access to a record field uses the dollar sign (``$``) operator, and
|
Access to a record field uses the dollar sign (``$``) operator, and
|
||||||
record fields can be assigned with this:
|
record fields can be assigned with this:
|
||||||
|
|
||||||
.. code:: bro
|
.. sourcecode:: bro
|
||||||
|
|
||||||
local r: MyRecordType;
|
local r: MyRecordType;
|
||||||
r$c = 13;
|
r$c = 13;
|
||||||
|
@ -701,7 +701,7 @@ Here is a more detailed description of each type:
|
||||||
value, use the ``?$`` operator (it returns a :bro:type:`bool` value of
|
value, use the ``?$`` operator (it returns a :bro:type:`bool` value of
|
||||||
``T`` if the field has been assigned a value, or ``F`` if not):
|
``T`` if the field has been assigned a value, or ``F`` if not):
|
||||||
|
|
||||||
.. code:: bro
|
.. sourcecode:: bro
|
||||||
|
|
||||||
if ( r ?$ s )
|
if ( r ?$ s )
|
||||||
...
|
...
|
||||||
|
@ -715,7 +715,7 @@ Here is a more detailed description of each type:
|
||||||
where *argument* is a (possibly empty) comma-separated list of
|
where *argument* is a (possibly empty) comma-separated list of
|
||||||
arguments, and *type* is an optional return type. For example:
|
arguments, and *type* is an optional return type. For example:
|
||||||
|
|
||||||
.. code:: bro
|
.. sourcecode:: bro
|
||||||
|
|
||||||
global greeting: function(name: string): string;
|
global greeting: function(name: string): string;
|
||||||
|
|
||||||
|
@ -724,7 +724,7 @@ Here is a more detailed description of each type:
|
||||||
have different function body values at different times. To define
|
have different function body values at different times. To define
|
||||||
a function including a body value, the syntax is like:
|
a function including a body value, the syntax is like:
|
||||||
|
|
||||||
.. code:: bro
|
.. sourcecode:: bro
|
||||||
|
|
||||||
function greeting(name: string): string
|
function greeting(name: string): string
|
||||||
{
|
{
|
||||||
|
@ -739,7 +739,7 @@ Here is a more detailed description of each type:
|
||||||
Here is an example function that takes no parameters and does not
|
Here is an example function that takes no parameters and does not
|
||||||
return a value:
|
return a value:
|
||||||
|
|
||||||
.. code:: bro
|
.. sourcecode:: bro
|
||||||
|
|
||||||
function my_func()
|
function my_func()
|
||||||
{
|
{
|
||||||
|
@ -748,20 +748,20 @@ Here is a more detailed description of each type:
|
||||||
|
|
||||||
Function types don't need to have a name and can be assigned anonymously:
|
Function types don't need to have a name and can be assigned anonymously:
|
||||||
|
|
||||||
.. code:: bro
|
.. sourcecode:: bro
|
||||||
|
|
||||||
greeting = function(name: string): string { return "Hi, " + name; };
|
greeting = function(name: string): string { return "Hi, " + name; };
|
||||||
|
|
||||||
And finally, the function can be called like:
|
And finally, the function can be called like:
|
||||||
|
|
||||||
.. code:: bro
|
.. sourcecode:: bro
|
||||||
|
|
||||||
print greeting("Dave");
|
print greeting("Dave");
|
||||||
|
|
||||||
Function parameters may specify default values as long as they appear
|
Function parameters may specify default values as long as they appear
|
||||||
last in the parameter list:
|
last in the parameter list:
|
||||||
|
|
||||||
.. code:: bro
|
.. sourcecode:: bro
|
||||||
|
|
||||||
global foo: function(s: string, t: string &default="abc", u: count &default=0);
|
global foo: function(s: string, t: string &default="abc", u: count &default=0);
|
||||||
|
|
||||||
|
@ -770,7 +770,7 @@ Here is a more detailed description of each type:
|
||||||
body and they will still be used for function calls that lack those
|
body and they will still be used for function calls that lack those
|
||||||
arguments.
|
arguments.
|
||||||
|
|
||||||
.. code:: bro
|
.. sourcecode:: bro
|
||||||
|
|
||||||
function foo(s: string, t: string, u: count)
|
function foo(s: string, t: string, u: count)
|
||||||
{
|
{
|
||||||
|
@ -779,7 +779,7 @@ Here is a more detailed description of each type:
|
||||||
|
|
||||||
And calls to the function may omit the defaults from the argument list:
|
And calls to the function may omit the defaults from the argument list:
|
||||||
|
|
||||||
.. code:: bro
|
.. sourcecode:: bro
|
||||||
|
|
||||||
foo("test");
|
foo("test");
|
||||||
|
|
||||||
|
@ -792,7 +792,7 @@ Here is a more detailed description of each type:
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
.. code:: bro
|
.. sourcecode:: bro
|
||||||
|
|
||||||
event my_event(r: bool, s: string)
|
event my_event(r: bool, s: string)
|
||||||
{
|
{
|
||||||
|
@ -815,7 +815,7 @@ Here is a more detailed description of each type:
|
||||||
|
|
||||||
Immediately queuing invocation of an event handler occurs like:
|
Immediately queuing invocation of an event handler occurs like:
|
||||||
|
|
||||||
.. code:: bro
|
.. sourcecode:: bro
|
||||||
|
|
||||||
event password_exposed(user, password);
|
event password_exposed(user, password);
|
||||||
|
|
||||||
|
@ -827,7 +827,7 @@ Here is a more detailed description of each type:
|
||||||
This delays the invocation of event handlers until some time in
|
This delays the invocation of event handlers until some time in
|
||||||
the future. For example:
|
the future. For example:
|
||||||
|
|
||||||
.. code:: bro
|
.. sourcecode:: bro
|
||||||
|
|
||||||
schedule 5 secs { password_exposed(user, password) };
|
schedule 5 secs { password_exposed(user, password) };
|
||||||
|
|
||||||
|
@ -856,7 +856,7 @@ Here is a more detailed description of each type:
|
||||||
where *argument* is a (possibly empty) comma-separated list of
|
where *argument* is a (possibly empty) comma-separated list of
|
||||||
arguments. For example:
|
arguments. For example:
|
||||||
|
|
||||||
.. code:: bro
|
.. sourcecode:: bro
|
||||||
|
|
||||||
global myhook: hook(s: string)
|
global myhook: hook(s: string)
|
||||||
|
|
||||||
|
@ -864,7 +864,7 @@ Here is a more detailed description of each type:
|
||||||
bodies have been defined for it yet. To define some hook handler
|
bodies have been defined for it yet. To define some hook handler
|
||||||
bodies the syntax looks like:
|
bodies the syntax looks like:
|
||||||
|
|
||||||
.. code:: bro
|
.. sourcecode:: bro
|
||||||
|
|
||||||
hook myhook(s: string) &priority=10
|
hook myhook(s: string) &priority=10
|
||||||
{
|
{
|
||||||
|
@ -891,13 +891,13 @@ Here is a more detailed description of each type:
|
||||||
are called similarly to a function, except preceded by the ``hook``
|
are called similarly to a function, except preceded by the ``hook``
|
||||||
keyword:
|
keyword:
|
||||||
|
|
||||||
.. code:: bro
|
.. sourcecode:: bro
|
||||||
|
|
||||||
hook myhook("hi");
|
hook myhook("hi");
|
||||||
|
|
||||||
or
|
or
|
||||||
|
|
||||||
.. code:: bro
|
.. sourcecode:: bro
|
||||||
|
|
||||||
if ( hook myhook("hi") )
|
if ( hook myhook("hi") )
|
||||||
print "all handlers ran";
|
print "all handlers ran";
|
||||||
|
@ -925,7 +925,7 @@ Here is a more detailed description of each type:
|
||||||
function. For example, declare, open, and write to a file and finally
|
function. For example, declare, open, and write to a file and finally
|
||||||
close it like:
|
close it like:
|
||||||
|
|
||||||
.. code:: bro
|
.. sourcecode:: bro
|
||||||
|
|
||||||
local f = open("myfile");
|
local f = open("myfile");
|
||||||
print f, "hello, world";
|
print f, "hello, world";
|
||||||
|
@ -945,7 +945,7 @@ Here is a more detailed description of each type:
|
||||||
An example use of this type is the set of built-in functions which
|
An example use of this type is the set of built-in functions which
|
||||||
perform hashing:
|
perform hashing:
|
||||||
|
|
||||||
.. code:: bro
|
.. sourcecode:: bro
|
||||||
|
|
||||||
local handle = md5_hash_init();
|
local handle = md5_hash_init();
|
||||||
md5_hash_update(handle, "test");
|
md5_hash_update(handle, "test");
|
||||||
|
|
|
@ -41,7 +41,7 @@ script :doc:`/scripts/policy/frameworks/files/detect-MHR.bro`
|
||||||
that is responsible for generating the
|
that is responsible for generating the
|
||||||
appropriate DNS lookup, parsing the response, and generating a notice if appropriate.
|
appropriate DNS lookup, parsing the response, and generating a notice if appropriate.
|
||||||
|
|
||||||
.. code:: bro
|
.. sourcecode:: bro
|
||||||
:caption: detect-MHR.bro
|
:caption: detect-MHR.bro
|
||||||
|
|
||||||
##! Detect file downloads that have hash values matching files in Team
|
##! Detect file downloads that have hash values matching files in Team
|
||||||
|
@ -126,7 +126,7 @@ specific event (``event file_hash``). Don't get discouraged if you don't
|
||||||
understand every section of the script; we'll cover the basics of the
|
understand every section of the script; we'll cover the basics of the
|
||||||
script and much more in following sections.
|
script and much more in following sections.
|
||||||
|
|
||||||
.. code:: bro
|
.. sourcecode:: bro
|
||||||
:caption: detect-MHR.bro
|
:caption: detect-MHR.bro
|
||||||
|
|
||||||
@load base/frameworks/files
|
@load base/frameworks/files
|
||||||
|
@ -145,7 +145,7 @@ this level of granularity might not be entirely necessary. The ``@load`` direct
|
||||||
are ensuring the Files framework, the Notice framework and the script to hash all files has
|
are ensuring the Files framework, the Notice framework and the script to hash all files has
|
||||||
been loaded by Bro.
|
been loaded by Bro.
|
||||||
|
|
||||||
.. code:: bro
|
.. sourcecode:: bro
|
||||||
:caption: detect-MHR.bro
|
:caption: detect-MHR.bro
|
||||||
|
|
||||||
export {
|
export {
|
||||||
|
@ -196,7 +196,7 @@ Up until this point, the script has merely done some basic setup. With
|
||||||
the next section, the script starts to define instructions to take in
|
the next section, the script starts to define instructions to take in
|
||||||
a given event.
|
a given event.
|
||||||
|
|
||||||
.. code:: bro
|
.. sourcecode:: bro
|
||||||
:caption: detect-MHR.bro
|
:caption: detect-MHR.bro
|
||||||
|
|
||||||
function do_mhr_lookup(hash: string, fi: Notice::FileInfo)
|
function do_mhr_lookup(hash: string, fi: Notice::FileInfo)
|
||||||
|
@ -324,7 +324,7 @@ This effort resulted in built-in-function files organized such that
|
||||||
each entry contains a descriptive event name, the arguments passed to
|
each entry contains a descriptive event name, the arguments passed to
|
||||||
the event, and a concise explanation of the functions use.
|
the event, and a concise explanation of the functions use.
|
||||||
|
|
||||||
.. code:: bro
|
.. sourcecode:: bro
|
||||||
|
|
||||||
## Generated for DNS requests. For requests with multiple queries, this event
|
## Generated for DNS requests. For requests with multiple queries, this event
|
||||||
## is raised once for each.
|
## is raised once for each.
|
||||||
|
@ -413,7 +413,7 @@ more layers of information about a connection. This will give us a
|
||||||
chance to see the contents of the connection record without it being
|
chance to see the contents of the connection record without it being
|
||||||
overly populated.
|
overly populated.
|
||||||
|
|
||||||
.. console::
|
.. sourcecode:: console
|
||||||
|
|
||||||
$ bro -b -r http/get.trace connection_record_01.bro
|
$ bro -b -r http/get.trace connection_record_01.bro
|
||||||
[id=[orig_h=141.142.228.5, orig_p=59856/tcp, resp_h=192.150.187.43, resp_p=80/tcp], orig=[size=136, state=5, num_pkts=7, num_bytes_ip=512, flow_label=0, l2_addr=c8:bc:c8:96:d2:a0], resp=[size=5007, state=5, num_pkts=7, num_bytes_ip=5379, flow_label=0, l2_addr=00:10:db:88:d2:ef], start_time=1362692526.869344, duration=0.211484, service={
|
[id=[orig_h=141.142.228.5, orig_p=59856/tcp, resp_h=192.150.187.43, resp_p=80/tcp], orig=[size=136, state=5, num_pkts=7, num_bytes_ip=512, flow_label=0, l2_addr=c8:bc:c8:96:d2:a0], resp=[size=5007, state=5, num_pkts=7, num_bytes_ip=5379, flow_label=0, l2_addr=00:10:db:88:d2:ef], start_time=1362692526.869344, duration=0.211484, service={
|
||||||
|
@ -449,7 +449,7 @@ brackets, which would correspond to the ``$``-delimiter in a Bro script.
|
||||||
:language: bro
|
:language: bro
|
||||||
:linenos:
|
:linenos:
|
||||||
|
|
||||||
.. console::
|
.. sourcecode:: console
|
||||||
|
|
||||||
$bro -b -r http/get.trace connection_record_02.bro
|
$bro -b -r http/get.trace connection_record_02.bro
|
||||||
[id=[orig_h=141.142.228.5, orig_p=59856/tcp, resp_h=192.150.187.43, resp_p=80/tcp], orig=[size=136, state=5, num_pkts=7, num_bytes_ip=512, flow_label=0, l2_addr=c8:bc:c8:96:d2:a0], resp=[size=5007, state=5, num_pkts=7, num_bytes_ip=5379, flow_label=0, l2_addr=00:10:db:88:d2:ef], start_time=1362692526.869344, duration=0.211484, service={
|
[id=[orig_h=141.142.228.5, orig_p=59856/tcp, resp_h=192.150.187.43, resp_p=80/tcp], orig=[size=136, state=5, num_pkts=7, num_bytes_ip=512, flow_label=0, l2_addr=c8:bc:c8:96:d2:a0], resp=[size=5007, state=5, num_pkts=7, num_bytes_ip=5379, flow_label=0, l2_addr=00:10:db:88:d2:ef], start_time=1362692526.869344, duration=0.211484, service={
|
||||||
|
@ -562,7 +562,7 @@ would fail.
|
||||||
:language: bro
|
:language: bro
|
||||||
:linenos:
|
:linenos:
|
||||||
|
|
||||||
.. console::
|
.. sourcecode:: console
|
||||||
|
|
||||||
$ bro -b data_type_const.bro
|
$ bro -b data_type_const.bro
|
||||||
{
|
{
|
||||||
|
@ -711,7 +711,7 @@ You can see the full script and its output below.
|
||||||
:language: bro
|
:language: bro
|
||||||
:linenos:
|
:linenos:
|
||||||
|
|
||||||
.. console::
|
.. sourcecode:: console
|
||||||
|
|
||||||
$ bro data_struct_set_declaration.bro
|
$ bro data_struct_set_declaration.bro
|
||||||
SSL Port: 22/tcp
|
SSL Port: 22/tcp
|
||||||
|
@ -735,7 +735,7 @@ to preserve a one-to-one mapping of keys to values.
|
||||||
:language: bro
|
:language: bro
|
||||||
:linenos:
|
:linenos:
|
||||||
|
|
||||||
.. console::
|
.. sourcecode:: console
|
||||||
|
|
||||||
$ bro data_struct_table_declaration.bro
|
$ bro data_struct_table_declaration.bro
|
||||||
Service Name: SSH - Common Port: 22/tcp
|
Service Name: SSH - Common Port: 22/tcp
|
||||||
|
@ -771,7 +771,7 @@ security platform.
|
||||||
:language: bro
|
:language: bro
|
||||||
:linenos:
|
:linenos:
|
||||||
|
|
||||||
.. console::
|
.. sourcecode:: console
|
||||||
|
|
||||||
$ bro -b data_struct_table_complex.bro
|
$ bro -b data_struct_table_complex.bro
|
||||||
Harakiri was released in 1962 by Shochiku Eiga studios, directed by Masaki Kobayashi and starring Tatsuya Nakadai
|
Harakiri was released in 1962 by Shochiku Eiga studios, directed by Masaki Kobayashi and starring Tatsuya Nakadai
|
||||||
|
@ -824,7 +824,7 @@ lengths.
|
||||||
:language: bro
|
:language: bro
|
||||||
:linenos:
|
:linenos:
|
||||||
|
|
||||||
.. console::
|
.. sourcecode:: console
|
||||||
|
|
||||||
$ bro data_struct_vector_declaration.bro
|
$ bro data_struct_vector_declaration.bro
|
||||||
contents of v1: [1, 2, 3, 4]
|
contents of v1: [1, 2, 3, 4]
|
||||||
|
@ -846,7 +846,7 @@ current item in the vector with ``addr_vector[i]``.
|
||||||
:language: bro
|
:language: bro
|
||||||
:linenos:
|
:linenos:
|
||||||
|
|
||||||
.. console::
|
.. sourcecode:: console
|
||||||
|
|
||||||
$ bro -b data_struct_vector_iter.bro
|
$ bro -b data_struct_vector_iter.bro
|
||||||
1.2.0.0/18
|
1.2.0.0/18
|
||||||
|
@ -923,7 +923,7 @@ For example, ``10.0.0.1 in 10.0.0.0/8`` would return true while
|
||||||
script, we get the output listing the IP address and the subnet in
|
script, we get the output listing the IP address and the subnet in
|
||||||
which it belongs.
|
which it belongs.
|
||||||
|
|
||||||
.. console::
|
.. sourcecode:: console
|
||||||
|
|
||||||
$ bro data_type_subnets.bro
|
$ bro data_type_subnets.bro
|
||||||
172.16.4.56 belongs to subnet 172.16.0.0/20
|
172.16.4.56 belongs to subnet 172.16.0.0/20
|
||||||
|
@ -959,7 +959,7 @@ produce a common date time formatted time stamp.
|
||||||
When the script is executed we get an output showing the details of
|
When the script is executed we get an output showing the details of
|
||||||
established connections.
|
established connections.
|
||||||
|
|
||||||
.. console::
|
.. sourcecode:: console
|
||||||
|
|
||||||
$ bro -r wikipedia.trace data_type_time.bro
|
$ bro -r wikipedia.trace data_type_time.bro
|
||||||
2011/06/18 19:03:08: New connection established from 141.142.220.118 to 208.80.152.118\x0a
|
2011/06/18 19:03:08: New connection established from 141.142.220.118 to 208.80.152.118\x0a
|
||||||
|
@ -1009,7 +1009,7 @@ This time, when we execute the script we see an additional line in the
|
||||||
output to display the time delta since the last fully established
|
output to display the time delta since the last fully established
|
||||||
connection.
|
connection.
|
||||||
|
|
||||||
.. console::
|
.. sourcecode:: console
|
||||||
|
|
||||||
$ bro -r wikipedia.trace data_type_interval.bro
|
$ bro -r wikipedia.trace data_type_interval.bro
|
||||||
2011/06/18 19:03:08: New connection established from 141.142.220.118 to 208.80.152.118
|
2011/06/18 19:03:08: New connection established from 141.142.220.118 to 208.80.152.118
|
||||||
|
@ -1064,7 +1064,7 @@ excluding the actual matches. In this case, our pattern matches
|
||||||
twice, and results in a table with three entries. The ``print`` statements
|
twice, and results in a table with three entries. The ``print`` statements
|
||||||
in the script will print the contents of the table in order.
|
in the script will print the contents of the table in order.
|
||||||
|
|
||||||
.. console::
|
.. sourcecode:: console
|
||||||
|
|
||||||
$ bro data_type_pattern_01.bro
|
$ bro data_type_pattern_01.bro
|
||||||
The
|
The
|
||||||
|
@ -1081,7 +1081,7 @@ on the result of the comparison between the pattern and the string.
|
||||||
|
|
||||||
.. literalinclude:: data_type_pattern_02.bro
|
.. literalinclude:: data_type_pattern_02.bro
|
||||||
|
|
||||||
.. console::
|
.. sourcecode:: console
|
||||||
|
|
||||||
$ bro data_type_pattern_02.bro
|
$ bro data_type_pattern_02.bro
|
||||||
equality and /^?(equal)$?/ are not equal
|
equality and /^?(equal)$?/ are not equal
|
||||||
|
@ -1126,7 +1126,7 @@ field is unique.
|
||||||
:language: bro
|
:language: bro
|
||||||
:linenos:
|
:linenos:
|
||||||
|
|
||||||
.. console::
|
.. sourcecode:: console
|
||||||
|
|
||||||
$ bro data_struct_record_01.bro
|
$ bro data_struct_record_01.bro
|
||||||
Service: dns(RFC1035)
|
Service: dns(RFC1035)
|
||||||
|
@ -1153,7 +1153,7 @@ record.
|
||||||
|
|
||||||
.. literalinclude:: data_struct_record_02.bro
|
.. literalinclude:: data_struct_record_02.bro
|
||||||
|
|
||||||
.. console::
|
.. sourcecode:: console
|
||||||
|
|
||||||
$ bro data_struct_record_02.bro
|
$ bro data_struct_record_02.bro
|
||||||
System: morlock
|
System: morlock
|
||||||
|
@ -1173,7 +1173,7 @@ It's also common to see a ``type`` used to simply alias a data
|
||||||
structure to a more descriptive name. The example below shows an
|
structure to a more descriptive name. The example below shows an
|
||||||
example of this from Bro's own type definitions file.
|
example of this from Bro's own type definitions file.
|
||||||
|
|
||||||
.. code:: bro
|
.. sourcecode:: bro
|
||||||
:caption: init-bare.bro
|
:caption: init-bare.bro
|
||||||
|
|
||||||
type string_array: table[count] of string;
|
type string_array: table[count] of string;
|
||||||
|
@ -1240,7 +1240,7 @@ into the Logging Framework.
|
||||||
:language: bro
|
:language: bro
|
||||||
:linenos:
|
:linenos:
|
||||||
|
|
||||||
.. console::
|
.. sourcecode:: console
|
||||||
|
|
||||||
$ bro framework_logging_factorial_01.bro
|
$ bro framework_logging_factorial_01.bro
|
||||||
1
|
1
|
||||||
|
@ -1297,7 +1297,7 @@ Now, if we run this script, instead of generating
|
||||||
logging information to stdout, no output is created. Instead the
|
logging information to stdout, no output is created. Instead the
|
||||||
output is all in ``factor.log``, properly formatted and organized.
|
output is all in ``factor.log``, properly formatted and organized.
|
||||||
|
|
||||||
.. console::
|
.. sourcecode:: console
|
||||||
|
|
||||||
$ bro framework_logging_factorial_02.bro
|
$ bro framework_logging_factorial_02.bro
|
||||||
$ cat factor.log
|
$ cat factor.log
|
||||||
|
@ -1371,7 +1371,7 @@ factorials that are a factors of 5, ``factor-non5.log`` with the
|
||||||
factorials that are not factors of 5, and ``factor.log`` which would have
|
factorials that are not factors of 5, and ``factor.log`` which would have
|
||||||
included all factorials.
|
included all factorials.
|
||||||
|
|
||||||
.. console::
|
.. sourcecode:: console
|
||||||
|
|
||||||
$ bro framework_logging_factorial_03.bro
|
$ bro framework_logging_factorial_03.bro
|
||||||
$ cat factor-mod5.log
|
$ cat factor-mod5.log
|
||||||
|
@ -1473,7 +1473,7 @@ or not that notice is acted upon is decided by the local Notice
|
||||||
Policy, but the script attempts to supply as much information as
|
Policy, but the script attempts to supply as much information as
|
||||||
possible while staying concise.
|
possible while staying concise.
|
||||||
|
|
||||||
.. code:: bro
|
.. sourcecode:: bro
|
||||||
:caption: scripts/policy/protocols/ssh/interesting-hostnames.bro
|
:caption: scripts/policy/protocols/ssh/interesting-hostnames.bro
|
||||||
|
|
||||||
##! This script will generate a notice if an apparent SSH login originates
|
##! This script will generate a notice if an apparent SSH login originates
|
||||||
|
@ -1604,7 +1604,7 @@ identifier. An identifier is a unique string of information collected
|
||||||
from the connection relative to the behavior that has been observed by
|
from the connection relative to the behavior that has been observed by
|
||||||
Bro.
|
Bro.
|
||||||
|
|
||||||
.. code:: bro
|
.. sourcecode:: bro
|
||||||
:caption: scripts/policy/protocols/ssl/expiring-certs.bro
|
:caption: scripts/policy/protocols/ssl/expiring-certs.bro
|
||||||
|
|
||||||
NOTICE([$note=Certificate_Expires_Soon,
|
NOTICE([$note=Certificate_Expires_Soon,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue