mirror of
https://github.com/zeek/zeek.git
synced 2025-10-05 16:18:19 +00:00
Remove Sphinx btest integrations and tests
This commit is contained in:
parent
be0d3021fa
commit
9e5e9d04b7
294 changed files with 1215 additions and 5590 deletions
|
@ -23,13 +23,14 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/broxygen.conf.in
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/broxygen.conf
|
${CMAKE_CURRENT_BINARY_DIR}/broxygen.conf
|
||||||
@ONLY)
|
@ONLY)
|
||||||
|
|
||||||
add_custom_target(sphinxdoc
|
add_custom_target(rstdoc
|
||||||
# Copy the template documentation to build directory to use as input tree
|
# Copy the template documentation to build directory to use as input tree
|
||||||
# for Sphinx. This is needed because some parts are dynamically generated
|
# for Sphinx. This is needed because some parts are dynamically generated
|
||||||
# in to that tree by Bro/Broxygen.
|
# in to that tree by Bro/Broxygen.
|
||||||
COMMAND rsync -q -r --copy-links --times --delete
|
COMMAND rsync -q -r --copy-links --times --delete
|
||||||
--filter='protect scripts/*'
|
--filter='protect scripts/*'
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/ ${SPHINX_INPUT_DIR}
|
${CMAKE_CURRENT_SOURCE_DIR}/
|
||||||
|
${SPHINX_INPUT_DIR}
|
||||||
# Use Bro/Broxygen to dynamically generate reST for all Bro scripts.
|
# Use Bro/Broxygen to dynamically generate reST for all Bro scripts.
|
||||||
COMMAND BROPATH=${BROPATH}
|
COMMAND BROPATH=${BROPATH}
|
||||||
${CMAKE_BINARY_DIR}/src/bro
|
${CMAKE_BINARY_DIR}/src/bro
|
||||||
|
@ -37,19 +38,26 @@ add_custom_target(sphinxdoc
|
||||||
broxygen >/dev/null
|
broxygen >/dev/null
|
||||||
# Rsync over the generated reST to the Sphinx source tree in the build dir.
|
# Rsync over the generated reST to the Sphinx source tree in the build dir.
|
||||||
COMMAND rsync -q -r --copy-links --times --delete --filter='protect *.bro'
|
COMMAND rsync -q -r --copy-links --times --delete --filter='protect *.bro'
|
||||||
${BROXYGEN_SCRIPT_OUTPUT}/ ${SPHINX_INPUT_DIR}/scripts
|
${BROXYGEN_SCRIPT_OUTPUT}/
|
||||||
|
${SPHINX_INPUT_DIR}/scripts
|
||||||
# Rsync over Bro scripts to the Sphinx source tree in the build dir.
|
# Rsync over Bro scripts to the Sphinx source tree in the build dir.
|
||||||
# These are used by :download: references in the generated script docs.
|
# These are used by :download: references in the generated script docs.
|
||||||
COMMAND rsync -q -r --copy-links --times --delete
|
COMMAND rsync -q -r --copy-links --times --delete
|
||||||
--filter='protect /base/bif/*' --filter='protect *.rst'
|
--filter='protect /base/bif/*' --filter='protect *.rst'
|
||||||
--filter='include */' --filter='include *.bro' --filter='exclude *'
|
--filter='include */' --filter='include *.bro' --filter='exclude *'
|
||||||
${CMAKE_SOURCE_DIR}/scripts/ ${SPHINX_INPUT_DIR}/scripts
|
${CMAKE_SOURCE_DIR}/scripts/
|
||||||
|
${SPHINX_INPUT_DIR}/scripts
|
||||||
# Rsync over Bro scripts created by BIF compiler to the Sphinx source tree.
|
# Rsync over Bro scripts created by BIF compiler to the Sphinx source tree.
|
||||||
COMMAND rsync -q -r --copy-links --times --delete
|
COMMAND rsync -q -r --copy-links --times --delete
|
||||||
--filter='protect *.rst' --filter='include */'
|
--filter='protect *.rst' --filter='include */'
|
||||||
--filter='include *.bro' --filter='exclude *'
|
--filter='include *.bro' --filter='exclude *'
|
||||||
${CMAKE_BINARY_DIR}/scripts/base/bif/
|
${CMAKE_BINARY_DIR}/scripts/base/bif/
|
||||||
${SPHINX_INPUT_DIR}/scripts/base/bif
|
${SPHINX_INPUT_DIR}/scripts/base/bif
|
||||||
|
)
|
||||||
|
|
||||||
|
add_dependencies(rstdoc bro)
|
||||||
|
|
||||||
|
add_custom_target(sphinxdoc
|
||||||
# Use Sphinx to build HTML.
|
# Use Sphinx to build HTML.
|
||||||
COMMAND sphinx-build
|
COMMAND sphinx-build
|
||||||
-b html
|
-b html
|
||||||
|
@ -64,19 +72,21 @@ add_custom_target(sphinxdoc
|
||||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
|
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
|
||||||
COMMENT "[Sphinx] Generate HTML documentation in ${CMAKE_BINARY_DIR}/html")
|
COMMENT "[Sphinx] Generate HTML documentation in ${CMAKE_BINARY_DIR}/html")
|
||||||
|
|
||||||
add_dependencies(sphinxdoc bro)
|
add_dependencies(sphinxdoc rstdoc)
|
||||||
|
|
||||||
add_custom_target(sphinxdoc_clean
|
add_custom_target(rstdoc_clean
|
||||||
COMMAND "${CMAKE_COMMAND}" -E remove_directory ${SPHINX_INPUT_DIR}
|
COMMAND "${CMAKE_COMMAND}" -E remove_directory ${SPHINX_INPUT_DIR}
|
||||||
COMMAND "${CMAKE_COMMAND}" -E remove_directory ${SPHINX_OUTPUT_DIR}
|
|
||||||
COMMAND "${CMAKE_COMMAND}" -E remove_directory ${BROXYGEN_SCRIPT_OUTPUT}
|
COMMAND "${CMAKE_COMMAND}" -E remove_directory ${BROXYGEN_SCRIPT_OUTPUT}
|
||||||
COMMAND "${CMAKE_COMMAND}" -E remove_directory ${BROXYGEN_CACHE_DIR}
|
COMMAND "${CMAKE_COMMAND}" -E remove_directory ${BROXYGEN_CACHE_DIR}
|
||||||
VERBATIM)
|
VERBATIM)
|
||||||
|
|
||||||
|
add_custom_target(sphinxdoc_clean
|
||||||
|
COMMAND "${CMAKE_COMMAND}" -E remove_directory ${SPHINX_OUTPUT_DIR})
|
||||||
|
|
||||||
if (NOT TARGET doc)
|
if (NOT TARGET doc)
|
||||||
add_custom_target(doc)
|
add_custom_target(doc)
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
add_custom_target(docclean)
|
add_custom_target(docclean)
|
||||||
add_dependencies(doc sphinxdoc)
|
add_dependencies(doc sphinxdoc)
|
||||||
add_dependencies(docclean sphinxdoc_clean)
|
add_dependencies(docclean sphinxdoc_clean rstdoc_clean)
|
||||||
|
|
|
@ -24,8 +24,26 @@ 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.
|
||||||
|
|
||||||
.. btest-include:: ${BRO_SRC_ROOT}/scripts/policy/protocols/ftp/detect-bruteforcing.bro
|
.. code-block:: bro
|
||||||
:lines: 9-25
|
:caption: detect-bruteforcing.bro
|
||||||
|
|
||||||
|
module FTP;
|
||||||
|
|
||||||
|
export {
|
||||||
|
redef enum Notice::Type += {
|
||||||
|
## Indicates a host bruteforcing FTP logins by watching for too
|
||||||
|
## many rejected usernames or failed passwords.
|
||||||
|
Bruteforcing
|
||||||
|
};
|
||||||
|
|
||||||
|
## How many rejected usernames or passwords are required before being
|
||||||
|
## considered to be bruteforcing.
|
||||||
|
const bruteforce_threshold: double = 20 &redef;
|
||||||
|
|
||||||
|
## The time period in which the threshold needs to be crossed before
|
||||||
|
## being reset.
|
||||||
|
const bruteforce_measurement_interval = 15mins &redef;
|
||||||
|
}
|
||||||
|
|
||||||
Using the ftp_reply event, we check for error codes from the `500
|
Using the ftp_reply event, we check for error codes from the `500
|
||||||
series <http://en.wikipedia.org/wiki/List_of_FTP_server_return_codes>`_
|
series <http://en.wikipedia.org/wiki/List_of_FTP_server_return_codes>`_
|
||||||
|
@ -35,24 +53,130 @@ 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.
|
||||||
|
|
||||||
.. btest-include:: ${BRO_SRC_ROOT}/scripts/policy/protocols/ftp/detect-bruteforcing.bro
|
.. code-block:: bro
|
||||||
:lines: 52-60
|
:caption: detect-bruteforcing.bro
|
||||||
|
|
||||||
|
event ftp_reply(c: connection, code: count, msg: string, cont_resp: bool)
|
||||||
|
{
|
||||||
|
local cmd = c$ftp$cmdarg$cmd;
|
||||||
|
if ( cmd == "USER" || cmd == "PASS" )
|
||||||
|
{
|
||||||
|
if ( FTP::parse_ftp_reply_code(code)$x == 5 )
|
||||||
|
SumStats::observe("ftp.failed_auth", [$host=c$id$orig_h], [$str=cat(c$id$resp_h)]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Next, we use the SumStats framework to raise a notice of the attack when
|
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.
|
||||||
|
|
||||||
.. btest-include:: ${BRO_SRC_ROOT}/scripts/policy/protocols/ftp/detect-bruteforcing.bro
|
.. code-block:: bro
|
||||||
:lines: 28-50
|
:caption: detect-bruteforcing.bro
|
||||||
|
|
||||||
|
event bro_init()
|
||||||
|
{
|
||||||
|
local r1: SumStats::Reducer = [$stream="ftp.failed_auth", $apply=set(SumStats::UNIQUE), $unique_max=double_to_count(bruteforce_threshold+2)];
|
||||||
|
SumStats::create([$name="ftp-detect-bruteforcing",
|
||||||
|
$epoch=bruteforce_measurement_interval,
|
||||||
|
$reducers=set(r1),
|
||||||
|
$threshold_val(key: SumStats::Key, result: SumStats::Result) =
|
||||||
|
{
|
||||||
|
return result["ftp.failed_auth"]$num+0.0;
|
||||||
|
},
|
||||||
|
$threshold=bruteforce_threshold,
|
||||||
|
$threshold_crossed(key: SumStats::Key, result: SumStats::Result) =
|
||||||
|
{
|
||||||
|
local r = result["ftp.failed_auth"];
|
||||||
|
local dur = duration_to_mins_secs(r$end-r$begin);
|
||||||
|
local plural = r$unique>1 ? "s" : "";
|
||||||
|
local message = fmt("%s had %d failed logins on %d FTP server%s in %s", key$host, r$num, r$unique, plural, dur);
|
||||||
|
NOTICE([$note=FTP::Bruteforcing,
|
||||||
|
$src=key$host,
|
||||||
|
$msg=message,
|
||||||
|
$identifier=cat(key$host)]);
|
||||||
|
}]);
|
||||||
|
}
|
||||||
|
|
||||||
Below is the final code for our script.
|
Below is the final code for our script.
|
||||||
|
|
||||||
.. btest-include:: ${BRO_SRC_ROOT}/scripts/policy/protocols/ftp/detect-bruteforcing.bro
|
.. code-block:: bro
|
||||||
|
:caption: detect-bruteforcing.bro
|
||||||
|
|
||||||
.. btest:: ftp-bruteforce
|
##! FTP brute-forcing detector, triggering when too many rejected usernames or
|
||||||
|
##! failed passwords have occurred from a single address.
|
||||||
|
|
||||||
@TEST-EXEC: btest-rst-cmd bro -r ${TRACES}/ftp/bruteforce.pcap protocols/ftp/detect-bruteforcing.bro
|
@load base/protocols/ftp
|
||||||
@TEST-EXEC: btest-rst-include notice.log
|
@load base/frameworks/sumstats
|
||||||
|
|
||||||
|
@load base/utils/time
|
||||||
|
|
||||||
|
module FTP;
|
||||||
|
|
||||||
|
export {
|
||||||
|
redef enum Notice::Type += {
|
||||||
|
## Indicates a host bruteforcing FTP logins by watching for too
|
||||||
|
## many rejected usernames or failed passwords.
|
||||||
|
Bruteforcing
|
||||||
|
};
|
||||||
|
|
||||||
|
## How many rejected usernames or passwords are required before being
|
||||||
|
## considered to be bruteforcing.
|
||||||
|
const bruteforce_threshold: double = 20 &redef;
|
||||||
|
|
||||||
|
## The time period in which the threshold needs to be crossed before
|
||||||
|
## being reset.
|
||||||
|
const bruteforce_measurement_interval = 15mins &redef;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
event bro_init()
|
||||||
|
{
|
||||||
|
local r1: SumStats::Reducer = [$stream="ftp.failed_auth", $apply=set(SumStats::UNIQUE), $unique_max=double_to_count(bruteforce_threshold+2)];
|
||||||
|
SumStats::create([$name="ftp-detect-bruteforcing",
|
||||||
|
$epoch=bruteforce_measurement_interval,
|
||||||
|
$reducers=set(r1),
|
||||||
|
$threshold_val(key: SumStats::Key, result: SumStats::Result) =
|
||||||
|
{
|
||||||
|
return result["ftp.failed_auth"]$num+0.0;
|
||||||
|
},
|
||||||
|
$threshold=bruteforce_threshold,
|
||||||
|
$threshold_crossed(key: SumStats::Key, result: SumStats::Result) =
|
||||||
|
{
|
||||||
|
local r = result["ftp.failed_auth"];
|
||||||
|
local dur = duration_to_mins_secs(r$end-r$begin);
|
||||||
|
local plural = r$unique>1 ? "s" : "";
|
||||||
|
local message = fmt("%s had %d failed logins on %d FTP server%s in %s", key$host, r$num, r$unique, plural, dur);
|
||||||
|
NOTICE([$note=FTP::Bruteforcing,
|
||||||
|
$src=key$host,
|
||||||
|
$msg=message,
|
||||||
|
$identifier=cat(key$host)]);
|
||||||
|
}]);
|
||||||
|
}
|
||||||
|
|
||||||
|
event ftp_reply(c: connection, code: count, msg: string, cont_resp: bool)
|
||||||
|
{
|
||||||
|
local cmd = c$ftp$cmdarg$cmd;
|
||||||
|
if ( cmd == "USER" || cmd == "PASS" )
|
||||||
|
{
|
||||||
|
if ( FTP::parse_ftp_reply_code(code)$x == 5 )
|
||||||
|
SumStats::observe("ftp.failed_auth", [$host=c$id$orig_h], [$str=cat(c$id$resp_h)]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.. code-block:: console
|
||||||
|
|
||||||
|
$ bro -r ftp/bruteforce.pcap protocols/ftp/detect-bruteforcing.bro
|
||||||
|
$ cat notice.log
|
||||||
|
#separator \x09
|
||||||
|
#set_separator ,
|
||||||
|
#empty_field (empty)
|
||||||
|
#unset_field -
|
||||||
|
#path notice
|
||||||
|
#open 2018-12-13-22-56-21
|
||||||
|
#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p fuid file_mime_type file_desc proto note msg sub src dst p n peer_descr actions suppress_for dropped remote_location.country_code remote_location.region remote_location.city remote_location.latitude remote_location.longitude
|
||||||
|
#types time string addr port addr port string string string enum enum string string addr addr port count string set[enum] interval bool string string string double double
|
||||||
|
1389721084.522861 - - - - - - - - - FTP::Bruteforcing 192.168.56.1 had 20 failed logins on 1 FTP server in 0m37s - 192.168.56.1 - - - - Notice::ACTION_LOG 3600.000000 F - - - - -
|
||||||
|
#close 2018-12-13-22-56-21
|
||||||
|
|
||||||
As a final note, the :doc:`detect-bruteforcing.bro
|
As a final note, the :doc:`detect-bruteforcing.bro
|
||||||
</scripts/policy/protocols/ftp/detect-bruteforcing.bro>` script above is
|
</scripts/policy/protocols/ftp/detect-bruteforcing.bro>` script above is
|
||||||
|
|
|
@ -19,20 +19,6 @@ extensions = []
|
||||||
# documentation root, use os.path.abspath to make it absolute, like shown here.
|
# documentation root, use os.path.abspath to make it absolute, like shown here.
|
||||||
sys.path.insert(0, os.path.abspath('sphinx_input/ext'))
|
sys.path.insert(0, os.path.abspath('sphinx_input/ext'))
|
||||||
|
|
||||||
# ----- Begin of BTest configuration. -----
|
|
||||||
btest = os.path.abspath("@CMAKE_SOURCE_DIR@/aux/btest")
|
|
||||||
brocut = os.path.abspath("@CMAKE_SOURCE_DIR@/build/aux/bro-aux/bro-cut")
|
|
||||||
bro = os.path.abspath("@CMAKE_SOURCE_DIR@/build/src")
|
|
||||||
|
|
||||||
os.environ["PATH"] += (":%s:%s/sphinx:%s:%s" % (btest, btest, bro, brocut))
|
|
||||||
sys.path.append(os.path.join(btest, "sphinx"))
|
|
||||||
|
|
||||||
extensions += ["btest-sphinx"]
|
|
||||||
|
|
||||||
btest_base="@CMAKE_SOURCE_DIR@/testing/btest"
|
|
||||||
btest_tests="doc/sphinx"
|
|
||||||
# ----- End of BTest configuration. -----
|
|
||||||
|
|
||||||
# ----- Begin of Broxygen configuration. -----
|
# ----- Begin of Broxygen configuration. -----
|
||||||
extensions += ["broxygen"]
|
extensions += ["broxygen"]
|
||||||
bro_binary = os.path.abspath("@CMAKE_SOURCE_DIR@/build/src/bro")
|
bro_binary = os.path.abspath("@CMAKE_SOURCE_DIR@/build/src/bro")
|
||||||
|
@ -49,9 +35,6 @@ os.environ["BROPATH"] = "@BROPATH@"
|
||||||
# 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', 'adapt-toc']
|
extensions += ['bro', 'rst_directive', 'sphinx.ext.todo', 'adapt-toc']
|
||||||
|
|
||||||
os.environ["BRO_SRC_ROOT"] = "@CMAKE_SOURCE_DIR@"
|
|
||||||
os.environ["DOC_ROOT"] = "@CMAKE_SOURCE_DIR@/doc"
|
|
||||||
|
|
||||||
# Add any paths that contain templates here, relative to this directory.
|
# Add any paths that contain templates here, relative to this directory.
|
||||||
templates_path = ['sphinx_input/_templates', 'sphinx_input/_static']
|
templates_path = ['sphinx_input/_templates', 'sphinx_input/_static']
|
||||||
|
|
||||||
|
@ -108,6 +91,8 @@ show_authors = True
|
||||||
# The name of the Pygments (syntax highlighting) style to use.
|
# The name of the Pygments (syntax highlighting) style to use.
|
||||||
pygments_style = 'sphinx'
|
pygments_style = 'sphinx'
|
||||||
|
|
||||||
|
highlight_language = 'none'
|
||||||
|
|
||||||
# A list of ignored prefixes for module index sorting.
|
# A list of ignored prefixes for module index sorting.
|
||||||
#modindex_common_prefix = []
|
#modindex_common_prefix = []
|
||||||
|
|
||||||
|
|
|
@ -296,11 +296,17 @@ Connecting to Peers
|
||||||
|
|
||||||
Bro can accept incoming connections by calling :bro:see:`Broker::listen`.
|
Bro can accept incoming connections by calling :bro:see:`Broker::listen`.
|
||||||
|
|
||||||
.. btest-include:: ${DOC_ROOT}/frameworks/broker/connecting-listener.bro
|
.. literalinclude:: broker/connecting-listener.bro
|
||||||
|
:caption: connecting-listener.bro
|
||||||
|
:language: bro
|
||||||
|
:linenos:
|
||||||
|
|
||||||
Bro can initiate outgoing connections by calling :bro:see:`Broker::peer`.
|
Bro can initiate outgoing connections by calling :bro:see:`Broker::peer`.
|
||||||
|
|
||||||
.. btest-include:: ${DOC_ROOT}/frameworks/broker/connecting-connector.bro
|
.. literalinclude:: broker/connecting-connector.bro
|
||||||
|
:caption: connecting-connector.bro
|
||||||
|
:language: bro
|
||||||
|
:linenos:
|
||||||
|
|
||||||
In either case, connection status updates are monitored via the
|
In either case, connection status updates are monitored via the
|
||||||
:bro:see:`Broker::peer_added` and :bro:see:`Broker::peer_lost` events.
|
:bro:see:`Broker::peer_added` and :bro:see:`Broker::peer_lost` events.
|
||||||
|
@ -317,7 +323,10 @@ more on how topics work and are chosen.
|
||||||
Use the :bro:see:`Broker::subscribe` function to subscribe to topics and
|
Use the :bro:see:`Broker::subscribe` function to subscribe to topics and
|
||||||
define any event handlers for events that peers will send.
|
define any event handlers for events that peers will send.
|
||||||
|
|
||||||
.. btest-include:: ${DOC_ROOT}/frameworks/broker/events-listener.bro
|
.. literalinclude:: broker/events-listener.bro
|
||||||
|
:caption: events-listener.bro
|
||||||
|
:language: bro
|
||||||
|
:linenos:
|
||||||
|
|
||||||
There are two different ways to send events.
|
There are two different ways to send events.
|
||||||
|
|
||||||
|
@ -333,7 +342,10 @@ whenever the event is called locally via the normal event invocation syntax.
|
||||||
When auto-publishing events, local event handlers for the event are called
|
When auto-publishing events, local event handlers for the event are called
|
||||||
in addition to sending the event to any subscribed peers.
|
in addition to sending the event to any subscribed peers.
|
||||||
|
|
||||||
.. btest-include:: ${DOC_ROOT}/frameworks/broker/events-connector.bro
|
.. literalinclude:: broker/events-connector.bro
|
||||||
|
:caption: events-connector.bro
|
||||||
|
:language: bro
|
||||||
|
:linenos:
|
||||||
|
|
||||||
Note that the subscription model is prefix-based, meaning that if you subscribe
|
Note that the subscription model is prefix-based, meaning that if you subscribe
|
||||||
to the "bro/events" topic prefix you would receive events that are published
|
to the "bro/events" topic prefix you would receive events that are published
|
||||||
|
@ -342,16 +354,25 @@ to topic names "bro/events/foo" and "bro/events/bar" but not "bro/misc".
|
||||||
Remote Logging
|
Remote Logging
|
||||||
--------------
|
--------------
|
||||||
|
|
||||||
.. btest-include:: ${DOC_ROOT}/frameworks/broker/testlog.bro
|
.. literalinclude:: broker/testlog.bro
|
||||||
|
:caption: testlog.bro
|
||||||
|
:language: bro
|
||||||
|
:linenos:
|
||||||
|
|
||||||
To toggle remote logs, redef :bro:see:`Log::enable_remote_logging`.
|
To toggle remote logs, redef :bro:see:`Log::enable_remote_logging`.
|
||||||
Use the :bro:see:`Broker::subscribe` function to advertise interest
|
Use the :bro:see:`Broker::subscribe` function to advertise interest
|
||||||
in logs written by peers. The topic names that Bro uses are determined by
|
in logs written by peers. The topic names that Bro uses are determined by
|
||||||
:bro:see:`Broker::log_topic`.
|
:bro:see:`Broker::log_topic`.
|
||||||
|
|
||||||
.. btest-include:: ${DOC_ROOT}/frameworks/broker/logs-listener.bro
|
.. literalinclude:: broker/logs-listener.bro
|
||||||
|
:caption: logs-listener.bro
|
||||||
|
:language: bro
|
||||||
|
:linenos:
|
||||||
|
|
||||||
.. btest-include:: ${DOC_ROOT}/frameworks/broker/logs-connector.bro
|
.. literalinclude:: broker/logs-connector.bro
|
||||||
|
:caption: logs-connector.bro
|
||||||
|
:language: bro
|
||||||
|
:linenos:
|
||||||
|
|
||||||
Note that logging events are only raised locally on the node that performs
|
Note that logging events are only raised locally on the node that performs
|
||||||
the :bro:see:`Log::write` and not automatically published to peers.
|
the :bro:see:`Log::write` and not automatically published to peers.
|
||||||
|
@ -379,9 +400,15 @@ use. E.g. In-memory versus SQLite for persistence.
|
||||||
Data stores also support expiration on a per-key basis using an amount of
|
Data stores also support expiration on a per-key basis using an amount of
|
||||||
time relative to the entry's last modification time.
|
time relative to the entry's last modification time.
|
||||||
|
|
||||||
.. btest-include:: ${DOC_ROOT}/frameworks/broker/stores-listener.bro
|
.. literalinclude:: broker/stores-listener.bro
|
||||||
|
:caption: stores-listener.bro
|
||||||
|
:language: bro
|
||||||
|
:linenos:
|
||||||
|
|
||||||
.. btest-include:: ${DOC_ROOT}/frameworks/broker/stores-connector.bro
|
.. literalinclude:: broker/stores-connector.bro
|
||||||
|
:caption: stores-connector.bro
|
||||||
|
:language: bro
|
||||||
|
:linenos:
|
||||||
|
|
||||||
Note that all data store queries must be made within Bro's asynchronous
|
Note that all data store queries must be made within Bro's asynchronous
|
||||||
``when`` statements and must specify a timeout block.
|
``when`` statements and must specify a timeout block.
|
||||||
|
|
|
@ -36,11 +36,23 @@ bytes have been transferred so far, and its MIME type.
|
||||||
|
|
||||||
Here's a simple example:
|
Here's a simple example:
|
||||||
|
|
||||||
.. btest-include:: ${DOC_ROOT}/frameworks/file_analysis_01.bro
|
.. literalinclude:: file_analysis_01.bro
|
||||||
|
:caption:
|
||||||
|
:language: bro
|
||||||
|
:linenos:
|
||||||
|
|
||||||
.. btest:: file-analysis-01
|
.. code-block:: console
|
||||||
|
|
||||||
@TEST-EXEC: btest-rst-cmd bro -r ${TRACES}/http/get.trace ${DOC_ROOT}/frameworks/file_analysis_01.bro
|
$ bro -r http/get.trace file_analysis_01.bro
|
||||||
|
file_state_remove
|
||||||
|
FakNcS1Jfe01uljb3
|
||||||
|
CHhAvVGS1DHFjwGM9
|
||||||
|
[orig_h=141.142.228.5, orig_p=59856/tcp, resp_h=192.150.187.43, resp_p=80/tcp]
|
||||||
|
HTTP
|
||||||
|
connection_state_remove
|
||||||
|
CHhAvVGS1DHFjwGM9
|
||||||
|
[orig_h=141.142.228.5, orig_p=59856/tcp, resp_h=192.150.187.43, resp_p=80/tcp]
|
||||||
|
HTTP
|
||||||
|
|
||||||
This doesn't perform any interesting analysis yet, but does highlight
|
This doesn't perform any interesting analysis yet, but does highlight
|
||||||
the similarity between analysis of connections and files. Connections
|
the similarity between analysis of connections and files. Connections
|
||||||
|
@ -71,11 +83,16 @@ explicit attachment decision.
|
||||||
Here's a simple example of how to use the MD5 file analyzer to
|
Here's a simple example of how to use the MD5 file analyzer to
|
||||||
calculate the MD5 of plain text files:
|
calculate the MD5 of plain text files:
|
||||||
|
|
||||||
.. btest-include:: ${DOC_ROOT}/frameworks/file_analysis_02.bro
|
.. literalinclude:: file_analysis_02.bro
|
||||||
|
:caption:
|
||||||
|
:language: bro
|
||||||
|
:linenos:
|
||||||
|
|
||||||
.. btest:: file-analysis-02
|
.. code-block:: console
|
||||||
|
|
||||||
@TEST-EXEC: btest-rst-cmd bro -r ${TRACES}/http/get.trace ${DOC_ROOT}/frameworks/file_analysis_02.bro
|
$ bro -r http/get.trace file_analysis_02.bro
|
||||||
|
new file, FakNcS1Jfe01uljb3
|
||||||
|
file_hash, FakNcS1Jfe01uljb3, md5, 397168fd09991a0e712254df7bc639ac
|
||||||
|
|
||||||
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`:
|
||||||
|
@ -109,19 +126,24 @@ in the same way it analyzes files that it sees coming over traffic from
|
||||||
a network interface it's monitoring. It only requires a call to
|
a network interface it's monitoring. It only requires a call to
|
||||||
:bro:see:`Input::add_analysis`:
|
:bro:see:`Input::add_analysis`:
|
||||||
|
|
||||||
.. btest-include:: ${DOC_ROOT}/frameworks/file_analysis_03.bro
|
.. literalinclude:: file_analysis_03.bro
|
||||||
|
:caption:
|
||||||
|
:language: bro
|
||||||
|
:linenos:
|
||||||
|
|
||||||
Note that the "source" field of :bro:see:`fa_file` corresponds to the
|
Note that the "source" field of :bro:see:`fa_file` corresponds to the
|
||||||
"name" field of :bro:see:`Input::AnalysisDescription` since that is what
|
"name" field of :bro:see:`Input::AnalysisDescription` since that is what
|
||||||
the input framework uses to uniquely identify an input stream.
|
the input framework uses to uniquely identify an input stream.
|
||||||
|
|
||||||
The output of the above script may be (assuming a file called "myfile"
|
Example output of the above script may be:
|
||||||
exists):
|
|
||||||
|
|
||||||
.. btest:: file-analysis-03
|
.. code-block:: console
|
||||||
|
|
||||||
@TEST-EXEC: echo "Hello world" > myfile
|
$ echo "Hello world" > myfile
|
||||||
@TEST-EXEC: btest-rst-cmd bro ${DOC_ROOT}/frameworks/file_analysis_03.bro
|
$ bro file_analysis_03.bro
|
||||||
|
new file, FZedLu4Ajcvge02jA8
|
||||||
|
file_hash, FZedLu4Ajcvge02jA8, md5, f0ef7081e1539ac00ef5b761b4fb01b3
|
||||||
|
file_state_remove
|
||||||
|
|
||||||
Nothing that special, but it at least verifies the MD5 file analyzer
|
Nothing that special, but it at least verifies the MD5 file analyzer
|
||||||
saw all the bytes of the input file and calculated the checksum
|
saw all the bytes of the input file and calculated the checksum
|
||||||
|
|
|
@ -38,12 +38,10 @@ You have to define a filter which specifies SQLite as the writer.
|
||||||
|
|
||||||
The following example code adds SQLite as a filter for the connection log:
|
The following example code adds SQLite as a filter for the connection log:
|
||||||
|
|
||||||
.. btest-include:: ${DOC_ROOT}/frameworks/sqlite-conn-filter.bro
|
.. literalinclude:: sqlite-conn-filter.bro
|
||||||
|
:caption:
|
||||||
.. btest:: sqlite-conn-filter-check
|
:language: bro
|
||||||
|
:linenos:
|
||||||
# Make sure this parses correctly at least.
|
|
||||||
@TEST-EXEC: bro ${DOC_ROOT}/frameworks/sqlite-conn-filter.bro
|
|
||||||
|
|
||||||
Bro will create the database file ``/var/db/conn.sqlite``, if it does not
|
Bro will create the database file ``/var/db/conn.sqlite``, if it does not
|
||||||
already exist. It will also create a table with the name ``conn`` (if it
|
already exist. It will also create a table with the name ``conn`` (if it
|
||||||
|
@ -115,12 +113,10 @@ The SQLite commands to create the schema are as follows::
|
||||||
After creating a file called ``hosts.sqlite`` with this content, we can
|
After creating a file called ``hosts.sqlite`` with this content, we can
|
||||||
read the resulting table into Bro:
|
read the resulting table into Bro:
|
||||||
|
|
||||||
.. btest-include:: ${DOC_ROOT}/frameworks/sqlite-read-table.bro
|
.. literalinclude:: sqlite-read-table.bro
|
||||||
|
:caption:
|
||||||
.. btest:: sqlite-read-table-check
|
:language: bro
|
||||||
|
:linenos:
|
||||||
# Make sure this parses correctly at least.
|
|
||||||
@TEST-EXEC: bro ${DOC_ROOT}/frameworks/sqlite-read-table.bro
|
|
||||||
|
|
||||||
Afterwards, that table can be used to check logins into hosts against
|
Afterwards, that table can be used to check logins into hosts against
|
||||||
the available userlist.
|
the available userlist.
|
||||||
|
@ -164,12 +160,10 @@ of files that are transmitted over the network. For each hash, a SQL-query
|
||||||
is run against SQLite. If the query returns with a result, we had a hit
|
is run against SQLite. If the query returns with a result, we had a hit
|
||||||
against our malware-database and output the matching hash.
|
against our malware-database and output the matching hash.
|
||||||
|
|
||||||
.. btest-include:: ${DOC_ROOT}/frameworks/sqlite-read-events.bro
|
.. literalinclude:: sqlite-read-events.bro
|
||||||
|
:caption:
|
||||||
.. btest:: sqlite-read-events-check
|
:language: bro
|
||||||
|
:linenos:
|
||||||
# Make sure this parses correctly at least.
|
|
||||||
@TEST-EXEC: bro ${DOC_ROOT}/frameworks/sqlite-read-events.bro
|
|
||||||
|
|
||||||
If you run this script against the trace in
|
If you run this script against the trace in
|
||||||
``testing/btest/Traces/ftp/ipv4.trace``, you will get one hit.
|
``testing/btest/Traces/ftp/ipv4.trace``, you will get one hit.
|
||||||
|
|
|
@ -133,17 +133,37 @@ start sending the rules to the added backend(s). To give a very simple example,
|
||||||
the following script will simply block the traffic of all connections that it
|
the following script will simply block the traffic of all connections that it
|
||||||
sees being established:
|
sees being established:
|
||||||
|
|
||||||
.. btest-include:: ${DOC_ROOT}/frameworks/netcontrol-1-drop-with-debug.bro
|
.. literalinclude:: netcontrol-1-drop-with-debug.bro
|
||||||
|
:caption:
|
||||||
|
:language: bro
|
||||||
|
:linenos:
|
||||||
|
|
||||||
Running this script on a file containing one connection will cause the debug
|
Running this script on a file containing one connection will cause the debug
|
||||||
plugin to print one line to the standard output, which contains information
|
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:
|
||||||
|
|
||||||
.. btest:: netcontrol-1-drop-with-debug.bro
|
.. code-block:: console
|
||||||
|
|
||||||
@TEST-EXEC: btest-rst-cmd bro -C -r ${TRACES}/tls/ecdhe.pcap ${DOC_ROOT}/frameworks/netcontrol-1-drop-with-debug.bro
|
$ bro -C -r tls/ecdhe.pcap netcontrol-1-drop-with-debug.bro
|
||||||
@TEST-EXEC: btest-rst-cmd cat netcontrol.log
|
netcontrol debug (Debug-All): init
|
||||||
|
netcontrol debug (Debug-All): add_rule: [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={\x0a\x0a}, _active_plugin_ids={\x0a\x0a}, _no_expire_plugins={\x0a\x0a}, _added=F]
|
||||||
|
|
||||||
|
$ cat netcontrol.log
|
||||||
|
#separator \x09
|
||||||
|
#set_separator ,
|
||||||
|
#empty_field (empty)
|
||||||
|
#unset_field -
|
||||||
|
#path netcontrol
|
||||||
|
#open 2018-12-14-18-50-53
|
||||||
|
#fields ts rule_id category cmd state action target entity_type entity mod msg priority expire location plugin
|
||||||
|
#types time string enum string enum string enum string string string string int interval string string
|
||||||
|
0.000000 - NetControl::MESSAGE - - - - - - - activating plugin with priority 0 - - - Debug-All
|
||||||
|
0.000000 - NetControl::MESSAGE - - - - - - - activation finished - - - Debug-All
|
||||||
|
0.000000 - NetControl::MESSAGE - - - - - - - plugin initialization done - - - -
|
||||||
|
1398529018.678276 2 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::CONNECTION 192.168.18.50/56981<->74.125.239.97/443 - - 0 20.000000 - Debug-All
|
||||||
|
1398529018.678276 2 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::CONNECTION 192.168.18.50/56981<->74.125.239.97/443 - - 0 20.000000 - Debug-All
|
||||||
|
#close 2018-12-14-18-50-53
|
||||||
|
|
||||||
In our case, `netcontrol.log` contains several :bro:see:`NetControl::MESSAGE`
|
In our case, `netcontrol.log` contains several :bro:see:`NetControl::MESSAGE`
|
||||||
entries, which show that the debug plugin has been initialized and added.
|
entries, which show that the debug plugin has been initialized and added.
|
||||||
|
@ -159,39 +179,99 @@ 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:
|
||||||
|
|
||||||
.. btest:: netcontrol-1-drop-with-debug.bro
|
.. code-block:: console
|
||||||
|
|
||||||
@TEST-EXEC: btest-rst-cmd cat netcontrol_drop.log
|
$ cat netcontrol_drop.log
|
||||||
|
#separator \x09
|
||||||
|
#set_separator ,
|
||||||
|
#empty_field (empty)
|
||||||
|
#unset_field -
|
||||||
|
#path netcontrol_drop
|
||||||
|
#open 2018-12-14-18-50-53
|
||||||
|
#fields ts rule_id orig_h orig_p resp_h resp_p expire location
|
||||||
|
#types time string addr port addr port interval string
|
||||||
|
1398529018.678276 2 192.168.18.50 56981 74.125.239.97 443 20.000000 -
|
||||||
|
#close 2018-12-14-18-50-53
|
||||||
|
|
||||||
While this example of blocking all connections is usually not very useful, the
|
While this example of blocking all connections is usually not very useful, the
|
||||||
high-level API gives an easy way to take action, for example when a host is
|
high-level API gives an easy way to take action, for example when a host is
|
||||||
identified doing some harmful activity. To give a more realistic example, the
|
identified doing some harmful activity. To give a more realistic example, the
|
||||||
following code automatically blocks a recognized SSH guesser:
|
following code automatically blocks a recognized SSH guesser:
|
||||||
|
|
||||||
.. btest-include:: ${DOC_ROOT}/frameworks/netcontrol-2-ssh-guesser.bro
|
.. literalinclude:: netcontrol-2-ssh-guesser.bro
|
||||||
|
:caption:
|
||||||
|
:language: bro
|
||||||
|
:linenos:
|
||||||
|
|
||||||
.. btest:: netcontrol-2-ssh-guesser.bro
|
.. code-block:: console
|
||||||
|
|
||||||
@TEST-EXEC: btest-rst-cmd bro -C -r ${TRACES}/ssh/sshguess.pcap ${DOC_ROOT}/frameworks/netcontrol-2-ssh-guesser.bro
|
$ bro -C -r ssh/sshguess.pcap netcontrol-2-ssh-guesser.bro
|
||||||
@TEST-EXEC: btest-rst-cmd cat netcontrol.log
|
netcontrol debug (Debug-All): init
|
||||||
|
netcontrol debug (Debug-All): add_rule: [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[ty=NetControl::ADDRESS, conn=<uninitialized>, flow=<uninitialized>, ip=192.168.56.1/32, mac=<uninitialized>], expire=1.0 hr, priority=0, location=, out_port=<uninitialized>, mod=<uninitialized>, id=2, cid=2, _plugin_ids={\x0a\x0a}, _active_plugin_ids={\x0a\x0a}, _no_expire_plugins={\x0a\x0a}, _added=F]
|
||||||
|
|
||||||
|
$ cat netcontrol.log
|
||||||
|
#separator \x09
|
||||||
|
#set_separator ,
|
||||||
|
#empty_field (empty)
|
||||||
|
#unset_field -
|
||||||
|
#path netcontrol
|
||||||
|
#open 2018-12-14-18-50-54
|
||||||
|
#fields ts rule_id category cmd state action target entity_type entity mod msg priority expire location plugin
|
||||||
|
#types time string enum string enum string enum string string string string int interval string string
|
||||||
|
0.000000 - NetControl::MESSAGE - - - - - - - activating plugin with priority 0 - - - Debug-All
|
||||||
|
0.000000 - NetControl::MESSAGE - - - - - - - activation finished - - - Debug-All
|
||||||
|
0.000000 - NetControl::MESSAGE - - - - - - - plugin initialization done - - - -
|
||||||
|
1427726759.303199 2 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.56.1/32 - - 0 3600.000000 - Debug-All
|
||||||
|
1427726759.303199 2 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.56.1/32 - - 0 3600.000000 - Debug-All
|
||||||
|
#close 2018-12-14-18-50-54
|
||||||
|
|
||||||
Note that in this case, instead of calling NetControl directly, we also can use
|
Note that in this case, instead of calling NetControl directly, we also can use
|
||||||
the :bro:see:`Notice::ACTION_DROP` action of the notice framework:
|
the :bro:see:`Notice::ACTION_DROP` action of the notice framework:
|
||||||
|
|
||||||
.. btest-include:: ${DOC_ROOT}/frameworks/netcontrol-3-ssh-guesser.bro
|
.. literalinclude:: netcontrol-3-ssh-guesser.bro
|
||||||
|
:caption:
|
||||||
|
:language: bro
|
||||||
|
:linenos:
|
||||||
|
|
||||||
.. btest:: netcontrol-3-ssh-guesser.bro
|
.. code-block:: console
|
||||||
|
|
||||||
@TEST-EXEC: btest-rst-cmd bro -C -r ${TRACES}/ssh/sshguess.pcap ${DOC_ROOT}/frameworks/netcontrol-3-ssh-guesser.bro
|
$ bro -C -r ssh/sshguess.pcap netcontrol-3-ssh-guesser.bro
|
||||||
@TEST-EXEC: btest-rst-cmd cat netcontrol.log
|
netcontrol debug (Debug-All): init
|
||||||
|
netcontrol debug (Debug-All): add_rule: [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[ty=NetControl::ADDRESS, conn=<uninitialized>, flow=<uninitialized>, ip=192.168.56.1/32, mac=<uninitialized>], expire=10.0 mins, priority=0, location=ACTION_DROP: T, out_port=<uninitialized>, mod=<uninitialized>, id=2, cid=2, _plugin_ids={\x0a\x0a}, _active_plugin_ids={\x0a\x0a}, _no_expire_plugins={\x0a\x0a}, _added=F]
|
||||||
|
|
||||||
|
$ cat netcontrol.log
|
||||||
|
#separator \x09
|
||||||
|
#set_separator ,
|
||||||
|
#empty_field (empty)
|
||||||
|
#unset_field -
|
||||||
|
#path netcontrol
|
||||||
|
#open 2018-12-14-18-50-55
|
||||||
|
#fields ts rule_id category cmd state action target entity_type entity mod msg priority expire location plugin
|
||||||
|
#types time string enum string enum string enum string string string string int interval string string
|
||||||
|
0.000000 - NetControl::MESSAGE - - - - - - - activating plugin with priority 0 - - - Debug-All
|
||||||
|
0.000000 - NetControl::MESSAGE - - - - - - - activation finished - - - Debug-All
|
||||||
|
0.000000 - NetControl::MESSAGE - - - - - - - plugin initialization done - - - -
|
||||||
|
1427726759.303199 2 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.56.1/32 - - 0 600.000000 ACTION_DROP: T Debug-All
|
||||||
|
1427726759.303199 2 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.56.1/32 - - 0 600.000000 ACTION_DROP: T Debug-All
|
||||||
|
#close 2018-12-14-18-50-55
|
||||||
|
|
||||||
Using the :bro:see:`Notice::ACTION_DROP` action of the notice framework also
|
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:
|
||||||
|
|
||||||
.. btest:: netcontrol-3-ssh-guesser.bro
|
.. code-block:: console
|
||||||
|
|
||||||
@TEST-EXEC: btest-rst-cmd cat notice.log
|
$ cat notice.log
|
||||||
|
#separator \x09
|
||||||
|
#set_separator ,
|
||||||
|
#empty_field (empty)
|
||||||
|
#unset_field -
|
||||||
|
#path notice
|
||||||
|
#open 2018-12-14-18-50-55
|
||||||
|
#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p fuid file_mime_type file_desc proto note msg sub src dst p n peer_descr actions suppress_for dropped remote_location.country_code remote_location.region remote_location.city remote_location.latitude remote_location.longitude
|
||||||
|
#types time string addr port addr port string string string enum enum string string addr addr port count string set[enum] interval bool string string string double double
|
||||||
|
1427726759.303199 - - - - - - - - - SSH::Password_Guessing 192.168.56.1 appears to be guessing SSH passwords (seen in 10 connections). Sampled servers: 192.168.56.103, 192.168.56.103, 192.168.56.103, 192.168.56.103, 192.168.56.103 192.168.56.1 - - - - Notice::ACTION_DROP,Notice::ACTION_LOG 3600.000000 F - - - - -
|
||||||
|
#close 2018-12-14-18-50-55
|
||||||
|
|
||||||
Rule API
|
Rule API
|
||||||
--------
|
--------
|
||||||
|
@ -241,12 +321,32 @@ that the NetControl function has additional functionality, e.g. for logging.
|
||||||
Once again, we are going to test our function with a simple example that simply
|
Once again, we are going to test our function with a simple example that simply
|
||||||
drops all connections on the network:
|
drops all connections on the network:
|
||||||
|
|
||||||
.. btest-include:: ${DOC_ROOT}/frameworks/netcontrol-4-drop.bro
|
.. literalinclude:: netcontrol-4-drop.bro
|
||||||
|
:caption:
|
||||||
|
:language: bro
|
||||||
|
:linenos:
|
||||||
|
|
||||||
.. btest:: netcontrol-4-drop.bro
|
.. code-block:: console
|
||||||
|
|
||||||
@TEST-EXEC: btest-rst-cmd bro -C -r ${TRACES}/tls/ecdhe.pcap ${DOC_ROOT}/frameworks/netcontrol-4-drop.bro
|
$ bro -C -r tls/ecdhe.pcap netcontrol-4-drop.bro
|
||||||
@TEST-EXEC: btest-rst-cmd cat netcontrol.log
|
netcontrol debug (Debug-All): init
|
||||||
|
netcontrol debug (Debug-All): add_rule: [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=<uninitialized>, out_port=<uninitialized>, mod=<uninitialized>, id=2, cid=2, _plugin_ids={\x0a\x0a}, _active_plugin_ids={\x0a\x0a}, _no_expire_plugins={\x0a\x0a}, _added=F]
|
||||||
|
|
||||||
|
$ cat netcontrol.log
|
||||||
|
#separator \x09
|
||||||
|
#set_separator ,
|
||||||
|
#empty_field (empty)
|
||||||
|
#unset_field -
|
||||||
|
#path netcontrol
|
||||||
|
#open 2018-12-14-18-50-55
|
||||||
|
#fields ts rule_id category cmd state action target entity_type entity mod msg priority expire location plugin
|
||||||
|
#types time string enum string enum string enum string string string string int interval string string
|
||||||
|
0.000000 - NetControl::MESSAGE - - - - - - - activating plugin with priority 0 - - - Debug-All
|
||||||
|
0.000000 - NetControl::MESSAGE - - - - - - - activation finished - - - Debug-All
|
||||||
|
0.000000 - NetControl::MESSAGE - - - - - - - plugin initialization done - - - -
|
||||||
|
1398529018.678276 2 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::CONNECTION 192.168.18.50/56981<->74.125.239.97/443 - - 0 20.000000 - Debug-All
|
||||||
|
1398529018.678276 2 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::CONNECTION 192.168.18.50/56981<->74.125.239.97/443 - - 0 20.000000 - Debug-All
|
||||||
|
#close 2018-12-14-18-50-55
|
||||||
|
|
||||||
The last example shows that :bro:see:`NetControl::add_rule` returns a string
|
The last example shows that :bro:see:`NetControl::add_rule` returns a string
|
||||||
identifier that is unique for each rule (uniqueness is not preserved across
|
identifier that is unique for each rule (uniqueness is not preserved across
|
||||||
|
@ -281,11 +381,16 @@ discarded before further processing.
|
||||||
Here is a simple example which tells Bro to discard all rules for connections
|
Here is a simple example which tells Bro to discard all rules for connections
|
||||||
originating from the 192.168.* network:
|
originating from the 192.168.* network:
|
||||||
|
|
||||||
.. btest-include:: ${DOC_ROOT}/frameworks/netcontrol-5-hook.bro
|
.. literalinclude:: netcontrol-5-hook.bro
|
||||||
|
:caption:
|
||||||
|
:language: bro
|
||||||
|
:linenos:
|
||||||
|
|
||||||
.. btest:: netcontrol-5-hook.bro
|
.. code-block:: console
|
||||||
|
|
||||||
@TEST-EXEC: btest-rst-cmd bro -C -r ${TRACES}/tls/ecdhe.pcap ${DOC_ROOT}/frameworks/netcontrol-5-hook.bro
|
$ bro -C -r tls/ecdhe.pcap netcontrol-5-hook.bro
|
||||||
|
netcontrol debug (Debug-All): init
|
||||||
|
Ignored connection from, 192.168.18.50
|
||||||
|
|
||||||
NetControl Events
|
NetControl Events
|
||||||
*****************
|
*****************
|
||||||
|
@ -355,11 +460,18 @@ Here is a simple example, which uses a trace that contains two connections from
|
||||||
the same IP address. After the first connection, the script recognizes that the
|
the same IP address. After the first connection, the script recognizes that the
|
||||||
address is already blocked in the second connection.
|
address is already blocked in the second connection.
|
||||||
|
|
||||||
.. btest-include:: ${DOC_ROOT}/frameworks/netcontrol-6-find.bro
|
.. literalinclude:: netcontrol-6-find.bro
|
||||||
|
:caption:
|
||||||
|
:language: bro
|
||||||
|
:linenos:
|
||||||
|
|
||||||
.. btest:: netcontrol-6-find.bro
|
.. code-block:: console
|
||||||
|
|
||||||
@TEST-EXEC: btest-rst-cmd bro -C -r ${TRACES}/tls/google-duplicate.trace ${DOC_ROOT}/frameworks/netcontrol-6-find.bro
|
$ bro -C -r tls/google-duplicate.trace netcontrol-6-find.bro
|
||||||
|
netcontrol debug (Debug-All): init
|
||||||
|
netcontrol debug (Debug-All): add_rule: [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[ty=NetControl::CONNECTION, conn=[orig_h=192.168.4.149, orig_p=60623/tcp, resp_h=74.125.239.129, 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={\x0a\x0a}, _active_plugin_ids={\x0a\x0a}, _no_expire_plugins={\x0a\x0a}, _added=F]
|
||||||
|
Rule added
|
||||||
|
Rule already exists
|
||||||
|
|
||||||
Notice that the functions return vectors because it is possible that several
|
Notice that the functions return vectors because it is possible that several
|
||||||
rules exist simultaneously that affect one IP; either there could be
|
rules exist simultaneously that affect one IP; either there could be
|
||||||
|
@ -402,11 +514,16 @@ release is contained in the file
|
||||||
Using catch and release in your scripts is easy; just use
|
Using catch and release in your scripts is easy; just use
|
||||||
:bro:see:`NetControl::drop_address_catch_release` like in this example:
|
:bro:see:`NetControl::drop_address_catch_release` like in this example:
|
||||||
|
|
||||||
.. btest-include:: ${DOC_ROOT}/frameworks/netcontrol-7-catch-release.bro
|
.. literalinclude:: netcontrol-7-catch-release.bro
|
||||||
|
:caption:
|
||||||
|
:language: bro
|
||||||
|
:linenos:
|
||||||
|
|
||||||
.. btest:: netcontrol-7-catch-release.bro
|
.. code-block:: console
|
||||||
|
|
||||||
@TEST-EXEC: btest-rst-cmd bro -C -r ${TRACES}/tls/ecdhe.pcap ${DOC_ROOT}/frameworks/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): add_rule: [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[ty=NetControl::ADDRESS, conn=<uninitialized>, flow=<uninitialized>, ip=192.168.18.50/32, mac=<uninitialized>], expire=10.0 mins, priority=0, location=, out_port=<uninitialized>, mod=<uninitialized>, id=2, cid=2, _plugin_ids={\x0a\x0a}, _active_plugin_ids={\x0a\x0a}, _no_expire_plugins={\x0a\x0a}, _added=F]
|
||||||
|
|
||||||
Note that you do not have to provide the block time for catch and release;
|
Note that you do not have to provide the block time for catch and release;
|
||||||
instead, catch and release uses the time intervals specified in
|
instead, catch and release uses the time intervals specified in
|
||||||
|
@ -418,9 +535,20 @@ 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):
|
||||||
|
|
||||||
.. btest:: netcontrol-7-catch-release.bro
|
.. code-block:: console
|
||||||
|
|
||||||
@TEST-EXEC: btest-rst-cmd cat netcontrol_catch_release.log
|
$ cat netcontrol_catch_release.log
|
||||||
|
#separator \x09
|
||||||
|
#set_separator ,
|
||||||
|
#empty_field (empty)
|
||||||
|
#unset_field -
|
||||||
|
#path netcontrol_catch_release
|
||||||
|
#open 2018-12-14-18-50-58
|
||||||
|
#fields ts rule_id ip action block_interval watch_interval blocked_until watched_until num_blocked location message
|
||||||
|
#types time string addr enum interval interval time time count string string
|
||||||
|
1398529018.678276 2 192.168.18.50 NetControl::DROP 600.000000 3600.000000 1398529618.678276 1398532618.678276 1 - -
|
||||||
|
1398529018.678276 2 192.168.18.50 NetControl::DROPPED 600.000000 3600.000000 1398529618.678276 1398532618.678276 1 - -
|
||||||
|
#close 2018-12-14-18-50-58
|
||||||
|
|
||||||
In addition to the blocking function, catch and release comes with the
|
In addition to the blocking function, catch and release comes with the
|
||||||
:bro:see:`NetControl::get_catch_release_info` function to
|
:bro:see:`NetControl::get_catch_release_info` function to
|
||||||
|
@ -531,27 +659,65 @@ the 192.168.17.0/24 network; all other rules will be passed on to the debug
|
||||||
plugin. We manually block a few addresses in the
|
plugin. We manually block a few addresses in the
|
||||||
:bro:see:`NetControl::init_done` event to verify the correct functionality.
|
:bro:see:`NetControl::init_done` event to verify the correct functionality.
|
||||||
|
|
||||||
.. btest-include:: ${DOC_ROOT}/frameworks/netcontrol-8-multiple.bro
|
.. literalinclude:: netcontrol-8-multiple.bro
|
||||||
|
:caption:
|
||||||
|
:language: bro
|
||||||
|
:linenos:
|
||||||
|
|
||||||
.. btest:: netcontrol-8-multiple.bro
|
.. code-block:: console
|
||||||
|
|
||||||
@TEST-EXEC: btest-rst-cmd bro ${DOC_ROOT}/frameworks/netcontrol-8-multiple.bro
|
$ bro netcontrol-8-multiple.bro
|
||||||
|
netcontrol debug (Debug-All): init
|
||||||
|
netcontrol debug (Debug-All): add_rule: [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[ty=NetControl::ADDRESS, conn=<uninitialized>, flow=<uninitialized>, ip=192.168.17.2/32, mac=<uninitialized>], expire=1.0 min, priority=0, location=, out_port=<uninitialized>, mod=<uninitialized>, id=3, cid=3, _plugin_ids={\x0a\x0a}, _active_plugin_ids={\x0a\x0a}, _no_expire_plugins={\x0a\x0a}, _added=F]
|
||||||
|
|
||||||
As you can see, only the single block affecting the 192.168.17.0/24 network is
|
As you can see, only the single block affecting the 192.168.17.0/24 network is
|
||||||
output to the command line. The other two lines are handled by the OpenFlow
|
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:
|
||||||
|
|
||||||
.. btest:: netcontrol-8-multiple.bro
|
.. code-block:: console
|
||||||
|
|
||||||
@TEST-EXEC: btest-rst-cmd cat netcontrol.log
|
$ cat netcontrol.log
|
||||||
|
#separator \x09
|
||||||
|
#set_separator ,
|
||||||
|
#empty_field (empty)
|
||||||
|
#unset_field -
|
||||||
|
#path netcontrol
|
||||||
|
#open 2018-12-14-18-50-58
|
||||||
|
#fields ts rule_id category cmd state action target entity_type entity mod msg priority expire location plugin
|
||||||
|
#types time string enum string enum string enum string string string string int interval string string
|
||||||
|
1544813458.913148 - NetControl::MESSAGE - - - - - - - activating plugin with priority 0 - - - Debug-All
|
||||||
|
1544813458.913148 - NetControl::MESSAGE - - - - - - - activation finished - - - Debug-All
|
||||||
|
1544813458.913148 - NetControl::MESSAGE - - - - - - - activating plugin with priority 10 - - - Openflow-Log-42
|
||||||
|
1544813458.913148 - NetControl::MESSAGE - - - - - - - activation finished - - - Openflow-Log-42
|
||||||
|
1544813458.913148 - NetControl::MESSAGE - - - - - - - plugin initialization done - - - -
|
||||||
|
1544813458.913148 2 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 10.0.0.1/32 - - 0 60.000000 - Openflow-Log-42
|
||||||
|
1544813458.913148 3 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.17.2/32 - - 0 60.000000 - Debug-All
|
||||||
|
1544813458.913148 4 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.2/32 - - 0 60.000000 - Openflow-Log-42
|
||||||
|
1544813458.913148 3 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.17.2/32 - - 0 60.000000 - Debug-All
|
||||||
|
1544813458.913148 2 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 10.0.0.1/32 - - 0 60.000000 - Openflow-Log-42
|
||||||
|
1544813458.913148 4 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.2/32 - - 0 60.000000 - Openflow-Log-42
|
||||||
|
#close 2018-12-14-18-50-58
|
||||||
|
|
||||||
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:
|
||||||
|
|
||||||
.. btest:: netcontrol-8-multiple.bro
|
.. code-block:: console
|
||||||
|
|
||||||
@TEST-EXEC: btest-rst-cmd cat openflow.log
|
$ cat openflow.log
|
||||||
|
#separator \x09
|
||||||
|
#set_separator ,
|
||||||
|
#empty_field (empty)
|
||||||
|
#unset_field -
|
||||||
|
#path openflow
|
||||||
|
#open 2018-12-14-18-50-58
|
||||||
|
#fields ts dpid match.in_port match.dl_src match.dl_dst match.dl_vlan match.dl_vlan_pcp match.dl_type match.nw_tos match.nw_proto match.nw_src match.nw_dst match.tp_src match.tp_dst flow_mod.cookie flow_mod.table_id flow_mod.command flow_mod.idle_timeout flow_mod.hard_timeout flow_mod.priority flow_mod.out_port flow_mod.out_group flow_mod.flags flow_mod.actions.out_ports flow_mod.actions.vlan_vid flow_mod.actions.vlan_pcp flow_mod.actions.vlan_strip flow_mod.actions.dl_src flow_mod.actions.dl_dst flow_mod.actions.nw_tos flow_mod.actions.nw_src flow_mod.actions.nw_dst flow_mod.actions.tp_src flow_mod.actions.tp_dst
|
||||||
|
#types time count count string string count count count count count subnet subnet count count count count enum count count count count count count vector[count] count count bool string string count addr addr count count
|
||||||
|
1544813458.913148 42 - - - - - 2048 - - 10.0.0.1/32 - - - 4398046511108 - OpenFlow::OFPFC_ADD 0 60 0 - - 1 (empty) - - F - - - - - - -
|
||||||
|
1544813458.913148 42 - - - - - 2048 - - - 10.0.0.1/32 - - 4398046511109 - OpenFlow::OFPFC_ADD 0 60 0 - - 1 (empty) - - F - - - - - - -
|
||||||
|
1544813458.913148 42 - - - - - 2048 - - 192.168.18.2/32 - - - 4398046511112 - OpenFlow::OFPFC_ADD 0 60 0 - - 1 (empty) - - F - - - - - - -
|
||||||
|
1544813458.913148 42 - - - - - 2048 - - - 192.168.18.2/32 - - 4398046511113 - OpenFlow::OFPFC_ADD 0 60 0 - - 1 (empty) - - F - - - - - - -
|
||||||
|
#close 2018-12-14-18-50-58
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
|
@ -613,16 +779,29 @@ raise the :bro:see:`NetControl::rule_added` and
|
||||||
:bro:see:`NetControl::rule_removed` events in your plugin to let NetControl know
|
:bro:see:`NetControl::rule_removed` events in your plugin to let NetControl know
|
||||||
when a rule was added and removed successfully.
|
when a rule was added and removed successfully.
|
||||||
|
|
||||||
.. btest-include:: ${DOC_ROOT}/frameworks/netcontrol-9-skeleton.bro
|
.. literalinclude:: netcontrol-9-skeleton.bro
|
||||||
|
:caption:
|
||||||
|
:language: bro
|
||||||
|
:linenos:
|
||||||
|
|
||||||
This example is already fully functional and we can use it with a script similar
|
This example is already fully functional and we can use it with a script similar
|
||||||
to our very first example:
|
to our very first example:
|
||||||
|
|
||||||
.. btest-include:: ${DOC_ROOT}/frameworks/netcontrol-10-use-skeleton.bro
|
.. literalinclude:: netcontrol-10-use-skeleton.bro
|
||||||
|
:caption:
|
||||||
|
:language: bro
|
||||||
|
:linenos:
|
||||||
|
|
||||||
.. btest:: netcontrol-9-skeleton.bro
|
.. code-block:: console
|
||||||
|
|
||||||
@TEST-EXEC: btest-rst-cmd bro -C -r ${TRACES}/tls/ecdhe.pcap ${DOC_ROOT}/frameworks/netcontrol-9-skeleton.bro ${DOC_ROOT}/frameworks/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={
|
||||||
|
|
||||||
|
}, _active_plugin_ids={
|
||||||
|
|
||||||
|
}, _no_expire_plugins={
|
||||||
|
|
||||||
|
}, _added=F]
|
||||||
|
|
||||||
If you want to write your own plugins, it will be worthwhile to look at the
|
If you want to write your own plugins, it will be worthwhile to look at the
|
||||||
plugins that ship with the NetControl framework to see how they define the
|
plugins that ship with the NetControl framework to see how they define the
|
||||||
|
|
|
@ -91,12 +91,25 @@ Here's a simple example which tells Bro to send an email for all notices of
|
||||||
type :bro:see:`SSH::Password_Guessing` if the guesser attempted to log in to
|
type :bro:see:`SSH::Password_Guessing` if the guesser attempted to log in to
|
||||||
the server at 192.168.56.103:
|
the server at 192.168.56.103:
|
||||||
|
|
||||||
.. btest-include:: ${DOC_ROOT}/frameworks/notice_ssh_guesser.bro
|
.. literalinclude:: notice_ssh_guesser.bro
|
||||||
|
:caption:
|
||||||
|
:language: bro
|
||||||
|
:linenos:
|
||||||
|
|
||||||
.. btest:: notice_ssh_guesser.bro
|
.. code-block:: console
|
||||||
|
|
||||||
@TEST-EXEC: btest-rst-cmd bro -C -r ${TRACES}/ssh/sshguess.pcap ${DOC_ROOT}/frameworks/notice_ssh_guesser.bro
|
$ bro -C -r ssh/sshguess.pcap notice_ssh_guesser.bro
|
||||||
@TEST-EXEC: btest-rst-cmd cat notice.log
|
$ cat notice.log
|
||||||
|
#separator \x09
|
||||||
|
#set_separator ,
|
||||||
|
#empty_field (empty)
|
||||||
|
#unset_field -
|
||||||
|
#path notice
|
||||||
|
#open 2018-12-13-22-56-35
|
||||||
|
#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p fuid file_mime_type file_desc proto note msg sub src dst p n peer_descr actions suppress_for dropped remote_location.country_code remote_location.region remote_location.city remote_location.latitude remote_location.longitude
|
||||||
|
#types time string addr port addr port string string string enum enum string string addr addr port count string set[enum] interval bool string string string double double
|
||||||
|
1427726759.303199 - - - - - - - - - SSH::Password_Guessing 192.168.56.1 appears to be guessing SSH passwords (seen in 10 connections). Sampled servers: 192.168.56.103, 192.168.56.103, 192.168.56.103, 192.168.56.103, 192.168.56.103 192.168.56.1 - - - - Notice::ACTION_EMAIL,Notice::ACTION_LOG 3600.000000 F - - - - -
|
||||||
|
#close 2018-12-13-22-56-35
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
|
|
|
@ -73,15 +73,18 @@ Sumstats provides a simple way of approaching the problem of trying to count
|
||||||
the number of connections over a given time interval. Here is a script with
|
the number of connections over a given time interval. Here is a script with
|
||||||
inline documentation that does this with the Sumstats framework:
|
inline documentation that does this with the Sumstats framework:
|
||||||
|
|
||||||
.. btest-include:: ${DOC_ROOT}/frameworks/sumstats-countconns.bro
|
.. literalinclude:: sumstats-countconns.bro
|
||||||
|
:caption:
|
||||||
|
:language: bro
|
||||||
|
:linenos:
|
||||||
|
|
||||||
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:
|
||||||
|
|
||||||
.. btest:: sumstats-countconns
|
.. code-block:: console
|
||||||
|
|
||||||
@TEST-EXEC: btest-rst-cmd bro -r ${TRACES}/workshop_2011_browse.trace ${DOC_ROOT}/frameworks/sumstats-countconns.bro
|
|
||||||
|
|
||||||
|
$ bro -r workshop_2011_browse.trace sumstats-countconns.bro
|
||||||
|
Number of connections established: 6
|
||||||
|
|
||||||
Toy scan detection
|
Toy scan detection
|
||||||
------------------
|
------------------
|
||||||
|
@ -92,14 +95,18 @@ demonstrate how thresholding works in Sumstats and is not meant to be a
|
||||||
real-world functional example, that is left to the
|
real-world functional example, that is left to the
|
||||||
:doc:`/scripts/policy/misc/scan.bro` script that is included with Bro.
|
:doc:`/scripts/policy/misc/scan.bro` script that is included with Bro.
|
||||||
|
|
||||||
.. btest-include:: ${DOC_ROOT}/frameworks/sumstats-toy-scan.bro
|
.. literalinclude:: sumstats-toy-scan.bro
|
||||||
|
:caption:
|
||||||
|
:language: bro
|
||||||
|
:linenos:
|
||||||
|
|
||||||
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:
|
||||||
|
|
||||||
.. btest:: sumstats-toy-scan
|
.. code-block:: console
|
||||||
|
|
||||||
@TEST-EXEC: btest-rst-cmd bro -r ${TRACES}/nmap-vsn.trace ${DOC_ROOT}/frameworks/sumstats-toy-scan.bro
|
$ bro -r nmap-vsn.trace sumstats-toy-scan.bro
|
||||||
|
192.168.1.71 attempted 5 or more connections
|
||||||
|
|
||||||
It seems the host running nmap was detected!
|
It seems the host running nmap was detected!
|
||||||
|
|
||||||
|
|
|
@ -84,31 +84,43 @@ use this to identify a proxy server.
|
||||||
We can write a basic script in Bro to handle the http_reply event and
|
We can write a basic script in Bro to handle the http_reply event and
|
||||||
detect a reply for a ``GET http://`` request.
|
detect a reply for a ``GET http://`` request.
|
||||||
|
|
||||||
.. btest-include:: ${DOC_ROOT}/httpmonitor/http_proxy_01.bro
|
.. literalinclude:: http_proxy_01.bro
|
||||||
|
:caption:
|
||||||
|
:language: bro
|
||||||
|
:linenos:
|
||||||
|
|
||||||
.. btest:: http_proxy_01
|
.. code-block:: console
|
||||||
|
|
||||||
@TEST-EXEC: btest-rst-cmd bro -r ${TRACES}/http/proxy.pcap ${DOC_ROOT}/httpmonitor/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
|
||||||
|
|
||||||
Basically, the script is checking for a "200 OK" status code on a reply
|
Basically, the script is checking for a "200 OK" status code on a reply
|
||||||
for a request that includes "http:" (case insensitive). In reality, the
|
for a request that includes "http:" (case insensitive). In reality, the
|
||||||
HTTP protocol defines several success status codes other than 200, so we
|
HTTP protocol defines several success status codes other than 200, so we
|
||||||
will extend our basic script to also consider the additional codes.
|
will extend our basic script to also consider the additional codes.
|
||||||
|
|
||||||
.. btest-include:: ${DOC_ROOT}/httpmonitor/http_proxy_02.bro
|
.. literalinclude:: http_proxy_02.bro
|
||||||
|
:caption:
|
||||||
|
:language: bro
|
||||||
|
:linenos:
|
||||||
|
|
||||||
.. btest:: http_proxy_02
|
.. code-block:: console
|
||||||
|
|
||||||
@TEST-EXEC: btest-rst-cmd bro -r ${TRACES}/http/proxy.pcap ${DOC_ROOT}/httpmonitor/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
|
||||||
|
|
||||||
Next, we will make sure that the responding proxy is part of our local
|
Next, we will make sure that the responding proxy is part of our local
|
||||||
network.
|
network.
|
||||||
|
|
||||||
.. btest-include:: ${DOC_ROOT}/httpmonitor/http_proxy_03.bro
|
.. literalinclude:: http_proxy_03.bro
|
||||||
|
:caption:
|
||||||
|
:language: bro
|
||||||
|
:linenos:
|
||||||
|
|
||||||
.. btest:: http_proxy_03
|
.. code-block:: console
|
||||||
|
|
||||||
@TEST-EXEC: btest-rst-cmd bro -r ${TRACES}/http/proxy.pcap ${DOC_ROOT}/httpmonitor/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
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
|
@ -123,12 +135,25 @@ we will tag the traffic accordingly and define a new ``Open_Proxy``
|
||||||
notification has been fired, we will further suppress it for one day.
|
notification has been fired, we will further suppress it for one day.
|
||||||
Below is the complete script.
|
Below is the complete script.
|
||||||
|
|
||||||
.. btest-include:: ${DOC_ROOT}/httpmonitor/http_proxy_04.bro
|
.. literalinclude:: http_proxy_04.bro
|
||||||
|
:caption:
|
||||||
|
:language: bro
|
||||||
|
:linenos:
|
||||||
|
|
||||||
.. btest:: http_proxy_04
|
.. code-block:: console
|
||||||
|
|
||||||
@TEST-EXEC: btest-rst-cmd bro -r ${TRACES}/http/proxy.pcap ${DOC_ROOT}/httpmonitor/http_proxy_04.bro
|
$ bro -r http/proxy.pcap http_proxy_04.bro
|
||||||
@TEST-EXEC: btest-rst-include notice.log
|
$ cat notice.log
|
||||||
|
#separator \x09
|
||||||
|
#set_separator ,
|
||||||
|
#empty_field (empty)
|
||||||
|
#unset_field -
|
||||||
|
#path notice
|
||||||
|
#open 2018-12-13-22-56-39
|
||||||
|
#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p fuid file_mime_type file_desc proto note msg sub src dst p n peer_descr actions suppress_for dropped remote_location.country_code remote_location.region remote_location.city remote_location.latitude remote_location.longitude
|
||||||
|
#types time string addr port addr port string string string enum enum string string addr addr port count string set[enum] interval bool string string string double double
|
||||||
|
1389654450.449603 CHhAvVGS1DHFjwGM9 192.168.56.1 52679 192.168.56.101 80 - - - tcp HTTP::Open_Proxy A local server is acting as an open proxy: 192.168.56.101 - 192.168.56.1 192.168.56.101 80 - - Notice::ACTION_LOG 86400.000000 F - - - - -
|
||||||
|
#close 2018-12-13-22-56-40
|
||||||
|
|
||||||
Note that this script only logs the presence of the proxy to
|
Note that this script only logs the presence of the proxy to
|
||||||
``notice.log``, but if an additional email is desired (and email
|
``notice.log``, but if an additional email is desired (and email
|
||||||
|
@ -148,11 +173,20 @@ instruct Bro to create a copy of all files of certain types that it sees
|
||||||
using the :ref:`File Analysis Framework <file-analysis-framework>`
|
using the :ref:`File Analysis Framework <file-analysis-framework>`
|
||||||
(introduced with Bro 2.2):
|
(introduced with Bro 2.2):
|
||||||
|
|
||||||
.. btest-include:: ${DOC_ROOT}/httpmonitor/file_extraction.bro
|
.. literalinclude:: file_extraction.bro
|
||||||
|
:caption:
|
||||||
|
:language: bro
|
||||||
|
:linenos:
|
||||||
|
|
||||||
.. btest:: file_extraction
|
.. code-block:: console
|
||||||
|
|
||||||
@TEST-EXEC: btest-rst-cmd -n 5 bro -r ${TRACES}/http/bro.org.pcap ${DOC_ROOT}/httpmonitor/file_extraction.bro
|
$ bro -r bro.org.pcap file_extraction.bro
|
||||||
|
Extracting file HTTP-FiIpIB2hRQSDBOSJRg.html
|
||||||
|
Extracting file HTTP-FMG4bMmVV64eOsCb.txt
|
||||||
|
Extracting file HTTP-FnaT2a3UDd093opCB9.txt
|
||||||
|
Extracting file HTTP-FfQGqj4Fhh3pH7nVQj.txt
|
||||||
|
Extracting file HTTP-FsvATF146kf1Emc21j.txt
|
||||||
|
[...]
|
||||||
|
|
||||||
Here, the ``mime_to_ext`` table serves two purposes. It defines which
|
Here, the ``mime_to_ext`` table serves two purposes. It defines which
|
||||||
mime types to extract and also the file suffix of the extracted files.
|
mime types to extract and also the file suffix of the extracted files.
|
||||||
|
|
|
@ -39,13 +39,23 @@ to the appropriate log file.
|
||||||
|
|
||||||
As the fields of the log entries can be further customized by the
|
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. This header entry can be see by running
|
it remains self-describing. Here's the first few lines of a ``conn.log``.
|
||||||
the Unix utility ``head`` and outputting the first lines of the file:
|
|
||||||
|
|
||||||
.. btest:: using_bro
|
.. code-block:: console
|
||||||
|
|
||||||
@TEST-EXEC: btest-rst-cmd bro -r $TRACES/wikipedia.trace
|
$ cat conn.log
|
||||||
@TEST-EXEC: btest-rst-include -n 15 conn.log
|
#separator \x09
|
||||||
|
#set_separator ,
|
||||||
|
#empty_field (empty)
|
||||||
|
#unset_field -
|
||||||
|
#path conn
|
||||||
|
#open 2018-12-10-22-18-00
|
||||||
|
#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p proto service duration orig_bytes resp_bytes conn_state local_orig local_resp missed_bytes history orig_pkts orig_ip_bytes resp_pkts resp_ip_bytes tunnel_parents
|
||||||
|
#types time string addr port addr port enum string interval count count string bool bool count string count count count count set[string]
|
||||||
|
1300475167.096535 CHhAvVGS1DHFjwGM9 141.142.220.202 5353 224.0.0.251 5353 udp dns - - - S0 - - 0 D 1 73 0 0 -
|
||||||
|
1300475167.097012 ClEkJM2Vm5giqnMf4h fe80::217:f2ff:fed7:cf65 5353 ff02::fb 5353 udp dns - - - S0 - - 0 D 1 199 0 0 -
|
||||||
|
1300475167.099816 C4J4Th3PJpwUYZZ6gc 141.142.220.50 5353 224.0.0.251 5353 udp dns - - - S0 - - 0 D 1 179 0 0 -
|
||||||
|
[...]
|
||||||
|
|
||||||
As you can see, the header consists of lines prefixed by ``#`` and
|
As you can see, the header consists of lines prefixed by ``#`` and
|
||||||
includes information such as what separators are being used for
|
includes information such as what separators are being used for
|
||||||
|
@ -129,15 +139,37 @@ 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``:
|
||||||
|
|
||||||
.. btest:: using_bro
|
.. code-block:: console
|
||||||
|
|
||||||
@TEST-EXEC: btest-rst-cmd -n 10 "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 -
|
||||||
|
fe80::217:f2ff:fed7:cf65 5353 ff02::fb -
|
||||||
|
141.142.220.50 5353 224.0.0.251 -
|
||||||
|
141.142.220.118 43927 141.142.2.2 0.000435
|
||||||
|
141.142.220.118 37676 141.142.2.2 0.000420
|
||||||
|
141.142.220.118 40526 141.142.2.2 0.000392
|
||||||
|
141.142.220.118 32902 141.142.2.2 0.000317
|
||||||
|
141.142.220.118 59816 141.142.2.2 0.000343
|
||||||
|
141.142.220.118 59714 141.142.2.2 0.000375
|
||||||
|
141.142.220.118 58206 141.142.2.2 0.000339
|
||||||
|
[...]
|
||||||
|
|
||||||
The corresponding ``awk`` command will look like this:
|
The corresponding ``awk`` command will look like this:
|
||||||
|
|
||||||
.. btest:: using_bro
|
.. code-block:: console
|
||||||
|
|
||||||
@TEST-EXEC: btest-rst-cmd -n 10 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 -
|
||||||
|
fe80::217:f2ff:fed7:cf65 5353 ff02::fb 5353 -
|
||||||
|
141.142.220.50 5353 224.0.0.251 5353 -
|
||||||
|
141.142.220.118 43927 141.142.2.2 53 0.000435
|
||||||
|
141.142.220.118 37676 141.142.2.2 53 0.000420
|
||||||
|
141.142.220.118 40526 141.142.2.2 53 0.000392
|
||||||
|
141.142.220.118 32902 141.142.2.2 53 0.000317
|
||||||
|
141.142.220.118 59816 141.142.2.2 53 0.000343
|
||||||
|
141.142.220.118 59714 141.142.2.2 53 0.000375
|
||||||
|
141.142.220.118 58206 141.142.2.2 53 0.000339
|
||||||
|
[...]
|
||||||
|
|
||||||
While the output is similar, the advantages to using bro-cut over
|
While the output is similar, the advantages to using bro-cut over
|
||||||
``awk`` lay in that, while ``awk`` is flexible and powerful, ``bro-cut``
|
``awk`` lay in that, while ``awk`` is flexible and powerful, ``bro-cut``
|
||||||
|
@ -191,17 +223,29 @@ 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:
|
||||||
|
|
||||||
.. btest:: using_bro
|
.. code-block:: console
|
||||||
|
|
||||||
@TEST-EXEC: btest-rst-cmd -n 5 "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 CwjjYJ2WqgTbAqiHl6 upload.wikimedia.org /wikipedia/commons/6/63/Wikipedia-logo.png
|
||||||
|
2011-03-18T19:06:08+0000 C3eiCBGOLw3VtHfOj upload.wikimedia.org /wikipedia/commons/thumb/b/bb/Wikipedia_wordmark.svg/174px-Wikipedia_wordmark.svg.png
|
||||||
|
2011-03-18T19:06:08+0000 Ck51lg1bScffFj34Ri upload.wikimedia.org /wikipedia/commons/b/bd/Bookshelf-40x201_6.png
|
||||||
|
2011-03-18T19:06:08+0000 CtxTCR2Yer0FR1tIBg upload.wikimedia.org /wikipedia/commons/thumb/8/8a/Wikinews-logo.png/35px-Wikinews-logo.png
|
||||||
|
[...]
|
||||||
|
|
||||||
Often times log files from multiple sources are stored in UTC time to
|
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:
|
||||||
|
|
||||||
.. btest:: using_bro
|
.. code-block:: console
|
||||||
|
|
||||||
@TEST-EXEC: btest-rst-cmd -n 5 "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 CwjjYJ2WqgTbAqiHl6 upload.wikimedia.org /wikipedia/commons/6/63/Wikipedia-logo.png
|
||||||
|
2011-03-18T19:06:08+0000 C3eiCBGOLw3VtHfOj upload.wikimedia.org /wikipedia/commons/thumb/b/bb/Wikipedia_wordmark.svg/174px-Wikipedia_wordmark.svg.png
|
||||||
|
2011-03-18T19:06:08+0000 Ck51lg1bScffFj34Ri upload.wikimedia.org /wikipedia/commons/b/bd/Bookshelf-40x201_6.png
|
||||||
|
2011-03-18T19:06:08+0000 CtxTCR2Yer0FR1tIBg upload.wikimedia.org /wikipedia/commons/thumb/8/8a/Wikinews-logo.png/35px-Wikinews-logo.png
|
||||||
|
[...]
|
||||||
|
|
||||||
The default time format when using the ``-d`` or ``-u`` is the
|
The default time format when using the ``-d`` or ``-u`` is the
|
||||||
``strftime`` format string ``%Y-%m-%dT%H:%M:%S%z`` which results in a
|
``strftime`` format string ``%Y-%m-%dT%H:%M:%S%z`` which results in a
|
||||||
|
@ -211,9 +255,15 @@ 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``
|
||||||
|
|
||||||
.. btest:: using_bro
|
.. code-block:: console
|
||||||
|
|
||||||
@TEST-EXEC: btest-rst-cmd -n 5 "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 CwjjYJ2WqgTbAqiHl6 upload.wikimedia.org /wikipedia/commons/6/63/Wikipedia-logo.png
|
||||||
|
18-03-2011T19:06:08+0000 C3eiCBGOLw3VtHfOj upload.wikimedia.org /wikipedia/commons/thumb/b/bb/Wikipedia_wordmark.svg/174px-Wikipedia_wordmark.svg.png
|
||||||
|
18-03-2011T19:06:08+0000 Ck51lg1bScffFj34Ri upload.wikimedia.org /wikipedia/commons/b/bd/Bookshelf-40x201_6.png
|
||||||
|
18-03-2011T19:06:08+0000 CtxTCR2Yer0FR1tIBg upload.wikimedia.org /wikipedia/commons/thumb/8/8a/Wikinews-logo.png/35px-Wikinews-logo.png
|
||||||
|
[...]
|
||||||
|
|
||||||
See ``man strfime`` for more options for the format string.
|
See ``man strfime`` for more options for the format string.
|
||||||
|
|
||||||
|
@ -235,16 +285,22 @@ 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.
|
||||||
|
|
||||||
.. btest:: using_bro
|
.. code-block:: console
|
||||||
|
|
||||||
@TEST-EXEC: btest-rst-cmd "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
|
||||||
|
CtxTCR2Yer0FR1tIBg 734
|
||||||
|
Ck51lg1bScffFj34Ri 734
|
||||||
|
CLNN1k2QMum1aexUK7 734
|
||||||
|
CykQaM33ztNt0csB9a 733
|
||||||
|
|
||||||
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.
|
||||||
|
|
||||||
.. btest:: using_bro
|
.. code-block:: console
|
||||||
|
|
||||||
@TEST-EXEC: btest-rst-cmd "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
|
||||||
|
|
||||||
As you can see there are two HTTP ``GET`` requests within the
|
As you can see there are two HTTP ``GET`` requests within the
|
||||||
session that Bro identified and logged. Given that HTTP is a stream
|
session that Bro identified and logged. Given that HTTP is a stream
|
||||||
|
|
|
@ -37,32 +37,69 @@ in the MIME type, size of the file ("response_body_len"), and the
|
||||||
originator host ("orig_h"). We use the MIME type as our key and create
|
originator host ("orig_h"). We use the MIME type as our key and create
|
||||||
observers for the other two values.
|
observers for the other two values.
|
||||||
|
|
||||||
.. btest-include:: ${DOC_ROOT}/mimestats/mimestats.bro
|
.. literalinclude:: mimestats.bro
|
||||||
:lines: 6-29, 54-64
|
:caption:
|
||||||
|
:language: bro
|
||||||
|
:linenos:
|
||||||
|
:lines: 6-29
|
||||||
|
:lineno-start: 6
|
||||||
|
|
||||||
|
.. literalinclude:: mimestats.bro
|
||||||
|
:caption:
|
||||||
|
:language: bro
|
||||||
|
:linenos:
|
||||||
|
:lines: 54-64
|
||||||
|
:lineno-start: 54
|
||||||
|
|
||||||
Next, we create the reducers. The first will accumulate file sizes
|
Next, we create the reducers. The first will accumulate file sizes
|
||||||
and the second will make sure we only store a host ID once. Below is
|
and the second will make sure we only store a host ID once. Below is
|
||||||
the partial code from a :bro:see:`bro_init` handler.
|
the partial code from a :bro:see:`bro_init` handler.
|
||||||
|
|
||||||
.. btest-include:: ${DOC_ROOT}/mimestats/mimestats.bro
|
.. literalinclude:: mimestats.bro
|
||||||
|
:caption:
|
||||||
|
:language: bro
|
||||||
|
:linenos:
|
||||||
:lines: 34-37
|
:lines: 34-37
|
||||||
|
:lineno-start: 34
|
||||||
|
|
||||||
In our final step, we create the SumStats where we check for the
|
In our final step, we create the SumStats where we check for the
|
||||||
observation interval. Once it expires, we populate the record
|
observation interval. Once it expires, we populate the record
|
||||||
(defined above) with all the relevant data and write it to a log.
|
(defined above) with all the relevant data and write it to a log.
|
||||||
|
|
||||||
.. btest-include:: ${DOC_ROOT}/mimestats/mimestats.bro
|
.. literalinclude:: mimestats.bro
|
||||||
|
:caption:
|
||||||
|
:language: bro
|
||||||
|
:linenos:
|
||||||
:lines: 38-51
|
:lines: 38-51
|
||||||
|
:lineno-start: 38
|
||||||
|
|
||||||
After putting the three pieces together we end up with the following final code for
|
After putting the three pieces together we end up with the following
|
||||||
our script.
|
final code for our script.
|
||||||
|
|
||||||
.. btest-include:: ${DOC_ROOT}/mimestats/mimestats.bro
|
.. literalinclude:: mimestats.bro
|
||||||
|
:caption:
|
||||||
|
:language: bro
|
||||||
|
:linenos:
|
||||||
|
|
||||||
.. btest:: mimestats
|
.. code-block:: console
|
||||||
|
|
||||||
@TEST-EXEC: btest-rst-cmd bro -r ${TRACES}/http/bro.org.pcap ${DOC_ROOT}/mimestats/mimestats.bro
|
$ bro -r http/bro.org.pcap mimestats.bro
|
||||||
@TEST-EXEC: btest-rst-include mime_metrics.log
|
#separator \x09
|
||||||
|
#set_separator ,
|
||||||
|
#empty_field (empty)
|
||||||
|
#unset_field -
|
||||||
|
#path mime_metrics
|
||||||
|
#open 2018-12-14-16-25-06
|
||||||
|
#fields ts ts_delta mtype uniq_hosts hits bytes
|
||||||
|
#types time interval string count count count
|
||||||
|
1389719059.311698 300.000000 image/png 1 9 82176
|
||||||
|
1389719059.311698 300.000000 image/gif 1 1 172
|
||||||
|
1389719059.311698 300.000000 image/x-icon 1 2 2300
|
||||||
|
1389719059.311698 300.000000 text/html 1 2 42231
|
||||||
|
1389719059.311698 300.000000 text/plain 1 15 128001
|
||||||
|
1389719059.311698 300.000000 image/jpeg 1 1 186859
|
||||||
|
1389719059.311698 300.000000 application/pgp-signature 1 1 836
|
||||||
|
#close 2018-12-14-16-25-06
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
|
|
|
@ -255,12 +255,25 @@ action taken on notices can be user-defined.
|
||||||
|
|
||||||
In ``local.bro``, let's define a new ``policy`` hook handler body:
|
In ``local.bro``, let's define a new ``policy`` hook handler body:
|
||||||
|
|
||||||
.. btest-include:: ${DOC_ROOT}/quickstart/conditional-notice.bro
|
.. literalinclude:: conditional-notice.bro
|
||||||
|
:caption:
|
||||||
|
:language: bro
|
||||||
|
:linenos:
|
||||||
|
|
||||||
.. btest:: conditional-notice
|
.. code-block:: console
|
||||||
|
|
||||||
@TEST-EXEC: btest-rst-cmd bro -r ${TRACES}/tls/tls-expired-cert.trace ${DOC_ROOT}/quickstart/conditional-notice.bro
|
$ bro -r tls/tls-expired-cert.trace conditional-notice.bro
|
||||||
@TEST-EXEC: btest-rst-cmd cat notice.log
|
$ cat notice.log
|
||||||
|
#separator \x09
|
||||||
|
#set_separator ,
|
||||||
|
#empty_field (empty)
|
||||||
|
#unset_field -
|
||||||
|
#path notice
|
||||||
|
#open 2018-12-14-17-36-05
|
||||||
|
#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p fuid file_mime_type file_desc proto note msg sub src dst p n peer_descr actions suppress_for dropped remote_location.country_code remote_location.region remote_location.city remote_location.latitude remote_location.longitude
|
||||||
|
#types time string addr port addr port string string string enum enum string string addr addr port count string set[enum] interval bool string string string double double
|
||||||
|
1394745603.293028 CHhAvVGS1DHFjwGM9 192.168.4.149 60539 87.98.220.10 443 F1fX1R2cDOzbvg17ye - - tcp SSL::Certificate_Expired Certificate CN=www.spidh.org,OU=COMODO SSL,OU=Domain Control Validated expired at 2014-03-04-23:59:59.000000000 - 192.168.4.149 87.98.220.10 443 - - Notice::ACTION_EMAIL,Notice::ACTION_LOG 86400.000000 F - - - - -
|
||||||
|
#close 2018-12-14-17-36-05
|
||||||
|
|
||||||
You'll just have to trust the syntax for now, but what we've done is
|
You'll just have to trust the syntax for now, but what we've done is
|
||||||
first declare our own variable to hold a set of watched addresses,
|
first declare our own variable to hold a set of watched addresses,
|
||||||
|
|
|
@ -37,10 +37,85 @@ Hash registry includes the ability to do a host lookup on a domain with the form
|
||||||
Team Cymru also populates the TXT record of their DNS responses with both a "first seen"
|
Team Cymru also populates the TXT record of their DNS responses with both a "first seen"
|
||||||
timestamp and a numerical "detection rate". The important aspect to understand is Bro already
|
timestamp and a numerical "detection rate". The important aspect to understand is Bro already
|
||||||
generating hashes for files via the Files framework, but it is the
|
generating hashes for files via the Files framework, but it is the
|
||||||
script ``detect-MHR.bro`` that is responsible for generating the
|
script :doc:`/scripts/policy/frameworks/files/detect-MHR.bro`
|
||||||
|
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.
|
||||||
|
|
||||||
.. btest-include:: ${BRO_SRC_ROOT}/scripts/policy/frameworks/files/detect-MHR.bro
|
.. code-block:: bro
|
||||||
|
:caption: detect-MHR.bro
|
||||||
|
|
||||||
|
##! Detect file downloads that have hash values matching files in Team
|
||||||
|
##! Cymru's Malware Hash Registry (http://www.team-cymru.org/Services/MHR/).
|
||||||
|
|
||||||
|
@load base/frameworks/files
|
||||||
|
@load base/frameworks/notice
|
||||||
|
@load frameworks/files/hash-all-files
|
||||||
|
|
||||||
|
module TeamCymruMalwareHashRegistry;
|
||||||
|
|
||||||
|
export {
|
||||||
|
redef enum Notice::Type += {
|
||||||
|
## The hash value of a file transferred over HTTP matched in the
|
||||||
|
## malware hash registry.
|
||||||
|
Match
|
||||||
|
};
|
||||||
|
|
||||||
|
## File types to attempt matching against the Malware Hash Registry.
|
||||||
|
option match_file_types = /application\/x-dosexec/ |
|
||||||
|
/application\/vnd.ms-cab-compressed/ |
|
||||||
|
/application\/pdf/ |
|
||||||
|
/application\/x-shockwave-flash/ |
|
||||||
|
/application\/x-java-applet/ |
|
||||||
|
/application\/jar/ |
|
||||||
|
/video\/mp4/;
|
||||||
|
|
||||||
|
## The Match notice has a sub message with a URL where you can get more
|
||||||
|
## information about the file. The %s will be replaced with the SHA-1
|
||||||
|
## hash of the file.
|
||||||
|
option match_sub_url = "https://www.virustotal.com/en/search/?query=%s";
|
||||||
|
|
||||||
|
## The malware hash registry runs each malware sample through several
|
||||||
|
## A/V engines. Team Cymru returns a percentage to indicate how
|
||||||
|
## many A/V engines flagged the sample as malicious. This threshold
|
||||||
|
## allows you to require a minimum detection rate.
|
||||||
|
option notice_threshold = 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
function do_mhr_lookup(hash: string, fi: Notice::FileInfo)
|
||||||
|
{
|
||||||
|
local hash_domain = fmt("%s.malware.hash.cymru.com", hash);
|
||||||
|
|
||||||
|
when ( local MHR_result = lookup_hostname_txt(hash_domain) )
|
||||||
|
{
|
||||||
|
# Data is returned as "<dateFirstDetected> <detectionRate>"
|
||||||
|
local MHR_answer = split_string1(MHR_result, / /);
|
||||||
|
|
||||||
|
if ( |MHR_answer| == 2 )
|
||||||
|
{
|
||||||
|
local mhr_detect_rate = to_count(MHR_answer[1]);
|
||||||
|
|
||||||
|
if ( mhr_detect_rate >= notice_threshold )
|
||||||
|
{
|
||||||
|
local mhr_first_detected = double_to_time(to_double(MHR_answer[0]));
|
||||||
|
local readable_first_detected = strftime("%Y-%m-%d %H:%M:%S", mhr_first_detected);
|
||||||
|
local message = fmt("Malware Hash Registry Detection rate: %d%% Last seen: %s", mhr_detect_rate, readable_first_detected);
|
||||||
|
local virustotal_url = fmt(match_sub_url, hash);
|
||||||
|
# We don't have the full fa_file record here in order to
|
||||||
|
# avoid the "when" statement cloning it (expensive!).
|
||||||
|
local n: Notice::Info = Notice::Info($note=Match, $msg=message, $sub=virustotal_url);
|
||||||
|
Notice::populate_file_info2(fi, n);
|
||||||
|
NOTICE(n);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
event file_hash(f: fa_file, kind: string, hash: string)
|
||||||
|
{
|
||||||
|
if ( kind == "sha1" && f?$info && f$info?$mime_type &&
|
||||||
|
match_file_types in f$info$mime_type )
|
||||||
|
do_mhr_lookup(hash, Notice::create_file_info(f));
|
||||||
|
}
|
||||||
|
|
||||||
Visually, there are three distinct sections of the script. First, there is a base
|
Visually, there are three distinct sections of the script. First, there is a base
|
||||||
level with no indentation where libraries are included in the script through ``@load``
|
level with no indentation where libraries are included in the script through ``@load``
|
||||||
|
@ -51,8 +126,12 @@ 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.
|
||||||
|
|
||||||
.. btest-include:: ${BRO_SRC_ROOT}/scripts/policy/frameworks/files/detect-MHR.bro
|
.. code-block:: bro
|
||||||
:lines: 4-6
|
:caption: detect-MHR.bro
|
||||||
|
|
||||||
|
@load base/frameworks/files
|
||||||
|
@load base/frameworks/notice
|
||||||
|
@load frameworks/files/hash-all-files
|
||||||
|
|
||||||
The first part of the script consists of ``@load`` directives which
|
The first part of the script consists of ``@load`` directives which
|
||||||
process the ``__load__.bro`` script in the
|
process the ``__load__.bro`` script in the
|
||||||
|
@ -66,8 +145,36 @@ 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.
|
||||||
|
|
||||||
.. btest-include:: ${BRO_SRC_ROOT}/scripts/policy/frameworks/files/detect-MHR.bro
|
.. code-block:: bro
|
||||||
:lines: 10-36
|
:caption: detect-MHR.bro
|
||||||
|
|
||||||
|
export {
|
||||||
|
redef enum Notice::Type += {
|
||||||
|
## The hash value of a file transferred over HTTP matched in the
|
||||||
|
## malware hash registry.
|
||||||
|
Match
|
||||||
|
};
|
||||||
|
|
||||||
|
## File types to attempt matching against the Malware Hash Registry.
|
||||||
|
option match_file_types = /application\/x-dosexec/ |
|
||||||
|
/application\/vnd.ms-cab-compressed/ |
|
||||||
|
/application\/pdf/ |
|
||||||
|
/application\/x-shockwave-flash/ |
|
||||||
|
/application\/x-java-applet/ |
|
||||||
|
/application\/jar/ |
|
||||||
|
/video\/mp4/;
|
||||||
|
|
||||||
|
## The Match notice has a sub message with a URL where you can get more
|
||||||
|
## information about the file. The %s will be replaced with the SHA-1
|
||||||
|
## hash of the file.
|
||||||
|
option match_sub_url = "https://www.virustotal.com/en/search/?query=%s";
|
||||||
|
|
||||||
|
## The malware hash registry runs each malware sample through several
|
||||||
|
## A/V engines. Team Cymru returns a percentage to indicate how
|
||||||
|
## many A/V engines flagged the sample as malicious. This threshold
|
||||||
|
## allows you to require a minimum detection rate.
|
||||||
|
option notice_threshold = 10;
|
||||||
|
}
|
||||||
|
|
||||||
The export section redefines an enumerable constant that describes the
|
The export section redefines an enumerable constant that describes the
|
||||||
type of notice we will generate with the Notice framework. Bro
|
type of notice we will generate with the Notice framework. Bro
|
||||||
|
@ -89,8 +196,43 @@ 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.
|
||||||
|
|
||||||
.. btest-include:: ${BRO_SRC_ROOT}/scripts/policy/frameworks/files/detect-MHR.bro
|
.. code-block:: bro
|
||||||
:lines: 38-71
|
:caption: detect-MHR.bro
|
||||||
|
|
||||||
|
function do_mhr_lookup(hash: string, fi: Notice::FileInfo)
|
||||||
|
{
|
||||||
|
local hash_domain = fmt("%s.malware.hash.cymru.com", hash);
|
||||||
|
|
||||||
|
when ( local MHR_result = lookup_hostname_txt(hash_domain) )
|
||||||
|
{
|
||||||
|
# Data is returned as "<dateFirstDetected> <detectionRate>"
|
||||||
|
local MHR_answer = split_string1(MHR_result, / /);
|
||||||
|
|
||||||
|
if ( |MHR_answer| == 2 )
|
||||||
|
{
|
||||||
|
local mhr_detect_rate = to_count(MHR_answer[1]);
|
||||||
|
|
||||||
|
if ( mhr_detect_rate >= notice_threshold )
|
||||||
|
{
|
||||||
|
local mhr_first_detected = double_to_time(to_double(MHR_answer[0]));
|
||||||
|
local readable_first_detected = strftime("%Y-%m-%d %H:%M:%S", mhr_first_detected);
|
||||||
|
local message = fmt("Malware Hash Registry Detection rate: %d%% Last seen: %s", mhr_detect_rate, readable_first_detected);
|
||||||
|
local virustotal_url = fmt(match_sub_url, hash);
|
||||||
|
# We don't have the full fa_file record here in order to
|
||||||
|
# avoid the "when" statement cloning it (expensive!).
|
||||||
|
local n: Notice::Info = Notice::Info($note=Match, $msg=message, $sub=virustotal_url);
|
||||||
|
Notice::populate_file_info2(fi, n);
|
||||||
|
NOTICE(n);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
event file_hash(f: fa_file, kind: string, hash: string)
|
||||||
|
{
|
||||||
|
if ( kind == "sha1" && f?$info && f$info?$mime_type &&
|
||||||
|
match_file_types in f$info$mime_type )
|
||||||
|
do_mhr_lookup(hash, Notice::create_file_info(f));
|
||||||
|
|
||||||
The workhorse of the script is contained in the event handler for
|
The workhorse of the script is contained in the event handler for
|
||||||
``file_hash``. The :bro:see:`file_hash` event allows scripts to access
|
``file_hash``. The :bro:see:`file_hash` event allows scripts to access
|
||||||
|
@ -182,8 +324,34 @@ 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.
|
||||||
|
|
||||||
.. btest-include:: ${BRO_SRC_ROOT}/build/scripts/base/bif/plugins/Bro_DNS.events.bif.bro
|
.. code-block:: bro
|
||||||
:lines: 29-54
|
|
||||||
|
## Generated for DNS requests. For requests with multiple queries, this event
|
||||||
|
## is raised once for each.
|
||||||
|
##
|
||||||
|
## See `Wikipedia <http://en.wikipedia.org/wiki/Domain_Name_System>`__ for more
|
||||||
|
## information about the DNS protocol. Bro analyzes both UDP and TCP DNS
|
||||||
|
## sessions.
|
||||||
|
##
|
||||||
|
## c: The connection, which may be UDP or TCP depending on the type of the
|
||||||
|
## transport-layer session being analyzed.
|
||||||
|
##
|
||||||
|
## msg: The parsed DNS message header.
|
||||||
|
##
|
||||||
|
## query: The queried name.
|
||||||
|
##
|
||||||
|
## qtype: The queried resource record type.
|
||||||
|
##
|
||||||
|
## qclass: The queried resource record class.
|
||||||
|
##
|
||||||
|
## .. bro:see:: dns_AAAA_reply dns_A_reply dns_CNAME_reply dns_EDNS_addl
|
||||||
|
## dns_HINFO_reply dns_MX_reply dns_NS_reply dns_PTR_reply dns_SOA_reply
|
||||||
|
## dns_SRV_reply dns_TSIG_addl dns_TXT_reply dns_WKS_reply dns_end
|
||||||
|
## dns_full_request dns_mapping_altered dns_mapping_lost_name dns_mapping_new_name
|
||||||
|
## dns_mapping_unverified dns_mapping_valid dns_message dns_query_reply
|
||||||
|
## dns_rejected non_dns_request dns_max_queries dns_session_timeout dns_skip_addl
|
||||||
|
## dns_skip_all_addl dns_skip_all_auth dns_skip_auth
|
||||||
|
event dns_request%(c: connection, msg: dns_msg, query: string, qtype: count, qclass: count%);
|
||||||
|
|
||||||
Above is a segment of the documentation for the event
|
Above is a segment of the documentation for the event
|
||||||
:bro:id:`dns_request` (and the preceding link points to the
|
:bro:id:`dns_request` (and the preceding link points to the
|
||||||
|
@ -226,7 +394,10 @@ remove this event from memory, effectively forgetting about it. Let's
|
||||||
take a look at a simple example script, that will output the connection record
|
take a look at a simple example script, that will output the connection record
|
||||||
for a single connection.
|
for a single connection.
|
||||||
|
|
||||||
.. btest-include:: ${DOC_ROOT}/scripting/connection_record_01.bro
|
.. literalinclude:: connection_record_01.bro
|
||||||
|
:caption:
|
||||||
|
:language: bro
|
||||||
|
:linenos:
|
||||||
|
|
||||||
Again, we start with ``@load``, this time importing the
|
Again, we start with ``@load``, this time importing the
|
||||||
:doc:`/scripts/base/protocols/conn/index` scripts which supply the tracking
|
:doc:`/scripts/base/protocols/conn/index` scripts which supply the tracking
|
||||||
|
@ -242,9 +413,12 @@ 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.
|
||||||
|
|
||||||
.. btest:: connection-record-01
|
.. code-block:: console
|
||||||
|
|
||||||
@TEST-EXEC: btest-rst-cmd bro -b -r ${TRACES}/http/get.trace ${DOC_ROOT}/scripting/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={
|
||||||
|
|
||||||
|
}, history=ShADadFf, uid=CHhAvVGS1DHFjwGM9, tunnel=<uninitialized>, vlan=<uninitialized>, inner_vlan=<uninitialized>, conn=[ts=1362692526.869344, uid=CHhAvVGS1DHFjwGM9, id=[orig_h=141.142.228.5, orig_p=59856/tcp, resp_h=192.150.187.43, resp_p=80/tcp], proto=tcp, service=<uninitialized>, duration=0.211484, orig_bytes=136, resp_bytes=5007, conn_state=SF, local_orig=<uninitialized>, local_resp=<uninitialized>, missed_bytes=0, history=ShADadFf, orig_pkts=7, orig_ip_bytes=512, resp_pkts=7, resp_ip_bytes=5379, tunnel_parents=<uninitialized>], extract_orig=F, extract_resp=F, thresholds=<uninitialized>]
|
||||||
|
|
||||||
As you can see from the output, the connection record is something of
|
As you can see from the output, the connection record is something of
|
||||||
a jumble when printed on its own. Regularly taking a peek at a
|
a jumble when printed on its own. Regularly taking a peek at a
|
||||||
|
@ -270,11 +444,21 @@ proper format of a dereferenced variable in scripts. In the output of
|
||||||
the script above, groups of information are collected between
|
the script above, groups of information are collected between
|
||||||
brackets, which would correspond to the ``$``-delimiter in a Bro script.
|
brackets, which would correspond to the ``$``-delimiter in a Bro script.
|
||||||
|
|
||||||
.. btest-include:: ${DOC_ROOT}/scripting/connection_record_02.bro
|
.. literalinclude:: connection_record_02.bro
|
||||||
|
:caption:
|
||||||
|
:language: bro
|
||||||
|
:linenos:
|
||||||
|
|
||||||
.. btest:: connection-record-02
|
.. code-block:: console
|
||||||
|
|
||||||
@TEST-EXEC: btest-rst-cmd bro -b -r ${TRACES}/http/get.trace ${DOC_ROOT}/scripting/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={
|
||||||
|
|
||||||
|
}, history=ShADadFf, uid=CHhAvVGS1DHFjwGM9, tunnel=<uninitialized>, vlan=<uninitialized>, inner_vlan=<uninitialized>, conn=[ts=1362692526.869344, uid=CHhAvVGS1DHFjwGM9, id=[orig_h=141.142.228.5, orig_p=59856/tcp, resp_h=192.150.187.43, resp_p=80/tcp], proto=tcp, service=<uninitialized>, duration=0.211484, orig_bytes=136, resp_bytes=5007, conn_state=SF, local_orig=<uninitialized>, local_resp=<uninitialized>, missed_bytes=0, history=ShADadFf, orig_pkts=7, orig_ip_bytes=512, resp_pkts=7, resp_ip_bytes=5379, tunnel_parents=<uninitialized>], extract_orig=F, extract_resp=F, thresholds=<uninitialized>, http=[ts=1362692526.939527, uid=CHhAvVGS1DHFjwGM9, id=[orig_h=141.142.228.5, orig_p=59856/tcp, resp_h=192.150.187.43, resp_p=80/tcp], trans_depth=1, method=GET, host=bro.org, uri=/download/CHANGES.bro-aux.txt, referrer=<uninitialized>, version=1.1, user_agent=Wget/1.14 (darwin12.2.0), request_body_len=0, response_body_len=4705, status_code=200, status_msg=OK, info_code=<uninitialized>, info_msg=<uninitialized>, tags={
|
||||||
|
|
||||||
|
}, username=<uninitialized>, password=<uninitialized>, capture_password=F, proxied=<uninitialized>, range_request=F, orig_fuids=<uninitialized>, orig_filenames=<uninitialized>, orig_mime_types=<uninitialized>, resp_fuids=[FakNcS1Jfe01uljb3], resp_filenames=<uninitialized>, resp_mime_types=[text/plain], current_entity=<uninitialized>, orig_mime_depth=1, resp_mime_depth=1], http_state=[pending={
|
||||||
|
|
||||||
|
}, current_request=1, current_response=1, trans_depth=1]]
|
||||||
|
|
||||||
The addition of the ``base/protocols/http`` scripts populates the
|
The addition of the ``base/protocols/http`` scripts populates the
|
||||||
``http=[]`` member of the connection record. While Bro is doing a
|
``http=[]`` member of the connection record. While Bro is doing a
|
||||||
|
@ -306,7 +490,10 @@ each of which produce the same result if ``EXPRESSION`` evaluates to the
|
||||||
same type as ``TYPE``. The decision as to which type of declaration to
|
same type as ``TYPE``. The decision as to which type of declaration to
|
||||||
use is likely to be dictated by personal preference and readability.
|
use is likely to be dictated by personal preference and readability.
|
||||||
|
|
||||||
.. btest-include:: ${DOC_ROOT}/scripting/data_type_declaration.bro
|
.. literalinclude:: data_type_declaration.bro
|
||||||
|
:caption:
|
||||||
|
:language: bro
|
||||||
|
:linenos:
|
||||||
|
|
||||||
Global Variables
|
Global Variables
|
||||||
~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~
|
||||||
|
@ -347,13 +534,19 @@ decrypted from HTTP streams is stored in
|
||||||
:bro:see:`HTTP::default_capture_password` as shown in the stripped down
|
:bro:see:`HTTP::default_capture_password` as shown in the stripped down
|
||||||
excerpt from :doc:`/scripts/base/protocols/http/main.bro` below.
|
excerpt from :doc:`/scripts/base/protocols/http/main.bro` below.
|
||||||
|
|
||||||
.. btest-include:: ${DOC_ROOT}/scripting/http_main.bro
|
.. literalinclude:: http_main.bro
|
||||||
|
:caption:
|
||||||
|
:language: bro
|
||||||
|
:linenos:
|
||||||
|
|
||||||
Because the constant was declared with the ``&redef`` attribute, if we
|
Because the constant was declared with the ``&redef`` attribute, if we
|
||||||
needed to turn this option on globally, we could do so by adding the
|
needed to turn this option on globally, we could do so by adding the
|
||||||
following line to our ``site/local.bro`` file before firing up Bro.
|
following line to our ``site/local.bro`` file before firing up Bro.
|
||||||
|
|
||||||
.. btest-include:: ${DOC_ROOT}/scripting/data_type_const_simple.bro
|
.. literalinclude:: data_type_const_simple.bro
|
||||||
|
:caption:
|
||||||
|
:language: bro
|
||||||
|
:linenos:
|
||||||
|
|
||||||
While the idea of a re-definable constant might be odd, the constraint
|
While the idea of a re-definable constant might be odd, the constraint
|
||||||
that constants can only be altered at parse-time remains even with the
|
that constants can only be altered at parse-time remains even with the
|
||||||
|
@ -364,11 +557,18 @@ in a :bro:id:`bro_init` event. Were we to try to alter the table in
|
||||||
an event handler, Bro would notify the user of an error and the script
|
an event handler, Bro would notify the user of an error and the script
|
||||||
would fail.
|
would fail.
|
||||||
|
|
||||||
.. btest-include:: ${DOC_ROOT}/scripting/data_type_const.bro
|
.. literalinclude:: data_type_const.bro
|
||||||
|
:caption:
|
||||||
|
:language: bro
|
||||||
|
:linenos:
|
||||||
|
|
||||||
.. btest:: data_type_const.bro
|
.. code-block:: console
|
||||||
|
|
||||||
@TEST-EXEC: btest-rst-cmd bro -b ${DOC_ROOT}/scripting/data_type_const.bro
|
$ bro -b data_type_const.bro
|
||||||
|
{
|
||||||
|
[80/tcp] = WWW,
|
||||||
|
[6666/tcp] = IRC
|
||||||
|
}
|
||||||
|
|
||||||
Local Variables
|
Local Variables
|
||||||
~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~
|
||||||
|
@ -382,7 +582,10 @@ of a script passes beyond that scope and no longer used, the variable
|
||||||
is deleted. Bro maintains names of locals separately from globally
|
is deleted. Bro maintains names of locals separately from globally
|
||||||
visible ones, an example of which is illustrated below.
|
visible ones, an example of which is illustrated below.
|
||||||
|
|
||||||
.. btest-include:: ${DOC_ROOT}/scripting/data_type_local.bro
|
.. literalinclude:: data_type_local.bro
|
||||||
|
:caption:
|
||||||
|
:language: bro
|
||||||
|
:linenos:
|
||||||
|
|
||||||
The script executes the event handler :bro:id:`bro_init` which in turn calls
|
The script executes the event handler :bro:id:`bro_init` which in turn calls
|
||||||
the function ``add_two(i: count)`` with an argument of ``10``. Once Bro
|
the function ``add_two(i: count)`` with an argument of ``10``. Once Bro
|
||||||
|
@ -455,7 +658,10 @@ for information that is already naturally unique such as ports or IP
|
||||||
addresses. The code snippet below shows both an explicit and implicit
|
addresses. The code snippet below shows both an explicit and implicit
|
||||||
declaration of a locally scoped set.
|
declaration of a locally scoped set.
|
||||||
|
|
||||||
.. btest-include:: ${DOC_ROOT}/scripting/data_struct_set_declaration.bro
|
.. literalinclude:: data_struct_set_declaration.bro
|
||||||
|
:caption:
|
||||||
|
:language: bro
|
||||||
|
:linenos:
|
||||||
:lines: 1-4,22
|
:lines: 1-4,22
|
||||||
|
|
||||||
As you can see, sets are declared using the format ``SCOPE var_name:
|
As you can see, sets are declared using the format ``SCOPE var_name:
|
||||||
|
@ -467,8 +673,12 @@ the ``in`` operator. In the case of iterating over a set, combining the
|
||||||
``for`` statement and the ``in`` operator will allow you to sequentially
|
``for`` statement and the ``in`` operator will allow you to sequentially
|
||||||
process each element of the set as seen below.
|
process each element of the set as seen below.
|
||||||
|
|
||||||
.. btest-include:: ${DOC_ROOT}/scripting/data_struct_set_declaration.bro
|
.. literalinclude:: data_struct_set_declaration.bro
|
||||||
|
:caption:
|
||||||
|
:language: bro
|
||||||
|
:linenos:
|
||||||
:lines: 17-21
|
:lines: 17-21
|
||||||
|
:lineno-start: 17
|
||||||
|
|
||||||
Here, the ``for`` statement loops over the contents of the set storing
|
Here, the ``for`` statement loops over the contents of the set storing
|
||||||
each element in the temporary variable ``i``. With each iteration of
|
each element in the temporary variable ``i``. With each iteration of
|
||||||
|
@ -487,16 +697,31 @@ negate the in operator itself. While the functionality is the same,
|
||||||
using the ``!in`` is more efficient as well as a more natural construct
|
using the ``!in`` is more efficient as well as a more natural construct
|
||||||
which will aid in the readability of your script.
|
which will aid in the readability of your script.
|
||||||
|
|
||||||
.. btest-include:: ${DOC_ROOT}/scripting/data_struct_set_declaration.bro
|
.. literalinclude:: data_struct_set_declaration.bro
|
||||||
|
:caption:
|
||||||
|
:language: bro
|
||||||
|
:linenos:
|
||||||
:lines: 13-15
|
:lines: 13-15
|
||||||
|
:lineno-start: 13
|
||||||
|
|
||||||
You can see the full script and its output below.
|
You can see the full script and its output below.
|
||||||
|
|
||||||
.. btest-include:: ${DOC_ROOT}/scripting/data_struct_set_declaration.bro
|
.. literalinclude:: data_struct_set_declaration.bro
|
||||||
|
:caption:
|
||||||
|
:language: bro
|
||||||
|
:linenos:
|
||||||
|
|
||||||
.. btest:: data_struct_set_declaration
|
.. code-block:: console
|
||||||
|
|
||||||
@TEST-EXEC: btest-rst-cmd bro ${DOC_ROOT}/scripting/data_struct_set_declaration.bro
|
$ bro data_struct_set_declaration.bro
|
||||||
|
SSL Port: 22/tcp
|
||||||
|
SSL Port: 443/tcp
|
||||||
|
SSL Port: 587/tcp
|
||||||
|
SSL Port: 993/tcp
|
||||||
|
Non-SSL Port: 80/tcp
|
||||||
|
Non-SSL Port: 25/tcp
|
||||||
|
Non-SSL Port: 143/tcp
|
||||||
|
Non-SSL Port: 23/tcp
|
||||||
|
|
||||||
Tables
|
Tables
|
||||||
~~~~~~
|
~~~~~~
|
||||||
|
@ -505,11 +730,18 @@ A table in Bro is a mapping of a key to a value or yield. While the
|
||||||
values don't have to be unique, each key in the table must be unique
|
values don't have to be unique, each key in the table must be unique
|
||||||
to preserve a one-to-one mapping of keys to values.
|
to preserve a one-to-one mapping of keys to values.
|
||||||
|
|
||||||
.. btest-include:: ${DOC_ROOT}/scripting/data_struct_table_declaration.bro
|
.. literalinclude:: data_struct_table_declaration.bro
|
||||||
|
:caption:
|
||||||
|
:language: bro
|
||||||
|
:linenos:
|
||||||
|
|
||||||
.. btest:: data_struct_table_declaration
|
.. code-block:: console
|
||||||
|
|
||||||
@TEST-EXEC: btest-rst-cmd bro ${DOC_ROOT}/scripting/data_struct_table_declaration.bro
|
$ bro data_struct_table_declaration.bro
|
||||||
|
Service Name: SSH - Common Port: 22/tcp
|
||||||
|
Service Name: HTTPS - Common Port: 443/tcp
|
||||||
|
Service Name: SMTPS - Common Port: 587/tcp
|
||||||
|
Service Name: IMAPS - Common Port: 993/tcp
|
||||||
|
|
||||||
In this example,
|
In this example,
|
||||||
we've compiled a table of SSL-enabled services and their common
|
we've compiled a table of SSL-enabled services and their common
|
||||||
|
@ -534,11 +766,18 @@ Bro implies a cost in complexity for the person writing the scripts
|
||||||
but pays off in effectiveness given the power of Bro as a network
|
but pays off in effectiveness given the power of Bro as a network
|
||||||
security platform.
|
security platform.
|
||||||
|
|
||||||
.. btest-include:: ${DOC_ROOT}/scripting/data_struct_table_complex.bro
|
.. literalinclude:: data_struct_table_complex.bro
|
||||||
|
:caption:
|
||||||
|
:language: bro
|
||||||
|
:linenos:
|
||||||
|
|
||||||
.. btest:: data_struct_table_complex
|
.. code-block:: console
|
||||||
|
|
||||||
@TEST-EXEC: btest-rst-cmd bro -b ${DOC_ROOT}/scripting/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
|
||||||
|
Goyokin was released in 1969 by Fuji studios, directed by Hideo Gosha and starring Tatsuya Nakadai
|
||||||
|
Tasogare Seibei was released in 2002 by Eisei Gekijo studios, directed by Yoji Yamada and starring Hiroyuki Sanada
|
||||||
|
Kiru was released in 1968 by Toho studios, directed by Kihachi Okamoto and starring Tatsuya Nakadai
|
||||||
|
|
||||||
This script shows a sample table of strings indexed by two
|
This script shows a sample table of strings indexed by two
|
||||||
strings, a count, and a final string. With a tuple acting as an
|
strings, a count, and a final string. With a tuple acting as an
|
||||||
|
@ -580,11 +819,18 @@ the vector name between two vertical pipes to get the vector's current
|
||||||
length before printing the contents of both Vectors and their current
|
length before printing the contents of both Vectors and their current
|
||||||
lengths.
|
lengths.
|
||||||
|
|
||||||
.. btest-include:: ${DOC_ROOT}/scripting/data_struct_vector_declaration.bro
|
.. literalinclude:: data_struct_vector_declaration.bro
|
||||||
|
:caption:
|
||||||
|
:language: bro
|
||||||
|
:linenos:
|
||||||
|
|
||||||
.. btest:: data_struct_vector_declaration
|
.. code-block:: console
|
||||||
|
|
||||||
@TEST-EXEC: btest-rst-cmd bro ${DOC_ROOT}/scripting/data_struct_vector_declaration.bro
|
$ bro data_struct_vector_declaration.bro
|
||||||
|
contents of v1: [1, 2, 3, 4]
|
||||||
|
length of v1: 4
|
||||||
|
contents of v2: [1, 2, 3, 4]
|
||||||
|
length of v2: 4
|
||||||
|
|
||||||
In a lot of cases, storing elements in a vector is simply a precursor
|
In a lot of cases, storing elements in a vector is simply a precursor
|
||||||
to then iterating over them. Iterating over a vector is easy with the
|
to then iterating over them. Iterating over a vector is easy with the
|
||||||
|
@ -595,12 +841,17 @@ called ``i`` which will hold the index of the current element in the
|
||||||
vector. Using ``i`` as an index to addr_vector we can access the
|
vector. Using ``i`` as an index to addr_vector we can access the
|
||||||
current item in the vector with ``addr_vector[i]``.
|
current item in the vector with ``addr_vector[i]``.
|
||||||
|
|
||||||
.. btest-include:: ${DOC_ROOT}/scripting/data_struct_vector_iter.bro
|
.. literalinclude:: data_struct_vector_iter.bro
|
||||||
|
:caption:
|
||||||
|
:language: bro
|
||||||
|
:linenos:
|
||||||
|
|
||||||
.. btest:: data_struct_vector_iter
|
.. code-block:: console
|
||||||
|
|
||||||
@TEST-EXEC: btest-rst-cmd bro -b ${DOC_ROOT}/scripting/data_struct_vector_iter.bro
|
|
||||||
|
|
||||||
|
$ bro -b data_struct_vector_iter.bro
|
||||||
|
1.2.0.0/18
|
||||||
|
2.3.0.0/18
|
||||||
|
3.4.0.0/18
|
||||||
|
|
||||||
Data Types Revisited
|
Data Types Revisited
|
||||||
--------------------
|
--------------------
|
||||||
|
@ -653,7 +904,10 @@ your scripts. The following example below uses a Bro script to
|
||||||
determine if a series of IP addresses are within a set of subnets
|
determine if a series of IP addresses are within a set of subnets
|
||||||
using a 20 bit subnet mask.
|
using a 20 bit subnet mask.
|
||||||
|
|
||||||
.. btest-include:: ${DOC_ROOT}/scripting/data_type_subnets.bro
|
.. literalinclude:: data_type_subnets.bro
|
||||||
|
:caption:
|
||||||
|
:language: bro
|
||||||
|
:linenos:
|
||||||
|
|
||||||
Because this is a script that doesn't use any kind of network
|
Because this is a script that doesn't use any kind of network
|
||||||
analysis, we can handle the event :bro:id:`bro_init` which is always
|
analysis, we can handle the event :bro:id:`bro_init` which is always
|
||||||
|
@ -669,9 +923,13 @@ 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.
|
||||||
|
|
||||||
.. btest:: data_type_subnets
|
.. code-block:: console
|
||||||
|
|
||||||
@TEST-EXEC: btest-rst-cmd bro ${DOC_ROOT}/scripting/data_type_subnets.bro
|
$ bro data_type_subnets.bro
|
||||||
|
172.16.4.56 belongs to subnet 172.16.0.0/20
|
||||||
|
172.16.47.254 belongs to subnet 172.16.32.0/20
|
||||||
|
172.16.22.45 belongs to subnet 172.16.16.0/20
|
||||||
|
172.16.1.1 belongs to subnet 172.16.0.0/20
|
||||||
|
|
||||||
time
|
time
|
||||||
~~~~
|
~~~~
|
||||||
|
@ -693,14 +951,26 @@ timestamp and an indication of who the originator and responder were.
|
||||||
We use the ``strftime`` format string of ``%Y%M%d %H:%m:%S`` to
|
We use the ``strftime`` format string of ``%Y%M%d %H:%m:%S`` to
|
||||||
produce a common date time formatted time stamp.
|
produce a common date time formatted time stamp.
|
||||||
|
|
||||||
.. btest-include:: ${DOC_ROOT}/scripting/data_type_time.bro
|
.. literalinclude:: data_type_time.bro
|
||||||
|
:caption:
|
||||||
|
:language: bro
|
||||||
|
:linenos:
|
||||||
|
|
||||||
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.
|
||||||
|
|
||||||
.. btest:: data_type_time
|
.. code-block:: console
|
||||||
|
|
||||||
@TEST-EXEC: btest-rst-cmd bro -r ${TRACES}/wikipedia.trace ${DOC_ROOT}/scripting/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.3\x0a
|
||||||
|
2011/06/18 19:03:08: New connection established from 141.142.220.118 to 208.80.152.3\x0a
|
||||||
|
2011/06/18 19:03:08: New connection established from 141.142.220.118 to 208.80.152.3\x0a
|
||||||
|
2011/06/18 19:03:08: New connection established from 141.142.220.118 to 208.80.152.3\x0a
|
||||||
|
2011/06/18 19:03:08: New connection established from 141.142.220.118 to 208.80.152.3\x0a
|
||||||
|
2011/06/18 19:03:08: New connection established from 141.142.220.118 to 208.80.152.3\x0a
|
||||||
|
2011/06/18 19:03:08: New connection established from 141.142.220.118 to 208.80.152.2\x0a
|
||||||
|
2011/06/18 19:03:09: New connection established from 141.142.220.235 to 173.192.163.128\x0a
|
||||||
|
|
||||||
interval
|
interval
|
||||||
~~~~~~~~
|
~~~~~~~~
|
||||||
|
@ -730,15 +1000,35 @@ operator. The script below amends the script started in the section
|
||||||
above to include a time delta value printed along with the connection
|
above to include a time delta value printed along with the connection
|
||||||
establishment report.
|
establishment report.
|
||||||
|
|
||||||
.. btest-include:: ${DOC_ROOT}/scripting/data_type_interval.bro
|
.. literalinclude:: data_type_interval.bro
|
||||||
|
:caption:
|
||||||
|
:language: bro
|
||||||
|
:linenos:
|
||||||
|
|
||||||
This time, when we execute the script we see an additional line in the
|
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.
|
||||||
|
|
||||||
.. btest:: data_type_interval
|
.. code-block:: console
|
||||||
|
|
||||||
@TEST-EXEC: btest-rst-cmd bro -r ${TRACES}/wikipedia.trace ${DOC_ROOT}/scripting/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.3
|
||||||
|
Time since last connection: 132.0 msecs 97.0 usecs
|
||||||
|
2011/06/18 19:03:08: New connection established from 141.142.220.118 to 208.80.152.3
|
||||||
|
Time since last connection: 177.0 usecs
|
||||||
|
2011/06/18 19:03:08: New connection established from 141.142.220.118 to 208.80.152.3
|
||||||
|
Time since last connection: 2.0 msecs 177.0 usecs
|
||||||
|
2011/06/18 19:03:08: New connection established from 141.142.220.118 to 208.80.152.3
|
||||||
|
Time since last connection: 33.0 msecs 898.0 usecs
|
||||||
|
2011/06/18 19:03:08: New connection established from 141.142.220.118 to 208.80.152.3
|
||||||
|
Time since last connection: 35.0 usecs
|
||||||
|
2011/06/18 19:03:08: New connection established from 141.142.220.118 to 208.80.152.3
|
||||||
|
Time since last connection: 2.0 msecs 532.0 usecs
|
||||||
|
2011/06/18 19:03:08: New connection established from 141.142.220.118 to 208.80.152.2
|
||||||
|
Time since last connection: 7.0 msecs 866.0 usecs
|
||||||
|
2011/06/18 19:03:09: New connection established from 141.142.220.235 to 173.192.163.128
|
||||||
|
Time since last connection: 817.0 msecs 703.0 usecs
|
||||||
|
|
||||||
|
|
||||||
Pattern
|
Pattern
|
||||||
|
@ -755,7 +1045,10 @@ adheres to a strict format, requiring the regular expression or
|
||||||
pattern constant to be on the left side of the ``in`` operator and the
|
pattern constant to be on the left side of the ``in`` operator and the
|
||||||
string against which it will be tested to be on the right.
|
string against which it will be tested to be on the right.
|
||||||
|
|
||||||
.. btest-include:: ${DOC_ROOT}/scripting/data_type_pattern_01.bro
|
.. literalinclude:: data_type_pattern_01.bro
|
||||||
|
:caption:
|
||||||
|
:language: bro
|
||||||
|
:linenos:
|
||||||
|
|
||||||
In the sample above, two local variables are declared to hold our
|
In the sample above, two local variables are declared to hold our
|
||||||
sample sentence and regular expression. Our regular expression in
|
sample sentence and regular expression. Our regular expression in
|
||||||
|
@ -771,9 +1064,12 @@ 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.
|
||||||
|
|
||||||
.. btest:: data_type_pattern
|
.. code-block:: console
|
||||||
|
|
||||||
@TEST-EXEC: btest-rst-cmd bro ${DOC_ROOT}/scripting/data_type_pattern_01.bro
|
$ bro data_type_pattern_01.bro
|
||||||
|
The
|
||||||
|
brown fox jumps over the
|
||||||
|
dog.
|
||||||
|
|
||||||
Patterns can also be used to compare strings using equality and
|
Patterns can also be used to compare strings using equality and
|
||||||
inequality operators through the ``==`` and ``!=`` operators
|
inequality operators through the ``==`` and ``!=`` operators
|
||||||
|
@ -783,13 +1079,13 @@ ternary conditional statements to illustrate the use of the ``==``
|
||||||
operator with patterns. The output is altered based
|
operator with patterns. The output is altered based
|
||||||
on the result of the comparison between the pattern and the string.
|
on the result of the comparison between the pattern and the string.
|
||||||
|
|
||||||
.. btest-include:: ${DOC_ROOT}/scripting/data_type_pattern_02.bro
|
.. literalinclude:: data_type_pattern_02.bro
|
||||||
|
|
||||||
.. btest:: data_type_pattern_02
|
|
||||||
|
|
||||||
@TEST-EXEC: btest-rst-cmd bro ${DOC_ROOT}/scripting/data_type_pattern_02.bro
|
|
||||||
|
|
||||||
|
.. code-block:: console
|
||||||
|
|
||||||
|
$ bro data_type_pattern_02.bro
|
||||||
|
equality and /^?(equal)$?/ are not equal
|
||||||
|
equality and /^?(equality)$?/ are equal
|
||||||
|
|
||||||
Record Data Type
|
Record Data Type
|
||||||
----------------
|
----------------
|
||||||
|
@ -809,7 +1105,10 @@ example of the ``record`` data type in the earlier sections, the
|
||||||
:bro:type:`Conn::Info`, which corresponds to the fields logged into
|
:bro:type:`Conn::Info`, which corresponds to the fields logged into
|
||||||
``conn.log``, is shown by the excerpt below.
|
``conn.log``, is shown by the excerpt below.
|
||||||
|
|
||||||
.. btest-include:: ${DOC_ROOT}/scripting/data_type_record.bro
|
.. literalinclude:: data_type_record.bro
|
||||||
|
:caption:
|
||||||
|
:language: bro
|
||||||
|
:linenos:
|
||||||
|
|
||||||
Looking at the structure of the definition, a new collection of data
|
Looking at the structure of the definition, a new collection of data
|
||||||
types is being defined as a type called ``Info``. Since this type
|
types is being defined as a type called ``Info``. Since this type
|
||||||
|
@ -822,11 +1121,20 @@ that make up the record. The individual fields that make up the new
|
||||||
record are not limited in type or number as long as the name for each
|
record are not limited in type or number as long as the name for each
|
||||||
field is unique.
|
field is unique.
|
||||||
|
|
||||||
.. btest-include:: ${DOC_ROOT}/scripting/data_struct_record_01.bro
|
.. literalinclude:: data_struct_record_01.bro
|
||||||
|
:caption:
|
||||||
|
:language: bro
|
||||||
|
:linenos:
|
||||||
|
|
||||||
.. btest:: data_struct_record_01
|
.. code-block:: console
|
||||||
|
|
||||||
@TEST-EXEC: btest-rst-cmd bro ${DOC_ROOT}/scripting/data_struct_record_01.bro
|
$ bro data_struct_record_01.bro
|
||||||
|
Service: dns(RFC1035)
|
||||||
|
port: 53/udp
|
||||||
|
port: 53/tcp
|
||||||
|
Service: http(RFC2616)
|
||||||
|
port: 8080/tcp
|
||||||
|
port: 80/tcp
|
||||||
|
|
||||||
The sample above shows a simple type definition that includes a
|
The sample above shows a simple type definition that includes a
|
||||||
string, a set of ports, and a count to define a service type. Also
|
string, a set of ports, and a count to define a service type. Also
|
||||||
|
@ -843,11 +1151,18 @@ records are even valid as fields within another record. We can extend
|
||||||
the example above to include another record that contains a Service
|
the example above to include another record that contains a Service
|
||||||
record.
|
record.
|
||||||
|
|
||||||
.. btest-include:: ${DOC_ROOT}/scripting/data_struct_record_02.bro
|
.. literalinclude:: data_struct_record_02.bro
|
||||||
|
|
||||||
.. btest:: data_struct_record_02
|
.. code-block:: console
|
||||||
|
|
||||||
@TEST-EXEC: btest-rst-cmd bro ${DOC_ROOT}/scripting/data_struct_record_02.bro
|
$ bro data_struct_record_02.bro
|
||||||
|
System: morlock
|
||||||
|
Service: http(RFC2616)
|
||||||
|
port: 8080/tcp
|
||||||
|
port: 80/tcp
|
||||||
|
Service: dns(RFC1035)
|
||||||
|
port: 53/udp
|
||||||
|
port: 53/tcp
|
||||||
|
|
||||||
The example above includes a second record type in which a field is
|
The example above includes a second record type in which a field is
|
||||||
used as the data type for a set. Records can be repeatedly nested
|
used as the data type for a set. Records can be repeatedly nested
|
||||||
|
@ -858,8 +1173,12 @@ 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.
|
||||||
|
|
||||||
.. btest-include:: ${BRO_SRC_ROOT}/scripts/base/init-bare.bro
|
.. code-block:: bro
|
||||||
:lines: 12,19,26
|
:caption: init-bare.bro
|
||||||
|
|
||||||
|
type string_array: table[count] of string;
|
||||||
|
type string_set: set[string];
|
||||||
|
type addr_set: set[addr];
|
||||||
|
|
||||||
The three lines above alias a type of data structure to a descriptive
|
The three lines above alias a type of data structure to a descriptive
|
||||||
name. Functionally, the operations are the same, however, each of the
|
name. Functionally, the operations are the same, however, each of the
|
||||||
|
@ -916,11 +1235,24 @@ It's always best to work through the problem once, simulating the
|
||||||
desired output with ``print`` and ``fmt`` before attempting to dive
|
desired output with ``print`` and ``fmt`` before attempting to dive
|
||||||
into the Logging Framework.
|
into the Logging Framework.
|
||||||
|
|
||||||
.. btest-include:: ${DOC_ROOT}/scripting/framework_logging_factorial_01.bro
|
.. literalinclude:: framework_logging_factorial_01.bro
|
||||||
|
:caption:
|
||||||
|
:language: bro
|
||||||
|
:linenos:
|
||||||
|
|
||||||
.. btest:: framework_logging_factorial
|
.. code-block:: console
|
||||||
|
|
||||||
@TEST-EXEC: btest-rst-cmd bro ${DOC_ROOT}/scripting/framework_logging_factorial_01.bro
|
$ bro framework_logging_factorial_01.bro
|
||||||
|
1
|
||||||
|
2
|
||||||
|
6
|
||||||
|
24
|
||||||
|
120
|
||||||
|
720
|
||||||
|
5040
|
||||||
|
40320
|
||||||
|
362880
|
||||||
|
3628800
|
||||||
|
|
||||||
This script defines a factorial function to recursively calculate the
|
This script defines a factorial function to recursively calculate the
|
||||||
factorial of a unsigned integer passed as an argument to the function. Using
|
factorial of a unsigned integer passed as an argument to the function. Using
|
||||||
|
@ -930,7 +1262,10 @@ calculations correctly as well get an idea of the answers ourselves.
|
||||||
The output of the script aligns with what we expect so now it's time
|
The output of the script aligns with what we expect so now it's time
|
||||||
to integrate the Logging Framework.
|
to integrate the Logging Framework.
|
||||||
|
|
||||||
.. btest-include:: ${DOC_ROOT}/scripting/framework_logging_factorial_02.bro
|
.. literalinclude:: framework_logging_factorial_02.bro
|
||||||
|
:caption:
|
||||||
|
:language: bro
|
||||||
|
:linenos:
|
||||||
|
|
||||||
As mentioned above we have to perform a few steps before we can
|
As mentioned above we have to perform a few steps before we can
|
||||||
issue the :bro:id:`Log::write` method and produce a logfile.
|
issue the :bro:id:`Log::write` method and produce a logfile.
|
||||||
|
@ -962,10 +1297,29 @@ 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.
|
||||||
|
|
||||||
.. btest:: framework_logging_factorial-2
|
.. code-block:: console
|
||||||
|
|
||||||
@TEST-EXEC: btest-rst-cmd bro ${DOC_ROOT}/scripting/framework_logging_factorial_02.bro
|
$ bro framework_logging_factorial_02.bro
|
||||||
@TEST-EXEC: btest-rst-include factor.log
|
$ cat factor.log
|
||||||
|
#separator \x09
|
||||||
|
#set_separator ,
|
||||||
|
#empty_field (empty)
|
||||||
|
#unset_field -
|
||||||
|
#path factor
|
||||||
|
#open 2018-12-14-21-47-18
|
||||||
|
#fields num factorial_num
|
||||||
|
#types count count
|
||||||
|
1 1
|
||||||
|
2 2
|
||||||
|
3 6
|
||||||
|
4 24
|
||||||
|
5 120
|
||||||
|
6 720
|
||||||
|
7 5040
|
||||||
|
8 40320
|
||||||
|
9 362880
|
||||||
|
10 3628800
|
||||||
|
#close 2018-12-14-21-47-18
|
||||||
|
|
||||||
While the previous example is a simplistic one, it serves to
|
While the previous example is a simplistic one, it serves to
|
||||||
demonstrate the small pieces of script code hat need to be in place in
|
demonstrate the small pieces of script code hat need to be in place in
|
||||||
|
@ -993,7 +1347,10 @@ example we've been using, let's extend it so as to write any factorial
|
||||||
which is a factor of 5 to an alternate file, while writing the
|
which is a factor of 5 to an alternate file, while writing the
|
||||||
remaining logs to factor.log.
|
remaining logs to factor.log.
|
||||||
|
|
||||||
.. btest-include:: ${DOC_ROOT}/scripting/framework_logging_factorial_03.bro
|
.. literalinclude:: framework_logging_factorial_03.bro
|
||||||
|
:caption:
|
||||||
|
:language: bro
|
||||||
|
:linenos:
|
||||||
|
|
||||||
To dynamically alter the file in which a stream writes its logs, a
|
To dynamically alter the file in which a stream writes its logs, a
|
||||||
filter can specify a function that returns a string to be used as the
|
filter can specify a function that returns a string to be used as the
|
||||||
|
@ -1014,10 +1371,25 @@ 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.
|
||||||
|
|
||||||
.. btest:: framework_logging_factorial-3
|
.. code-block:: console
|
||||||
|
|
||||||
@TEST-EXEC: btest-rst-cmd bro ${DOC_ROOT}/scripting/framework_logging_factorial_03.bro
|
$ bro framework_logging_factorial_03.bro
|
||||||
@TEST-EXEC: btest-rst-include factor-mod5.log
|
$ cat factor-mod5.log
|
||||||
|
#separator \x09
|
||||||
|
#set_separator ,
|
||||||
|
#empty_field (empty)
|
||||||
|
#unset_field -
|
||||||
|
#path factor-mod5
|
||||||
|
#open 2018-12-14-21-47-18
|
||||||
|
#fields num factorial_num
|
||||||
|
#types count count
|
||||||
|
5 120
|
||||||
|
6 720
|
||||||
|
7 5040
|
||||||
|
8 40320
|
||||||
|
9 362880
|
||||||
|
10 3628800
|
||||||
|
#close 2018-12-14-21-47-1
|
||||||
|
|
||||||
The ability of Bro to generate easily customizable and extensible logs
|
The ability of Bro to generate easily customizable and extensible logs
|
||||||
which remain easily parsable is a big part of the reason Bro has
|
which remain easily parsable is a big part of the reason Bro has
|
||||||
|
@ -1047,7 +1419,10 @@ block and define the value to be passed to it, in this case the
|
||||||
``Factor::Info`` record. We then list the ``log_factor`` function as
|
``Factor::Info`` record. We then list the ``log_factor`` function as
|
||||||
the ``$ev`` field in the call to ``Log::create_stream``
|
the ``$ev`` field in the call to ``Log::create_stream``
|
||||||
|
|
||||||
.. btest-include:: ${DOC_ROOT}/scripting/framework_logging_factorial_04.bro
|
.. literalinclude:: framework_logging_factorial_04.bro
|
||||||
|
:caption:
|
||||||
|
:language: bro
|
||||||
|
:linenos:
|
||||||
|
|
||||||
|
|
||||||
Raising Notices
|
Raising Notices
|
||||||
|
@ -1098,8 +1473,60 @@ 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.
|
||||||
|
|
||||||
.. btest-include:: ${BRO_SRC_ROOT}/scripts/policy/protocols/ssh/interesting-hostnames.bro
|
.. code-block:: bro
|
||||||
:lines: 1-52
|
:caption: scripts/policy/protocols/ssh/interesting-hostnames.bro
|
||||||
|
|
||||||
|
##! This script will generate a notice if an apparent SSH login originates
|
||||||
|
##! or heads to a host with a reverse hostname that looks suspicious. By
|
||||||
|
##! default, the regular expression to match "interesting" hostnames includes
|
||||||
|
##! names that are typically used for infrastructure hosts like nameservers,
|
||||||
|
##! mail servers, web servers and ftp servers.
|
||||||
|
|
||||||
|
@load base/frameworks/notice
|
||||||
|
|
||||||
|
module SSH;
|
||||||
|
|
||||||
|
export {
|
||||||
|
redef enum Notice::Type += {
|
||||||
|
## Generated if a login originates or responds with a host where
|
||||||
|
## the reverse hostname lookup resolves to a name matched by the
|
||||||
|
## :bro:id:`SSH::interesting_hostnames` regular expression.
|
||||||
|
Interesting_Hostname_Login,
|
||||||
|
};
|
||||||
|
|
||||||
|
## Strange/bad host names to see successful SSH logins from or to.
|
||||||
|
option interesting_hostnames =
|
||||||
|
/^d?ns[0-9]*\./ |
|
||||||
|
/^smtp[0-9]*\./ |
|
||||||
|
/^mail[0-9]*\./ |
|
||||||
|
/^pop[0-9]*\./ |
|
||||||
|
/^imap[0-9]*\./ |
|
||||||
|
/^www[0-9]*\./ |
|
||||||
|
/^ftp[0-9]*\./;
|
||||||
|
}
|
||||||
|
|
||||||
|
function check_ssh_hostname(id: conn_id, uid: string, host: addr)
|
||||||
|
{
|
||||||
|
when ( local hostname = lookup_addr(host) )
|
||||||
|
{
|
||||||
|
if ( interesting_hostnames in hostname )
|
||||||
|
{
|
||||||
|
NOTICE([$note=Interesting_Hostname_Login,
|
||||||
|
$msg=fmt("Possible SSH login involving a %s %s with an interesting hostname.",
|
||||||
|
Site::is_local_addr(host) ? "local" : "remote",
|
||||||
|
host == id$orig_h ? "client" : "server"),
|
||||||
|
$sub=hostname, $id=id, $uid=uid]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
event ssh_auth_successful(c: connection, auth_method_none: bool)
|
||||||
|
{
|
||||||
|
for ( host in set(c$id$orig_h, c$id$resp_h) )
|
||||||
|
{
|
||||||
|
check_ssh_hostname(c$id, c$uid, host);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
While much of the script relates to the actual detection, the parts
|
While much of the script relates to the actual detection, the parts
|
||||||
specific to the Notice Framework are actually quite interesting in
|
specific to the Notice Framework are actually quite interesting in
|
||||||
|
@ -1137,7 +1564,10 @@ action based on the answer. The hook below adds the
|
||||||
``SSH::Interesting_Hostname_Login`` notice raised in the
|
``SSH::Interesting_Hostname_Login`` notice raised in the
|
||||||
:doc:`/scripts/policy/protocols/ssh/interesting-hostnames.bro` script.
|
:doc:`/scripts/policy/protocols/ssh/interesting-hostnames.bro` script.
|
||||||
|
|
||||||
.. btest-include:: ${DOC_ROOT}/scripting/framework_notice_hook_01.bro
|
.. literalinclude:: framework_notice_hook_01.bro
|
||||||
|
:caption:
|
||||||
|
:language: bro
|
||||||
|
:linenos:
|
||||||
|
|
||||||
In the example above we've added ``Notice::ACTION_EMAIL`` to the
|
In the example above we've added ``Notice::ACTION_EMAIL`` to the
|
||||||
``n$actions`` set. This set, defined in the Notice Framework scripts,
|
``n$actions`` set. This set, defined in the Notice Framework scripts,
|
||||||
|
@ -1174,8 +1604,14 @@ 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.
|
||||||
|
|
||||||
.. btest-include:: ${BRO_SRC_ROOT}/scripts/policy/protocols/ssl/expiring-certs.bro
|
.. code-block:: bro
|
||||||
:lines: 64-68
|
:caption: scripts/policy/protocols/ssl/expiring-certs.bro
|
||||||
|
|
||||||
|
NOTICE([$note=Certificate_Expires_Soon,
|
||||||
|
$msg=fmt("Certificate %s is going to expire at %T", cert$subject, cert$not_valid_after),
|
||||||
|
$conn=c, $suppress_for=1day,
|
||||||
|
$identifier=cat(c$id$resp_h, c$id$resp_p, hash),
|
||||||
|
$fuid=fuid]);
|
||||||
|
|
||||||
In the :doc:`/scripts/policy/protocols/ssl/expiring-certs.bro` script
|
In the :doc:`/scripts/policy/protocols/ssl/expiring-certs.bro` script
|
||||||
which identifies when SSL certificates are set to expire and raises
|
which identifies when SSL certificates are set to expire and raises
|
||||||
|
@ -1206,7 +1642,10 @@ environment in which it is be run. Using the example of
|
||||||
``SSL::Certificate_Expires_Soon`` to configure the ``$suppress_for``
|
``SSL::Certificate_Expires_Soon`` to configure the ``$suppress_for``
|
||||||
variable to a shorter time.
|
variable to a shorter time.
|
||||||
|
|
||||||
.. btest-include:: ${DOC_ROOT}/scripting/framework_notice_hook_suppression_01.bro
|
.. literalinclude:: framework_notice_hook_suppression_01.bro
|
||||||
|
:caption:
|
||||||
|
:language: bro
|
||||||
|
:linenos:
|
||||||
|
|
||||||
While ``Notice::policy`` hooks allow you to build custom
|
While ``Notice::policy`` hooks allow you to build custom
|
||||||
predicate-based policies for a deployment, there are bound to be times
|
predicate-based policies for a deployment, there are bound to be times
|
||||||
|
@ -1253,11 +1692,17 @@ suppression from a notice while ``Notice::type_suppression_intervals``
|
||||||
can be used to alter the suppression interval defined by $suppress_for
|
can be used to alter the suppression interval defined by $suppress_for
|
||||||
in the call to ``NOTICE``.
|
in the call to ``NOTICE``.
|
||||||
|
|
||||||
.. btest-include:: ${DOC_ROOT}/scripting/framework_notice_shortcuts_01.bro
|
.. literalinclude:: framework_notice_shortcuts_01.bro
|
||||||
|
:caption:
|
||||||
|
:language: bro
|
||||||
|
:linenos:
|
||||||
|
|
||||||
The Notice Policy shortcut above adds the ``Notice::Type`` of
|
The Notice Policy shortcut above adds the ``Notice::Type`` of
|
||||||
``SSH::Interesting_Hostname_Login`` to the
|
``SSH::Interesting_Hostname_Login`` to the
|
||||||
``Notice::emailed_types`` set while the shortcut below alters the length
|
``Notice::emailed_types`` set while the shortcut below alters the length
|
||||||
of time for which those notices will be suppressed.
|
of time for which those notices will be suppressed.
|
||||||
|
|
||||||
.. btest-include:: ${DOC_ROOT}/scripting/framework_notice_shortcuts_02.bro
|
.. literalinclude:: framework_notice_shortcuts_02.bro
|
||||||
|
:caption:
|
||||||
|
:language: bro
|
||||||
|
:linenos:
|
||||||
|
|
|
@ -1,26 +0,0 @@
|
||||||
.. rst-class:: btest-cmd
|
|
||||||
|
|
||||||
.. code-block:: none
|
|
||||||
:linenos:
|
|
||||||
:emphasize-lines: 1,1
|
|
||||||
|
|
||||||
# bro -r tls/tls-expired-cert.trace conditional-notice.bro
|
|
||||||
|
|
||||||
.. rst-class:: btest-cmd
|
|
||||||
|
|
||||||
.. code-block:: none
|
|
||||||
:linenos:
|
|
||||||
:emphasize-lines: 1,1
|
|
||||||
|
|
||||||
# cat notice.log
|
|
||||||
#separator \x09
|
|
||||||
#set_separator ,
|
|
||||||
#empty_field (empty)
|
|
||||||
#unset_field -
|
|
||||||
#path notice
|
|
||||||
#open 2017-12-21-02-23-46
|
|
||||||
#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p fuid file_mime_type file_desc proto note msg sub src dst p n peer_descr actions suppress_for dropped remote_location.country_code remote_location.region remote_location.city remote_location.latitude remote_location.longitude
|
|
||||||
#types time string addr port addr port string string string enum enum string string addr addr port count string set[enum] interval bool string string string double double
|
|
||||||
1394745603.293028 CHhAvVGS1DHFjwGM9 192.168.4.149 60539 87.98.220.10 443 F1fX1R2cDOzbvg17ye - - tcp SSL::Certificate_Expired Certificate CN=www.spidh.org,OU=COMODO SSL,OU=Domain Control Validated expired at 2014-03-04-23:59:59.000000000 - 192.168.4.149 87.98.220.10 443 - - Notice::ACTION_EMAIL,Notice::ACTION_LOG 86400.000000 F - - - - -
|
|
||||||
#close 2017-12-21-02-23-46
|
|
||||||
|
|
|
@ -1,11 +0,0 @@
|
||||||
.. rst-class:: btest-cmd
|
|
||||||
|
|
||||||
.. code-block:: none
|
|
||||||
:linenos:
|
|
||||||
:emphasize-lines: 1,1
|
|
||||||
|
|
||||||
# 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={
|
|
||||||
|
|
||||||
}, history=ShADadFf, uid=CHhAvVGS1DHFjwGM9, tunnel=<uninitialized>, vlan=<uninitialized>, inner_vlan=<uninitialized>, conn=[ts=1362692526.869344, uid=CHhAvVGS1DHFjwGM9, id=[orig_h=141.142.228.5, orig_p=59856/tcp, resp_h=192.150.187.43, resp_p=80/tcp], proto=tcp, service=<uninitialized>, duration=0.211484, orig_bytes=136, resp_bytes=5007, conn_state=SF, local_orig=<uninitialized>, local_resp=<uninitialized>, missed_bytes=0, history=ShADadFf, orig_pkts=7, orig_ip_bytes=512, resp_pkts=7, resp_ip_bytes=5379, tunnel_parents=<uninitialized>], extract_orig=F, extract_resp=F, thresholds=<uninitialized>]
|
|
||||||
|
|
|
@ -1,15 +0,0 @@
|
||||||
.. rst-class:: btest-cmd
|
|
||||||
|
|
||||||
.. code-block:: none
|
|
||||||
:linenos:
|
|
||||||
:emphasize-lines: 1,1
|
|
||||||
|
|
||||||
# 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={
|
|
||||||
|
|
||||||
}, history=ShADadFf, uid=CHhAvVGS1DHFjwGM9, tunnel=<uninitialized>, vlan=<uninitialized>, inner_vlan=<uninitialized>, conn=[ts=1362692526.869344, uid=CHhAvVGS1DHFjwGM9, id=[orig_h=141.142.228.5, orig_p=59856/tcp, resp_h=192.150.187.43, resp_p=80/tcp], proto=tcp, service=<uninitialized>, duration=0.211484, orig_bytes=136, resp_bytes=5007, conn_state=SF, local_orig=<uninitialized>, local_resp=<uninitialized>, missed_bytes=0, history=ShADadFf, orig_pkts=7, orig_ip_bytes=512, resp_pkts=7, resp_ip_bytes=5379, tunnel_parents=<uninitialized>], extract_orig=F, extract_resp=F, thresholds=<uninitialized>, http=[ts=1362692526.939527, uid=CHhAvVGS1DHFjwGM9, id=[orig_h=141.142.228.5, orig_p=59856/tcp, resp_h=192.150.187.43, resp_p=80/tcp], trans_depth=1, method=GET, host=bro.org, uri=/download/CHANGES.bro-aux.txt, referrer=<uninitialized>, version=1.1, user_agent=Wget/1.14 (darwin12.2.0), request_body_len=0, response_body_len=4705, status_code=200, status_msg=OK, info_code=<uninitialized>, info_msg=<uninitialized>, tags={
|
|
||||||
|
|
||||||
}, username=<uninitialized>, password=<uninitialized>, capture_password=F, proxied=<uninitialized>, range_request=F, orig_fuids=<uninitialized>, orig_filenames=<uninitialized>, orig_mime_types=<uninitialized>, resp_fuids=[FakNcS1Jfe01uljb3], resp_filenames=<uninitialized>, resp_mime_types=[text/plain], current_entity=<uninitialized>, orig_mime_depth=1, resp_mime_depth=1], http_state=[pending={
|
|
||||||
|
|
||||||
}, current_request=1, current_response=1, trans_depth=1]]
|
|
||||||
|
|
|
@ -1,14 +0,0 @@
|
||||||
.. rst-class:: btest-cmd
|
|
||||||
|
|
||||||
.. code-block:: none
|
|
||||||
:linenos:
|
|
||||||
:emphasize-lines: 1,1
|
|
||||||
|
|
||||||
# bro data_struct_record_01.bro
|
|
||||||
Service: dns(RFC1035)
|
|
||||||
port: 53/udp
|
|
||||||
port: 53/tcp
|
|
||||||
Service: http(RFC2616)
|
|
||||||
port: 8080/tcp
|
|
||||||
port: 80/tcp
|
|
||||||
|
|
|
@ -1,15 +0,0 @@
|
||||||
.. rst-class:: btest-cmd
|
|
||||||
|
|
||||||
.. code-block:: none
|
|
||||||
:linenos:
|
|
||||||
:emphasize-lines: 1,1
|
|
||||||
|
|
||||||
# bro data_struct_record_02.bro
|
|
||||||
System: morlock
|
|
||||||
Service: http(RFC2616)
|
|
||||||
port: 8080/tcp
|
|
||||||
port: 80/tcp
|
|
||||||
Service: dns(RFC1035)
|
|
||||||
port: 53/udp
|
|
||||||
port: 53/tcp
|
|
||||||
|
|
|
@ -1,16 +0,0 @@
|
||||||
.. rst-class:: btest-cmd
|
|
||||||
|
|
||||||
.. code-block:: none
|
|
||||||
:linenos:
|
|
||||||
:emphasize-lines: 1,1
|
|
||||||
|
|
||||||
# bro data_struct_set_declaration.bro
|
|
||||||
SSL Port: 22/tcp
|
|
||||||
SSL Port: 443/tcp
|
|
||||||
SSL Port: 587/tcp
|
|
||||||
SSL Port: 993/tcp
|
|
||||||
Non-SSL Port: 80/tcp
|
|
||||||
Non-SSL Port: 25/tcp
|
|
||||||
Non-SSL Port: 143/tcp
|
|
||||||
Non-SSL Port: 23/tcp
|
|
||||||
|
|
|
@ -1,12 +0,0 @@
|
||||||
.. rst-class:: btest-cmd
|
|
||||||
|
|
||||||
.. code-block:: none
|
|
||||||
:linenos:
|
|
||||||
:emphasize-lines: 1,1
|
|
||||||
|
|
||||||
# bro -b data_struct_table_complex.bro
|
|
||||||
Harakiri was released in 1962 by Shochiku Eiga studios, directed by Masaki Kobayashi and starring Tatsuya Nakadai
|
|
||||||
Goyokin was released in 1969 by Fuji studios, directed by Hideo Gosha and starring Tatsuya Nakadai
|
|
||||||
Tasogare Seibei was released in 2002 by Eisei Gekijo studios, directed by Yoji Yamada and starring Hiroyuki Sanada
|
|
||||||
Kiru was released in 1968 by Toho studios, directed by Kihachi Okamoto and starring Tatsuya Nakadai
|
|
||||||
|
|
|
@ -1,12 +0,0 @@
|
||||||
.. rst-class:: btest-cmd
|
|
||||||
|
|
||||||
.. code-block:: none
|
|
||||||
:linenos:
|
|
||||||
:emphasize-lines: 1,1
|
|
||||||
|
|
||||||
# bro data_struct_table_declaration.bro
|
|
||||||
Service Name: SSH - Common Port: 22/tcp
|
|
||||||
Service Name: HTTPS - Common Port: 443/tcp
|
|
||||||
Service Name: SMTPS - Common Port: 587/tcp
|
|
||||||
Service Name: IMAPS - Common Port: 993/tcp
|
|
||||||
|
|
|
@ -1,12 +0,0 @@
|
||||||
.. rst-class:: btest-cmd
|
|
||||||
|
|
||||||
.. code-block:: none
|
|
||||||
:linenos:
|
|
||||||
:emphasize-lines: 1,1
|
|
||||||
|
|
||||||
# bro data_struct_vector_declaration.bro
|
|
||||||
contents of v1: [1, 2, 3, 4]
|
|
||||||
length of v1: 4
|
|
||||||
contents of v2: [1, 2, 3, 4]
|
|
||||||
length of v2: 4
|
|
||||||
|
|
|
@ -1,11 +0,0 @@
|
||||||
.. rst-class:: btest-cmd
|
|
||||||
|
|
||||||
.. code-block:: none
|
|
||||||
:linenos:
|
|
||||||
:emphasize-lines: 1,1
|
|
||||||
|
|
||||||
# bro -b data_struct_vector_iter.bro
|
|
||||||
1.2.0.0/18
|
|
||||||
2.3.0.0/18
|
|
||||||
3.4.0.0/18
|
|
||||||
|
|
|
@ -1,12 +0,0 @@
|
||||||
.. rst-class:: btest-cmd
|
|
||||||
|
|
||||||
.. code-block:: none
|
|
||||||
:linenos:
|
|
||||||
:emphasize-lines: 1,1
|
|
||||||
|
|
||||||
# bro -b data_type_const.bro
|
|
||||||
{
|
|
||||||
[80/tcp] = WWW,
|
|
||||||
[6666/tcp] = IRC
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,25 +0,0 @@
|
||||||
.. rst-class:: btest-cmd
|
|
||||||
|
|
||||||
.. code-block:: none
|
|
||||||
:linenos:
|
|
||||||
:emphasize-lines: 1,1
|
|
||||||
|
|
||||||
# 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.3
|
|
||||||
Time since last connection: 132.0 msecs 97.0 usecs
|
|
||||||
2011/06/18 19:03:08: New connection established from 141.142.220.118 to 208.80.152.3
|
|
||||||
Time since last connection: 177.0 usecs
|
|
||||||
2011/06/18 19:03:08: New connection established from 141.142.220.118 to 208.80.152.3
|
|
||||||
Time since last connection: 2.0 msecs 177.0 usecs
|
|
||||||
2011/06/18 19:03:08: New connection established from 141.142.220.118 to 208.80.152.3
|
|
||||||
Time since last connection: 33.0 msecs 898.0 usecs
|
|
||||||
2011/06/18 19:03:08: New connection established from 141.142.220.118 to 208.80.152.3
|
|
||||||
Time since last connection: 35.0 usecs
|
|
||||||
2011/06/18 19:03:08: New connection established from 141.142.220.118 to 208.80.152.3
|
|
||||||
Time since last connection: 2.0 msecs 532.0 usecs
|
|
||||||
2011/06/18 19:03:08: New connection established from 141.142.220.118 to 208.80.152.2
|
|
||||||
Time since last connection: 7.0 msecs 866.0 usecs
|
|
||||||
2011/06/18 19:03:09: New connection established from 141.142.220.235 to 173.192.163.128
|
|
||||||
Time since last connection: 817.0 msecs 703.0 usecs
|
|
||||||
|
|
|
@ -1,11 +0,0 @@
|
||||||
.. rst-class:: btest-cmd
|
|
||||||
|
|
||||||
.. code-block:: none
|
|
||||||
:linenos:
|
|
||||||
:emphasize-lines: 1,1
|
|
||||||
|
|
||||||
# bro data_type_pattern_01.bro
|
|
||||||
The
|
|
||||||
brown fox jumps over the
|
|
||||||
dog.
|
|
||||||
|
|
|
@ -1,10 +0,0 @@
|
||||||
.. rst-class:: btest-cmd
|
|
||||||
|
|
||||||
.. code-block:: none
|
|
||||||
:linenos:
|
|
||||||
:emphasize-lines: 1,1
|
|
||||||
|
|
||||||
# bro data_type_pattern_02.bro
|
|
||||||
equality and /^?(equal)$?/ are not equal
|
|
||||||
equality and /^?(equality)$?/ are equal
|
|
||||||
|
|
|
@ -1,12 +0,0 @@
|
||||||
.. rst-class:: btest-cmd
|
|
||||||
|
|
||||||
.. code-block:: none
|
|
||||||
:linenos:
|
|
||||||
:emphasize-lines: 1,1
|
|
||||||
|
|
||||||
# bro data_type_subnets.bro
|
|
||||||
172.16.4.56 belongs to subnet 172.16.0.0/20
|
|
||||||
172.16.47.254 belongs to subnet 172.16.32.0/20
|
|
||||||
172.16.22.45 belongs to subnet 172.16.16.0/20
|
|
||||||
172.16.1.1 belongs to subnet 172.16.0.0/20
|
|
||||||
|
|
|
@ -1,17 +0,0 @@
|
||||||
.. rst-class:: btest-cmd
|
|
||||||
|
|
||||||
.. code-block:: none
|
|
||||||
:linenos:
|
|
||||||
:emphasize-lines: 1,1
|
|
||||||
|
|
||||||
# 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.3\x0a
|
|
||||||
2011/06/18 19:03:08: New connection established from 141.142.220.118 to 208.80.152.3\x0a
|
|
||||||
2011/06/18 19:03:08: New connection established from 141.142.220.118 to 208.80.152.3\x0a
|
|
||||||
2011/06/18 19:03:08: New connection established from 141.142.220.118 to 208.80.152.3\x0a
|
|
||||||
2011/06/18 19:03:08: New connection established from 141.142.220.118 to 208.80.152.3\x0a
|
|
||||||
2011/06/18 19:03:08: New connection established from 141.142.220.118 to 208.80.152.3\x0a
|
|
||||||
2011/06/18 19:03:08: New connection established from 141.142.220.118 to 208.80.152.2\x0a
|
|
||||||
2011/06/18 19:03:09: New connection established from 141.142.220.235 to 173.192.163.128\x0a
|
|
||||||
|
|
|
@ -1,17 +0,0 @@
|
||||||
.. rst-class:: btest-cmd
|
|
||||||
|
|
||||||
.. code-block:: none
|
|
||||||
:linenos:
|
|
||||||
:emphasize-lines: 1,1
|
|
||||||
|
|
||||||
# bro -r http/get.trace file_analysis_01.bro
|
|
||||||
file_state_remove
|
|
||||||
FakNcS1Jfe01uljb3
|
|
||||||
CHhAvVGS1DHFjwGM9
|
|
||||||
[orig_h=141.142.228.5, orig_p=59856/tcp, resp_h=192.150.187.43, resp_p=80/tcp]
|
|
||||||
HTTP
|
|
||||||
connection_state_remove
|
|
||||||
CHhAvVGS1DHFjwGM9
|
|
||||||
[orig_h=141.142.228.5, orig_p=59856/tcp, resp_h=192.150.187.43, resp_p=80/tcp]
|
|
||||||
HTTP
|
|
||||||
|
|
|
@ -1,10 +0,0 @@
|
||||||
.. rst-class:: btest-cmd
|
|
||||||
|
|
||||||
.. code-block:: none
|
|
||||||
:linenos:
|
|
||||||
:emphasize-lines: 1,1
|
|
||||||
|
|
||||||
# bro -r http/get.trace file_analysis_02.bro
|
|
||||||
new file, FakNcS1Jfe01uljb3
|
|
||||||
file_hash, FakNcS1Jfe01uljb3, md5, 397168fd09991a0e712254df7bc639ac
|
|
||||||
|
|
|
@ -1,11 +0,0 @@
|
||||||
.. rst-class:: btest-cmd
|
|
||||||
|
|
||||||
.. code-block:: none
|
|
||||||
:linenos:
|
|
||||||
:emphasize-lines: 1,1
|
|
||||||
|
|
||||||
# bro file_analysis_03.bro
|
|
||||||
new file, FZedLu4Ajcvge02jA8
|
|
||||||
file_hash, FZedLu4Ajcvge02jA8, md5, f0ef7081e1539ac00ef5b761b4fb01b3
|
|
||||||
file_state_remove
|
|
||||||
|
|
|
@ -1,14 +0,0 @@
|
||||||
.. rst-class:: btest-cmd
|
|
||||||
|
|
||||||
.. code-block:: none
|
|
||||||
:linenos:
|
|
||||||
:emphasize-lines: 1,1
|
|
||||||
|
|
||||||
# bro -r http/bro.org.pcap file_extraction.bro
|
|
||||||
Extracting file HTTP-FiIpIB2hRQSDBOSJRg.html
|
|
||||||
Extracting file HTTP-FMG4bMmVV64eOsCb.txt
|
|
||||||
Extracting file HTTP-FnaT2a3UDd093opCB9.txt
|
|
||||||
Extracting file HTTP-FfQGqj4Fhh3pH7nVQj.txt
|
|
||||||
Extracting file HTTP-FsvATF146kf1Emc21j.txt
|
|
||||||
[...]
|
|
||||||
|
|
|
@ -1,33 +0,0 @@
|
||||||
.. rst-class:: btest-cmd
|
|
||||||
|
|
||||||
.. code-block:: none
|
|
||||||
:linenos:
|
|
||||||
:emphasize-lines: 1,1
|
|
||||||
|
|
||||||
# bro framework_logging_factorial_02.bro
|
|
||||||
|
|
||||||
.. rst-class:: btest-include
|
|
||||||
|
|
||||||
.. code-block:: guess
|
|
||||||
:linenos:
|
|
||||||
|
|
||||||
#separator \x09
|
|
||||||
#set_separator ,
|
|
||||||
#empty_field (empty)
|
|
||||||
#unset_field -
|
|
||||||
#path factor
|
|
||||||
#open 2013-10-07-23-48-11
|
|
||||||
#fields num factorial_num
|
|
||||||
#types count count
|
|
||||||
1 1
|
|
||||||
2 2
|
|
||||||
3 6
|
|
||||||
4 24
|
|
||||||
5 120
|
|
||||||
6 720
|
|
||||||
7 5040
|
|
||||||
8 40320
|
|
||||||
9 362880
|
|
||||||
10 3628800
|
|
||||||
#close 2013-10-07-23-48-11
|
|
||||||
|
|
|
@ -1,29 +0,0 @@
|
||||||
.. rst-class:: btest-cmd
|
|
||||||
|
|
||||||
.. code-block:: none
|
|
||||||
:linenos:
|
|
||||||
:emphasize-lines: 1,1
|
|
||||||
|
|
||||||
# bro framework_logging_factorial_03.bro
|
|
||||||
|
|
||||||
.. rst-class:: btest-include
|
|
||||||
|
|
||||||
.. code-block:: guess
|
|
||||||
:linenos:
|
|
||||||
|
|
||||||
#separator \x09
|
|
||||||
#set_separator ,
|
|
||||||
#empty_field (empty)
|
|
||||||
#unset_field -
|
|
||||||
#path factor-mod5
|
|
||||||
#open 2013-10-07-23-48-12
|
|
||||||
#fields num factorial_num
|
|
||||||
#types count count
|
|
||||||
5 120
|
|
||||||
6 720
|
|
||||||
7 5040
|
|
||||||
8 40320
|
|
||||||
9 362880
|
|
||||||
10 3628800
|
|
||||||
#close 2013-10-07-23-48-12
|
|
||||||
|
|
|
@ -1,18 +0,0 @@
|
||||||
.. rst-class:: btest-cmd
|
|
||||||
|
|
||||||
.. code-block:: none
|
|
||||||
:linenos:
|
|
||||||
:emphasize-lines: 1,1
|
|
||||||
|
|
||||||
# bro framework_logging_factorial_01.bro
|
|
||||||
1
|
|
||||||
2
|
|
||||||
6
|
|
||||||
24
|
|
||||||
120
|
|
||||||
720
|
|
||||||
5040
|
|
||||||
40320
|
|
||||||
362880
|
|
||||||
3628800
|
|
||||||
|
|
|
@ -1,24 +0,0 @@
|
||||||
.. rst-class:: btest-cmd
|
|
||||||
|
|
||||||
.. code-block:: none
|
|
||||||
:linenos:
|
|
||||||
:emphasize-lines: 1,1
|
|
||||||
|
|
||||||
# bro -r ftp/bruteforce.pcap protocols/ftp/detect-bruteforcing.bro
|
|
||||||
|
|
||||||
.. rst-class:: btest-include
|
|
||||||
|
|
||||||
.. code-block:: guess
|
|
||||||
:linenos:
|
|
||||||
|
|
||||||
#separator \x09
|
|
||||||
#set_separator ,
|
|
||||||
#empty_field (empty)
|
|
||||||
#unset_field -
|
|
||||||
#path notice
|
|
||||||
#open 2017-12-21-02-24-08
|
|
||||||
#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p fuid file_mime_type file_desc proto note msg sub src dst p n peer_descr actions suppress_for dropped remote_location.country_code remote_location.region remote_location.city remote_location.latitude remote_location.longitude
|
|
||||||
#types time string addr port addr port string string string enum enum string string addr addr port count string set[enum] interval bool string string string double double
|
|
||||||
1389721084.522861 - - - - - - - - - FTP::Bruteforcing 192.168.56.1 had 20 failed logins on 1 FTP server in 0m37s - 192.168.56.1 - - - - Notice::ACTION_LOG 3600.000000 F - - - - -
|
|
||||||
#close 2017-12-21-02-24-08
|
|
||||||
|
|
|
@ -1,9 +0,0 @@
|
||||||
.. rst-class:: btest-cmd
|
|
||||||
|
|
||||||
.. code-block:: none
|
|
||||||
:linenos:
|
|
||||||
:emphasize-lines: 1,1
|
|
||||||
|
|
||||||
# bro -r http/proxy.pcap http_proxy_01.bro
|
|
||||||
A local server is acting as an open proxy: 192.168.56.101
|
|
||||||
|
|
|
@ -1,9 +0,0 @@
|
||||||
.. rst-class:: btest-cmd
|
|
||||||
|
|
||||||
.. code-block:: none
|
|
||||||
:linenos:
|
|
||||||
:emphasize-lines: 1,1
|
|
||||||
|
|
||||||
# bro -r http/proxy.pcap http_proxy_02.bro
|
|
||||||
A local server is acting as an open proxy: 192.168.56.101
|
|
||||||
|
|
|
@ -1,9 +0,0 @@
|
||||||
.. rst-class:: btest-cmd
|
|
||||||
|
|
||||||
.. code-block:: none
|
|
||||||
:linenos:
|
|
||||||
:emphasize-lines: 1,1
|
|
||||||
|
|
||||||
# bro -r http/proxy.pcap http_proxy_03.bro
|
|
||||||
A local server is acting as an open proxy: 192.168.56.101
|
|
||||||
|
|
|
@ -1,24 +0,0 @@
|
||||||
.. rst-class:: btest-cmd
|
|
||||||
|
|
||||||
.. code-block:: none
|
|
||||||
:linenos:
|
|
||||||
:emphasize-lines: 1,1
|
|
||||||
|
|
||||||
# bro -r http/proxy.pcap http_proxy_04.bro
|
|
||||||
|
|
||||||
.. rst-class:: btest-include
|
|
||||||
|
|
||||||
.. code-block:: guess
|
|
||||||
:linenos:
|
|
||||||
|
|
||||||
#separator \x09
|
|
||||||
#set_separator ,
|
|
||||||
#empty_field (empty)
|
|
||||||
#unset_field -
|
|
||||||
#path notice
|
|
||||||
#open 2017-12-21-02-24-33
|
|
||||||
#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p fuid file_mime_type file_desc proto note msg sub src dst p n peer_descr actions suppress_for dropped remote_location.country_code remote_location.region remote_location.city remote_location.latitude remote_location.longitude
|
|
||||||
#types time string addr port addr port string string string enum enum string string addr addr port count string set[enum] interval bool string string string double double
|
|
||||||
1389654450.449603 CHhAvVGS1DHFjwGM9 192.168.56.1 52679 192.168.56.101 80 - - - tcp HTTP::Open_Proxy A local server is acting as an open proxy: 192.168.56.101 - 192.168.56.1 192.168.56.101 80 - - Notice::ACTION_LOG 86400.000000 F - - - - -
|
|
||||||
#close 2017-12-21-02-24-33
|
|
||||||
|
|
|
@ -1,30 +0,0 @@
|
||||||
# @TEST-EXEC: cat %INPUT >output && btest-diff output
|
|
||||||
|
|
||||||
Bro_DNS.events.bif.bro
|
|
||||||
|
|
||||||
## Generated for DNS requests. For requests with multiple queries, this event
|
|
||||||
## is raised once for each.
|
|
||||||
##
|
|
||||||
## See `Wikipedia <http://en.wikipedia.org/wiki/Domain_Name_System>`__ for more
|
|
||||||
## information about the DNS protocol. Bro analyzes both UDP and TCP DNS
|
|
||||||
## sessions.
|
|
||||||
##
|
|
||||||
## c: The connection, which may be UDP or TCP depending on the type of the
|
|
||||||
## transport-layer session being analyzed.
|
|
||||||
##
|
|
||||||
## msg: The parsed DNS message header.
|
|
||||||
##
|
|
||||||
## query: The queried name.
|
|
||||||
##
|
|
||||||
## qtype: The queried resource record type.
|
|
||||||
##
|
|
||||||
## qclass: The queried resource record class.
|
|
||||||
##
|
|
||||||
## .. bro:see:: dns_AAAA_reply dns_A_reply dns_CNAME_reply dns_EDNS_addl
|
|
||||||
## dns_HINFO_reply dns_MX_reply dns_NS_reply dns_PTR_reply dns_SOA_reply
|
|
||||||
## dns_SRV_reply dns_TSIG_addl dns_TXT_reply dns_WKS_reply dns_end
|
|
||||||
## dns_full_request dns_mapping_altered dns_mapping_lost_name dns_mapping_new_name
|
|
||||||
## dns_mapping_unverified dns_mapping_valid dns_message dns_query_reply
|
|
||||||
## dns_rejected non_dns_request dns_max_queries dns_session_timeout dns_skip_addl
|
|
||||||
## dns_skip_all_addl dns_skip_all_auth dns_skip_auth
|
|
||||||
global dns_request: event(c: connection , msg: dns_msg , query: string , qtype: count , qclass: count );
|
|
|
@ -1,16 +0,0 @@
|
||||||
# @TEST-EXEC: cat %INPUT >output && btest-diff output
|
|
||||||
|
|
||||||
connecting-connector.bro
|
|
||||||
|
|
||||||
redef exit_only_after_terminate = T;
|
|
||||||
|
|
||||||
event bro_init()
|
|
||||||
{
|
|
||||||
Broker::peer("127.0.0.1");
|
|
||||||
}
|
|
||||||
|
|
||||||
event Broker::peer_added(endpoint: Broker::EndpointInfo, msg: string)
|
|
||||||
{
|
|
||||||
print "peer added", endpoint;
|
|
||||||
terminate();
|
|
||||||
}
|
|
|
@ -1,21 +0,0 @@
|
||||||
# @TEST-EXEC: cat %INPUT >output && btest-diff output
|
|
||||||
|
|
||||||
connecting-listener.bro
|
|
||||||
|
|
||||||
redef exit_only_after_terminate = T;
|
|
||||||
|
|
||||||
event bro_init()
|
|
||||||
{
|
|
||||||
Broker::listen("127.0.0.1");
|
|
||||||
}
|
|
||||||
|
|
||||||
event Broker::peer_added(endpoint: Broker::EndpointInfo, msg: string)
|
|
||||||
{
|
|
||||||
print "peer added", endpoint;
|
|
||||||
}
|
|
||||||
|
|
||||||
event Broker::peer_lost(endpoint: Broker::EndpointInfo, msg: string)
|
|
||||||
{
|
|
||||||
print "peer lost", endpoint;
|
|
||||||
terminate();
|
|
||||||
}
|
|
|
@ -1,39 +0,0 @@
|
||||||
# @TEST-EXEC: cat %INPUT >output && btest-diff output
|
|
||||||
|
|
||||||
events-connector.bro
|
|
||||||
|
|
||||||
redef exit_only_after_terminate = T;
|
|
||||||
global my_event: event(msg: string, c: count);
|
|
||||||
global my_auto_event: event(msg: string, c: count);
|
|
||||||
|
|
||||||
event bro_init()
|
|
||||||
{
|
|
||||||
Broker::peer("127.0.0.1");
|
|
||||||
Broker::auto_publish("bro/event/my_auto_event", my_auto_event);
|
|
||||||
}
|
|
||||||
|
|
||||||
event Broker::peer_added(endpoint: Broker::EndpointInfo, msg: string)
|
|
||||||
{
|
|
||||||
print "peer added", endpoint;
|
|
||||||
Broker::publish("bro/event/my_event", my_event, "hi", 0);
|
|
||||||
event my_auto_event("stuff", 88);
|
|
||||||
Broker::publish("bro/event/my_event", my_event, "...", 1);
|
|
||||||
event my_auto_event("more stuff", 51);
|
|
||||||
local e = Broker::make_event(my_event, "bye", 2);
|
|
||||||
Broker::publish("bro/event/my_event", e);
|
|
||||||
}
|
|
||||||
|
|
||||||
event Broker::peer_lost(endpoint: Broker::EndpointInfo, msg: string)
|
|
||||||
{
|
|
||||||
terminate();
|
|
||||||
}
|
|
||||||
|
|
||||||
event my_event(msg: string, c: count)
|
|
||||||
{
|
|
||||||
print "got my_event", msg, c;
|
|
||||||
}
|
|
||||||
|
|
||||||
event my_auto_event(msg: string, c: count)
|
|
||||||
{
|
|
||||||
print "got my_auto_event", msg, c;
|
|
||||||
}
|
|
|
@ -1,37 +0,0 @@
|
||||||
# @TEST-EXEC: cat %INPUT >output && btest-diff output
|
|
||||||
|
|
||||||
events-listener.bro
|
|
||||||
|
|
||||||
redef exit_only_after_terminate = T;
|
|
||||||
global msg_count = 0;
|
|
||||||
global my_event: event(msg: string, c: count);
|
|
||||||
global my_auto_event: event(msg: string, c: count);
|
|
||||||
|
|
||||||
event bro_init()
|
|
||||||
{
|
|
||||||
Broker::subscribe("bro/event/");
|
|
||||||
Broker::listen("127.0.0.1");
|
|
||||||
}
|
|
||||||
|
|
||||||
event Broker::peer_added(endpoint: Broker::EndpointInfo, msg: string)
|
|
||||||
{
|
|
||||||
print "peer added", endpoint;
|
|
||||||
}
|
|
||||||
|
|
||||||
event my_event(msg: string, c: count)
|
|
||||||
{
|
|
||||||
++msg_count;
|
|
||||||
print "got my_event", msg, c;
|
|
||||||
|
|
||||||
if ( msg_count == 5 )
|
|
||||||
terminate();
|
|
||||||
}
|
|
||||||
|
|
||||||
event my_auto_event(msg: string, c: count)
|
|
||||||
{
|
|
||||||
++msg_count;
|
|
||||||
print "got my_auto_event", msg, c;
|
|
||||||
|
|
||||||
if ( msg_count == 5 )
|
|
||||||
terminate();
|
|
||||||
}
|
|
|
@ -1,40 +0,0 @@
|
||||||
# @TEST-EXEC: cat %INPUT >output && btest-diff output
|
|
||||||
|
|
||||||
logs-connector.bro
|
|
||||||
|
|
||||||
@load ./testlog
|
|
||||||
|
|
||||||
redef exit_only_after_terminate = T;
|
|
||||||
global n = 0;
|
|
||||||
|
|
||||||
event bro_init()
|
|
||||||
{
|
|
||||||
Broker::peer("127.0.0.1");
|
|
||||||
}
|
|
||||||
|
|
||||||
event do_write()
|
|
||||||
{
|
|
||||||
if ( n == 6 )
|
|
||||||
return;
|
|
||||||
|
|
||||||
Log::write(Test::LOG, [$msg = "ping", $num = n]);
|
|
||||||
++n;
|
|
||||||
event do_write();
|
|
||||||
}
|
|
||||||
|
|
||||||
event Broker::peer_added(endpoint: Broker::EndpointInfo, msg: string)
|
|
||||||
{
|
|
||||||
print "peer added", endpoint;
|
|
||||||
event do_write();
|
|
||||||
}
|
|
||||||
|
|
||||||
event Broker::peer_lost(endpoint: Broker::EndpointInfo, msg: string)
|
|
||||||
{
|
|
||||||
terminate();
|
|
||||||
}
|
|
||||||
|
|
||||||
event Test::log_test(rec: Test::Info)
|
|
||||||
{
|
|
||||||
print "wrote log", rec;
|
|
||||||
Broker::publish("bro/logs/forward/test", Test::log_test, rec);
|
|
||||||
}
|
|
|
@ -1,26 +0,0 @@
|
||||||
# @TEST-EXEC: cat %INPUT >output && btest-diff output
|
|
||||||
|
|
||||||
logs-listener.bro
|
|
||||||
|
|
||||||
@load ./testlog
|
|
||||||
|
|
||||||
redef exit_only_after_terminate = T;
|
|
||||||
|
|
||||||
event bro_init()
|
|
||||||
{
|
|
||||||
Broker::subscribe("bro/logs");
|
|
||||||
Broker::listen("127.0.0.1");
|
|
||||||
}
|
|
||||||
|
|
||||||
event Broker::peer_added(endpoint: Broker::EndpointInfo, msg: string)
|
|
||||||
{
|
|
||||||
print "peer added", endpoint;
|
|
||||||
}
|
|
||||||
|
|
||||||
event Test::log_test(rec: Test::Info)
|
|
||||||
{
|
|
||||||
print "got log event", rec;
|
|
||||||
|
|
||||||
if ( rec$num == 5 )
|
|
||||||
terminate();
|
|
||||||
}
|
|
|
@ -1,33 +0,0 @@
|
||||||
# @TEST-EXEC: cat %INPUT >output && btest-diff output
|
|
||||||
|
|
||||||
stores-connector.bro
|
|
||||||
|
|
||||||
redef exit_only_after_terminate = T;
|
|
||||||
|
|
||||||
global h: opaque of Broker::Store;
|
|
||||||
|
|
||||||
global ready: event();
|
|
||||||
|
|
||||||
event Broker::peer_lost(endpoint: Broker::EndpointInfo, msg: string)
|
|
||||||
{
|
|
||||||
terminate();
|
|
||||||
}
|
|
||||||
|
|
||||||
event bro_init()
|
|
||||||
{
|
|
||||||
h = Broker::create_master("mystore");
|
|
||||||
|
|
||||||
local myset: set[string] = {"a", "b", "c"};
|
|
||||||
local myvec: vector of string = {"alpha", "beta", "gamma"};
|
|
||||||
Broker::put(h, "one", 110);
|
|
||||||
Broker::put(h, "two", 223);
|
|
||||||
Broker::put(h, "myset", myset);
|
|
||||||
Broker::put(h, "myvec", myvec);
|
|
||||||
Broker::increment(h, "one");
|
|
||||||
Broker::decrement(h, "two");
|
|
||||||
Broker::insert_into_set(h, "myset", "d");
|
|
||||||
Broker::remove_from(h, "myset", "b");
|
|
||||||
Broker::push(h, "myvec", "delta");
|
|
||||||
|
|
||||||
Broker::peer("127.0.0.1");
|
|
||||||
}
|
|
|
@ -1,83 +0,0 @@
|
||||||
# @TEST-EXEC: cat %INPUT >output && btest-diff output
|
|
||||||
|
|
||||||
stores-listener.bro
|
|
||||||
|
|
||||||
redef exit_only_after_terminate = T;
|
|
||||||
|
|
||||||
global h: opaque of Broker::Store;
|
|
||||||
global expected_key_count = 4;
|
|
||||||
global key_count = 0;
|
|
||||||
|
|
||||||
# Lookup a value in the store based on an arbitrary key string.
|
|
||||||
function do_lookup(key: string)
|
|
||||||
{
|
|
||||||
when ( local res = Broker::get(h, key) )
|
|
||||||
{
|
|
||||||
++key_count;
|
|
||||||
print "lookup", key, res;
|
|
||||||
|
|
||||||
# End after we iterated over looking up each key in the store twice.
|
|
||||||
if ( key_count == expected_key_count * 2 )
|
|
||||||
terminate();
|
|
||||||
}
|
|
||||||
# All data store queries must specify a timeout
|
|
||||||
timeout 3sec
|
|
||||||
{ print "timeout", key; }
|
|
||||||
}
|
|
||||||
|
|
||||||
event check_keys()
|
|
||||||
{
|
|
||||||
# Here we just query for the list of keys in the store, and show how to
|
|
||||||
# look up each one's value.
|
|
||||||
when ( local res = Broker::keys(h) )
|
|
||||||
{
|
|
||||||
print "clone keys", res;
|
|
||||||
|
|
||||||
if ( res?$result )
|
|
||||||
{
|
|
||||||
# Since we know that the keys we are storing are all strings,
|
|
||||||
# we can conveniently cast the result of Broker::keys to
|
|
||||||
# a native Bro type, namely 'set[string]'.
|
|
||||||
for ( k in res$result as string_set )
|
|
||||||
do_lookup(k);
|
|
||||||
|
|
||||||
# Alternatively, we can use a generic iterator to iterate
|
|
||||||
# over the results (which we know is of the 'set' type because
|
|
||||||
# that's what Broker::keys() always returns). If the keys
|
|
||||||
# we stored were not all of the same type, then you would
|
|
||||||
# likely want to use this method of inspecting the store's keys.
|
|
||||||
local i = Broker::set_iterator(res$result);
|
|
||||||
|
|
||||||
while ( ! Broker::set_iterator_last(i) )
|
|
||||||
{
|
|
||||||
do_lookup(Broker::set_iterator_value(i) as string);
|
|
||||||
Broker::set_iterator_next(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
# All data store queries must specify a timeout.
|
|
||||||
# You also might see timeouts on connecting/initializing a clone since
|
|
||||||
# it hasn't had time to get fully set up yet.
|
|
||||||
timeout 1sec
|
|
||||||
{
|
|
||||||
print "timeout";
|
|
||||||
schedule 1sec { check_keys() };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
event Broker::peer_added(endpoint: Broker::EndpointInfo, msg: string)
|
|
||||||
{
|
|
||||||
print "peer added";
|
|
||||||
# We could create a clone early, like in bro_init and it will periodically
|
|
||||||
# try to synchronize with its master once it connects, however, we just
|
|
||||||
# create it now since we know the peer w/ the master store has just
|
|
||||||
# connected.
|
|
||||||
h = Broker::create_clone("mystore");
|
|
||||||
|
|
||||||
event check_keys();
|
|
||||||
}
|
|
||||||
|
|
||||||
event bro_init()
|
|
||||||
{
|
|
||||||
Broker::listen("127.0.0.1");
|
|
||||||
}
|
|
|
@ -1,21 +0,0 @@
|
||||||
# @TEST-EXEC: cat %INPUT >output && btest-diff output
|
|
||||||
|
|
||||||
testlog.bro
|
|
||||||
|
|
||||||
module Test;
|
|
||||||
|
|
||||||
export {
|
|
||||||
redef enum Log::ID += { LOG };
|
|
||||||
|
|
||||||
type Info: record {
|
|
||||||
msg: string &log;
|
|
||||||
num: count &log;
|
|
||||||
};
|
|
||||||
|
|
||||||
global log_test: event(rec: Test::Info);
|
|
||||||
}
|
|
||||||
|
|
||||||
event bro_init() &priority=5
|
|
||||||
{
|
|
||||||
Log::create_stream(Test::LOG, [$columns=Test::Info, $ev=log_test, $path="test"]);
|
|
||||||
}
|
|
|
@ -1,24 +0,0 @@
|
||||||
# @TEST-EXEC: cat %INPUT >output && btest-diff output
|
|
||||||
|
|
||||||
file_analysis_01.bro
|
|
||||||
|
|
||||||
event connection_state_remove(c: connection)
|
|
||||||
{
|
|
||||||
print "connection_state_remove";
|
|
||||||
print c$uid;
|
|
||||||
print c$id;
|
|
||||||
for ( s in c$service )
|
|
||||||
print s;
|
|
||||||
}
|
|
||||||
|
|
||||||
event file_state_remove(f: fa_file)
|
|
||||||
{
|
|
||||||
print "file_state_remove";
|
|
||||||
print f$id;
|
|
||||||
for ( cid in f$conns )
|
|
||||||
{
|
|
||||||
print f$conns[cid]$uid;
|
|
||||||
print cid;
|
|
||||||
}
|
|
||||||
print f$source;
|
|
||||||
}
|
|
|
@ -1,16 +0,0 @@
|
||||||
# @TEST-EXEC: cat %INPUT >output && btest-diff output
|
|
||||||
|
|
||||||
file_analysis_02.bro
|
|
||||||
|
|
||||||
event file_sniff(f: fa_file, meta: fa_metadata)
|
|
||||||
{
|
|
||||||
if ( ! meta?$mime_type ) return;
|
|
||||||
print "new file", f$id;
|
|
||||||
if ( meta$mime_type == "text/plain" )
|
|
||||||
Files::add_analyzer(f, Files::ANALYZER_MD5);
|
|
||||||
}
|
|
||||||
|
|
||||||
event file_hash(f: fa_file, kind: string, hash: string)
|
|
||||||
{
|
|
||||||
print "file_hash", f$id, kind, hash;
|
|
||||||
}
|
|
|
@ -1,29 +0,0 @@
|
||||||
# @TEST-EXEC: cat %INPUT >output && btest-diff output
|
|
||||||
|
|
||||||
file_analysis_03.bro
|
|
||||||
|
|
||||||
redef exit_only_after_terminate = T;
|
|
||||||
|
|
||||||
event file_new(f: fa_file)
|
|
||||||
{
|
|
||||||
print "new file", f$id;
|
|
||||||
Files::add_analyzer(f, Files::ANALYZER_MD5);
|
|
||||||
}
|
|
||||||
|
|
||||||
event file_state_remove(f: fa_file)
|
|
||||||
{
|
|
||||||
print "file_state_remove";
|
|
||||||
Input::remove(f$source);
|
|
||||||
terminate();
|
|
||||||
}
|
|
||||||
|
|
||||||
event file_hash(f: fa_file, kind: string, hash: string)
|
|
||||||
{
|
|
||||||
print "file_hash", f$id, kind, hash;
|
|
||||||
}
|
|
||||||
|
|
||||||
event bro_init()
|
|
||||||
{
|
|
||||||
local source: string = "./myfile";
|
|
||||||
Input::add_analysis([$source=source, $name=source]);
|
|
||||||
}
|
|
|
@ -1,14 +0,0 @@
|
||||||
# @TEST-EXEC: cat %INPUT >output && btest-diff output
|
|
||||||
|
|
||||||
netcontrol-1-drop-with-debug.bro
|
|
||||||
|
|
||||||
event NetControl::init()
|
|
||||||
{
|
|
||||||
local debug_plugin = NetControl::create_debug(T);
|
|
||||||
NetControl::activate(debug_plugin, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
event connection_established(c: connection)
|
|
||||||
{
|
|
||||||
NetControl::drop_connection(c$id, 20 secs);
|
|
||||||
}
|
|
|
@ -1,14 +0,0 @@
|
||||||
# @TEST-EXEC: cat %INPUT >output && btest-diff output
|
|
||||||
|
|
||||||
netcontrol-10-use-skeleton.bro
|
|
||||||
|
|
||||||
event NetControl::init()
|
|
||||||
{
|
|
||||||
local skeleton_plugin = NetControl::create_skeleton("");
|
|
||||||
NetControl::activate(skeleton_plugin, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
event connection_established(c: connection)
|
|
||||||
{
|
|
||||||
NetControl::drop_connection(c$id, 20 secs);
|
|
||||||
}
|
|
|
@ -1,20 +0,0 @@
|
||||||
# @TEST-EXEC: cat %INPUT >output && btest-diff output
|
|
||||||
|
|
||||||
netcontrol-2-ssh-guesser.bro
|
|
||||||
|
|
||||||
|
|
||||||
@load protocols/ssh/detect-bruteforcing
|
|
||||||
|
|
||||||
redef SSH::password_guesses_limit=10;
|
|
||||||
|
|
||||||
event NetControl::init()
|
|
||||||
{
|
|
||||||
local debug_plugin = NetControl::create_debug(T);
|
|
||||||
NetControl::activate(debug_plugin, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
hook Notice::policy(n: Notice::Info)
|
|
||||||
{
|
|
||||||
if ( n$note == SSH::Password_Guessing )
|
|
||||||
NetControl::drop_address(n$src, 60min);
|
|
||||||
}
|
|
|
@ -1,20 +0,0 @@
|
||||||
# @TEST-EXEC: cat %INPUT >output && btest-diff output
|
|
||||||
|
|
||||||
netcontrol-3-ssh-guesser.bro
|
|
||||||
|
|
||||||
|
|
||||||
@load protocols/ssh/detect-bruteforcing
|
|
||||||
|
|
||||||
redef SSH::password_guesses_limit=10;
|
|
||||||
|
|
||||||
event NetControl::init()
|
|
||||||
{
|
|
||||||
local debug_plugin = NetControl::create_debug(T);
|
|
||||||
NetControl::activate(debug_plugin, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
hook Notice::policy(n: Notice::Info)
|
|
||||||
{
|
|
||||||
if ( n$note == SSH::Password_Guessing )
|
|
||||||
add n$actions[Notice::ACTION_DROP];
|
|
||||||
}
|
|
|
@ -1,30 +0,0 @@
|
||||||
# @TEST-EXEC: cat %INPUT >output && btest-diff output
|
|
||||||
|
|
||||||
netcontrol-4-drop.bro
|
|
||||||
|
|
||||||
function our_drop_connection(c: conn_id, t: interval)
|
|
||||||
{
|
|
||||||
# As a first step, create the NetControl::Entity that we want to block
|
|
||||||
local e = NetControl::Entity($ty=NetControl::CONNECTION, $conn=c);
|
|
||||||
# Then, use the entity to create the rule to drop the entity in the forward path
|
|
||||||
local r = NetControl::Rule($ty=NetControl::DROP,
|
|
||||||
$target=NetControl::FORWARD, $entity=e, $expire=t);
|
|
||||||
|
|
||||||
# Add the rule
|
|
||||||
local id = NetControl::add_rule(r);
|
|
||||||
|
|
||||||
if ( id == "" )
|
|
||||||
print "Error while dropping";
|
|
||||||
}
|
|
||||||
|
|
||||||
event NetControl::init()
|
|
||||||
{
|
|
||||||
local debug_plugin = NetControl::create_debug(T);
|
|
||||||
NetControl::activate(debug_plugin, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
event connection_established(c: connection)
|
|
||||||
{
|
|
||||||
our_drop_connection(c$id, 20 secs);
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,26 +0,0 @@
|
||||||
# @TEST-EXEC: cat %INPUT >output && btest-diff output
|
|
||||||
|
|
||||||
netcontrol-5-hook.bro
|
|
||||||
|
|
||||||
hook NetControl::rule_policy(r: NetControl::Rule)
|
|
||||||
{
|
|
||||||
if ( r$ty == NetControl::DROP &&
|
|
||||||
r$entity$ty == NetControl::CONNECTION &&
|
|
||||||
r$entity$conn$orig_h in 192.168.0.0/16 )
|
|
||||||
{
|
|
||||||
print "Ignored connection from", r$entity$conn$orig_h;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
event NetControl::init()
|
|
||||||
{
|
|
||||||
local debug_plugin = NetControl::create_debug(T);
|
|
||||||
NetControl::activate(debug_plugin, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
event connection_established(c: connection)
|
|
||||||
{
|
|
||||||
NetControl::drop_connection(c$id, 20 secs);
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,21 +0,0 @@
|
||||||
# @TEST-EXEC: cat %INPUT >output && btest-diff output
|
|
||||||
|
|
||||||
netcontrol-6-find.bro
|
|
||||||
|
|
||||||
event NetControl::init()
|
|
||||||
{
|
|
||||||
local netcontrol_debug = NetControl::create_debug(T);
|
|
||||||
NetControl::activate(netcontrol_debug, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
event connection_established(c: connection)
|
|
||||||
{
|
|
||||||
if ( |NetControl::find_rules_addr(c$id$orig_h)| > 0 )
|
|
||||||
{
|
|
||||||
print "Rule already exists";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
NetControl::drop_connection(c$id, 20 secs);
|
|
||||||
print "Rule added";
|
|
||||||
}
|
|
|
@ -1,14 +0,0 @@
|
||||||
# @TEST-EXEC: cat %INPUT >output && btest-diff output
|
|
||||||
|
|
||||||
netcontrol-7-catch-release.bro
|
|
||||||
|
|
||||||
event NetControl::init()
|
|
||||||
{
|
|
||||||
local debug_plugin = NetControl::create_debug(T);
|
|
||||||
NetControl::activate(debug_plugin, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
event connection_established(c: connection)
|
|
||||||
{
|
|
||||||
NetControl::drop_address_catch_release(c$id$orig_h);
|
|
||||||
}
|
|
|
@ -1,33 +0,0 @@
|
||||||
# @TEST-EXEC: cat %INPUT >output && btest-diff output
|
|
||||||
|
|
||||||
netcontrol-8-multiple.bro
|
|
||||||
|
|
||||||
function our_openflow_check(p: NetControl::PluginState, r: NetControl::Rule): bool
|
|
||||||
{
|
|
||||||
if ( r$ty == NetControl::DROP &&
|
|
||||||
r$entity$ty == NetControl::ADDRESS &&
|
|
||||||
subnet_width(r$entity$ip) == 32 &&
|
|
||||||
subnet_to_addr(r$entity$ip) in 192.168.17.0/24 )
|
|
||||||
return F;
|
|
||||||
|
|
||||||
return T;
|
|
||||||
}
|
|
||||||
|
|
||||||
event NetControl::init()
|
|
||||||
{
|
|
||||||
# Add debug plugin with low priority
|
|
||||||
local debug_plugin = NetControl::create_debug(T);
|
|
||||||
NetControl::activate(debug_plugin, 0);
|
|
||||||
|
|
||||||
# Instantiate OpenFlow debug plugin with higher priority
|
|
||||||
local of_controller = OpenFlow::log_new(42);
|
|
||||||
local netcontrol_of = NetControl::create_openflow(of_controller, [$check_pred=our_openflow_check]);
|
|
||||||
NetControl::activate(netcontrol_of, 10);
|
|
||||||
}
|
|
||||||
|
|
||||||
event NetControl::init_done()
|
|
||||||
{
|
|
||||||
NetControl::drop_address(10.0.0.1, 1min);
|
|
||||||
NetControl::drop_address(192.168.17.2, 1min);
|
|
||||||
NetControl::drop_address(192.168.18.2, 1min);
|
|
||||||
}
|
|
|
@ -1,43 +0,0 @@
|
||||||
# @TEST-EXEC: cat %INPUT >output && btest-diff output
|
|
||||||
|
|
||||||
netcontrol-9-skeleton.bro
|
|
||||||
|
|
||||||
module NetControl;
|
|
||||||
|
|
||||||
export {
|
|
||||||
## Instantiates the plugin.
|
|
||||||
global create_skeleton: function(argument: string) : PluginState;
|
|
||||||
}
|
|
||||||
|
|
||||||
function skeleton_name(p: PluginState) : string
|
|
||||||
{
|
|
||||||
return "NetControl skeleton plugin";
|
|
||||||
}
|
|
||||||
|
|
||||||
function skeleton_add_rule_fun(p: PluginState, r: Rule) : bool
|
|
||||||
{
|
|
||||||
print "add", r;
|
|
||||||
event NetControl::rule_added(r, p);
|
|
||||||
return T;
|
|
||||||
}
|
|
||||||
|
|
||||||
function skeleton_remove_rule_fun(p: PluginState, r: Rule, reason: string &default="") : bool
|
|
||||||
{
|
|
||||||
print "remove", r;
|
|
||||||
event NetControl::rule_removed(r, p);
|
|
||||||
return T;
|
|
||||||
}
|
|
||||||
|
|
||||||
global skeleton_plugin = Plugin(
|
|
||||||
$name = skeleton_name,
|
|
||||||
$can_expire = F,
|
|
||||||
$add_rule = skeleton_add_rule_fun,
|
|
||||||
$remove_rule = skeleton_remove_rule_fun
|
|
||||||
);
|
|
||||||
|
|
||||||
function create_skeleton(argument: string) : PluginState
|
|
||||||
{
|
|
||||||
local p = PluginState($plugin=skeleton_plugin);
|
|
||||||
|
|
||||||
return p;
|
|
||||||
}
|
|
|
@ -1,14 +0,0 @@
|
||||||
# @TEST-EXEC: cat %INPUT >output && btest-diff output
|
|
||||||
|
|
||||||
notice_ssh_guesser.bro
|
|
||||||
|
|
||||||
|
|
||||||
@load protocols/ssh/detect-bruteforcing
|
|
||||||
|
|
||||||
redef SSH::password_guesses_limit=10;
|
|
||||||
|
|
||||||
hook Notice::policy(n: Notice::Info)
|
|
||||||
{
|
|
||||||
if ( n$note == SSH::Password_Guessing && /192\.168\.56\.103/ in n$sub )
|
|
||||||
add n$actions[Notice::ACTION_EMAIL];
|
|
||||||
}
|
|
|
@ -1,16 +0,0 @@
|
||||||
# @TEST-EXEC: cat %INPUT >output && btest-diff output
|
|
||||||
|
|
||||||
sqlite-conn-filter.bro
|
|
||||||
|
|
||||||
event bro_init()
|
|
||||||
{
|
|
||||||
local filter: Log::Filter =
|
|
||||||
[
|
|
||||||
$name="sqlite",
|
|
||||||
$path="/var/db/conn",
|
|
||||||
$config=table(["tablename"] = "conn"),
|
|
||||||
$writer=Log::WRITER_SQLITE
|
|
||||||
];
|
|
||||||
|
|
||||||
Log::add_filter(Conn::LOG, filter);
|
|
||||||
}
|
|
|
@ -1,44 +0,0 @@
|
||||||
# @TEST-EXEC: cat %INPUT >output && btest-diff output
|
|
||||||
|
|
||||||
sqlite-read-events.bro
|
|
||||||
|
|
||||||
@load frameworks/files/hash-all-files
|
|
||||||
|
|
||||||
type Val: record {
|
|
||||||
hash: string;
|
|
||||||
description: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
event line(description: Input::EventDescription, tpe: Input::Event, r: Val)
|
|
||||||
{
|
|
||||||
print fmt("malware-hit with hash %s, description %s", r$hash, r$description);
|
|
||||||
}
|
|
||||||
|
|
||||||
global malware_source = "/var/db/malware";
|
|
||||||
|
|
||||||
event file_hash(f: fa_file, kind: string, hash: string)
|
|
||||||
{
|
|
||||||
|
|
||||||
# check all sha1 hashes
|
|
||||||
if ( kind=="sha1" )
|
|
||||||
{
|
|
||||||
Input::add_event(
|
|
||||||
[
|
|
||||||
$source=malware_source,
|
|
||||||
$name=hash,
|
|
||||||
$fields=Val,
|
|
||||||
$ev=line,
|
|
||||||
$want_record=T,
|
|
||||||
$config=table(
|
|
||||||
["query"] = fmt("select * from malware_hashes where hash='%s';", hash)
|
|
||||||
),
|
|
||||||
$reader=Input::READER_SQLITE
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
event Input::end_of_data(name: string, source:string)
|
|
||||||
{
|
|
||||||
if ( source == malware_source )
|
|
||||||
Input::remove(name);
|
|
||||||
}
|
|
|
@ -1,39 +0,0 @@
|
||||||
# @TEST-EXEC: cat %INPUT >output && btest-diff output
|
|
||||||
|
|
||||||
sqlite-read-table.bro
|
|
||||||
|
|
||||||
type Idx: record {
|
|
||||||
host: addr;
|
|
||||||
};
|
|
||||||
|
|
||||||
type Val: record {
|
|
||||||
users: set[string];
|
|
||||||
};
|
|
||||||
|
|
||||||
global hostslist: table[addr] of Val = table();
|
|
||||||
|
|
||||||
event bro_init()
|
|
||||||
{
|
|
||||||
Input::add_table([$source="/var/db/hosts",
|
|
||||||
$name="hosts",
|
|
||||||
$idx=Idx,
|
|
||||||
$val=Val,
|
|
||||||
$destination=hostslist,
|
|
||||||
$reader=Input::READER_SQLITE,
|
|
||||||
$config=table(["query"] = "select * from machines_to_users;")
|
|
||||||
]);
|
|
||||||
|
|
||||||
Input::remove("hosts");
|
|
||||||
}
|
|
||||||
|
|
||||||
event Input::end_of_data(name: string, source: string)
|
|
||||||
{
|
|
||||||
if ( name != "hosts" )
|
|
||||||
return;
|
|
||||||
|
|
||||||
# now all data is in the table
|
|
||||||
print "Hosts list has been successfully imported";
|
|
||||||
|
|
||||||
# List the users of one host.
|
|
||||||
print hostslist[192.168.17.1]$users;
|
|
||||||
}
|
|
|
@ -1,40 +0,0 @@
|
||||||
# @TEST-EXEC: cat %INPUT >output && btest-diff output
|
|
||||||
|
|
||||||
sumstats-countconns.bro
|
|
||||||
|
|
||||||
@load base/frameworks/sumstats
|
|
||||||
|
|
||||||
event connection_established(c: connection)
|
|
||||||
{
|
|
||||||
# Make an observation!
|
|
||||||
# This observation is global so the key is empty.
|
|
||||||
# Each established connection counts as one so the observation is always 1.
|
|
||||||
SumStats::observe("conn established",
|
|
||||||
SumStats::Key(),
|
|
||||||
SumStats::Observation($num=1));
|
|
||||||
}
|
|
||||||
|
|
||||||
event bro_init()
|
|
||||||
{
|
|
||||||
# Create the reducer.
|
|
||||||
# The reducer attaches to the "conn established" observation stream
|
|
||||||
# and uses the summing calculation on the observations.
|
|
||||||
local r1 = SumStats::Reducer($stream="conn established",
|
|
||||||
$apply=set(SumStats::SUM));
|
|
||||||
|
|
||||||
# Create the final sumstat.
|
|
||||||
# We give it an arbitrary name and make it collect data every minute.
|
|
||||||
# The reducer is then attached and a $epoch_result callback is given
|
|
||||||
# to finally do something with the data collected.
|
|
||||||
SumStats::create([$name = "counting connections",
|
|
||||||
$epoch = 1min,
|
|
||||||
$reducers = set(r1),
|
|
||||||
$epoch_result(ts: time, key: SumStats::Key, result: SumStats::Result) =
|
|
||||||
{
|
|
||||||
# This is the body of the callback that is called when a single
|
|
||||||
# result has been collected. We are just printing the total number
|
|
||||||
# of connections that were seen. The $sum field is provided as a
|
|
||||||
# double type value so we need to use %f as the format specifier.
|
|
||||||
print fmt("Number of connections established: %.0f", result["conn established"]$sum);
|
|
||||||
}]);
|
|
||||||
}
|
|
|
@ -1,49 +0,0 @@
|
||||||
# @TEST-EXEC: cat %INPUT >output && btest-diff output
|
|
||||||
|
|
||||||
sumstats-toy-scan.bro
|
|
||||||
|
|
||||||
@load base/frameworks/sumstats
|
|
||||||
|
|
||||||
# We use the connection_attempt event to limit our observations to those
|
|
||||||
# which were attempted and not successful.
|
|
||||||
event connection_attempt(c: connection)
|
|
||||||
{
|
|
||||||
# Make an observation!
|
|
||||||
# This observation is about the host attempting the connection.
|
|
||||||
# Each established connection counts as one so the observation is always 1.
|
|
||||||
SumStats::observe("conn attempted",
|
|
||||||
SumStats::Key($host=c$id$orig_h),
|
|
||||||
SumStats::Observation($num=1));
|
|
||||||
}
|
|
||||||
|
|
||||||
event bro_init()
|
|
||||||
{
|
|
||||||
# Create the reducer.
|
|
||||||
# The reducer attaches to the "conn attempted" observation stream
|
|
||||||
# and uses the summing calculation on the observations. Keep
|
|
||||||
# in mind that there will be one result per key (connection originator).
|
|
||||||
local r1 = SumStats::Reducer($stream="conn attempted",
|
|
||||||
$apply=set(SumStats::SUM));
|
|
||||||
|
|
||||||
# Create the final sumstat.
|
|
||||||
# This is slightly different from the last example since we're providing
|
|
||||||
# a callback to calculate a value to check against the threshold with
|
|
||||||
# $threshold_val. The actual threshold itself is provided with $threshold.
|
|
||||||
# Another callback is provided for when a key crosses the threshold.
|
|
||||||
SumStats::create([$name = "finding scanners",
|
|
||||||
$epoch = 5min,
|
|
||||||
$reducers = set(r1),
|
|
||||||
# Provide a threshold.
|
|
||||||
$threshold = 5.0,
|
|
||||||
# Provide a callback to calculate a value from the result
|
|
||||||
# to check against the threshold field.
|
|
||||||
$threshold_val(key: SumStats::Key, result: SumStats::Result) =
|
|
||||||
{
|
|
||||||
return result["conn attempted"]$sum;
|
|
||||||
},
|
|
||||||
# Provide a callback for when a key crosses the threshold.
|
|
||||||
$threshold_crossed(key: SumStats::Key, result: SumStats::Result) =
|
|
||||||
{
|
|
||||||
print fmt("%s attempted %.0f or more connections", key$host, result["conn attempted"]$sum);
|
|
||||||
}]);
|
|
||||||
}
|
|
|
@ -1,28 +0,0 @@
|
||||||
# @TEST-EXEC: cat %INPUT >output && btest-diff output
|
|
||||||
|
|
||||||
file_extraction.bro
|
|
||||||
|
|
||||||
|
|
||||||
global mime_to_ext: table[string] of string = {
|
|
||||||
["application/x-dosexec"] = "exe",
|
|
||||||
["text/plain"] = "txt",
|
|
||||||
["image/jpeg"] = "jpg",
|
|
||||||
["image/png"] = "png",
|
|
||||||
["text/html"] = "html",
|
|
||||||
};
|
|
||||||
|
|
||||||
event file_sniff(f: fa_file, meta: fa_metadata)
|
|
||||||
{
|
|
||||||
if ( f$source != "HTTP" )
|
|
||||||
return;
|
|
||||||
|
|
||||||
if ( ! meta?$mime_type )
|
|
||||||
return;
|
|
||||||
|
|
||||||
if ( meta$mime_type !in mime_to_ext )
|
|
||||||
return;
|
|
||||||
|
|
||||||
local fname = fmt("%s-%s.%s", f$source, f$id, mime_to_ext[meta$mime_type]);
|
|
||||||
print fmt("Extracting file %s", fname);
|
|
||||||
Files::add_analyzer(f, Files::ANALYZER_EXTRACT, [$extract_filename=fname]);
|
|
||||||
}
|
|
|
@ -1,9 +0,0 @@
|
||||||
# @TEST-EXEC: cat %INPUT >output && btest-diff output
|
|
||||||
|
|
||||||
http_proxy_01.bro
|
|
||||||
|
|
||||||
event http_reply(c: connection, version: string, code: count, reason: string)
|
|
||||||
{
|
|
||||||
if ( /^[hH][tT][tT][pP]:/ in c$http$uri && c$http$status_code == 200 )
|
|
||||||
print fmt("A local server is acting as an open proxy: %s", c$id$resp_h);
|
|
||||||
}
|
|
|
@ -1,30 +0,0 @@
|
||||||
# @TEST-EXEC: cat %INPUT >output && btest-diff output
|
|
||||||
|
|
||||||
http_proxy_02.bro
|
|
||||||
|
|
||||||
|
|
||||||
module HTTP;
|
|
||||||
|
|
||||||
export {
|
|
||||||
|
|
||||||
global success_status_codes: set[count] = {
|
|
||||||
200,
|
|
||||||
201,
|
|
||||||
202,
|
|
||||||
203,
|
|
||||||
204,
|
|
||||||
205,
|
|
||||||
206,
|
|
||||||
207,
|
|
||||||
208,
|
|
||||||
226,
|
|
||||||
304
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
event http_reply(c: connection, version: string, code: count, reason: string)
|
|
||||||
{
|
|
||||||
if ( /^[hH][tT][tT][pP]:/ in c$http$uri &&
|
|
||||||
c$http$status_code in HTTP::success_status_codes )
|
|
||||||
print fmt("A local server is acting as an open proxy: %s", c$id$resp_h);
|
|
||||||
}
|
|
|
@ -1,35 +0,0 @@
|
||||||
# @TEST-EXEC: cat %INPUT >output && btest-diff output
|
|
||||||
|
|
||||||
http_proxy_03.bro
|
|
||||||
|
|
||||||
|
|
||||||
@load base/utils/site
|
|
||||||
|
|
||||||
redef Site::local_nets += { 192.168.0.0/16 };
|
|
||||||
|
|
||||||
module HTTP;
|
|
||||||
|
|
||||||
export {
|
|
||||||
|
|
||||||
global success_status_codes: set[count] = {
|
|
||||||
200,
|
|
||||||
201,
|
|
||||||
202,
|
|
||||||
203,
|
|
||||||
204,
|
|
||||||
205,
|
|
||||||
206,
|
|
||||||
207,
|
|
||||||
208,
|
|
||||||
226,
|
|
||||||
304
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
event http_reply(c: connection, version: string, code: count, reason: string)
|
|
||||||
{
|
|
||||||
if ( Site::is_local_addr(c$id$resp_h) &&
|
|
||||||
/^[hH][tT][tT][pP]:/ in c$http$uri &&
|
|
||||||
c$http$status_code in HTTP::success_status_codes )
|
|
||||||
print fmt("A local server is acting as an open proxy: %s", c$id$resp_h);
|
|
||||||
}
|
|
|
@ -1,44 +0,0 @@
|
||||||
# @TEST-EXEC: cat %INPUT >output && btest-diff output
|
|
||||||
|
|
||||||
http_proxy_04.bro
|
|
||||||
|
|
||||||
@load base/utils/site
|
|
||||||
@load base/frameworks/notice
|
|
||||||
|
|
||||||
redef Site::local_nets += { 192.168.0.0/16 };
|
|
||||||
|
|
||||||
module HTTP;
|
|
||||||
|
|
||||||
export {
|
|
||||||
|
|
||||||
redef enum Notice::Type += {
|
|
||||||
Open_Proxy
|
|
||||||
};
|
|
||||||
|
|
||||||
global success_status_codes: set[count] = {
|
|
||||||
200,
|
|
||||||
201,
|
|
||||||
202,
|
|
||||||
203,
|
|
||||||
204,
|
|
||||||
205,
|
|
||||||
206,
|
|
||||||
207,
|
|
||||||
208,
|
|
||||||
226,
|
|
||||||
304
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
event http_reply(c: connection, version: string, code: count, reason: string)
|
|
||||||
{
|
|
||||||
if ( Site::is_local_addr(c$id$resp_h) &&
|
|
||||||
/^[hH][tT][tT][pP]:/ in c$http$uri &&
|
|
||||||
c$http$status_code in HTTP::success_status_codes )
|
|
||||||
NOTICE([$note=HTTP::Open_Proxy,
|
|
||||||
$msg=fmt("A local server is acting as an open proxy: %s",
|
|
||||||
c$id$resp_h),
|
|
||||||
$conn=c,
|
|
||||||
$identifier=cat(c$id$resp_h),
|
|
||||||
$suppress_for=1day]);
|
|
||||||
}
|
|
|
@ -1,39 +0,0 @@
|
||||||
# @TEST-EXEC: cat %INPUT >output && btest-diff output
|
|
||||||
|
|
||||||
mimestats.bro
|
|
||||||
|
|
||||||
module MimeMetrics;
|
|
||||||
|
|
||||||
export {
|
|
||||||
|
|
||||||
redef enum Log::ID += { LOG };
|
|
||||||
|
|
||||||
type Info: record {
|
|
||||||
## Timestamp when the log line was finished and written.
|
|
||||||
ts: time &log;
|
|
||||||
## Time interval that the log line covers.
|
|
||||||
ts_delta: interval &log;
|
|
||||||
## The mime type
|
|
||||||
mtype: string &log;
|
|
||||||
## The number of unique local hosts that fetched this mime type
|
|
||||||
uniq_hosts: count &log;
|
|
||||||
## The number of hits to the mime type
|
|
||||||
hits: count &log;
|
|
||||||
## The total number of bytes received by this mime type
|
|
||||||
bytes: count &log;
|
|
||||||
};
|
|
||||||
|
|
||||||
## The frequency of logging the stats collected by this script.
|
|
||||||
const break_interval = 5mins &redef;
|
|
||||||
}
|
|
||||||
event HTTP::log_http(rec: HTTP::Info)
|
|
||||||
{
|
|
||||||
if ( Site::is_local_addr(rec$id$orig_h) && rec?$resp_mime_types )
|
|
||||||
{
|
|
||||||
local mime_type = rec$resp_mime_types[0];
|
|
||||||
SumStats::observe("mime.bytes", [$str=mime_type],
|
|
||||||
[$num=rec$response_body_len]);
|
|
||||||
SumStats::observe("mime.hits", [$str=mime_type],
|
|
||||||
[$str=cat(rec$id$orig_h)]);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,8 +0,0 @@
|
||||||
# @TEST-EXEC: cat %INPUT >output && btest-diff output
|
|
||||||
|
|
||||||
mimestats.bro
|
|
||||||
|
|
||||||
local r1: SumStats::Reducer = [$stream="mime.bytes",
|
|
||||||
$apply=set(SumStats::SUM)];
|
|
||||||
local r2: SumStats::Reducer = [$stream="mime.hits",
|
|
||||||
$apply=set(SumStats::UNIQUE)];
|
|
|
@ -1,18 +0,0 @@
|
||||||
# @TEST-EXEC: cat %INPUT >output && btest-diff output
|
|
||||||
|
|
||||||
mimestats.bro
|
|
||||||
|
|
||||||
SumStats::create([$name="mime-metrics",
|
|
||||||
$epoch=break_interval,
|
|
||||||
$reducers=set(r1, r2),
|
|
||||||
$epoch_result(ts: time, key: SumStats::Key, result: SumStats::Result) =
|
|
||||||
{
|
|
||||||
local l: Info;
|
|
||||||
l$ts = network_time();
|
|
||||||
l$ts_delta = break_interval;
|
|
||||||
l$mtype = key$str;
|
|
||||||
l$bytes = double_to_count(floor(result["mime.bytes"]$sum));
|
|
||||||
l$hits = result["mime.hits"]$num;
|
|
||||||
l$uniq_hosts = result["mime.hits"]$unique;
|
|
||||||
Log::write(MimeMetrics::LOG, l);
|
|
||||||
}]);
|
|
|
@ -1,68 +0,0 @@
|
||||||
# @TEST-EXEC: cat %INPUT >output && btest-diff output
|
|
||||||
|
|
||||||
mimestats.bro
|
|
||||||
|
|
||||||
@load base/utils/site
|
|
||||||
@load base/frameworks/sumstats
|
|
||||||
|
|
||||||
redef Site::local_nets += { 10.0.0.0/8 };
|
|
||||||
|
|
||||||
module MimeMetrics;
|
|
||||||
|
|
||||||
export {
|
|
||||||
|
|
||||||
redef enum Log::ID += { LOG };
|
|
||||||
|
|
||||||
type Info: record {
|
|
||||||
## Timestamp when the log line was finished and written.
|
|
||||||
ts: time &log;
|
|
||||||
## Time interval that the log line covers.
|
|
||||||
ts_delta: interval &log;
|
|
||||||
## The mime type
|
|
||||||
mtype: string &log;
|
|
||||||
## The number of unique local hosts that fetched this mime type
|
|
||||||
uniq_hosts: count &log;
|
|
||||||
## The number of hits to the mime type
|
|
||||||
hits: count &log;
|
|
||||||
## The total number of bytes received by this mime type
|
|
||||||
bytes: count &log;
|
|
||||||
};
|
|
||||||
|
|
||||||
## The frequency of logging the stats collected by this script.
|
|
||||||
const break_interval = 5mins &redef;
|
|
||||||
}
|
|
||||||
|
|
||||||
event bro_init() &priority=3
|
|
||||||
{
|
|
||||||
Log::create_stream(MimeMetrics::LOG, [$columns=Info, $path="mime_metrics"]);
|
|
||||||
local r1: SumStats::Reducer = [$stream="mime.bytes",
|
|
||||||
$apply=set(SumStats::SUM)];
|
|
||||||
local r2: SumStats::Reducer = [$stream="mime.hits",
|
|
||||||
$apply=set(SumStats::UNIQUE)];
|
|
||||||
SumStats::create([$name="mime-metrics",
|
|
||||||
$epoch=break_interval,
|
|
||||||
$reducers=set(r1, r2),
|
|
||||||
$epoch_result(ts: time, key: SumStats::Key, result: SumStats::Result) =
|
|
||||||
{
|
|
||||||
local l: Info;
|
|
||||||
l$ts = network_time();
|
|
||||||
l$ts_delta = break_interval;
|
|
||||||
l$mtype = key$str;
|
|
||||||
l$bytes = double_to_count(floor(result["mime.bytes"]$sum));
|
|
||||||
l$hits = result["mime.hits"]$num;
|
|
||||||
l$uniq_hosts = result["mime.hits"]$unique;
|
|
||||||
Log::write(MimeMetrics::LOG, l);
|
|
||||||
}]);
|
|
||||||
}
|
|
||||||
|
|
||||||
event HTTP::log_http(rec: HTTP::Info)
|
|
||||||
{
|
|
||||||
if ( Site::is_local_addr(rec$id$orig_h) && rec?$resp_mime_types )
|
|
||||||
{
|
|
||||||
local mime_type = rec$resp_mime_types[0];
|
|
||||||
SumStats::observe("mime.bytes", [$str=mime_type],
|
|
||||||
[$num=rec$response_body_len]);
|
|
||||||
SumStats::observe("mime.hits", [$str=mime_type],
|
|
||||||
[$str=cat(rec$id$orig_h)]);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,28 +0,0 @@
|
||||||
# @TEST-EXEC: cat %INPUT >output && btest-diff output
|
|
||||||
|
|
||||||
conditional-notice.bro
|
|
||||||
|
|
||||||
@load protocols/ssl/expiring-certs
|
|
||||||
|
|
||||||
const watched_servers: set[addr] = {
|
|
||||||
87.98.220.10,
|
|
||||||
} &redef;
|
|
||||||
|
|
||||||
# Site::local_nets usually isn't something you need to modify if
|
|
||||||
# BroControl automatically sets it up from networks.cfg. It's
|
|
||||||
# shown here for completeness.
|
|
||||||
redef Site::local_nets += {
|
|
||||||
87.98.0.0/16,
|
|
||||||
};
|
|
||||||
|
|
||||||
hook Notice::policy(n: Notice::Info)
|
|
||||||
{
|
|
||||||
if ( n$note != SSL::Certificate_Expired )
|
|
||||||
return;
|
|
||||||
|
|
||||||
if ( n$id$resp_h !in watched_servers )
|
|
||||||
return;
|
|
||||||
|
|
||||||
add n$actions[Notice::ACTION_EMAIL];
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,10 +0,0 @@
|
||||||
# @TEST-EXEC: cat %INPUT >output && btest-diff output
|
|
||||||
|
|
||||||
connection_record_01.bro
|
|
||||||
|
|
||||||
@load base/protocols/conn
|
|
||||||
|
|
||||||
event connection_state_remove(c: connection)
|
|
||||||
{
|
|
||||||
print c;
|
|
||||||
}
|
|
|
@ -1,11 +0,0 @@
|
||||||
# @TEST-EXEC: cat %INPUT >output && btest-diff output
|
|
||||||
|
|
||||||
connection_record_02.bro
|
|
||||||
|
|
||||||
@load base/protocols/conn
|
|
||||||
@load base/protocols/http
|
|
||||||
|
|
||||||
event connection_state_remove(c: connection)
|
|
||||||
{
|
|
||||||
print c;
|
|
||||||
}
|
|
|
@ -1,26 +0,0 @@
|
||||||
# @TEST-EXEC: cat %INPUT >output && btest-diff output
|
|
||||||
|
|
||||||
data_struct_record_01.bro
|
|
||||||
|
|
||||||
type Service: record {
|
|
||||||
name: string;
|
|
||||||
ports: set[port];
|
|
||||||
rfc: count;
|
|
||||||
};
|
|
||||||
|
|
||||||
function print_service(serv: Service)
|
|
||||||
{
|
|
||||||
print fmt("Service: %s(RFC%d)",serv$name, serv$rfc);
|
|
||||||
|
|
||||||
for ( p in serv$ports )
|
|
||||||
print fmt(" port: %s", p);
|
|
||||||
}
|
|
||||||
|
|
||||||
event bro_init()
|
|
||||||
{
|
|
||||||
local dns: Service = [$name="dns", $ports=set(53/udp, 53/tcp), $rfc=1035];
|
|
||||||
local http: Service = [$name="http", $ports=set(80/tcp, 8080/tcp), $rfc=2616];
|
|
||||||
|
|
||||||
print_service(dns);
|
|
||||||
print_service(http);
|
|
||||||
}
|
|
|
@ -1,45 +0,0 @@
|
||||||
# @TEST-EXEC: cat %INPUT >output && btest-diff output
|
|
||||||
|
|
||||||
data_struct_record_02.bro
|
|
||||||
|
|
||||||
type Service: record {
|
|
||||||
name: string;
|
|
||||||
ports: set[port];
|
|
||||||
rfc: count;
|
|
||||||
};
|
|
||||||
|
|
||||||
type System: record {
|
|
||||||
name: string;
|
|
||||||
services: set[Service];
|
|
||||||
};
|
|
||||||
|
|
||||||
function print_service(serv: Service)
|
|
||||||
{
|
|
||||||
print fmt(" Service: %s(RFC%d)",serv$name, serv$rfc);
|
|
||||||
|
|
||||||
for ( p in serv$ports )
|
|
||||||
print fmt(" port: %s", p);
|
|
||||||
}
|
|
||||||
|
|
||||||
function print_system(sys: System)
|
|
||||||
{
|
|
||||||
print fmt("System: %s", sys$name);
|
|
||||||
|
|
||||||
for ( s in sys$services )
|
|
||||||
print_service(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
event bro_init()
|
|
||||||
{
|
|
||||||
local server01: System;
|
|
||||||
server01$name = "morlock";
|
|
||||||
add server01$services[[ $name="dns", $ports=set(53/udp, 53/tcp), $rfc=1035]];
|
|
||||||
add server01$services[[ $name="http", $ports=set(80/tcp, 8080/tcp), $rfc=2616]];
|
|
||||||
print_system(server01);
|
|
||||||
|
|
||||||
|
|
||||||
# local dns: Service = [ $name="dns", $ports=set(53/udp, 53/tcp), $rfc=1035];
|
|
||||||
# local http: Service = [ $name="http", $ports=set(80/tcp, 8080/tcp), $rfc=2616];
|
|
||||||
# print_service(dns);
|
|
||||||
# print_service(http);
|
|
||||||
}
|
|
|
@ -1,9 +0,0 @@
|
||||||
# @TEST-EXEC: cat %INPUT >output && btest-diff output
|
|
||||||
|
|
||||||
data_struct_set_declaration.bro
|
|
||||||
|
|
||||||
event bro_init()
|
|
||||||
{
|
|
||||||
local ssl_ports: set[port];
|
|
||||||
local non_ssl_ports = set( 23/tcp, 80/tcp, 143/tcp, 25/tcp );
|
|
||||||
}
|
|
|
@ -1,9 +0,0 @@
|
||||||
# @TEST-EXEC: cat %INPUT >output && btest-diff output
|
|
||||||
|
|
||||||
data_struct_set_declaration.bro
|
|
||||||
|
|
||||||
for ( i in ssl_ports )
|
|
||||||
print fmt("SSL Port: %s", i);
|
|
||||||
|
|
||||||
for ( i in non_ssl_ports )
|
|
||||||
print fmt("Non-SSL Port: %s", i);
|
|
|
@ -1,7 +0,0 @@
|
||||||
# @TEST-EXEC: cat %INPUT >output && btest-diff output
|
|
||||||
|
|
||||||
data_struct_set_declaration.bro
|
|
||||||
|
|
||||||
# Check for SMTPS
|
|
||||||
if ( 587/tcp !in ssl_ports )
|
|
||||||
add ssl_ports[587/tcp];
|
|
|
@ -1,26 +0,0 @@
|
||||||
# @TEST-EXEC: cat %INPUT >output && btest-diff output
|
|
||||||
|
|
||||||
data_struct_set_declaration.bro
|
|
||||||
|
|
||||||
event bro_init()
|
|
||||||
{
|
|
||||||
local ssl_ports: set[port];
|
|
||||||
local non_ssl_ports = set( 23/tcp, 80/tcp, 143/tcp, 25/tcp );
|
|
||||||
|
|
||||||
# SSH
|
|
||||||
add ssl_ports[22/tcp];
|
|
||||||
# HTTPS
|
|
||||||
add ssl_ports[443/tcp];
|
|
||||||
# IMAPS
|
|
||||||
add ssl_ports[993/tcp];
|
|
||||||
|
|
||||||
# Check for SMTPS
|
|
||||||
if ( 587/tcp !in ssl_ports )
|
|
||||||
add ssl_ports[587/tcp];
|
|
||||||
|
|
||||||
for ( i in ssl_ports )
|
|
||||||
print fmt("SSL Port: %s", i);
|
|
||||||
|
|
||||||
for ( i in non_ssl_ports )
|
|
||||||
print fmt("Non-SSL Port: %s", i);
|
|
||||||
}
|
|
|
@ -1,17 +0,0 @@
|
||||||
# @TEST-EXEC: cat %INPUT >output && btest-diff output
|
|
||||||
|
|
||||||
data_struct_table_complex.bro
|
|
||||||
|
|
||||||
event bro_init()
|
|
||||||
{
|
|
||||||
local samurai_flicks: table[string, string, count, string] of string;
|
|
||||||
|
|
||||||
samurai_flicks["Kihachi Okamoto", "Toho", 1968, "Tatsuya Nakadai"] = "Kiru";
|
|
||||||
samurai_flicks["Hideo Gosha", "Fuji", 1969, "Tatsuya Nakadai"] = "Goyokin";
|
|
||||||
samurai_flicks["Masaki Kobayashi", "Shochiku Eiga", 1962, "Tatsuya Nakadai" ] = "Harakiri";
|
|
||||||
samurai_flicks["Yoji Yamada", "Eisei Gekijo", 2002, "Hiroyuki Sanada" ] = "Tasogare Seibei";
|
|
||||||
|
|
||||||
for ( [d, s, y, a] in samurai_flicks )
|
|
||||||
print fmt("%s was released in %d by %s studios, directed by %s and starring %s", samurai_flicks[d, s, y, a], y, s, d, a);
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,23 +0,0 @@
|
||||||
# @TEST-EXEC: cat %INPUT >output && btest-diff output
|
|
||||||
|
|
||||||
data_struct_table_declaration.bro
|
|
||||||
|
|
||||||
event bro_init()
|
|
||||||
{
|
|
||||||
# Declaration of the table.
|
|
||||||
local ssl_services: table[string] of port;
|
|
||||||
|
|
||||||
# Initialize the table.
|
|
||||||
ssl_services = table(["SSH"] = 22/tcp, ["HTTPS"] = 443/tcp);
|
|
||||||
|
|
||||||
# Insert one key-yield pair into the table.
|
|
||||||
ssl_services["IMAPS"] = 993/tcp;
|
|
||||||
|
|
||||||
# Check if the key "SMTPS" is not in the table.
|
|
||||||
if ( "SMTPS" !in ssl_services )
|
|
||||||
ssl_services["SMTPS"] = 587/tcp;
|
|
||||||
|
|
||||||
# Iterate over each key in the table.
|
|
||||||
for ( k in ssl_services )
|
|
||||||
print fmt("Service Name: %s - Common Port: %s", k, ssl_services[k]);
|
|
||||||
}
|
|
|
@ -1,19 +0,0 @@
|
||||||
# @TEST-EXEC: cat %INPUT >output && btest-diff output
|
|
||||||
|
|
||||||
data_struct_vector_declaration.bro
|
|
||||||
|
|
||||||
event bro_init()
|
|
||||||
{
|
|
||||||
local v1: vector of count;
|
|
||||||
local v2 = vector(1, 2, 3, 4);
|
|
||||||
|
|
||||||
v1 += 1;
|
|
||||||
v1 += 2;
|
|
||||||
v1 += 3;
|
|
||||||
v1 += 4;
|
|
||||||
|
|
||||||
print fmt("contents of v1: %s", v1);
|
|
||||||
print fmt("length of v1: %d", |v1|);
|
|
||||||
print fmt("contents of v2: %s", v2);
|
|
||||||
print fmt("length of v2: %d", |v2|);
|
|
||||||
}
|
|
|
@ -1,11 +0,0 @@
|
||||||
# @TEST-EXEC: cat %INPUT >output && btest-diff output
|
|
||||||
|
|
||||||
data_struct_vector_iter.bro
|
|
||||||
|
|
||||||
event bro_init()
|
|
||||||
{
|
|
||||||
local addr_vector: vector of addr = vector(1.2.3.4, 2.3.4.5, 3.4.5.6);
|
|
||||||
|
|
||||||
for (i in addr_vector)
|
|
||||||
print mask_addr(addr_vector[i], 18);
|
|
||||||
}
|
|
|
@ -1,13 +0,0 @@
|
||||||
# @TEST-EXEC: cat %INPUT >output && btest-diff output
|
|
||||||
|
|
||||||
data_type_const.bro
|
|
||||||
|
|
||||||
const port_list: table[port] of string &redef;
|
|
||||||
|
|
||||||
redef port_list += { [6666/tcp] = "IRC"};
|
|
||||||
redef port_list += { [80/tcp] = "WWW" };
|
|
||||||
|
|
||||||
event bro_init()
|
|
||||||
{
|
|
||||||
print port_list;
|
|
||||||
}
|
|
|
@ -1,8 +0,0 @@
|
||||||
# @TEST-EXEC: cat %INPUT >output && btest-diff output
|
|
||||||
|
|
||||||
data_type_const_simple.bro
|
|
||||||
|
|
||||||
@load base/protocols/http
|
|
||||||
|
|
||||||
redef HTTP::default_capture_password = T;
|
|
||||||
|
|
|
@ -1,13 +0,0 @@
|
||||||
# @TEST-EXEC: cat %INPUT >output && btest-diff output
|
|
||||||
|
|
||||||
data_type_declaration.bro
|
|
||||||
|
|
||||||
event bro_init()
|
|
||||||
{
|
|
||||||
local a: int;
|
|
||||||
a = 10;
|
|
||||||
local b = 10;
|
|
||||||
|
|
||||||
if ( a == b )
|
|
||||||
print fmt("A: %d, B: %d", a, b);
|
|
||||||
}
|
|
|
@ -1,22 +0,0 @@
|
||||||
# @TEST-EXEC: cat %INPUT >output && btest-diff output
|
|
||||||
|
|
||||||
data_type_interval.bro
|
|
||||||
|
|
||||||
# Store the time the previous connection was established.
|
|
||||||
global last_connection_time: time;
|
|
||||||
|
|
||||||
# boolean value to indicate whether we have seen a previous connection.
|
|
||||||
global connection_seen: bool = F;
|
|
||||||
|
|
||||||
event connection_established(c: connection)
|
|
||||||
{
|
|
||||||
local net_time: time = network_time();
|
|
||||||
|
|
||||||
print fmt("%s: New connection established from %s to %s", strftime("%Y/%M/%d %H:%m:%S", net_time), c$id$orig_h, c$id$resp_h);
|
|
||||||
|
|
||||||
if ( connection_seen )
|
|
||||||
print fmt(" Time since last connection: %s", net_time - last_connection_time);
|
|
||||||
|
|
||||||
last_connection_time = net_time;
|
|
||||||
connection_seen = T;
|
|
||||||
}
|
|
|
@ -1,15 +0,0 @@
|
||||||
# @TEST-EXEC: cat %INPUT >output && btest-diff output
|
|
||||||
|
|
||||||
data_type_local.bro
|
|
||||||
|
|
||||||
function add_two(i: count): count
|
|
||||||
{
|
|
||||||
local added_two = i+2;
|
|
||||||
print fmt("i + 2 = %d", added_two);
|
|
||||||
return added_two;
|
|
||||||
}
|
|
||||||
|
|
||||||
event bro_init()
|
|
||||||
{
|
|
||||||
local test = add_two(10);
|
|
||||||
}
|
|
|
@ -1,17 +0,0 @@
|
||||||
# @TEST-EXEC: cat %INPUT >output && btest-diff output
|
|
||||||
|
|
||||||
data_type_pattern_01.bro
|
|
||||||
|
|
||||||
event bro_init()
|
|
||||||
{
|
|
||||||
local test_string = "The quick brown fox jumps over the lazy dog.";
|
|
||||||
local test_pattern = /quick|lazy/;
|
|
||||||
|
|
||||||
if ( test_pattern in test_string )
|
|
||||||
{
|
|
||||||
local results = split(test_string, test_pattern);
|
|
||||||
print results[1];
|
|
||||||
print results[2];
|
|
||||||
print results[3];
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,14 +0,0 @@
|
||||||
# @TEST-EXEC: cat %INPUT >output && btest-diff output
|
|
||||||
|
|
||||||
data_type_pattern_02.bro
|
|
||||||
|
|
||||||
event bro_init()
|
|
||||||
{
|
|
||||||
local test_string = "equality";
|
|
||||||
|
|
||||||
local test_pattern = /equal/;
|
|
||||||
print fmt("%s and %s %s equal", test_string, test_pattern, test_pattern == test_string ? "are" : "are not");
|
|
||||||
|
|
||||||
test_pattern = /equality/;
|
|
||||||
print fmt("%s and %s %s equal", test_string, test_pattern, test_pattern == test_string ? "are" : "are not");
|
|
||||||
}
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue