Merge remote-tracking branch 'origin/master' into topic/johanna/websockets

This commit is contained in:
Johanna Amann 2018-01-12 10:27:23 -08:00
commit cd345caadb
229 changed files with 6335 additions and 1407 deletions

258
CHANGES
View file

@ -1,4 +1,260 @@
2.5-381 | 2018-01-12 10:03:21 -0800
* Preallocate all possible PortVals, mark PortVal ctors deprecated.
The performance benefit is small (maybe ~1% at most), however, it's a
trivial change without downsides. (Jon Siwek)
* Add BRO_DEPRECATED macro. (Jon Siwek)
* Add functions for retrieving files by their id.
There are two new script level functions to query and lookup files
from the core by their IDs. These are adding feature parity for
similarly named functions for files. The function prototypes are
as follows:
Files::file_exists(fuid: string): bool
Files::lookup_File(fuid: string): fa_file (Seth Hall)
2.5-375 | 2018-01-11 11:47:01 -0600
* Fix a test that fails in some environments (Daniel Thayer)
* Add CVE ID for BIT-1856. (Johanna Amann)
2.5-372 | 2017-12-15 15:08:51 -0600
* Remove some DNS weirds that caused volume and are generally not useful:
dns_unmatched_msg, dns_unmatched_msg_quantity, dns_unmatched_reply.
(Corelight)
2.5-369 | 2017-12-13 14:22:47 -0600
* Fix typo in analyzer::Manager API docs (Corelight)
2.5-368 | 2017-12-08 13:09:25 -0600
* Improve for-loop iteration performance over empty tables. (Justin Azoff)
* Fix gcc7 warnings. (Johanna Amann)
2.5-363 | 2017-12-05 11:00:09 -0600
* Fix documentation for ReassemblerStats. (Corelight)
2.5-362 | 2017-12-02 09:45:04 -0600
* BIT-1791: Do not log SOCKS passwords by default and add
SOCKS::default_capture_password option. (Johanna Amann)
* Add missing ; in SSL binpac parser, found by Luke Valenta. (Johanna Amann)
2.5-359 | 2017-11-29 14:01:37 -0600
* Add --ccache option to configure script (requires CMake 3.10+). (Corelight)
2.5-358 | 2017-11-28 12:28:14 -0800
* Extend the TLS analyzer with several events containing cryptographic
parameters from the client and server key exchanges.
The new events are:
ssl_ecdh_server_params, ssl_dh_server_params, ssl_server_signature,
ssl_ecdh_client_params, ssl_dh_client_params, ssl_rsa_client_pms
Since ssl_ecdh_server_params contains more information than the old
ssl_server_curve event, ssl_server_curve is now marked as deprecated.
(Luke Valenta)
2.5-352 | 2017-11-21 13:21:51 -0600
* Fix assignments to event arguments becoming visible to subsequent
handlers. (Robin Sommer)
2.5-350 | 2017-11-21 12:19:28 -0600
* Add HookReporter plugin hook function.
This hook gives access to basically all information that is available in
the function in Reporter.cc that performs the logging. The hook is
called each time when anything passes through the reporter in the cases
in which an event usually would be called. This includes weirds. The
hook can return false to prevent the normal reporter events from being
raised. (Corelight)
2.5-348 | 2017-11-21 11:30:55 -0600
* Fix a nb_dns.c compile error (older OSs) due to C90 vs C99. (Corelight)
2.5-347 | 2017-11-20 14:00:37 -0600
* Fix and extend behavior of HookLoadFile. (Corelight)
2.5-345 | 2017-11-20 11:28:59 -0600
* BIT-1827: fix error on initializing DNS w/ IPv6 nameserver. (Corelight)
* Add --build-type flag to configure wrapper. (Corelight)
2.5-343 | 2017-11-17 15:27:04 -0800
* Fix ASCII logging of very large values of type "double".
Previously, the nonsensical "NAN.0" would be written to ASCII logs
for any value >= 1e248). (Daniel Thayer)
* Add more test cases to ascii-double.bro (Daniel Thayer)
* Enforce a maximum line length in ContentLine analyzer. (Justin Azoff)
* Fix OOB read with IP packets that have a header length greater than the total
length of their packet. (Johanna Amann)
* Verify version field of IP packets read from tunnels. (Johanna Amann)
2.5-332 | 2017-10-27 13:27:16 -0700
* Bro docs tweaks for correctness and readability. (Christian Kreibich)
* Fix use-after-free in Trigger.cc. (Johanna Amann)
2.5-328 | 2017-10-16 13:13:41 -0700
* Patch OOB write in content-line analyzer.
A combination of packets can trigger an out of bound write of '0' byte
in the content-line analyzer. Addresses BIT-1856 / CVE-2017-1000458.
(Frank Meier/Johanna Amann)
2.5-327 | 2017-10-16 12:21:01 -0700
* Updating submodule(s).
2.5-326 | 2017-10-05 14:34:20 -0700
* Update the SSH analyzer to support the "curve25519-sha256" KEX.
(Vlad Grigorescu)
2.5-321 | 2017-10-03 12:00:29 -0500
* Add "-B scripts" flag to allow debug output of script load order.
(Corelight)
* Fix segmentation fault on eval condition with no return value. (Corelight)
2.5-317 | 2017-09-29 09:54:50 -0400
* BIT-1853 - Fix an issue with broctl triggering reporter error in the
intel framework. (Justin Azoff)
* BIT-1845 - Make "in" keyword work with binary data. (Johanna Amann)
* Add TLS 1.3 fix and testcase due to Google Chrome's use of TLS 1.3.
It turns out that Chrome supports an experimental mode to support TLS
1.3, which uses a non-standard way to negotiate TLS 1.3 with a server.
This non-standard way to negotiate TLS 1.3 breaks the current draft RFC
and re-uses an extension on the server-side with a different binary
formatting, causing us to throw a binpac exception.
This patch ignores the extension when sent by the server, continuing to
correctly parse the server_hello reply (as far as possible).
From what I can tell this seems to be google working around the fac
that MITM equipment cannot deal with TLS 1.3 server hellos; this change
makes the fact that TLS 1.3 is used completely opaque unless one looks
into a few extensions.
We currently log this as TLS 1.2. (Johanna Amann)
2.5-310 | 2017-09-21 09:10:21 -0700
* fix interaction of gridftp scripts with other thresholds. (Justin Azoff)
2.5-307 | 2017-09-20 10:51:09 -0500
* BIT-1846: Updating broctl submodule to include fix for symlinking
issue (Jon Siwek)
2.5-306 | 2017-09-18 14:43:42 -0700
* Make strerror_r portable, supporting XSI/gnu versions. (Thomas Petersen)
* Prevent crash when calling bro -U. (Thomas Petersen)
* Remove annoying error message from connsize bifs. (Johanna Amann)
* Add test to verify that log rotation works with gzipped logs (Daniel Thayer)
* Fix ascii writer to not discard a ".gz" file extension. (Daniel Thayer)
When Bro writes a compressed log, it uses a file extension of ".gz".
However, upon log rotation the ascii writer script function
"default_rotation_postprocessor_func" was discarding the ".gz"
file extension. Fixed so that the correct file extension is
preserved after rotation. (Daniel Thayer)
2.5-297 | 2017-09-11 09:26:33 -0700
* Fix small OCSP parser bug; serial numbers were not passed to events
(Johanna Amann)
* Fix expire-redef.bro test. (Daniel Thayer)
2.5-294 | 2017-08-11 13:51:49 -0500
* Fix core.truncation unit test on macOS. (Jon Siwek)
* Fix a netcontrol test that often fails (Daniel Thayer)
* Update install instructions for Fedora 26 (Daniel Thayer)
2.5-288 | 2017-08-04 14:17:10 -0700
* Fix field not being populated, which resulted in a reporter
messsage. Addresses BIT-1831. Reported by Chris Herdt. (Seth Hall)
* Support for OCSP and Signed Certificate Timestamp. (Liang
Zhu/Johanna Amann)
- OCSP parsing is added to the X.509 module.
- Signed Certificate Timestamp extraction, parsing, & validation
is added to the SSL, X.509, and OCSP analyzers. Validation is
added to the X.509 BIFs.
This adds the following events and BIFs:
- event ocsp_request(f: fa_file, version: count, requestorName: string);
- event ocsp_request_certificate(f: fa_file, hashAlgorithm: string, issuerNameHash: string, issuerKeyHash: string, serialNumber: string);
- event ocsp_response_status(f: fa_file, status: string);
- event ocsp_response_bytes(f: fa_file, resp_ref: opaque of ocsp_resp, status: string, version: count, responderId: string, producedAt: time, signatureAlgorithm: string, certs: x509_opaque_vector);
- event ocsp_response_certificate(f: fa_file, hashAlgorithm: string, issuerNameHash: string, issuerKeyHash: string, serialNumber: string, certStatus: string, revokeTime: time, revokeReason: string, thisUpdate: time, nextUpdate: time);
- event ocsp_extension(f: fa_file, ext: X509::Extension, global_resp: bool);
- event x509_ocsp_ext_signed_certificate_timestamp(f: fa_file, version: count, logid: string, timestamp: count, hash_algorithm: count, signature_algorithm: count, signature: string);
- event ssl_extension_signed_certificate_timestamp(c: connection, is_orig: bool, version: count, logid: string, timestamp: count, signature_and_hashalgorithm: SSL::SignatureAndHashAlgorithm, signature: string);
- function sct_verify(cert: opaque of x509, logid: string, log_key: string, signature: string, timestamp: count, hash_algorithm: count, issuer_key_hash: string &default=""): bool
- function x509_subject_name_hash(cert: opaque of x509, hash_alg: count): string
- function x509_issuer_name_hash(cert: opaque of x509, hash_alg: count): string
- function x509_spki_hash(cert: opaque of x509, hash_alg: count): string
This also changes the MIME types that we use to identify X.509
certificates in SSL connections from "application/pkix-cert" to
"application/x-x509-user-cert" for host certificates and
"application/x-x509-ca-cert" for CA certificates.
* The SSL scripts provide a new hook "ssl_finishing(c: connection)"
to trigger actions after the handshake has concluded. (Johanna
Amann)
* Add an internal API for protocol analyzers to provide the MIME
type of file data directly, disabling automatic inferrence.
(Johanna Amann).
2.5-186 | 2017-07-28 12:22:20 -0700 2.5-186 | 2017-07-28 12:22:20 -0700
* Improved handling of '%' at end of line in HTTP analyzer. (Johanna * Improved handling of '%' at end of line in HTTP analyzer. (Johanna
@ -800,7 +1056,7 @@
2.4-683 | 2016-07-08 14:55:04 -0700 2.4-683 | 2016-07-08 14:55:04 -0700
* Extendign connection history field to flag with '^' when Bro flips * Extending connection history field to flag with '^' when Bro flips
a connection's endpoints. Addresses BIT-1629. (Robin Sommer) a connection's endpoints. Addresses BIT-1629. (Robin Sommer)
2.4-680 | 2016-07-06 09:18:21 -0700 2.4-680 | 2016-07-06 09:18:21 -0700

View file

@ -9,6 +9,18 @@ include(cmake/CommonCMakeConfig.cmake)
######################################################################## ########################################################################
## Project/Build Configuration ## Project/Build Configuration
if ( ENABLE_CCACHE )
find_program(CCACHE_PROGRAM ccache)
if ( NOT CCACHE_PROGRAM )
message(FATAL_ERROR "ccache not found")
endif ()
message(STATUS "Using ccache: ${CCACHE_PROGRAM}")
set(CMAKE_C_COMPILER_LAUNCHER ${CCACHE_PROGRAM})
set(CMAKE_CXX_COMPILER_LAUNCHER ${CCACHE_PROGRAM})
endif ()
set(BRO_ROOT_DIR ${CMAKE_INSTALL_PREFIX}) set(BRO_ROOT_DIR ${CMAKE_INSTALL_PREFIX})
if (NOT BRO_SCRIPT_INSTALL_PATH) if (NOT BRO_SCRIPT_INSTALL_PATH)
# set the default Bro script installation path (user did not specify one) # set the default Bro script installation path (user did not specify one)
@ -246,6 +258,8 @@ endif ()
message( message(
"\n====================| Bro Build Summary |=====================" "\n====================| Bro Build Summary |====================="
"\n" "\n"
"\nBuild type: ${CMAKE_BUILD_TYPE}"
"\nBuild dir: ${CMAKE_BINARY_DIR}"
"\nInstall prefix: ${CMAKE_INSTALL_PREFIX}" "\nInstall prefix: ${CMAKE_INSTALL_PREFIX}"
"\nBro Script Path: ${BRO_SCRIPT_INSTALL_PATH}" "\nBro Script Path: ${BRO_SCRIPT_INSTALL_PATH}"
"\nDebug mode: ${ENABLE_DEBUG}" "\nDebug mode: ${ENABLE_DEBUG}"

55
NEWS
View file

@ -8,6 +8,61 @@ their own ``CHANGES``.)
Bro 2.6 (in progress) Bro 2.6 (in progress)
===================== =====================
New Functionality
-----------------
- Support for OCSP and Signed Certificate Timestamp. This adds the
following events and BIFs:
- Events: ocsp_request, ocsp_request_certificate,
ocsp_response_status, ocsp_response_bytes
ocsp_response_certificate ocsp_extension
x509_ocsp_ext_signed_certificate_timestamp
ssl_extension_signed_certificate_timestamp
- Functions: sct_verify, x509_subject_name_hash,
x509_issuer_name_hash x509_spki_hash
- The SSL scripts provide a new hook "ssl_finishing(c: connection)"
to trigger actions after the handshake has concluded.
- New functionality has been added to the TLS parser, adding several
events. These events mostly extract information from the server and client
key exchange messages. The new events are:
ssl_ecdh_server_params, ssl_dh_server_params, ssl_server_signature,
ssl_ecdh_client_params, ssl_dh_client_params, ssl_rsa_client_pms
Since ssl_ecdh_server_params contains more information than the old
ssl_server_curve event, ssl_server_curve is now marked as deprecated.
- Functions for retrieving files by their ID have been added:
Files::file_exists, Files::lookup_File
Changed Functionality
---------------------
- The MIME types used to identify X.509 certificates in SSL
connections changed from "application/pkix-cert" to
"application/x-x509-user-cert" for host certificates and
"application/x-x509-ca-cert" for CA certificates.
- With the new ssl_ecdh_server_params event, the ssl_server_curve
event is considered deprecated and will be removed in a future
version of Bro.
- The Socks analyzer no longer logs passwords by default. This
brings its behavior in line with the FTP/HTTP analyzers which also
do not log passwords by default.
To restore the previous behavior and log Socks passwords, use:
redef SOCKS::default_capture_password = T;
- The DNS base scripts no longer generate some noisy and annoying
weirds (dns_unmatched_msg, dns_unmatched_msg_quantity, dns_unmatched_reply)
Removed Functionality Removed Functionality
--------------------- ---------------------

View file

@ -1 +1 @@
2.5-186 2.5-381

@ -1 +1 @@
Subproject commit 27356ae52ff9ff639b53a7325ea3262e1a13b704 Subproject commit e6d13e5dfc9f727f7c59c0496b529bdb2a1d9b62

@ -1 +1 @@
Subproject commit 43f4b90bbaf87dae1a1073e7bf13301e58866011 Subproject commit e9e91eac74bf1a240e40bc62ad4f4dc3d88bc126

@ -1 +1 @@
Subproject commit 25907f6b0a5347304d1ec8213bfad3d114260ca0 Subproject commit 13fe5fba7ebd314e6bf2bedbac465d4c3f2e4301

@ -1 +1 @@
Subproject commit 1ab5ed3d3b0f2a3ff231de77816a697d55abccb8 Subproject commit a075a80639b7d543b55cc31191965eb1364e3623

@ -1 +1 @@
Subproject commit 862c982f35e342fb10fa281120135cf61eca66bb Subproject commit 761ef15d9b72d189d29af7dd09c9e576d61fd78f

@ -1 +1 @@
Subproject commit 2810ccee25f6f20be5cd241155f12d02a79d592a Subproject commit b3a5742b6b04acdd851dba4e08723a568c4aa755

2
cmake

@ -1 +1 @@
Subproject commit 79f2b2e944da77774675be4d5254156451967371 Subproject commit 9bac5950664ac7b50fb576a2f9422b819b505e21

20
configure vendored
View file

@ -18,7 +18,15 @@ Usage: $0 [OPTION]... [VAR=VALUE]...
Build Options: Build Options:
--builddir=DIR place build files in directory [build] --builddir=DIR place build files in directory [build]
--build-type=TYPE set CMake build type [RelWithDebInfo]:
- Debug: optimizations off, debug symbols + flags
- MinSizeRel: size optimizations, debugging off
- Release: optimizations on, debugging off
- RelWithDebInfo: optimizations on,
debug symbols on, debug flags off
--generator=GENERATOR CMake generator to use (see cmake --help) --generator=GENERATOR CMake generator to use (see cmake --help)
--ccache use ccache to speed up recompilation (requires
ccache installation and CMake 3.10+)
Installation Directories: Installation Directories:
--prefix=PREFIX installation directory [/usr/local/bro] --prefix=PREFIX installation directory [/usr/local/bro]
@ -34,7 +42,7 @@ Usage: $0 [OPTION]... [VAR=VALUE]...
--conf-files-dir=PATH config files installation directory [PREFIX/etc] --conf-files-dir=PATH config files installation directory [PREFIX/etc]
Optional Features: Optional Features:
--enable-debug compile in debugging mode --enable-debug compile in debugging mode (like --build-type=Debug)
--enable-mobile-ipv6 analyze mobile IPv6 features defined by RFC 6275 --enable-mobile-ipv6 analyze mobile IPv6 features defined by RFC 6275
--enable-perftools force use of Google perftools on non-Linux systems --enable-perftools force use of Google perftools on non-Linux systems
(automatically on when perftools is present on Linux) (automatically on when perftools is present on Linux)
@ -153,9 +161,19 @@ while [ $# -ne 0 ]; do
--builddir=*) --builddir=*)
builddir=$optarg builddir=$optarg
;; ;;
--build-type=*)
append_cache_entry CMAKE_BUILD_TYPE STRING $optarg
if [ $(echo "$optarg" | tr [:upper:] [:lower:]) = "debug" ]; then
append_cache_entry ENABLE_DEBUG BOOL true
fi
;;
--generator=*) --generator=*)
CMakeGenerator="$optarg" CMakeGenerator="$optarg"
;; ;;
--ccache)
append_cache_entry ENABLE_CCACHE BOOL true
;;
--prefix=*) --prefix=*)
prefix=$optarg prefix=$optarg
append_cache_entry CMAKE_INSTALL_PREFIX PATH $optarg append_cache_entry CMAKE_INSTALL_PREFIX PATH $optarg

View file

@ -153,10 +153,8 @@ sup, sub {
pre, code { pre, code {
white-space: pre; white-space: pre;
overflow: auto; overflow: auto;
margin-left: 2em; margin-left: 0.25em;
margin-right: 2em; margin-right: 0.25em;
margin-top: .5em;
margin-bottom: 1.5em;
word-wrap: normal; word-wrap: normal;
} }

View file

@ -10,7 +10,7 @@
{% endblock %} {% endblock %}
{% block header %} {% block header %}
<iframe src="//www.bro.org/frames/header-no-logo.html" width="100%" height="100px" frameborder="0" marginheight="0" scrolling="no" marginwidth="0"> <iframe src="https://www.bro.org/frames/header-no-logo.html" width="100%" height="100px" frameborder="0" marginheight="0" scrolling="no" marginwidth="0">
</iframe> </iframe>
{% endblock %} {% endblock %}
@ -108,6 +108,6 @@
{% endblock %} {% endblock %}
{% block footer %} {% block footer %}
<iframe src="//www.bro.org/frames/footer.html" width="100%" height="420px" frameborder="0" marginheight="0" scrolling="no" marginwidth="0"> <iframe src="https://www.bro.org/frames/footer.html" width="100%" height="420px" frameborder="0" marginheight="0" scrolling="no" marginwidth="0">
</iframe> </iframe>
{% endblock %} {% endblock %}

View file

@ -54,6 +54,9 @@ To install the required dependencies, you can use:
sudo yum install cmake make gcc gcc-c++ flex bison libpcap-devel openssl-devel python-devel swig zlib-devel sudo yum install cmake make gcc gcc-c++ flex bison libpcap-devel openssl-devel python-devel swig zlib-devel
In order to build Bro on Fedora 26, install ``compat-openssl10-devel`` instead
of ``openssl-devel``.
* DEB/Debian-based Linux: * DEB/Debian-based Linux:
.. console:: .. console::

View file

@ -76,6 +76,10 @@ Files
+============================+=======================================+=================================+ +============================+=======================================+=================================+
| files.log | File analysis results | :bro:type:`Files::Info` | | files.log | File analysis results | :bro:type:`Files::Info` |
+----------------------------+---------------------------------------+---------------------------------+ +----------------------------+---------------------------------------+---------------------------------+
| ocsp.log | Online Certificate Status Protocol | :bro:type:`OCSP::Info` |
| | (OCSP). Only created if policy script | |
| | is loaded. | |
+----------------------------+---------------------------------------+---------------------------------+
| pe.log | Portable Executable (PE) | :bro:type:`PE::Info` | | pe.log | Portable Executable (PE) | :bro:type:`PE::Info` |
+----------------------------+---------------------------------------+---------------------------------+ +----------------------------+---------------------------------------+---------------------------------+
| x509.log | X.509 certificate info | :bro:type:`X509::Info` | | x509.log | X.509 certificate info | :bro:type:`X509::Info` |

View file

@ -1 +1,2 @@
Support for X509 certificates with the file analysis framework. Support for X509 certificates with the file analysis framework.
Also supports parsing OCSP requests and responses.

View file

@ -10,23 +10,17 @@ export {
type Info: record { type Info: record {
## Current timestamp. ## Current timestamp.
ts: time &log; ts: time &log;
## File id of this certificate. ## File id of this certificate.
id: string &log; id: string &log;
## Basic information about the certificate. ## Basic information about the certificate.
certificate: X509::Certificate &log; certificate: X509::Certificate &log;
## The opaque wrapping the certificate. Mainly used ## The opaque wrapping the certificate. Mainly used
## for the verify operations. ## for the verify operations.
handle: opaque of x509; handle: opaque of x509;
## All extensions that were encountered in the certificate. ## All extensions that were encountered in the certificate.
extensions: vector of X509::Extension &default=vector(); extensions: vector of X509::Extension &default=vector();
## Subject alternative name extension of the certificate. ## Subject alternative name extension of the certificate.
san: X509::SubjectAlternativeName &optional &log; san: X509::SubjectAlternativeName &optional &log;
## Basic constraints extension of the certificate. ## Basic constraints extension of the certificate.
basic_constraints: X509::BasicConstraints &optional &log; basic_constraints: X509::BasicConstraints &optional &log;
}; };
@ -38,6 +32,24 @@ export {
event bro_init() &priority=5 event bro_init() &priority=5
{ {
Log::create_stream(X509::LOG, [$columns=Info, $ev=log_x509, $path="x509"]); Log::create_stream(X509::LOG, [$columns=Info, $ev=log_x509, $path="x509"]);
# We use MIME types internally to distinguish between user and CA certificates.
# The first certificate in a connection always gets tagged as user-cert, all
# following certificates get tagged as CA certificates. Certificates gotten via
# other means (e.g. identified from HTTP traffic when they are transfered in plain
# text) get tagged as application/pkix-cert.
Files::register_for_mime_type(Files::ANALYZER_X509, "application/x-x509-user-cert");
Files::register_for_mime_type(Files::ANALYZER_X509, "application/x-x509-ca-cert");
Files::register_for_mime_type(Files::ANALYZER_X509, "application/pkix-cert");
# Always calculate hashes. They are not necessary for base scripts
# but very useful for identification, and required for policy scripts
Files::register_for_mime_type(Files::ANALYZER_MD5, "application/x-x509-user-cert");
Files::register_for_mime_type(Files::ANALYZER_MD5, "application/x-x509-ca-cert");
Files::register_for_mime_type(Files::ANALYZER_MD5, "application/pkix-cert");
Files::register_for_mime_type(Files::ANALYZER_SHA1, "application/x-x509-user-cert");
Files::register_for_mime_type(Files::ANALYZER_SHA1, "application/x-x509-ca-cert");
Files::register_for_mime_type(Files::ANALYZER_SHA1, "application/pkix-cert");
} }
redef record Files::Info += { redef record Files::Info += {
@ -48,9 +60,6 @@ redef record Files::Info += {
event x509_certificate(f: fa_file, cert_ref: opaque of x509, cert: X509::Certificate) &priority=5 event x509_certificate(f: fa_file, cert_ref: opaque of x509, cert: X509::Certificate) &priority=5
{ {
if ( ! f$info?$mime_type )
f$info$mime_type = "application/pkix-cert";
f$info$x509 = [$ts=f$info$ts, $id=f$id, $certificate=cert, $handle=cert_ref]; f$info$x509 = [$ts=f$info$ts, $id=f$id, $certificate=cert, $handle=cert_ref];
} }

View file

@ -135,6 +135,20 @@ export {
## The default per-file reassembly buffer size. ## The default per-file reassembly buffer size.
const reassembly_buffer_size = 524288 &redef; const reassembly_buffer_size = 524288 &redef;
## Lookup to see if a particular file id exists and is still valid.
##
## fuid: the file id.
##
## Returns: T if the file uid is known.
global file_exists: function(fuid: string): bool;
## Lookup an :bro:see:`fa_file` record with the file id.
##
## fuid: the file id.
##
## Returns: the associated :bro:see:`fa_file` record.
global lookup_file: function(fuid: string): fa_file;
## Allows the file reassembler to be used if it's necessary because the ## Allows the file reassembler to be used if it's necessary because the
## file is transferred out of order. ## file is transferred out of order.
## ##
@ -338,6 +352,16 @@ function set_info(f: fa_file)
f$info$is_orig = f$is_orig; f$info$is_orig = f$is_orig;
} }
function file_exists(fuid: string): bool
{
return __file_exists(fuid);
}
function lookup_file(fuid: string): fa_file
{
return __lookup_file(fuid);
}
function set_timeout_interval(f: fa_file, t: interval): bool function set_timeout_interval(f: fa_file, t: interval): bool
{ {
return __set_timeout_interval(f$id, t); return __set_timeout_interval(f$id, t);

View file

@ -32,7 +32,7 @@ event remote_connection_handshake_done(p: event_peer)
{ {
# When a worker connects, send it the complete minimal data store. # When a worker connects, send it the complete minimal data store.
# It will be kept up to date after this by the cluster_new_item event. # It will be kept up to date after this by the cluster_new_item event.
if ( Cluster::nodes[p$descr]$node_type == Cluster::WORKER ) if ( p$descr in Cluster::nodes && Cluster::nodes[p$descr]$node_type == Cluster::WORKER )
{ {
send_id(p, "Intel::min_data_store"); send_id(p, "Intel::min_data_store");
} }

View file

@ -79,9 +79,12 @@ export {
# runs the writer's default postprocessor command on it. # runs the writer's default postprocessor command on it.
function default_rotation_postprocessor_func(info: Log::RotationInfo) : bool function default_rotation_postprocessor_func(info: Log::RotationInfo) : bool
{ {
# If the filename has a ".gz" extension, then keep it.
local gz = info$fname[-3:] == ".gz" ? ".gz" : "";
# Move file to name including both opening and closing time. # Move file to name including both opening and closing time.
local dst = fmt("%s.%s.log", info$path, local dst = fmt("%s.%s.log%s", info$path,
strftime(Log::default_rotation_date_format, info$open)); strftime(Log::default_rotation_date_format, info$open), gz);
system(fmt("/bin/mv %s %s", info$fname, dst)); system(fmt("/bin/mv %s %s", info$fname, dst));

View file

@ -106,6 +106,7 @@ export {
["baroque_SYN"] = ACTION_LOG, ["baroque_SYN"] = ACTION_LOG,
["base64_illegal_encoding"] = ACTION_LOG, ["base64_illegal_encoding"] = ACTION_LOG,
["connection_originator_SYN_ack"] = ACTION_LOG_PER_ORIG, ["connection_originator_SYN_ack"] = ACTION_LOG_PER_ORIG,
["contentline_size_exceeded"] = ACTION_LOG,
["corrupt_tcp_options"] = ACTION_LOG_PER_ORIG, ["corrupt_tcp_options"] = ACTION_LOG_PER_ORIG,
["crud_trailing_HTTP_request"] = ACTION_LOG, ["crud_trailing_HTTP_request"] = ACTION_LOG,
["data_after_reset"] = ACTION_LOG, ["data_after_reset"] = ACTION_LOG,

View file

@ -442,10 +442,13 @@ type fa_file: record {
## Metadata that's been inferred about a particular file. ## Metadata that's been inferred about a particular file.
type fa_metadata: record { type fa_metadata: record {
## The strongest matching mime type if one was discovered. ## The strongest matching MIME type if one was discovered.
mime_type: string &optional; mime_type: string &optional;
## All matching mime types if any were discovered. ## All matching MIME types if any were discovered.
mime_types: mime_matches &optional; mime_types: mime_matches &optional;
## Specifies whether the MIME type was inferred using signatures,
## or provided directly by the protocol the file appeared in.
inferred: bool &default=T;
}; };
## Fields of a SYN packet. ## Fields of a SYN packet.
@ -528,7 +531,7 @@ type EventStats: record {
dispatched: count; ##< Total number of events dispatched so far. dispatched: count; ##< Total number of events dispatched so far.
}; };
## Summary statistics of all regular expression matchers. ## Holds statistics for all types of reassembly.
## ##
## .. bro:see:: get_reassembler_stats ## .. bro:see:: get_reassembler_stats
type ReassemblerStats: record { type ReassemblerStats: record {

View file

@ -2,7 +2,6 @@
##! their responses. ##! their responses.
@load base/utils/queue @load base/utils/queue
@load base/frameworks/notice/weird
@load ./consts @load ./consts
module DNS; module DNS;
@ -177,9 +176,6 @@ function log_unmatched_msgs_queue(q: Queue::Queue)
for ( i in infos ) for ( i in infos )
{ {
local wi = Weird::Info($ts=network_time(), $name="dns_unmatched_msg", $uid=infos[i]$uid,
$id=infos[i]$id);
Weird::weird(wi);
Log::write(DNS::LOG, infos[i]); Log::write(DNS::LOG, infos[i]);
} }
} }
@ -187,21 +183,19 @@ function log_unmatched_msgs_queue(q: Queue::Queue)
function log_unmatched_msgs(msgs: PendingMessages) function log_unmatched_msgs(msgs: PendingMessages)
{ {
for ( trans_id in msgs ) for ( trans_id in msgs )
{
log_unmatched_msgs_queue(msgs[trans_id]); log_unmatched_msgs_queue(msgs[trans_id]);
}
clear_table(msgs); clear_table(msgs);
} }
function enqueue_new_msg(msgs: PendingMessages, id: count, msg: Info) function enqueue_new_msg(msgs: PendingMessages, id: count, msg: Info)
{ {
local wi: Weird::Info;
if ( id !in msgs ) if ( id !in msgs )
{ {
if ( |msgs| > max_pending_query_ids ) if ( |msgs| > max_pending_query_ids )
{ {
wi = Weird::Info($ts=network_time(), $name="dns_unmatched_msg", $uid=msg$uid,
$id=msg$id);
Weird::weird(wi);
# Throw away all unmatched on assumption they'll never be matched. # Throw away all unmatched on assumption they'll never be matched.
log_unmatched_msgs(msgs); log_unmatched_msgs(msgs);
} }
@ -212,9 +206,6 @@ function enqueue_new_msg(msgs: PendingMessages, id: count, msg: Info)
{ {
if ( Queue::len(msgs[id]) > max_pending_msgs ) if ( Queue::len(msgs[id]) > max_pending_msgs )
{ {
wi = Weird::Info($ts=network_time(), $name="dns_unmatched_msg_quantity", $uid=msg$uid,
$id=msg$id);
Weird::weird(wi);
log_unmatched_msgs_queue(msgs[id]); log_unmatched_msgs_queue(msgs[id]);
# Throw away all unmatched on assumption they'll never be matched. # Throw away all unmatched on assumption they'll never be matched.
msgs[id] = Queue::init(); msgs[id] = Queue::init();
@ -271,7 +262,6 @@ hook set_session(c: connection, msg: dns_msg, is_query: bool) &priority=5
# Create a new DNS session and put it in the reply queue so # Create a new DNS session and put it in the reply queue so
# we can wait for a matching query. # we can wait for a matching query.
c$dns = new_session(c, msg$id); c$dns = new_session(c, msg$id);
event conn_weird("dns_unmatched_reply", c, "");
enqueue_new_msg(c$dns_state$pending_replies, msg$id, c$dns); enqueue_new_msg(c$dns_state$pending_replies, msg$id, c$dns);
} }
} }

View file

@ -75,6 +75,9 @@ event ConnThreshold::bytes_threshold_crossed(c: connection, threshold: count, is
if ( threshold < size_threshold || "gridftp-data" in c$service || c$duration > max_time ) if ( threshold < size_threshold || "gridftp-data" in c$service || c$duration > max_time )
return; return;
if ( ! data_channel_initial_criteria(c) )
return;
add c$service["gridftp-data"]; add c$service["gridftp-data"];
event GridFTP::data_channel_detected(c); event GridFTP::data_channel_detected(c);

View file

@ -90,12 +90,6 @@ event file_over_new_connection(f: fa_file, c: connection, is_orig: bool) &priori
c$krb$server_cert = f$info; c$krb$server_cert = f$info;
c$krb$server_cert_fuid = f$id; c$krb$server_cert_fuid = f$id;
} }
Files::add_analyzer(f, Files::ANALYZER_X509);
# Always calculate hashes. They are not necessary for base scripts
# but very useful for identification, and required for policy scripts
Files::add_analyzer(f, Files::ANALYZER_MD5);
Files::add_analyzer(f, Files::ANALYZER_SHA1);
} }
function fill_in_subjects(c: connection) function fill_in_subjects(c: connection)

View file

@ -236,10 +236,6 @@ event file_over_new_connection(f: fa_file, c: connection, is_orig: bool) &priori
{ {
# Count up X509 certs. # Count up X509 certs.
++c$rdp$cert_count; ++c$rdp$cert_count;
Files::add_analyzer(f, Files::ANALYZER_X509);
Files::add_analyzer(f, Files::ANALYZER_MD5);
Files::add_analyzer(f, Files::ANALYZER_SHA1);
} }
} }

View file

@ -6,6 +6,9 @@ module SOCKS;
export { export {
redef enum Log::ID += { LOG }; redef enum Log::ID += { LOG };
## Whether passwords are captured or not.
const default_capture_password = F &redef;
## The record type which contains the fields of the SOCKS log. ## The record type which contains the fields of the SOCKS log.
type Info: record { type Info: record {
## Time when the proxy connection was first detected. ## Time when the proxy connection was first detected.
@ -32,6 +35,8 @@ export {
bound: SOCKS::Address &log &optional; bound: SOCKS::Address &log &optional;
## Server bound port. ## Server bound port.
bound_p: port &log &optional; bound_p: port &log &optional;
## Determines if the password will be captured for this request.
capture_password: bool &default=default_capture_password;
}; };
## Event that can be handled to access the SOCKS ## Event that can be handled to access the SOCKS
@ -93,6 +98,8 @@ event socks_login_userpass_request(c: connection, user: string, password: string
set_session(c, 5); set_session(c, 5);
c$socks$user = user; c$socks$user = user;
if ( c$socks$capture_password )
c$socks$password = password; c$socks$password = password;
} }

View file

@ -1 +1 @@
Support for Secure Sockets Layer (SSL) protocol analysis. Support for Secure Sockets Layer (SSL)/Transport Layer Security(TLS) protocol analysis.

View file

@ -1,6 +1,7 @@
@load ./consts @load ./consts
@load ./main @load ./main
@load ./mozilla-ca-list @load ./mozilla-ca-list
@load ./ct-list
@load ./files @load ./files
@load-sigs ./dpd.sig @load-sigs ./dpd.sig

View file

@ -0,0 +1,48 @@
#
# Do not edit this file. This file is automatically generated by gen-ct-list.pl
# File generated at Thu Jul 27 16:59:25 2017
# File generated from https://www.gstatic.com/ct/log_list/all_logs_list.json
#
@load base/protocols/ssl
module SSL;
redef ct_logs += {
["\x68\xf6\x98\xf8\x1f\x64\x82\xbe\x3a\x8c\xee\xb9\x28\x1d\x4c\xfc\x71\x51\x5d\x67\x93\xd4\x44\xd1\x0a\x67\xac\xbb\x4f\x4f\xfb\xc4"] = CTInfo($description="Google 'Aviator' log", $operator="Google", $url="ct.googleapis.com/aviator/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\xd7\xf4\xcc\x69\xb2\xe4\x0e\x90\xa3\x8a\xea\x5a\x70\x09\x4f\xef\x13\x62\xd0\x8d\x49\x60\xff\x1b\x40\x50\x07\x0c\x6d\x71\x86\xda\x25\x49\x8d\x65\xe1\x08\x0d\x47\x34\x6b\xbd\x27\xbc\x96\x21\x3e\x34\xf5\x87\x76\x31\xb1\x7f\x1d\xc9\x85\x3b\x0d\xf7\x1f\x3f\xe9"),
["\x29\x3c\x51\x96\x54\xc8\x39\x65\xba\xaa\x50\xfc\x58\x07\xd4\xb7\x6f\xbf\x58\x7a\x29\x72\xdc\xa4\xc3\x0c\xf4\xe5\x45\x47\xf4\x78"] = CTInfo($description="Google 'Icarus' log", $operator="Google", $url="ct.googleapis.com/icarus/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x4e\xd2\xbc\xbf\xb3\x08\x0a\xf7\xb9\xea\xa4\xc7\x1c\x38\x61\x04\xeb\x95\xe0\x89\x54\x68\x44\xb1\x66\xbc\x82\x7e\x4f\x50\x6c\x6f\x5c\xa3\xf0\xaa\x3e\xf4\xec\x80\xf0\xdb\x0a\x9a\x7a\xa0\x5b\x72\x00\x7c\x25\x0e\x19\xef\xaf\xb2\x62\x8d\x74\x43\xf4\x26\xf6\x14"),
["\xa4\xb9\x09\x90\xb4\x18\x58\x14\x87\xbb\x13\xa2\xcc\x67\x70\x0a\x3c\x35\x98\x04\xf9\x1b\xdf\xb8\xe3\x77\xcd\x0e\xc8\x0d\xdc\x10"] = CTInfo($description="Google 'Pilot' log", $operator="Google", $url="ct.googleapis.com/pilot/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x7d\xa8\x4b\x12\x29\x80\xa3\x3d\xad\xd3\x5a\x77\xb8\xcc\xe2\x88\xb3\xa5\xfd\xf1\xd3\x0c\xcd\x18\x0c\xe8\x41\x46\xe8\x81\x01\x1b\x15\xe1\x4b\xf1\x1b\x62\xdd\x36\x0a\x08\x18\xba\xed\x0b\x35\x84\xd0\x9e\x40\x3c\x2d\x9e\x9b\x82\x65\xbd\x1f\x04\x10\x41\x4c\xa0"),
["\xee\x4b\xbd\xb7\x75\xce\x60\xba\xe1\x42\x69\x1f\xab\xe1\x9e\x66\xa3\x0f\x7e\x5f\xb0\x72\xd8\x83\x00\xc4\x7b\x89\x7a\xa8\xfd\xcb"] = CTInfo($description="Google 'Rocketeer' log", $operator="Google", $url="ct.googleapis.com/rocketeer/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x20\x5b\x18\xc8\x3c\xc1\x8b\xb3\x31\x08\x00\xbf\xa0\x90\x57\x2b\xb7\x47\x8c\x6f\xb5\x68\xb0\x8e\x90\x78\xe9\xa0\x73\xea\x4f\x28\x21\x2e\x9c\xc0\xf4\x16\x1b\xaa\xf9\xd5\xd7\xa9\x80\xc3\x4e\x2f\x52\x3c\x98\x01\x25\x46\x24\x25\x28\x23\x77\x2d\x05\xc2\x40\x7a"),
["\xbb\xd9\xdf\xbc\x1f\x8a\x71\xb5\x93\x94\x23\x97\xaa\x92\x7b\x47\x38\x57\x95\x0a\xab\x52\xe8\x1a\x90\x96\x64\x36\x8e\x1e\xd1\x85"] = CTInfo($description="Google 'Skydiver' log", $operator="Google", $url="ct.googleapis.com/skydiver/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x12\x6c\x86\x0e\xf6\x17\xb1\x12\x6c\x37\x25\xd2\xad\x87\x3d\x0e\x31\xec\x21\xad\xb1\xcd\xbe\x14\x47\xb6\x71\x56\x85\x7a\x9a\xb7\x3d\x89\x90\x7b\xc6\x32\x3a\xf8\xda\xce\x8b\x01\xfe\x3f\xfc\x71\x91\x19\x8e\x14\x6e\x89\x7a\x5d\xb4\xab\x7e\xe1\x4e\x1e\x7c\xac"),
["\xa8\x99\xd8\x78\x0c\x92\x90\xaa\xf4\x62\xf3\x18\x80\xcc\xfb\xd5\x24\x51\xe9\x70\xd0\xfb\xf5\x91\xef\x75\xb0\xd9\x9b\x64\x56\x81"] = CTInfo($description="Google 'Submariner' log", $operator="Google", $url="ct.googleapis.com/submariner/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x39\xf8\x9f\x20\x62\xd4\x57\x55\x68\xa2\xef\x49\x2d\xf0\x39\x2d\x9a\xde\x44\xb4\x94\x30\xe0\x9e\x7a\x27\x3c\xab\x70\xf0\xd1\xfa\x51\x90\x63\x16\x57\x41\xad\xab\x6d\x1f\x80\x74\x30\x79\x02\x5e\x2d\x59\x84\x07\x24\x23\xf6\x9f\x35\xb8\x85\xb8\x42\x45\xa4\x4f"),
["\x1d\x02\x4b\x8e\xb1\x49\x8b\x34\x4d\xfd\x87\xea\x3e\xfc\x09\x96\xf7\x50\x6f\x23\x5d\x1d\x49\x70\x61\xa4\x77\x3c\x43\x9c\x25\xfb"] = CTInfo($description="Google 'Daedalus' log", $operator="Google", $url="ct.googleapis.com/daedalus/", $maximum_merge_delay=604800, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x6e\x0c\x1c\xba\xee\x2b\x6a\x41\x85\x60\x1d\x7b\x7e\xab\x08\x2c\xfc\x0c\x0a\xa5\x08\xb3\x3e\xd5\x70\x24\xd1\x6d\x1d\x2d\xb6\xb7\xf3\x8b\x36\xdc\x23\x4d\x95\x63\x12\xbb\xe4\x86\x8d\xcc\xe9\xd1\xee\xa1\x40\xa2\xdf\x0b\xa3\x06\x0a\x30\xca\x8d\xac\xa4\x29\x56"),
["\xb0\xcc\x83\xe5\xa5\xf9\x7d\x6b\xaf\x7c\x09\xcc\x28\x49\x04\x87\x2a\xc7\xe8\x8b\x13\x2c\x63\x50\xb7\xc6\xfd\x26\xe1\x6c\x6c\x77"] = CTInfo($description="Google 'Testtube' log", $operator="Google", $url="ct.googleapis.com/testtube/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\xc3\xc8\xbc\x4b\xba\xa2\x18\x4b\x3d\x35\x7b\xf4\x64\x91\x61\xea\xeb\x8e\x99\x1d\x90\xed\xd3\xe9\xaf\x39\x3d\x5c\xd3\x46\x91\x45\xe3\xce\xac\x76\x48\x3b\xd1\x7e\x2c\x0a\x63\x00\x65\x8d\xf5\xae\x8e\x8c\xc7\x11\x25\x4f\x43\x2c\x9d\x19\xa1\xe1\x91\xa4\xb3\xfe"),
["\x56\x14\x06\x9a\x2f\xd7\xc2\xec\xd3\xf5\xe1\xbd\x44\xb2\x3e\xc7\x46\x76\xb9\xbc\x99\x11\x5c\xc0\xef\x94\x98\x55\xd6\x89\xd0\xdd"] = CTInfo($description="DigiCert Log Server", $operator="DigiCert", $url="ct1.digicert-ct.com/log/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x02\x46\xc5\xbe\x1b\xbb\x82\x40\x16\xe8\xc1\xd2\xac\x19\x69\x13\x59\xf8\xf8\x70\x85\x46\x40\xb9\x38\xb0\x23\x82\xa8\x64\x4c\x7f\xbf\xbb\x34\x9f\x4a\x5f\x28\x8a\xcf\x19\xc4\x00\xf6\x36\x06\x93\x65\xed\x4c\xf5\xa9\x21\x62\x5a\xd8\x91\xeb\x38\x24\x40\xac\xe8"),
["\x87\x75\xbf\xe7\x59\x7c\xf8\x8c\x43\x99\x5f\xbd\xf3\x6e\xff\x56\x8d\x47\x56\x36\xff\x4a\xb5\x60\xc1\xb4\xea\xff\x5e\xa0\x83\x0f"] = CTInfo($description="DigiCert Log Server 2", $operator="DigiCert", $url="ct2.digicert-ct.com/log/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\xcc\x5d\x39\x2f\x66\xb8\x4c\x7f\xc1\x2e\x03\xa1\x34\xa3\xe8\x8a\x86\x02\xae\x4a\x11\xc6\xf7\x26\x6a\x37\x9b\xf0\x38\xf8\x5d\x09\x8d\x63\xe8\x31\x6b\x86\x66\xcf\x79\xb3\x25\x3c\x1e\xdf\x78\xb4\xa8\xc5\x69\xfa\xb7\xf0\x82\x79\x62\x43\xf6\xcc\xfe\x81\x66\x84"),
["\xdd\xeb\x1d\x2b\x7a\x0d\x4f\xa6\x20\x8b\x81\xad\x81\x68\x70\x7e\x2e\x8e\x9d\x01\xd5\x5c\x88\x8d\x3d\x11\xc4\xcd\xb6\xec\xbe\xcc"] = CTInfo($description="Symantec log", $operator="Symantec", $url="ct.ws.symantec.com/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x96\xea\xac\x1c\x46\x0c\x1b\x55\xdc\x0d\xfc\xb5\x94\x27\x46\x57\x42\x70\x3a\x69\x18\xe2\xbf\x3b\xc4\xdb\xab\xa0\xf4\xb6\x6c\xc0\x53\x3f\x4d\x42\x10\x33\xf0\x58\x97\x8f\x6b\xbe\x72\xf4\x2a\xec\x1c\x42\xaa\x03\x2f\x1a\x7e\x28\x35\x76\x99\x08\x3d\x21\x14\x86"),
["\xbc\x78\xe1\xdf\xc5\xf6\x3c\x68\x46\x49\x33\x4d\xa1\x0f\xa1\x5f\x09\x79\x69\x20\x09\xc0\x81\xb4\xf3\xf6\x91\x7f\x3e\xd9\xb8\xa5"] = CTInfo($description="Symantec 'Vega' log", $operator="Symantec", $url="vega.ws.symantec.com/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\xea\x95\x9e\x02\xff\xee\xf1\x33\x6d\x4b\x87\xbc\xcd\xfd\x19\x17\x62\xff\x94\xd3\xd0\x59\x07\x3f\x02\x2d\x1c\x90\xfe\xc8\x47\x30\x3b\xf1\xdd\x0d\xb8\x11\x0c\x5d\x1d\x86\xdd\xab\xd3\x2b\x46\x66\xfb\x6e\x65\xb7\x3b\xfd\x59\x68\xac\xdf\xa6\xf8\xce\xd2\x18\x4d"),
["\xa7\xce\x4a\x4e\x62\x07\xe0\xad\xde\xe5\xfd\xaa\x4b\x1f\x86\x76\x87\x67\xb5\xd0\x02\xa5\x5d\x47\x31\x0e\x7e\x67\x0a\x95\xea\xb2"] = CTInfo($description="Symantec Deneb", $operator="Symantec", $url="deneb.ws.symantec.com/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x96\x82\x1e\xa3\xcd\x3a\x80\x84\x1e\x97\xb8\xb7\x07\x19\xae\x76\x1a\x0e\xf8\x55\x76\x9d\x12\x33\x4e\x91\x88\xe4\xd0\x48\x50\x5c\xc1\x9f\x6a\x72\xd6\x01\xf5\x14\xd6\xd0\x38\x6e\xe1\x32\xbc\x67\x0d\x37\xe8\xba\x22\x10\xd1\x72\x86\x79\x28\x96\xf9\x17\x1e\x98"),
["\x15\x97\x04\x88\xd7\xb9\x97\xa0\x5b\xeb\x52\x51\x2a\xde\xe8\xd2\xe8\xb4\xa3\x16\x52\x64\x12\x1a\x9f\xab\xfb\xd5\xf8\x5a\xd9\x3f"] = CTInfo($description="Symantec 'Sirius' log", $operator="Symantec", $url="sirius.ws.symantec.com/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\xa3\x02\x64\x84\x22\xbb\x25\xec\x0d\xe3\xbc\xc2\xc9\x89\x7d\xdd\x45\xd0\xee\xe6\x15\x85\x8f\xd9\xe7\x17\x1b\x13\x80\xea\xed\xb2\x85\x37\xad\x6a\xc5\xd8\x25\x9d\xfa\xf4\xb4\xf3\x6e\x16\x28\x25\x37\xea\xa3\x37\x64\xb2\xc7\x0b\xfd\x51\xe5\xc1\x05\xf4\x0e\xb5"),
["\xcd\xb5\x17\x9b\x7f\xc1\xc0\x46\xfe\xea\x31\x13\x6a\x3f\x8f\x00\x2e\x61\x82\xfa\xf8\x89\x6f\xec\xc8\xb2\xf5\xb5\xab\x60\x49\x00"] = CTInfo($description="Certly.IO log", $operator="Certly", $url="log.certly.io/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x0b\x23\xcb\x85\x62\x98\x61\x48\x04\x73\xeb\x54\x5d\xf3\xd0\x07\x8c\x2d\x19\x2d\x8c\x36\xf5\xeb\x8f\x01\x42\x0a\x7c\x98\x26\x27\xc1\xb5\xdd\x92\x93\xb0\xae\xf8\x9b\x3d\x0c\xd8\x4c\x4e\x1d\xf9\x15\xfb\x47\x68\x7b\xba\x66\xb7\x25\x9c\xd0\x4a\xc2\x66\xdb\x48"),
["\x74\x61\xb4\xa0\x9c\xfb\x3d\x41\xd7\x51\x59\x57\x5b\x2e\x76\x49\xa4\x45\xa8\xd2\x77\x09\xb0\xcc\x56\x4a\x64\x82\xb7\xeb\x41\xa3"] = CTInfo($description="Izenpe log", $operator="Izenpe", $url="ct.izenpe.com/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x27\x64\x39\x0c\x2d\xdc\x50\x18\xf8\x21\x00\xa2\x0e\xed\x2c\xea\x3e\x75\xba\x9f\x93\x64\x09\x00\x11\xc4\x11\x17\xab\x5c\xcf\x0f\x74\xac\xb5\x97\x90\x93\x00\x5b\xb8\xeb\xf7\x27\x3d\xd9\xb2\x0a\x81\x5f\x2f\x0d\x75\x38\x94\x37\x99\x1e\xf6\x07\x76\xe0\xee\xbe"),
["\x89\x41\x44\x9c\x70\x74\x2e\x06\xb9\xfc\x9c\xe7\xb1\x16\xba\x00\x24\xaa\x36\xd5\x9a\xf4\x4f\x02\x04\x40\x4f\x00\xf7\xea\x85\x66"] = CTInfo($description="Izenpe 'Argi' log", $operator="Izenpe", $url="ct.izenpe.eus/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\xd7\xc8\x0e\x23\x3e\x9e\x02\x3c\x9a\xb8\x07\x4a\x2a\x05\xff\x4a\x4b\x88\xd4\x8a\x4d\x39\xce\xf7\xc5\xf2\xb6\x37\xe9\xa3\xed\xe4\xf5\x45\x09\x0e\x67\x14\xfd\x53\x24\xd5\x3a\x94\xf2\xea\xb5\x13\xd9\x1d\x8b\x5c\xa7\xc3\xf3\x6b\xd8\x3f\x2d\x3b\x65\x72\x58\xd6"),
["\x9e\x4f\xf7\x3d\xc3\xce\x22\x0b\x69\x21\x7c\x89\x9e\x46\x80\x76\xab\xf8\xd7\x86\x36\xd5\xcc\xfc\x85\xa3\x1a\x75\x62\x8b\xa8\x8b"] = CTInfo($description="WoSign CT log #1", $operator="Wosign", $url="ct.wosign.com/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\xd7\xec\x2f\x2b\x75\x4f\x37\xbc\xa3\x43\xba\x8b\x65\x66\x3c\x7d\x6a\xe5\x0c\x2a\xa6\xc2\xe5\x26\xfe\x0c\x7d\x4e\x7c\xf0\x3a\xbc\xe2\xd3\x22\xdc\x01\xd0\x1f\x6e\x43\x9c\x5c\x6e\x83\xad\x9c\x15\xf6\xc4\x8d\x60\xb5\x1d\xbb\xa3\x62\x69\x7e\xeb\xa7\xaa\x01\x9b"),
["\x41\xb2\xdc\x2e\x89\xe6\x3c\xe4\xaf\x1b\xa7\xbb\x29\xbf\x68\xc6\xde\xe6\xf9\xf1\xcc\x04\x7e\x30\xdf\xfa\xe3\xb3\xba\x25\x92\x63"] = CTInfo($description="WoSign log", $operator="Wosign", $url="ctlog.wosign.com/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\xcc\x11\x88\x7b\x2d\x66\xcb\xae\x8f\x4d\x30\x66\x27\x19\x25\x22\x93\x21\x46\xb4\x2f\x01\xd3\xc6\xf9\x2b\xd5\xc8\xba\x73\x9b\x06\xa2\xf0\x8a\x02\x9c\xd0\x6b\x46\x18\x30\x85\xba\xe9\x24\x8b\x0e\xd1\x5b\x70\x28\x0c\x7e\xf1\x3a\x45\x7f\x5a\xf3\x82\x42\x60\x31"),
["\x63\xd0\x00\x60\x26\xdd\xe1\x0b\xb0\x60\x1f\x45\x24\x46\x96\x5e\xe2\xb6\xea\x2c\xd4\xfb\xc9\x5a\xc8\x66\xa5\x50\xaf\x90\x75\xb7"] = CTInfo($description="WoSign log 2", $operator="Wosign", $url="ctlog2.wosign.com/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\xa5\x8c\xe8\x35\x2e\x8e\xe5\x6a\x75\xad\x5c\x4b\x31\x61\x29\x9d\x30\x57\x8e\x02\x13\x5f\xe9\xca\xbb\x52\xa8\x43\x05\x60\xbf\x0d\x73\x57\x77\xb2\x05\xd8\x67\xf6\xf0\x33\xc9\xf9\x44\xde\xb6\x53\x73\xaa\x0c\x55\xc2\x83\x0a\x4b\xce\x5e\x1a\xc7\x17\x1d\xb3\xcd"),
["\xc9\xcf\x89\x0a\x21\x10\x9c\x66\x6c\xc1\x7a\x3e\xd0\x65\xc9\x30\xd0\xe0\x13\x5a\x9f\xeb\xa8\x5a\xf1\x42\x10\xb8\x07\x24\x21\xaa"] = CTInfo($description="GDCA CT log #1", $operator="Wang Shengnan", $url="ct.gdca.com.cn/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\xad\x0f\x30\xad\x9e\x79\xa4\x38\x89\x26\x54\x86\xab\x41\x72\x90\x6f\xfb\xca\x17\xa6\xac\xee\xc6\x9f\x7d\x02\x05\xec\x41\xa8\xc7\x41\x9d\x32\x49\xad\xb0\x39\xbd\x3a\x87\x3e\x7c\xee\x68\x6c\x60\xd1\x47\x2a\x93\xae\xe1\x40\xf4\x0b\xc8\x35\x3c\x1d\x0f\x65\xd3"),
["\x92\x4a\x30\xf9\x09\x33\x6f\xf4\x35\xd6\x99\x3a\x10\xac\x75\xa2\xc6\x41\x72\x8e\x7f\xc2\xd6\x59\xae\x61\x88\xff\xad\x40\xce\x01"] = CTInfo($description="GDCA CT log #2", $operator="GDCA", $url="ctlog.gdca.com.cn/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x5b\x4a\xc7\x01\xb7\x74\x54\xba\x40\x9c\x43\x75\x94\x3f\xac\xef\xb3\x71\x56\xb8\xd3\xe2\x7b\xae\xa1\xb1\x3e\x53\xaa\x97\x33\xa1\x82\xbb\x5f\x5d\x1c\x0b\xfa\x85\x0d\xbc\xf7\xe5\xa0\xe0\x22\xf0\xa0\x89\xd9\x0a\x7f\x5f\x26\x94\xd3\x24\xe3\x99\x2e\xe4\x15\x8d"),
["\xdb\x76\xfd\xad\xac\x65\xe7\xd0\x95\x08\x88\x6e\x21\x59\xbd\x8b\x90\x35\x2f\x5f\xea\xd3\xe3\xdc\x5e\x22\xeb\x35\x0a\xcc\x7b\x98"] = CTInfo($description="Comodo 'Dodo' CT log", $operator="Comodo", $url="dodo.ct.comodo.com/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x2c\xf5\xc2\x31\xf5\x63\x43\x6a\x16\x4a\x0a\xde\xc2\xee\x1f\x21\x6e\x12\x7e\x1d\xe5\x72\x8f\x74\x0b\x02\x99\xd3\xad\x69\xbc\x02\x35\x79\xf9\x61\xe9\xcf\x00\x08\x4f\x74\xa4\xa3\x34\x9a\xe0\x43\x1c\x23\x7e\x8f\x41\xd5\xee\xc7\x1c\xa3\x82\x8a\x40\xfa\xaa\xe0"),
["\xac\x3b\x9a\xed\x7f\xa9\x67\x47\x57\x15\x9e\x6d\x7d\x57\x56\x72\xf9\xd9\x81\x00\x94\x1e\x9b\xde\xff\xec\xa1\x31\x3b\x75\x78\x2d"] = CTInfo($description="Venafi log", $operator="Venafi", $url="ctlog.api.venafi.com/", $maximum_merge_delay=86400, $key="\x30\x82\x01\x22\x30\x0d\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x01\x01\x05\x00\x03\x82\x01\x0f\x00\x30\x82\x01\x0a\x02\x82\x01\x01\x00\xa2\x5a\x48\x1f\x17\x52\x95\x35\xcb\xa3\x5b\x3a\x1f\x53\x82\x76\x94\xa3\xff\x80\xf2\x1c\x37\x3c\xc0\xb1\xbd\xc1\x59\x8b\xab\x2d\x65\x93\xd7\xf3\xe0\x04\xd5\x9a\x6f\xbf\xd6\x23\x76\x36\x4f\x23\x99\xcb\x54\x28\xad\x8c\x15\x4b\x65\x59\x76\x41\x4a\x9c\xa6\xf7\xb3\x3b\x7e\xb1\xa5\x49\xa4\x17\x51\x6c\x80\xdc\x2a\x90\x50\x4b\x88\x24\xe9\xa5\x12\x32\x93\x04\x48\x90\x02\xfa\x5f\x0e\x30\x87\x8e\x55\x76\x05\xee\x2a\x4c\xce\xa3\x6a\x69\x09\x6e\x25\xad\x82\x76\x0f\x84\x92\xfa\x38\xd6\x86\x4e\x24\x8f\x9b\xb0\x72\xcb\x9e\xe2\x6b\x3f\xe1\x6d\xc9\x25\x75\x23\x88\xa1\x18\x58\x06\x23\x33\x78\xda\x00\xd0\x38\x91\x67\xd2\xa6\x7d\x27\x97\x67\x5a\xc1\xf3\x2f\x17\xe6\xea\xd2\x5b\xe8\x81\xcd\xfd\x92\x68\xe7\xf3\x06\xf0\xe9\x72\x84\xee\x01\xa5\xb1\xd8\x33\xda\xce\x83\xa5\xdb\xc7\xcf\xd6\x16\x7e\x90\x75\x18\xbf\x16\xdc\x32\x3b\x6d\x8d\xab\x82\x17\x1f\x89\x20\x8d\x1d\x9a\xe6\x4d\x23\x08\xdf\x78\x6f\xc6\x05\xbf\x5f\xae\x94\x97\xdb\x5f\x64\xd4\xee\x16\x8b\xa3\x84\x6c\x71\x2b\xf1\xab\x7f\x5d\x0d\x32\xee\x04\xe2\x90\xec\x41\x9f\xfb\x39\xc1\x02\x03\x01\x00\x01"),
["\x03\x01\x9d\xf3\xfd\x85\xa6\x9a\x8e\xbd\x1f\xac\xc6\xda\x9b\xa7\x3e\x46\x97\x74\xfe\x77\xf5\x79\xfc\x5a\x08\xb8\x32\x8c\x1d\x6b"] = CTInfo($description="Venafi Gen2 CT log", $operator="Venafi", $url="ctlog-gen2.api.venafi.com/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x8e\x27\x27\x7a\xb6\x55\x09\x74\xeb\x6c\x4b\x94\x84\x65\xbc\xe4\x15\xf1\xea\x5a\xd8\x7c\x0e\x37\xce\xba\x3f\x6c\x09\xda\xe7\x29\x96\xd3\x45\x50\x6f\xde\x1e\xb4\x1c\xd2\x83\x88\xff\x29\x2f\xce\xa9\xff\xdf\x34\xde\x75\x0f\xc0\xcc\x18\x0d\x94\x2e\xfc\x37\x01"),
["\xa5\x77\xac\x9c\xed\x75\x48\xdd\x8f\x02\x5b\x67\xa2\x41\x08\x9d\xf8\x6e\x0f\x47\x6e\xc2\x03\xc2\xec\xbe\xdb\x18\x5f\x28\x26\x38"] = CTInfo($description="CNNIC CT log", $operator="CNNIC", $url="ctserver.cnnic.cn/", $maximum_merge_delay=86400, $key="\x30\x82\x01\x22\x30\x0d\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x01\x01\x05\x00\x03\x82\x01\x0f\x00\x30\x82\x01\x0a\x02\x82\x01\x01\x00\xbf\xb5\x08\x61\x9a\x29\x32\x04\xd3\x25\x63\xe9\xd8\x85\xe1\x86\xe0\x1f\xd6\x5e\x9a\xf7\x33\x3b\x80\x1b\xe7\xb6\x3e\x5f\x2d\xa1\x66\xf6\x95\x4a\x84\xa6\x21\x56\x79\xe8\xf7\x85\xee\x5d\xe3\x7c\x12\xc0\xe0\x89\x22\x09\x22\x3e\xba\x16\x95\x06\xbd\xa8\xb9\xb1\xa9\xb2\x7a\xd6\x61\x2e\x87\x11\xb9\x78\x40\x89\x75\xdb\x0c\xdc\x90\xe0\xa4\x79\xd6\xd5\x5e\x6e\xd1\x2a\xdb\x34\xf4\x99\x3f\x65\x89\x3b\x46\xc2\x29\x2c\x15\x07\x1c\xc9\x4b\x1a\x54\xf8\x6c\x1e\xaf\x60\x27\x62\x0a\x65\xd5\x9a\xb9\x50\x36\x16\x6e\x71\xf6\x1f\x01\xf7\x12\xa7\xfc\xbf\xf6\x21\xa3\x29\x90\x86\x2d\x77\xde\xbb\x4c\xd4\xcf\xfd\xd2\xcf\x82\x2c\x4d\xd4\xf2\xc2\x2d\xac\xa9\xbe\xea\xc3\x19\x25\x43\xb2\xe5\x9a\x6c\x0d\xc5\x1c\xa5\x8b\xf7\x3f\x30\xaf\xb9\x01\x91\xb7\x69\x12\x12\xe5\x83\x61\xfe\x34\x00\xbe\xf6\x71\x8a\xc7\xeb\x50\x92\xe8\x59\xfe\x15\x91\xeb\x96\x97\xf8\x23\x54\x3f\x2d\x8e\x07\xdf\xee\xda\xb3\x4f\xc8\x3c\x9d\x6f\xdf\x3c\x2c\x43\x57\xa1\x47\x0c\x91\x04\xf4\x75\x4d\xda\x89\x81\xa4\x14\x06\x34\xb9\x98\xc3\xda\xf1\xfd\xed\x33\x36\xd3\x16\x2d\x35\x02\x03\x01\x00\x01"),
["\x34\xbb\x6a\xd6\xc3\xdf\x9c\x03\xee\xa8\xa4\x99\xff\x78\x91\x48\x6c\x9d\x5e\x5c\xac\x92\xd0\x1f\x7b\xfd\x1b\xce\x19\xdb\x48\xef"] = CTInfo($description="StartCom log", $operator="StartSSL", $url="ct.startssl.com/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x48\xf3\x59\xf3\xf6\x05\x18\xd3\xdb\xb2\xed\x46\x7e\xcf\xc8\x11\xb5\x57\xb1\xa8\xd6\x4c\xe6\x9f\xb7\x4a\x1a\x14\x86\x43\xa9\x48\xb0\xcb\x5a\x3f\x3c\x4a\xca\xdf\xc4\x82\x14\x55\x9a\xf8\xf7\x8e\x40\x55\xdc\xf4\xd2\xaf\xea\x75\x74\xfb\x4e\x7f\x60\x86\x2e\x51"),
["\xe0\x12\x76\x29\xe9\x04\x96\x56\x4e\x3d\x01\x47\x98\x44\x98\xaa\x48\xf8\xad\xb1\x66\x00\xeb\x79\x02\xa1\xef\x99\x09\x90\x62\x73"] = CTInfo($description="PuChuangSiDa CT log", $operator="Beijing PuChuangSiDa Technology Ltd.", $url="www.certificatetransparency.cn/ct/", $maximum_merge_delay=86400, $key="\x30\x82\x01\x22\x30\x0d\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x01\x01\x05\x00\x03\x82\x01\x0f\x00\x30\x82\x01\x0a\x02\x82\x01\x01\x00\xac\xcf\x2f\x4b\x70\xac\xf1\x0d\x96\xbf\xe8\x0a\xfe\x44\x9d\xd4\x8c\x17\x9d\xc3\x9a\x10\x11\x84\x13\xed\x8c\xf9\x37\x6d\x83\xe4\x00\x6f\xb1\x4b\xc0\xa6\x89\xc7\x61\x8f\x9a\x34\xbb\x56\x52\xca\x03\x56\x50\xef\x24\x7f\x4b\x49\xe9\x35\x81\xdd\xf0\xe7\x17\xf5\x72\xd2\x23\xc5\xe3\x13\x7f\xd7\x8e\x78\x35\x8f\x49\xde\x98\x04\x8a\x63\xaf\xad\xa2\x39\x70\x95\x84\x68\x4b\x91\x33\xfe\x4c\xe1\x32\x17\xc2\xf2\x61\xb8\x3a\x8d\x39\x7f\xd5\x95\x82\x3e\x56\x19\x50\x45\x6f\xcb\x08\x33\x0d\xd5\x19\x42\x08\x1a\x48\x42\x10\xf1\x68\xc3\xc3\x41\x13\xcb\x0d\x1e\xdb\x02\xb7\x24\x7a\x51\x96\x6e\xbc\x08\xea\x69\xaf\x6d\xef\x92\x98\x8e\x55\xf3\x65\xe5\xe8\x9c\xbe\x1a\x47\x60\x30\x7d\x7a\x80\xad\x56\x83\x7a\x93\xc3\xae\x93\x2b\x6a\x28\x8a\xa6\x5f\x63\x19\x0c\xbe\x7c\x7b\x21\x63\x41\x38\xb7\xf7\xe8\x76\x73\x6b\x85\xcc\xbc\x72\x2b\xc1\x52\xd0\x5b\x5d\x31\x4e\x9d\x2a\xf3\x4d\x9b\x64\x14\x99\x26\xc6\x71\xf8\x7b\xf8\x44\xd5\xe3\x23\x20\xf3\x0a\xd7\x8b\x51\x3e\x72\x80\xd2\x78\x78\x35\x2d\x4a\xe7\x40\x99\x11\x95\x34\xd4\x2f\x7f\xf9\x5f\x35\x37\x02\x03\x01\x00\x01"),
["\x55\x81\xd4\xc2\x16\x90\x36\x01\x4a\xea\x0b\x9b\x57\x3c\x53\xf0\xc0\xe4\x38\x78\x70\x25\x08\x17\x2f\xa3\xaa\x1d\x07\x13\xd3\x0c"] = CTInfo($description="Comodo 'Sabre' CT log", $operator="Comodo", $url="sabre.ct.comodo.com/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\xf2\x6f\xd2\x89\x0f\x3f\xc5\xf8\x87\x1e\xab\x65\xb3\xd9\xbb\x17\x23\x8c\x06\x0e\x09\x55\x96\x3d\x0a\x08\xa2\xc5\x71\xb3\xd1\xa9\x2f\x28\x3e\x83\x10\xbf\x12\xd0\x44\x66\x15\xef\x54\xe1\x98\x80\xd0\xce\x24\x6d\x3e\x67\x9a\xe9\x37\x23\xce\x52\x93\x86\xda\x80"),
["\x6f\x53\x76\xac\x31\xf0\x31\x19\xd8\x99\x00\xa4\x51\x15\xff\x77\x15\x1c\x11\xd9\x02\xc1\x00\x29\x06\x8d\xb2\x08\x9a\x37\xd9\x13"] = CTInfo($description="Comodo 'Mammoth' CT log", $operator="Comodo", $url="mammoth.ct.comodo.com/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\xef\xe4\x7d\x74\x2e\x15\x15\xb6\xe9\xbb\x23\x8b\xfb\x2c\xb5\xe1\xc7\x80\x98\x47\xfb\x40\x69\x68\xfc\x49\xad\x61\x4e\x83\x47\x3c\x1a\xb7\x8d\xdf\xff\x7b\x30\xb4\xba\xff\x2f\xcb\xa0\x14\xe3\xad\xd5\x85\x3f\x44\x59\x8c\x8c\x60\x8b\xd7\xb8\xb1\xbf\xae\x8c\x67"),
["\x53\x7b\x69\xa3\x56\x43\x35\xa9\xc0\x49\x04\xe3\x95\x93\xb2\xc2\x98\xeb\x8d\x7a\x6e\x83\x02\x36\x35\xc6\x27\x24\x8c\xd6\xb4\x40"] = CTInfo($description="Nordu 'flimsy' log", $operator="NORDUnet", $url="flimsy.ct.nordu.net:8080/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\xe2\xa5\xaa\xe9\xa7\xe1\x05\x48\xb4\x39\xd7\x16\x51\x88\x72\x24\xb3\x57\x4e\x41\xaa\x43\xd3\xcc\x4b\x99\x6a\xa0\x28\x24\x57\x68\x75\x66\xfa\x4d\x8c\x11\xf6\xbb\xc5\x1b\x81\xc3\x90\xc2\xa0\xe8\xeb\xac\xfa\x05\x64\x09\x1a\x89\x68\xcd\x96\x26\x34\x71\x36\x91"),
["\xaa\xe7\x0b\x7f\x3c\xb8\xd5\x66\xc8\x6c\x2f\x16\x97\x9c\x9f\x44\x5f\x69\xab\x0e\xb4\x53\x55\x89\xb2\xf7\x7a\x03\x01\x04\xf3\xcd"] = CTInfo($description="Nordu 'plausible' log", $operator="NORDUnet", $url="plausible.ct.nordu.net/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\xf5\x45\x7d\xfa\x33\xb6\x30\x24\xf3\x91\xa6\xe8\x74\xed\x85\xec\xb3\x34\xdc\xc5\x01\x73\xc3\x2b\x74\x0b\x64\x71\x6e\xaf\xe8\x60\x3d\xb5\xa4\xd3\xc3\xd4\x09\xaa\x87\xe6\xd0\x16\xdd\x02\xc6\xed\x24\xbf\xee\x9f\x21\x1f\xd3\x32\x24\x46\x05\xe3\x8f\x36\x98\xa9"),
["\xcf\x55\xe2\x89\x23\x49\x7c\x34\x0d\x52\x06\xd0\x53\x53\xae\xb2\x58\x34\xb5\x2f\x1f\x8d\xc9\x52\x68\x09\xf2\x12\xef\xdd\x7c\xa6"] = CTInfo($description="SHECA CT log 1", $operator="SHECA", $url="ctlog.sheca.com/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x11\xa9\x60\x2b\xb4\x71\x45\x66\xe0\x2e\xde\xd5\x87\x3b\xd5\xfe\xf0\x92\x37\xf4\x68\xc6\x92\xdd\x3f\x1a\xe2\xbc\x0c\x22\xd6\x99\x63\x29\x6e\x32\x28\x14\xc0\x76\x2c\x80\xa8\x22\x51\x91\xd6\xeb\xa6\xd8\xf1\xec\xf0\x07\x7e\xb0\xfc\x76\x70\x76\x72\x7c\x91\xe9"),
["\x32\xdc\x59\xc2\xd4\xc4\x19\x68\xd5\x6e\x14\xbc\x61\xac\x8f\x0e\x45\xdb\x39\xfa\xf3\xc1\x55\xaa\x42\x52\xf5\x00\x1f\xa0\xc6\x23"] = CTInfo($description="SHECA CT log 2", $operator="SHECA", $url="ct.sheca.com/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\xb1\x8e\x1d\x8a\xaa\x3a\xac\xce\x86\xcb\x53\x76\xe8\xa8\x9d\x59\xbe\x17\x88\x03\x07\xf2\x27\xe0\x82\xbe\xb1\xfc\x67\x3b\x46\xee\xd3\xf1\x8d\xd6\x77\xe8\xa3\xb4\xdb\x09\x5c\xa0\x09\x43\xfc\x5f\xd0\x68\x34\x23\x24\x08\xc2\x4f\xd8\xd2\xb6\x9d\xed\xd5\x8c\xdb"),
["\x96\x06\xc0\x2c\x69\x00\x33\xaa\x1d\x14\x5f\x59\xc6\xe2\x64\x8d\x05\x49\xf0\xdf\x96\xaa\xb8\xdb\x91\x5a\x70\xd8\xec\xf3\x90\xa5"] = CTInfo($description="Akamai CT Log", $operator="Akamai", $url="ct.akamai.com/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x43\x79\xeb\x49\x5c\x50\x2a\x4a\x6a\x8f\x59\x93\xbc\xc3\x42\x76\xc2\x99\xf8\x27\x81\x3c\x06\x6c\xd2\xc8\x04\x8f\x74\x7b\xb4\xb5\x21\xf2\xe3\xa8\xdc\x33\xb9\xfe\x25\xe9\x3d\x04\xfc\x3f\xb4\xae\x40\xe3\x45\x7e\x84\x92\x2a\xd8\x52\xeb\x1f\x3f\x73\x13\xd0\xc8"),
["\x39\x37\x6f\x54\x5f\x7b\x46\x07\xf5\x97\x42\xd7\x68\xcd\x5d\x24\x37\xbf\x34\x73\xb6\x53\x4a\x48\x34\xbc\xf7\x2e\x68\x1c\x83\xc9"] = CTInfo($description="Alpha CT Log", $operator="Matt Palmer", $url="alpha.ctlogs.org/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\xa2\xf7\xed\x13\xe1\xd3\x5c\x02\x08\xc4\x8e\x8b\x9b\x8b\x3b\x39\x68\xc7\x92\x6a\x38\xa1\x4f\x23\xc5\xa5\x6f\x6f\xd7\x65\x81\xf8\xc1\x9b\xf4\x9f\xa9\x8b\x45\xf4\xb9\x4e\x1b\xc9\xa2\x69\x17\xa5\x78\x87\xd9\xce\x88\x6f\x41\x03\xbb\xa3\x2a\xe3\x77\x97\x8d\x78"),
["\x29\x6a\xfa\x2d\x56\x8b\xca\x0d\x2e\xa8\x44\x95\x6a\xe9\x72\x1f\xc3\x5f\xa3\x55\xec\xda\x99\x69\x3a\xaf\xd4\x58\xa7\x1a\xef\xdd"] = CTInfo($description="Let's Encrypt 'Clicky' log", $operator="Let's Encrypt", $url="clicky.ct.letsencrypt.org/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x1f\x1a\x15\x83\x77\x00\x75\x62\xb9\x9f\xf6\x06\x05\xed\x95\x89\x83\x41\x81\x97\xe7\xe0\xd4\x33\xfe\x76\xba\x3b\xc9\x49\xc2\xcd\xf1\xcf\xfe\x12\x70\xd7\xbe\xa8\x22\x5f\xb2\xa4\x67\x02\x7b\x71\xae\x1d\xac\xa8\xe9\xd1\x08\xd5\xce\xef\x33\x7a\xc3\x5f\x00\xdc"),
["\xb0\xb7\x84\xbc\x81\xc0\xdd\xc4\x75\x44\xe8\x83\xf0\x59\x85\xbb\x90\x77\xd1\x34\xd8\xab\x88\xb2\xb2\xe5\x33\x98\x0b\x8e\x50\x8b"] = CTInfo($description="Up In The Air 'Behind the Sofa' log", $operator="Up In The Air Consulting", $url="ct.filippo.io/behindthesofa/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x59\x39\xb2\xa6\x94\xc6\x32\xb9\xfe\x63\x69\x1e\x30\x3b\xa3\x5b\xd5\xb0\x43\xc9\x50\x1e\x95\xa5\x2d\xa7\x4c\x4a\x49\x8e\x8b\x8f\xb7\xf8\xcc\xe2\x5b\x97\x72\xd5\xea\x3f\xb1\x21\x48\xe8\x44\x6b\x7f\xea\xef\x22\xff\xdf\xf4\x5f\x3b\x6d\x77\x04\xb1\xaf\x90\x8f"),
};

View file

@ -91,11 +91,26 @@ event bro_init() &priority=5
$describe = SSL::describe_file]); $describe = SSL::describe_file]);
} }
event file_over_new_connection(f: fa_file, c: connection, is_orig: bool) &priority=5 event file_sniff(f: fa_file, meta: fa_metadata) &priority=5
{ {
if ( ! c?$ssl ) if ( |f$conns| != 1 )
return; return;
if ( ! f?$info || ! f$info?$mime_type )
return;
if ( ! ( f$info$mime_type == "application/x-x509-ca-cert" || f$info$mime_type == "application/x-x509-user-cert"
|| f$info$mime_type == "application/pkix-cert" ) )
return;
for ( cid in f$conns )
{
if ( ! f$conns[cid]?$ssl )
return;
local c = f$conns[cid];
}
if ( ! c$ssl?$cert_chain ) if ( ! c$ssl?$cert_chain )
{ {
c$ssl$cert_chain = vector(); c$ssl$cert_chain = vector();
@ -104,7 +119,7 @@ event file_over_new_connection(f: fa_file, c: connection, is_orig: bool) &priori
c$ssl$client_cert_chain_fuids = string_vec(); c$ssl$client_cert_chain_fuids = string_vec();
} }
if ( is_orig ) if ( f$is_orig )
{ {
c$ssl$client_cert_chain[|c$ssl$client_cert_chain|] = f$info; c$ssl$client_cert_chain[|c$ssl$client_cert_chain|] = f$info;
c$ssl$client_cert_chain_fuids[|c$ssl$client_cert_chain_fuids|] = f$id; c$ssl$client_cert_chain_fuids[|c$ssl$client_cert_chain_fuids|] = f$id;
@ -114,12 +129,6 @@ event file_over_new_connection(f: fa_file, c: connection, is_orig: bool) &priori
c$ssl$cert_chain[|c$ssl$cert_chain|] = f$info; c$ssl$cert_chain[|c$ssl$cert_chain|] = f$info;
c$ssl$cert_chain_fuids[|c$ssl$cert_chain_fuids|] = f$id; c$ssl$cert_chain_fuids[|c$ssl$cert_chain_fuids|] = f$id;
} }
Files::add_analyzer(f, Files::ANALYZER_X509);
# Always calculate hashes. They are not necessary for base scripts
# but very useful for identification, and required for policy scripts.
Files::add_analyzer(f, Files::ANALYZER_MD5);
Files::add_analyzer(f, Files::ANALYZER_SHA1);
} }
event ssl_established(c: connection) &priority=6 event ssl_established(c: connection) &priority=6

View file

@ -64,7 +64,6 @@ export {
## Flag to indicate if this ssl session has been established ## Flag to indicate if this ssl session has been established
## successfully, or if it was aborted during the handshake. ## successfully, or if it was aborted during the handshake.
established: bool &log &default=F; established: bool &log &default=F;
## Flag to indicate if this record already has been logged, to ## Flag to indicate if this record already has been logged, to
## prevent duplicates. ## prevent duplicates.
logged: bool &default=F; logged: bool &default=F;
@ -74,6 +73,26 @@ export {
## script sets this to Mozilla's root CA list. ## script sets this to Mozilla's root CA list.
const root_certs: table[string] of string = {} &redef; const root_certs: table[string] of string = {} &redef;
## The record type which contains the field for the Certificate
## Transparency log bundle.
type CTInfo: record {
## Description of the Log
description: string;
## Operator of the Log
operator: string;
## Public key of the Log.
key: string;
## Maximum merge delay of the Log
maximum_merge_delay: count;
## URL of the Log
url: string;
};
## The Certificate Transparency log bundle. By default, the ct-list.bro
## script sets this to the current list of known logs. Entries
## are indexed by (binary) log-id.
const ct_logs: table[string] of CTInfo = {} &redef;
## If true, detach the SSL analyzer from the connection to prevent ## If true, detach the SSL analyzer from the connection to prevent
## continuing to process encrypted traffic. Helps with performance ## continuing to process encrypted traffic. Helps with performance
## (especially with large file transfers). ## (especially with large file transfers).
@ -90,6 +109,10 @@ export {
## Event that can be handled to access the SSL ## Event that can be handled to access the SSL
## record as it is sent on to the logging framework. ## record as it is sent on to the logging framework.
global log_ssl: event(rec: Info); global log_ssl: event(rec: Info);
# Hook that can be used to perform actions right before the log record
# is written.
global ssl_finishing: hook(c: connection);
} }
redef record connection += { redef record connection += {
@ -201,7 +224,7 @@ event ssl_server_hello(c: connection, version: count, possible_ts: time, server_
c$ssl$resumed = T; c$ssl$resumed = T;
} }
event ssl_server_curve(c: connection, curve: count) &priority=5 event ssl_ecdh_server_params(c: connection, curve: count, point: string) &priority=5
{ {
set_session(c); set_session(c);
@ -281,11 +304,22 @@ event ssl_established(c: connection) &priority=7
c$ssl$established = T; c$ssl$established = T;
} }
event ssl_established(c: connection) &priority=20
{
hook ssl_finishing(c);
}
event ssl_established(c: connection) &priority=-5 event ssl_established(c: connection) &priority=-5
{ {
finish(c, T); finish(c, T);
} }
event connection_state_remove(c: connection) &priority=20
{
if ( c?$ssl && ! c$ssl$logged )
hook ssl_finishing(c);
}
event connection_state_remove(c: connection) &priority=-5 event connection_state_remove(c: connection) &priority=-5
{ {
if ( c?$ssl ) if ( c?$ssl )

View file

@ -0,0 +1,62 @@
##! Enable logging of OCSP responses.
#
# This script is in policy and not loaded by default because OCSP logging
# does not provide a lot of interesting information in most environments.
module OCSP;
export {
redef enum Log::ID += { LOG };
## The record type which contains the fields of the OCSP log.
type Info: record {
## Time when the OCSP reply was encountered.
ts: time &log;
## File id of the OCSP reply.
id: string &log;
## Hash algorithm used to generate issuerNameHash and issuerKeyHash.
hashAlgorithm: string &log;
## Hash of the issuer's distingueshed name.
issuerNameHash: string &log;
## Hash of the issuer's public key.
issuerKeyHash: string &log;
## Serial number of the affected certificate.
serialNumber: string &log;
## Status of the affected certificate.
certStatus: string &log;
## Time at which the certificate was revoked.
revoketime: time &log &optional;
## Reason for which the certificate was revoked.
revokereason: string &log &optional;
## The time at which the status being shows is known to have been correct.
thisUpdate: time &log;
## The latest time at which new information about the status of the certificate will be available.
nextUpdate: time &log &optional;
};
## Event that can be handled to access the OCSP record
## as it is sent to the logging framework.
global log_ocsp: event(rec: Info);
}
event bro_init()
{
Log::create_stream(LOG, [$columns=Info, $ev=log_ocsp, $path="ocsp"]);
Files::register_for_mime_type(Files::ANALYZER_OCSP_REPLY, "application/ocsp-response");
}
event ocsp_response_certificate(f: fa_file, hashAlgorithm: string, issuerNameHash: string, issuerKeyHash: string, serialNumber: string, certStatus: string, revoketime: time, revokereason: string, thisUpdate: time, nextUpdate: time)
{
local wr = OCSP::Info($ts=f$info$ts, $id=f$id, $hashAlgorithm=hashAlgorithm, $issuerNameHash=issuerNameHash,
$issuerKeyHash=issuerKeyHash, $serialNumber=serialNumber, $certStatus=certStatus,
$thisUpdate=thisUpdate);
if ( revokereason != "" )
wr$revokereason = revokereason;
if ( time_to_double(revoketime) != 0 )
wr$revoketime = revoketime;
if ( time_to_double(nextUpdate) != 0 )
wr$nextUpdate = nextUpdate;
Log::write(LOG, wr);
}

View file

@ -8,7 +8,7 @@ module X509;
export { export {
redef record Info += { redef record Info += {
# Logging is suppressed if field is set to F ## Logging of certificate is suppressed if set to F
logcert: bool &default=T; logcert: bool &default=T;
}; };
} }
@ -39,14 +39,29 @@ event bro_init() &priority=2
Log::add_filter(X509::LOG, f); Log::add_filter(X509::LOG, f);
} }
event file_over_new_connection(f: fa_file, c: connection, is_orig: bool) &priority=2 event file_sniff(f: fa_file, meta: fa_metadata) &priority=4
{ {
if ( ! c?$ssl ) if ( |f$conns| != 1 )
return; return;
if ( ! f?$info || ! f$info?$mime_type )
return;
if ( ! ( f$info$mime_type == "application/x-x509-ca-cert" || f$info$mime_type == "application/x-x509-user-cert"
|| f$info$mime_type == "application/pkix-cert" ) )
return;
for ( cid in f$conns )
{
if ( ! f$conns[cid]?$ssl )
return;
local c = f$conns[cid];
}
local chain: vector of string; local chain: vector of string;
if ( is_orig ) if ( f$is_orig )
chain = c$ssl$client_cert_chain_fuids; chain = c$ssl$client_cert_chain_fuids;
else else
chain = c$ssl$cert_chain_fuids; chain = c$ssl$cert_chain_fuids;

View file

@ -19,12 +19,17 @@ export {
redef record Info += { redef record Info += {
## Result of certificate validation for this connection. ## Result of certificate validation for this connection.
validation_status: string &log &optional; validation_status: string &log &optional;
## Result of certificate validation for this connection, given
## as OpenSSL validation code.
validation_code: int &optional;
## Ordered chain of validated certificate, if validation succeeded.
valid_chain: vector of opaque of x509 &optional;
}; };
## MD5 hash values for recently validated chains along with the ## Result values for recently validated chains along with the
## validation status are kept in this table to avoid constant ## validation status are kept in this table to avoid constant
## validation every time the same certificate chain is seen. ## validation every time the same certificate chain is seen.
global recently_validated_certs: table[string] of string = table() global recently_validated_certs: table[string] of X509::Result = table()
&read_expire=5mins &redef; &read_expire=5mins &redef;
## Use intermediate CA certificate caching when trying to validate ## Use intermediate CA certificate caching when trying to validate
@ -39,6 +44,11 @@ export {
## that you encounter. Only disable if you want to find misconfigured servers. ## that you encounter. Only disable if you want to find misconfigured servers.
global ssl_cache_intermediate_ca: bool = T &redef; global ssl_cache_intermediate_ca: bool = T &redef;
## Store the valid chain in c$ssl$valid_chain if validation succeeds.
## This has a potentially high memory impact, depending on the local environment
## and is thus disabled by default.
global ssl_store_valid_chain: bool = F &redef;
## Event from a worker to the manager that it has encountered a new ## Event from a worker to the manager that it has encountered a new
## valid intermediate. ## valid intermediate.
global intermediate_add: event(key: string, value: vector of opaque of x509); global intermediate_add: event(key: string, value: vector of opaque of x509);
@ -83,7 +93,7 @@ event SSL::new_intermediate(key: string, value: vector of opaque of x509)
} }
@endif @endif
function cache_validate(chain: vector of opaque of x509): string function cache_validate(chain: vector of opaque of x509): X509::Result
{ {
local chain_hash: vector of string = vector(); local chain_hash: vector of string = vector();
@ -97,7 +107,10 @@ function cache_validate(chain: vector of opaque of x509): string
return recently_validated_certs[chain_id]; return recently_validated_certs[chain_id];
local result = x509_verify(chain, root_certs); local result = x509_verify(chain, root_certs);
recently_validated_certs[chain_id] = result$result_string; if ( ! ssl_store_valid_chain && result?$chain_certs )
recently_validated_certs[chain_id] = X509::Result($result=result$result, $result_string=result$result_string);
else
recently_validated_certs[chain_id] = result;
# if we have a working chain where we did not store the intermediate certs # if we have a working chain where we did not store the intermediate certs
# in our cache yet - do so # in our cache yet - do so
@ -107,8 +120,8 @@ function cache_validate(chain: vector of opaque of x509): string
|result$chain_certs| > 2 ) |result$chain_certs| > 2 )
{ {
local result_chain = result$chain_certs; local result_chain = result$chain_certs;
local icert = x509_parse(result_chain[1]); local isnh = x509_subject_name_hash(result_chain[1], 4); # SHA256
if ( icert$subject !in intermediate_cache ) if ( isnh !in intermediate_cache )
{ {
local cachechain: vector of opaque of x509; local cachechain: vector of opaque of x509;
for ( i in result_chain ) for ( i in result_chain )
@ -116,14 +129,14 @@ function cache_validate(chain: vector of opaque of x509): string
if ( i >=1 && i<=|result_chain|-2 ) if ( i >=1 && i<=|result_chain|-2 )
cachechain[i-1] = result_chain[i]; cachechain[i-1] = result_chain[i];
} }
add_to_cache(icert$subject, cachechain); add_to_cache(isnh, cachechain);
} }
} }
return result$result_string; return result;
} }
event ssl_established(c: connection) &priority=3 hook ssl_finishing(c: connection) &priority=20
{ {
# If there aren't any certs we can't very well do certificate validation. # If there aren't any certs we can't very well do certificate validation.
if ( ! c$ssl?$cert_chain || |c$ssl$cert_chain| == 0 || if ( ! c$ssl?$cert_chain || |c$ssl$cert_chain| == 0 ||
@ -131,23 +144,26 @@ event ssl_established(c: connection) &priority=3
return; return;
local intermediate_chain: vector of opaque of x509 = vector(); local intermediate_chain: vector of opaque of x509 = vector();
local issuer = c$ssl$cert_chain[0]$x509$certificate$issuer; local issuer_name_hash = x509_issuer_name_hash(c$ssl$cert_chain[0]$x509$handle, 4); # SHA256
local hash = c$ssl$cert_chain[0]$sha1; local hash = c$ssl$cert_chain[0]$sha1;
local result: string; local result: X509::Result;
# Look if we already have a working chain for the issuer of this cert. # Look if we already have a working chain for the issuer of this cert.
# If yes, try this chain first instead of using the chain supplied from # If yes, try this chain first instead of using the chain supplied from
# the server. # the server.
if ( ssl_cache_intermediate_ca && issuer in intermediate_cache ) if ( ssl_cache_intermediate_ca && issuer_name_hash in intermediate_cache )
{ {
intermediate_chain[0] = c$ssl$cert_chain[0]$x509$handle; intermediate_chain[0] = c$ssl$cert_chain[0]$x509$handle;
for ( i in intermediate_cache[issuer] ) for ( i in intermediate_cache[issuer_name_hash] )
intermediate_chain[i+1] = intermediate_cache[issuer][i]; intermediate_chain[i+1] = intermediate_cache[issuer_name_hash][i];
result = cache_validate(intermediate_chain); result = cache_validate(intermediate_chain);
if ( result == "ok" ) if ( result$result_string == "ok" )
{ {
c$ssl$validation_status = result; c$ssl$validation_status = result$result_string;
c$ssl$validation_code = result$result;
if ( result?$chain_certs )
c$ssl$valid_chain = result$chain_certs;
return; return;
} }
} }
@ -163,13 +179,16 @@ event ssl_established(c: connection) &priority=3
} }
result = cache_validate(chain); result = cache_validate(chain);
c$ssl$validation_status = result; c$ssl$validation_status = result$result_string;
c$ssl$validation_code = result$result;
if ( result?$chain_certs )
c$ssl$valid_chain = result$chain_certs;
if ( result != "ok" ) if ( result$result_string != "ok" )
{ {
local message = fmt("SSL certificate validation failed with (%s)", c$ssl$validation_status); local message = fmt("SSL certificate validation failed with (%s)", c$ssl$validation_status);
NOTICE([$note=Invalid_Server_Cert, $msg=message, NOTICE([$note=Invalid_Server_Cert, $msg=message,
$sub=c$ssl$subject, $conn=c, $sub=c$ssl$cert_chain[0]$x509$certificate$subject, $conn=c,
$identifier=cat(c$id$resp_h,c$id$resp_p,hash,c$ssl$validation_status)]); $identifier=cat(c$id$resp_h,c$id$resp_p,hash,c$ssl$validation_code)]);
} }
} }

View file

@ -1,4 +1,9 @@
##! Perform OCSP response validation. ##! Perform validation of stapled OCSP responses.
#!
#! Note: this _only_ performs validation of stapled OCSP responsed. It does
#! not validate OCSP responses that are retrieved via HTTP, because we do not
#! have a mapping to certificates.
@load base/frameworks/notice @load base/frameworks/notice
@load base/protocols/ssl @load base/protocols/ssl
@ -15,7 +20,6 @@ export {
redef record Info += { redef record Info += {
## Result of ocsp validation for this connection. ## Result of ocsp validation for this connection.
ocsp_status: string &log &optional; ocsp_status: string &log &optional;
## ocsp response as string. ## ocsp response as string.
ocsp_response: string &optional; ocsp_response: string &optional;
}; };

View file

@ -0,0 +1,210 @@
##! Perform validation of Signed Certificate Timestamps, as used
##! for Certificate Transparency. See RFC6962 for more details.
@load base/protocols/ssl
@load protocols/ssl/validate-certs
# We need to know issuer certificates to be able to determine the IssuerKeyHash,
# which is required for validating certificate extensions.
redef SSL::ssl_store_valid_chain = T;
module SSL;
export {
## List of the different sources for Signed Certificate Timestamp
type SctSource: enum {
## Signed Certificate Timestamp was encountered in the extension of
## an X.509 certificate.
SCT_X509_EXT,
## Signed Certificate Timestamp was encountered in an TLS session
## extension.
SCT_TLS_EXT,
## Signed Certificate Timestamp was encountered in the extension of
## an stapled OCSP reply.
SCT_OCSP_EXT
};
## This record is used to store information about the SCTs that are
## encountered in a SSL connection.
type SctInfo: record {
## The version of the encountered SCT (should always be 0 for v1).
version: count;
## The ID of the log issuing this SCT.
logid: string;
## The timestamp at which this SCT was issued measured since the
## epoch (January 1, 1970, 00:00), ignoring leap seconds, in
## milliseconds. Not converted to a Bro timestamp because we need
## the exact value for validation.
timestamp: count;
## The signature algorithm used for this sct.
sig_alg: count;
## The hash algorithm used for this sct.
hash_alg: count;
## The signature of this SCT.
signature: string;
## Source of this SCT.
source: SctSource;
## Validation result of this SCT.
valid: bool &optional;
};
redef record Info += {
## Number of valid SCTs that were encountered in the connection.
valid_scts: count &optional;
## Number of SCTs that could not be validated that were encountered in the connection.
invalid_scts: count &optional;
## Number of different Logs for which valid SCTs were encountered in the connection.
valid_ct_logs: count &log &optional;
## Number of different Log operators of which valid SCTs were encountered in the connection.
valid_ct_operators: count &log &optional;
## List of operators for which valid SCTs were encountered in the connection.
valid_ct_operators_list: set[string] &optional;
## Information about all SCTs that were encountered in the connection.
ct_proofs: vector of SctInfo &default=vector();
};
}
# Used to cache validations for 5 minutes to lessen computational load.
global recently_validated_scts: table[string] of bool = table()
&read_expire=5mins &redef;
event bro_init()
{
Files::register_for_mime_type(Files::ANALYZER_OCSP_REPLY, "application/ocsp-response");
}
event ssl_extension_signed_certificate_timestamp(c: connection, is_orig: bool, version: count, logid: string, timestamp: count, signature_and_hashalgorithm: SSL::SignatureAndHashAlgorithm, signature: string) &priority=5
{
c$ssl$ct_proofs[|c$ssl$ct_proofs|] = SctInfo($version=version, $logid=logid, $timestamp=timestamp, $sig_alg=signature_and_hashalgorithm$SignatureAlgorithm, $hash_alg=signature_and_hashalgorithm$HashAlgorithm, $signature=signature, $source=SCT_TLS_EXT);
}
event x509_ocsp_ext_signed_certificate_timestamp(f: fa_file, version: count, logid: string, timestamp: count, hash_algorithm: count, signature_algorithm: count, signature: string) &priority=5
{
local src: SctSource;
if ( ! f?$info )
return;
if ( f$source == "SSL" && f$info$mime_type == "application/ocsp-response" )
src = SCT_OCSP_EXT;
else if ( f$source == "SSL" && f$info$mime_type == "application/x-x509-user-cert" )
src = SCT_X509_EXT;
else
return;
if ( |f$conns| != 1 )
return;
for ( cid in f$conns )
{
if ( ! f$conns[cid]?$ssl )
return;
local c = f$conns[cid];
}
c$ssl$ct_proofs[|c$ssl$ct_proofs|] = SctInfo($version=version, $logid=logid, $timestamp=timestamp, $sig_alg=signature_algorithm, $hash_alg=hash_algorithm, $signature=signature, $source=src);
}
# Priority = 19 will be handled after validation is done
hook ssl_finishing(c: connection) &priority=19
{
if ( ! c$ssl?$cert_chain || |c$ssl$cert_chain| == 0 || ! c$ssl$cert_chain[0]?$x509 )
return;
local cert = c$ssl$cert_chain[0]$x509$handle;
local certhash = c$ssl$cert_chain[0]$sha1;
local issuer_name_hash = x509_issuer_name_hash(cert, 4);
local valid_proofs = 0;
local invalid_proofs = 0;
c$ssl$valid_ct_operators_list = string_set();
local valid_logs = string_set();
local issuer_key_hash = "";
for ( i in c$ssl$ct_proofs )
{
local proof = c$ssl$ct_proofs[i];
if ( proof$logid !in SSL::ct_logs )
{
# Well, if we don't know the log, there is nothing to do here...
proof$valid = F;
next;
}
local log = SSL::ct_logs[proof$logid];
local valid = F;
local found_cache = F;
local validatestring = cat(certhash,proof$logid,proof$timestamp,proof$hash_alg,proof$signature,proof$source);
if ( proof$source == SCT_X509_EXT && c$ssl?$validation_code )
validatestring = cat(validatestring, c$ssl$validation_code);
local validate_hash = sha1_hash(validatestring);
if ( validate_hash in recently_validated_scts )
{
valid = recently_validated_scts[validate_hash];
found_cache = T;
}
if ( found_cache == F && ( proof$source == SCT_TLS_EXT || proof$source == SCT_OCSP_EXT ) )
{
valid = sct_verify(cert, proof$logid, log$key, proof$signature, proof$timestamp, proof$hash_alg);
}
else if ( found_cache == F )
{
# X.509 proof. Here things get awkward because we need information about
# the issuer cert... and we need to try a few times, because we have to see if we got
# the right issuer cert.
#
# First - Let's try if a previous round already established the correct issuer key hash.
if ( issuer_key_hash != "" )
{
valid = sct_verify(cert, proof$logid, log$key, proof$signature, proof$timestamp, proof$hash_alg, issuer_key_hash);
}
# Second - let's see if we might already know the issuer cert through verification.
if ( ! valid && issuer_name_hash in intermediate_cache )
{
issuer_key_hash = x509_spki_hash(intermediate_cache[issuer_name_hash][0], 4);
valid = sct_verify(cert, proof$logid, log$key, proof$signature, proof$timestamp, proof$hash_alg, issuer_key_hash);
}
if ( ! valid && c$ssl?$valid_chain && |c$ssl$valid_chain| >= 2 )
{
issuer_key_hash = x509_spki_hash(c$ssl$valid_chain[1], 4);
valid = sct_verify(cert, proof$logid, log$key, proof$signature, proof$timestamp, proof$hash_alg, issuer_key_hash);
}
# ok, if it still did not work - let's just try with all the certs that were sent
# in the connection. Perhaps it will work with one of them.
if ( !valid )
for ( i in c$ssl$cert_chain )
{
if ( i == 0 ) # end-host-cert
next;
issuer_key_hash = x509_spki_hash(c$ssl$cert_chain[i]$x509$handle, 4);
valid = sct_verify(cert, proof$logid, log$key, proof$signature, proof$timestamp, proof$hash_alg, issuer_key_hash);
if ( valid )
break;
}
}
if ( ! found_cache )
recently_validated_scts[validate_hash] = valid;
proof$valid = valid;
if ( valid )
{
++valid_proofs;
add c$ssl$valid_ct_operators_list[log$operator];
add valid_logs[proof$logid];
}
else
++invalid_proofs;
}
c$ssl$valid_scts = valid_proofs;
c$ssl$invalid_scts = invalid_proofs;
c$ssl$valid_ct_operators = |c$ssl$valid_ct_operators_list|;
c$ssl$valid_ct_logs = |valid_logs|;
}

View file

@ -34,6 +34,7 @@
@load frameworks/files/entropy-test-all-files.bro @load frameworks/files/entropy-test-all-files.bro
#@load frameworks/files/extract-all-files.bro #@load frameworks/files/extract-all-files.bro
@load frameworks/files/hash-all-files.bro @load frameworks/files/hash-all-files.bro
@load files/x509/log-ocsp.bro
@load frameworks/packet-filter/shunt.bro @load frameworks/packet-filter/shunt.bro
@load frameworks/software/version-changes.bro @load frameworks/software/version-changes.bro
@load frameworks/software/vulnerable.bro @load frameworks/software/vulnerable.bro
@ -98,6 +99,7 @@
#@load protocols/ssl/notary.bro #@load protocols/ssl/notary.bro
@load protocols/ssl/validate-certs.bro @load protocols/ssl/validate-certs.bro
@load protocols/ssl/validate-ocsp.bro @load protocols/ssl/validate-ocsp.bro
@load protocols/ssl/validate-sct.bro
@load protocols/ssl/weak-keys.bro @load protocols/ssl/weak-keys.bro
@load tuning/__load__.bro @load tuning/__load__.bro
@load tuning/defaults/__load__.bro @load tuning/defaults/__load__.bro

View file

@ -82,7 +82,8 @@ int AnonymizeIPAddr::PreserveNet(ipaddr32_t input)
ipaddr32_t AnonymizeIPAddr_Seq::anonymize(ipaddr32_t /* input */) ipaddr32_t AnonymizeIPAddr_Seq::anonymize(ipaddr32_t /* input */)
{ {
return htonl(seq++); ++seq;
return htonl(seq);
} }
ipaddr32_t AnonymizeIPAddr_RandomMD5::anonymize(ipaddr32_t input) ipaddr32_t AnonymizeIPAddr_RandomMD5::anonymize(ipaddr32_t input)

View file

@ -703,7 +703,7 @@ const char* CompositeHash::RecoverOneVal(const HashKey* k, const char* kp0,
break; break;
case TYPE_PORT: case TYPE_PORT:
pval = new PortVal(*kp); pval = port_mgr->Get(*kp);
break; break;
default: default:

View file

@ -364,9 +364,9 @@ RecordVal* Connection::BuildConnVal()
RecordVal* id_val = new RecordVal(conn_id); RecordVal* id_val = new RecordVal(conn_id);
id_val->Assign(0, new AddrVal(orig_addr)); id_val->Assign(0, new AddrVal(orig_addr));
id_val->Assign(1, new PortVal(ntohs(orig_port), prot_type)); id_val->Assign(1, port_mgr->Get(ntohs(orig_port), prot_type));
id_val->Assign(2, new AddrVal(resp_addr)); id_val->Assign(2, new AddrVal(resp_addr));
id_val->Assign(3, new PortVal(ntohs(resp_port), prot_type)); id_val->Assign(3, port_mgr->Get(ntohs(resp_port), prot_type));
RecordVal *orig_endp = new RecordVal(endpoint); RecordVal *orig_endp = new RecordVal(endpoint);
orig_endp->Assign(0, new Val(0, TYPE_COUNT)); orig_endp->Assign(0, new Val(0, TYPE_COUNT));

View file

@ -19,7 +19,8 @@ DebugLogger::Stream DebugLogger::streams[NUM_DBGS] = {
{ "logging", 0, false }, {"input", 0, false }, { "logging", 0, false }, {"input", 0, false },
{ "threading", 0, false }, { "file_analysis", 0, false }, { "threading", 0, false }, { "file_analysis", 0, false },
{ "plugins", 0, false }, { "broxygen", 0, false }, { "plugins", 0, false }, { "broxygen", 0, false },
{ "pktio", 0, false }, { "broker", 0, false } { "pktio", 0, false }, { "broker", 0, false },
{ "scripts", 0, false}
}; };
DebugLogger::DebugLogger() DebugLogger::DebugLogger()

View file

@ -33,6 +33,7 @@ enum DebugStream {
DBG_BROXYGEN, // Broxygen DBG_BROXYGEN, // Broxygen
DBG_PKTIO, // Packet sources and dumpers. DBG_PKTIO, // Packet sources and dumpers.
DBG_BROKER, // Broker communication DBG_BROKER, // Broker communication
DBG_SCRIPTS, // Script initialization
NUM_DBGS // Has to be last NUM_DBGS // Has to be last
}; };

View file

@ -145,7 +145,9 @@ void ODesc::Add(double d, bool no_exp)
AddBytes(&d, sizeof(d)); AddBytes(&d, sizeof(d));
else else
{ {
char tmp[256]; // Buffer needs enough chars to store max. possible "double" value
// of 1.79e308 without using scientific notation.
char tmp[350];
if ( no_exp ) if ( no_exp )
modp_dtoa3(d, tmp, sizeof(tmp), IsReadable() ? 6 : 8); modp_dtoa3(d, tmp, sizeof(tmp), IsReadable() ? 6 : 8);

View file

@ -166,7 +166,7 @@ RecordVal* EventMgr::GetLocalPeerVal()
src_val = new RecordVal(peer); src_val = new RecordVal(peer);
src_val->Assign(0, new Val(0, TYPE_COUNT)); src_val->Assign(0, new Val(0, TYPE_COUNT));
src_val->Assign(1, new AddrVal("127.0.0.1")); src_val->Assign(1, new AddrVal("127.0.0.1"));
src_val->Assign(2, new PortVal(0)); src_val->Assign(2, port_mgr->Get(0));
src_val->Assign(3, new Val(true, TYPE_BOOL)); src_val->Assign(3, new Val(true, TYPE_BOOL));
Ref(peer_description); Ref(peer_description);

View file

@ -4351,9 +4351,8 @@ Val* InExpr::Fold(Val* v1, Val* v2) const
const BroString* s1 = v1->AsString(); const BroString* s1 = v1->AsString();
const BroString* s2 = v2->AsString(); const BroString* s2 = v2->AsString();
// Could do better here - either roll our own, to deal with // Could do better here e.g. Boyer-Moore if done repeatedly.
// NULs, and/or Boyer-Moore if done repeatedly. return new Val(strstr_n(s2->Len(), s2->Bytes(), s1->Len(), reinterpret_cast<const unsigned char*>(s1->CheckString())) != -1, TYPE_BOOL);
return new Val(strstr(s2->CheckString(), s1->CheckString()) != 0, TYPE_BOOL);
} }
if ( v1->Type()->Tag() == TYPE_ADDR && if ( v1->Type()->Tag() == TYPE_ADDR &&

View file

@ -302,7 +302,7 @@ FILE* BroFile::BringIntoCache()
if ( ! f ) if ( ! f )
{ {
strerror_r(errno, buf, sizeof(buf)); bro_strerror_r(errno, buf, sizeof(buf));
reporter->Error("can't open %s: %s", name, buf); reporter->Error("can't open %s: %s", name, buf);
f = fopen("/dev/null", "w"); f = fopen("/dev/null", "w");
@ -313,7 +313,7 @@ FILE* BroFile::BringIntoCache()
return f; return f;
} }
strerror_r(errno, buf, sizeof(buf)); bro_strerror_r(errno, buf, sizeof(buf));
reporter->Error("can't open /dev/null: %s", buf); reporter->Error("can't open /dev/null: %s", buf);
return 0; return 0;
} }
@ -323,7 +323,7 @@ FILE* BroFile::BringIntoCache()
if ( fseek(f, position, SEEK_SET) < 0 ) if ( fseek(f, position, SEEK_SET) < 0 )
{ {
strerror_r(errno, buf, sizeof(buf)); bro_strerror_r(errno, buf, sizeof(buf));
reporter->Error("reopen seek failed: %s", buf); reporter->Error("reopen seek failed: %s", buf);
} }
@ -413,7 +413,7 @@ void BroFile::Suspend()
if ( (position = ftell(f)) < 0 ) if ( (position = ftell(f)) < 0 )
{ {
char buf[256]; char buf[256];
strerror_r(errno, buf, sizeof(buf)); bro_strerror_r(errno, buf, sizeof(buf));
reporter->Error("ftell failed: %s", buf); reporter->Error("ftell failed: %s", buf);
position = 0; position = 0;
} }

View file

@ -16,7 +16,7 @@ Flare::Flare()
static void bad_pipe_op(const char* which) static void bad_pipe_op(const char* which)
{ {
char buf[256]; char buf[256];
strerror_r(errno, buf, sizeof(buf)); bro_strerror_r(errno, buf, sizeof(buf));
reporter->FatalErrorWithCore("unexpected pipe %s failure: %s", which, buf); reporter->FatalErrorWithCore("unexpected pipe %s failure: %s", which, buf);
} }

View file

@ -383,11 +383,7 @@ Val* BroFunc::Call(val_list* args, Frame* parent) const
FType()->FlavorString().c_str(), d.Description()); FType()->FlavorString().c_str(), d.Description());
} }
loop_over_list(*args, i)
f->SetElement(i, (*args)[i]);
stmt_flow_type flow = FLOW_NEXT; stmt_flow_type flow = FLOW_NEXT;
Val* result = 0; Val* result = 0;
for ( size_t i = 0; i < bodies.size(); ++i ) for ( size_t i = 0; i < bodies.size(); ++i )
@ -397,6 +393,20 @@ Val* BroFunc::Call(val_list* args, Frame* parent) const
bodies[i].stmts->GetLocationInfo()); bodies[i].stmts->GetLocationInfo());
Unref(result); Unref(result);
loop_over_list(*args, j)
{
Val* arg = (*args)[j];
if ( f->NthElement(j) != arg )
{
// Either not yet set, or somebody reassigned
// the frame slot.
Ref(arg);
f->SetElement(j, arg);
}
}
f->Reset(args->length()); f->Reset(args->length());
try try
@ -434,6 +444,11 @@ Val* BroFunc::Call(val_list* args, Frame* parent) const
} }
} }
// We have an extra Ref for each argument (so that they don't get
// deleted between bodies), release that.
loop_over_list(*args, k)
Unref((*args)[k]);
if ( Flavor() == FUNC_FLAVOR_HOOK ) if ( Flavor() == FUNC_FLAVOR_HOOK )
{ {
if ( ! result ) if ( ! result )

View file

@ -370,8 +370,8 @@ RecordVal* IP_Hdr::BuildPktHdrVal(RecordVal* pkt_hdr, int sindex) const
int tcp_hdr_len = tp->th_off * 4; int tcp_hdr_len = tp->th_off * 4;
int data_len = PayloadLen() - tcp_hdr_len; int data_len = PayloadLen() - tcp_hdr_len;
tcp_hdr->Assign(0, new PortVal(ntohs(tp->th_sport), TRANSPORT_TCP)); tcp_hdr->Assign(0, port_mgr->Get(ntohs(tp->th_sport), TRANSPORT_TCP));
tcp_hdr->Assign(1, new PortVal(ntohs(tp->th_dport), TRANSPORT_TCP)); tcp_hdr->Assign(1, port_mgr->Get(ntohs(tp->th_dport), TRANSPORT_TCP));
tcp_hdr->Assign(2, new Val(uint32(ntohl(tp->th_seq)), TYPE_COUNT)); tcp_hdr->Assign(2, new Val(uint32(ntohl(tp->th_seq)), TYPE_COUNT));
tcp_hdr->Assign(3, new Val(uint32(ntohl(tp->th_ack)), TYPE_COUNT)); tcp_hdr->Assign(3, new Val(uint32(ntohl(tp->th_ack)), TYPE_COUNT));
tcp_hdr->Assign(4, new Val(tcp_hdr_len, TYPE_COUNT)); tcp_hdr->Assign(4, new Val(tcp_hdr_len, TYPE_COUNT));
@ -388,8 +388,8 @@ RecordVal* IP_Hdr::BuildPktHdrVal(RecordVal* pkt_hdr, int sindex) const
const struct udphdr* up = (const struct udphdr*) data; const struct udphdr* up = (const struct udphdr*) data;
RecordVal* udp_hdr = new RecordVal(udp_hdr_type); RecordVal* udp_hdr = new RecordVal(udp_hdr_type);
udp_hdr->Assign(0, new PortVal(ntohs(up->uh_sport), TRANSPORT_UDP)); udp_hdr->Assign(0, port_mgr->Get(ntohs(up->uh_sport), TRANSPORT_UDP));
udp_hdr->Assign(1, new PortVal(ntohs(up->uh_dport), TRANSPORT_UDP)); udp_hdr->Assign(1, port_mgr->Get(ntohs(up->uh_dport), TRANSPORT_UDP));
udp_hdr->Assign(2, new Val(ntohs(up->uh_ulen), TYPE_COUNT)); udp_hdr->Assign(2, new Val(ntohs(up->uh_ulen), TYPE_COUNT));
pkt_hdr->Assign(sindex + 3, udp_hdr); pkt_hdr->Assign(sindex + 3, udp_hdr);

View file

@ -191,7 +191,7 @@ void PersistenceSerializer::RaiseFinishedSendState()
{ {
val_list* vl = new val_list; val_list* vl = new val_list;
vl->append(new AddrVal(htonl(remote_host))); vl->append(new AddrVal(htonl(remote_host)));
vl->append(new PortVal(remote_port)); vl->append(port_mgr->Get(remote_port));
mgr.QueueEvent(finished_send_state, vl); mgr.QueueEvent(finished_send_state, vl);
reporter->Log("Serialization done."); reporter->Log("Serialization done.");

View file

@ -12,7 +12,7 @@ using namespace bro;
static void pipe_fail(int eno) static void pipe_fail(int eno)
{ {
char tmp[256]; char tmp[256];
strerror_r(eno, tmp, sizeof(tmp)); bro_strerror_r(eno, tmp, sizeof(tmp));
reporter->FatalError("Pipe failure: %s", tmp); reporter->FatalError("Pipe failure: %s", tmp);
} }

View file

@ -84,7 +84,7 @@ bool LoadPolicyFileText(const char* policy_filename)
if ( fstat(fileno(f), &st) != 0 ) if ( fstat(fileno(f), &st) != 0 )
{ {
char buf[256]; char buf[256];
strerror_r(errno, buf, sizeof(buf)); bro_strerror_r(errno, buf, sizeof(buf));
reporter->Error("fstat failed on %s: %s", policy_filename, buf); reporter->Error("fstat failed on %s: %s", policy_filename, buf);
fclose(f); fclose(f);
return false; return false;

View file

@ -1809,7 +1809,7 @@ RecordVal* RemoteSerializer::MakePeerVal(Peer* peer)
v->Assign(0, new Val(uint32(peer->id), TYPE_COUNT)); v->Assign(0, new Val(uint32(peer->id), TYPE_COUNT));
// Sic! Network order for AddrVal, host order for PortVal. // Sic! Network order for AddrVal, host order for PortVal.
v->Assign(1, new AddrVal(peer->ip)); v->Assign(1, new AddrVal(peer->ip));
v->Assign(2, new PortVal(peer->port, TRANSPORT_TCP)); v->Assign(2, port_mgr->Get(peer->port, TRANSPORT_TCP));
v->Assign(3, new Val(false, TYPE_BOOL)); v->Assign(3, new Val(false, TYPE_BOOL));
v->Assign(4, new StringVal("")); // set when received v->Assign(4, new StringVal("")); // set when received
v->Assign(5, peer->peer_class.size() ? v->Assign(5, peer->peer_class.size() ?

View file

@ -10,6 +10,8 @@
#include "NetVar.h" #include "NetVar.h"
#include "Net.h" #include "Net.h"
#include "Conn.h" #include "Conn.h"
#include "plugin/Plugin.h"
#include "plugin/Manager.h"
#ifdef SYSLOG_INT #ifdef SYSLOG_INT
extern "C" { extern "C" {
@ -323,7 +325,24 @@ void Reporter::DoLog(const char* prefix, EventHandlerPtr event, FILE* out,
// buffer size above. // buffer size above.
safe_snprintf(buffer + strlen(buffer), size - strlen(buffer), " [%s]", postfix); safe_snprintf(buffer + strlen(buffer), size - strlen(buffer), " [%s]", postfix);
if ( event && via_events && ! in_error_handler ) bool raise_event = true;
if ( via_events && ! in_error_handler )
{
if ( locations.size() )
{
auto locs = locations.back();
raise_event = PLUGIN_HOOK_WITH_RESULT(HOOK_REPORTER,
HookReporter(prefix, event, conn, addl, location,
locs.first, locs.second, time, buffer), true);
}
else
raise_event = PLUGIN_HOOK_WITH_RESULT(HOOK_REPORTER,
HookReporter(prefix, event, conn, addl, location,
nullptr, nullptr, time, buffer), true);
}
if ( raise_event && event && via_events && ! in_error_handler )
{ {
val_list* vl = new val_list; val_list* vl = new val_list;

View file

@ -175,9 +175,15 @@ bool RuleConditionEval::DoMatch(Rule* rule, RuleEndpointState* state,
try try
{ {
Val* val = id->ID_Val()->AsFunc()->Call(&args); Val* val = id->ID_Val()->AsFunc()->Call(&args);
if ( val )
{
result = val->AsBool(); result = val->AsBool();
Unref(val); Unref(val);
} }
else
result = false;
}
catch ( InterpreterException& e ) catch ( InterpreterException& e )
{ {

View file

@ -115,6 +115,7 @@ SERIAL_VAL(CARDINALITY_VAL, 22)
SERIAL_VAL(X509_VAL, 23) SERIAL_VAL(X509_VAL, 23)
SERIAL_VAL(COMM_STORE_HANDLE_VAL, 24) SERIAL_VAL(COMM_STORE_HANDLE_VAL, 24)
SERIAL_VAL(COMM_DATA_VAL, 25) SERIAL_VAL(COMM_DATA_VAL, 25)
SERIAL_VAL(OCSP_RESP_VAL, 26)
#define SERIAL_EXPR(name, val) SERIAL_CONST(name, val, EXPR) #define SERIAL_EXPR(name, val) SERIAL_CONST(name, val, EXPR)
SERIAL_EXPR(EXPR, 1) SERIAL_EXPR(EXPR, 1)

View file

@ -337,11 +337,25 @@ void NetSessions::DoNextPacket(double t, const Packet* pkt, const IP_Hdr* ip_hdr
return; return;
} }
// For both of these it is safe to pass ip_hdr because the presence
// is guaranteed for the functions that pass data to us.
uint16 ip_hdr_len = ip_hdr->HdrLen();
if ( ip_hdr_len > len )
{
Weird("invalid_IP_header_size", ip_hdr, encapsulation);
return;
}
if ( ip_hdr_len > caplen )
{
Weird("internally_truncated_header", ip_hdr, encapsulation);
return;
}
// Ignore if packet matches packet filter. // Ignore if packet matches packet filter.
if ( packet_filter && packet_filter->Match(ip_hdr, len, caplen) ) if ( packet_filter && packet_filter->Match(ip_hdr, len, caplen) )
return; return;
int ip_hdr_len = ip_hdr->HdrLen();
if ( ! ignore_checksums && ip4 && if ( ! ignore_checksums && ip4 &&
ones_complement_checksum((void*) ip4, ip_hdr_len, 0) != 0xffff ) ones_complement_checksum((void*) ip4, ip_hdr_len, 0) != 0xffff )
{ {
@ -381,6 +395,12 @@ void NetSessions::DoNextPacket(double t, const Packet* pkt, const IP_Hdr* ip_hdr
caplen = len = ip_hdr->TotalLen(); caplen = len = ip_hdr->TotalLen();
ip_hdr_len = ip_hdr->HdrLen(); ip_hdr_len = ip_hdr->HdrLen();
if ( ip_hdr_len > len )
{
Weird("invalid_IP_header_size", ip_hdr, encapsulation);
return;
}
} }
} }
@ -618,9 +638,10 @@ void NetSessions::DoNextPacket(double t, const Packet* pkt, const IP_Hdr* ip_hdr
// Check for a valid inner packet first. // Check for a valid inner packet first.
IP_Hdr* inner = 0; IP_Hdr* inner = 0;
int result = ParseIPPacket(caplen, data, proto, inner); int result = ParseIPPacket(caplen, data, proto, inner);
if ( result < 0 ) if ( result == -2 )
Weird("invalid_inner_IP_version", ip_hdr, encapsulation);
else if ( result < 0 )
Weird("truncated_inner_IP", ip_hdr, encapsulation); Weird("truncated_inner_IP", ip_hdr, encapsulation);
else if ( result > 0 ) else if ( result > 0 )
Weird("inner_IP_payload_length_mismatch", ip_hdr, encapsulation); Weird("inner_IP_payload_length_mismatch", ip_hdr, encapsulation);
@ -819,7 +840,10 @@ int NetSessions::ParseIPPacket(int caplen, const u_char* const pkt, int proto,
if ( caplen < (int)sizeof(struct ip6_hdr) ) if ( caplen < (int)sizeof(struct ip6_hdr) )
return -1; return -1;
inner = new IP_Hdr((const struct ip6_hdr*) pkt, false, caplen); const struct ip6_hdr* ip6 = (const struct ip6_hdr*) pkt;
inner = new IP_Hdr(ip6, false, caplen);
if ( ( ip6->ip6_ctlun.ip6_un2_vfc & 0xF0 ) != 0x60 )
return -2;
} }
else if ( proto == IPPROTO_IPV4 ) else if ( proto == IPPROTO_IPV4 )
@ -827,7 +851,10 @@ int NetSessions::ParseIPPacket(int caplen, const u_char* const pkt, int proto,
if ( caplen < (int)sizeof(struct ip) ) if ( caplen < (int)sizeof(struct ip) )
return -1; return -1;
inner = new IP_Hdr((const struct ip*) pkt, false); const struct ip* ip4 = (const struct ip*) pkt;
inner = new IP_Hdr(ip4, false);
if ( ip4->ip_v != 4 )
return -2;
} }
else else

View file

@ -151,8 +151,9 @@ public:
/** /**
* Returns a wrapper IP_Hdr object if \a pkt appears to be a valid IPv4 * Returns a wrapper IP_Hdr object if \a pkt appears to be a valid IPv4
* or IPv6 header based on whether it's long enough to contain such a header * or IPv6 header based on whether it's long enough to contain such a header,
* and also that the payload length field of that header matches the actual * if version given in the header matches the proto argument, and also checks
* that the payload length field of that header matches the actual
* length of \a pkt given by \a caplen. * length of \a pkt given by \a caplen.
* *
* @param caplen The length of \a pkt in bytes. * @param caplen The length of \a pkt in bytes.
@ -163,7 +164,8 @@ public:
* if \a pkt looks like a valid IP packet or at least long enough * if \a pkt looks like a valid IP packet or at least long enough
* to hold an IP header. * to hold an IP header.
* @return 0 If the inner IP packet appeared valid, else -1 if \a caplen * @return 0 If the inner IP packet appeared valid, else -1 if \a caplen
* is greater than the supposed IP packet's payload length field or * is greater than the supposed IP packet's payload length field, -2
* if the version of the inner header does not match proto or
* 1 if \a caplen is less than the supposed packet's payload length. * 1 if \a caplen is less than the supposed packet's payload length.
* In the -1 case, \a inner may still be non-null if \a caplen was * In the -1 case, \a inner may still be non-null if \a caplen was
* long enough to be an IP header, and \a inner is always non-null * long enough to be an IP header, and \a inner is always non-null

View file

@ -1293,6 +1293,9 @@ Val* ForStmt::DoExec(Frame* f, Val* v, stmt_flow_type& flow) const
TableVal* tv = v->AsTableVal(); TableVal* tv = v->AsTableVal();
const PDict(TableEntryVal)* loop_vals = tv->AsTable(); const PDict(TableEntryVal)* loop_vals = tv->AsTable();
if ( ! loop_vals->Length() )
return 0;
HashKey* k; HashKey* k;
IterCookie* c = loop_vals->InitForIteration(); IterCookie* c = loop_vals->InitForIteration();
while ( loop_vals->NextEntry(k, c) ) while ( loop_vals->NextEntry(k, c) )

View file

@ -136,8 +136,8 @@ Trigger::Trigger(Expr* arg_cond, Stmt* arg_body, Stmt* arg_timeout_stmts,
if ( timeout_val ) if ( timeout_val )
{ {
Unref(timeout_val);
timeout_value = timeout_val->AsInterval(); timeout_value = timeout_val->AsInterval();
Unref(timeout_val);
} }
// Make sure we don't get deleted if somebody calls a method like // Make sure we don't get deleted if somebody calls a method like

View file

@ -22,9 +22,9 @@ RecordVal* EncapsulatingConn::GetRecordVal() const
RecordVal* id_val = new RecordVal(conn_id); RecordVal* id_val = new RecordVal(conn_id);
id_val->Assign(0, new AddrVal(src_addr)); id_val->Assign(0, new AddrVal(src_addr));
id_val->Assign(1, new PortVal(ntohs(src_port), proto)); id_val->Assign(1, port_mgr->Get(ntohs(src_port), proto));
id_val->Assign(2, new AddrVal(dst_addr)); id_val->Assign(2, new AddrVal(dst_addr));
id_val->Assign(3, new PortVal(ntohs(dst_port), proto)); id_val->Assign(3, port_mgr->Get(ntohs(dst_port), proto));
rv->Assign(0, id_val); rv->Assign(0, id_val);
rv->Assign(1, new EnumVal(type, BifType::Enum::Tunnel::Type)); rv->Assign(1, new EnumVal(type, BifType::Enum::Tunnel::Type));

View file

@ -545,7 +545,7 @@ bool IndexType::DoUnserialize(UnserialInfo* info)
DO_UNSERIALIZE(BroType); DO_UNSERIALIZE(BroType);
UNSERIALIZE_OPTIONAL(yield_type, BroType::Unserialize(info)); UNSERIALIZE_OPTIONAL(yield_type, BroType::Unserialize(info));
indices = (TypeList*) BroType::Unserialize(info, TYPE_LIST); indices = (TypeList*) BroType::Unserialize(info);
return indices != 0; return indices != 0;
} }
@ -865,11 +865,11 @@ bool FuncType::DoUnserialize(UnserialInfo* info)
UNSERIALIZE_OPTIONAL(yield, BroType::Unserialize(info)); UNSERIALIZE_OPTIONAL(yield, BroType::Unserialize(info));
args = (RecordType*) BroType::Unserialize(info, TYPE_RECORD); args = (RecordType*) BroType::Unserialize(info);
if ( ! args ) if ( ! args )
return false; return false;
arg_types = (TypeList*) BroType::Unserialize(info, TYPE_LIST); arg_types = (TypeList*) BroType::Unserialize(info);
if ( ! arg_types ) if ( ! arg_types )
return false; return false;

View file

@ -628,6 +628,7 @@ extern OpaqueType* cardinality_type;
extern OpaqueType* topk_type; extern OpaqueType* topk_type;
extern OpaqueType* bloomfilter_type; extern OpaqueType* bloomfilter_type;
extern OpaqueType* x509_opaque_type; extern OpaqueType* x509_opaque_type;
extern OpaqueType* ocsp_resp_opaque_type;
// Returns the Bro basic (non-parameterized) type with the given type. // Returns the Bro basic (non-parameterized) type with the given type.
// The reference count of the type is not increased. // The reference count of the type is not increased.

View file

@ -760,34 +760,92 @@ bool IntervalVal::DoUnserialize(UnserialInfo* info)
return true; return true;
} }
PortVal::PortVal(uint32 p, TransportProto port_type) : Val(TYPE_PORT) PortManager::PortManager()
{
for ( auto i = 0u; i < ports.size(); ++i )
{
auto& arr = ports[i];
auto port_type = (TransportProto)i;
for ( auto j = 0u; j < arr.size(); ++j )
arr[j] = new PortVal(Mask(j, port_type), true);
}
}
PortManager::~PortManager()
{
for ( auto& arr : ports )
for ( auto& pv : arr )
Unref(pv);
}
PortVal* PortManager::Get(uint32 port_num) const
{
auto mask = port_num & PORT_SPACE_MASK;
port_num &= ~PORT_SPACE_MASK;
if ( mask == TCP_PORT_MASK )
return Get(port_num, TRANSPORT_TCP);
else if ( mask == UDP_PORT_MASK )
return Get(port_num, TRANSPORT_UDP);
else if ( mask == ICMP_PORT_MASK )
return Get(port_num, TRANSPORT_ICMP);
else
return Get(port_num, TRANSPORT_UNKNOWN);
}
PortVal* PortManager::Get(uint32 port_num, TransportProto port_type) const
{
if ( port_num >= 65536 )
{
reporter->Warning("bad port number %d", port_num);
port_num = 0;
}
auto rval = ports[port_type][port_num];
::Ref(rval);
return rval;
}
uint32 PortManager::Mask(uint32 port_num, TransportProto port_type) const
{ {
// Note, for ICMP one-way connections: // Note, for ICMP one-way connections:
// src_port = icmp_type, dst_port = icmp_code. // src_port = icmp_type, dst_port = icmp_code.
if ( p >= 65536 ) if ( port_num >= 65536 )
{ {
InternalWarning("bad port number"); reporter->Warning("bad port number %d", port_num);
p = 0; port_num = 0;
} }
switch ( port_type ) { switch ( port_type ) {
case TRANSPORT_TCP: case TRANSPORT_TCP:
p |= TCP_PORT_MASK; port_num |= TCP_PORT_MASK;
break; break;
case TRANSPORT_UDP: case TRANSPORT_UDP:
p |= UDP_PORT_MASK; port_num |= UDP_PORT_MASK;
break; break;
case TRANSPORT_ICMP: case TRANSPORT_ICMP:
p |= ICMP_PORT_MASK; port_num |= ICMP_PORT_MASK;
break; break;
default: default:
break; // "other" break; // "unknown/other"
} }
return port_num;
}
PortVal::PortVal(uint32 p, TransportProto port_type) : Val(TYPE_PORT)
{
auto port_num = port_mgr->Mask(p, port_type);
val.uint_val = static_cast<bro_uint_t>(port_num);
}
PortVal::PortVal(uint32 p, bool unused) : Val(TYPE_PORT)
{
val.uint_val = static_cast<bro_uint_t>(p); val.uint_val = static_cast<bro_uint_t>(p);
} }

View file

@ -7,6 +7,7 @@
#include <vector> #include <vector>
#include <list> #include <list>
#include <array>
#include "net_util.h" #include "net_util.h"
#include "Type.h" #include "Type.h"
@ -503,11 +504,35 @@ protected:
#define UDP_PORT_MASK 0x20000 #define UDP_PORT_MASK 0x20000
#define ICMP_PORT_MASK 0x30000 #define ICMP_PORT_MASK 0x30000
class PortManager {
public:
PortManager();
~PortManager();
// Port number given in host order.
PortVal* Get(uint32 port_num, TransportProto port_type) const;
// Host-order port number already masked with port space protocol mask.
PortVal* Get(uint32 port_num) const;
// Returns a masked port number
uint32 Mask(uint32 port_num, TransportProto port_type) const;
private:
std::array<std::array<PortVal*, 65536>, NUM_PORT_SPACES> ports;
};
extern PortManager* port_mgr;
class PortVal : public Val { class PortVal : public Val {
public: public:
// Constructors - both take the port number in host order. // Port number given in host order.
BRO_DEPRECATED("use port_mgr->Get() instead")
PortVal(uint32 p, TransportProto port_type); PortVal(uint32 p, TransportProto port_type);
PortVal(uint32 p); // used for already-massaged port value.
// Host-order port number already masked with port space protocol mask.
BRO_DEPRECATED("use port_mgr->Get() instead")
PortVal(uint32 p);
Val* SizeVal() const override { return new Val(val.uint_val, TYPE_INT); } Val* SizeVal() const override { return new Val(val.uint_val, TYPE_INT); }
@ -533,7 +558,9 @@ public:
protected: protected:
friend class Val; friend class Val;
friend class PortManager;
PortVal() {} PortVal() {}
PortVal(uint32 p, bool unused);
void ValDescribe(ODesc* d) const override; void ValDescribe(ODesc* d) const override;

View file

@ -434,14 +434,16 @@ bool Manager::BuildInitialAnalyzerTree(Connection* conn)
if ( tcp_contents && ! reass ) if ( tcp_contents && ! reass )
{ {
PortVal dport(ntohs(conn->RespPort()), TRANSPORT_TCP); auto dport = port_mgr->Get(ntohs(conn->RespPort()), TRANSPORT_TCP);
Val* result; Val* result;
if ( ! reass ) if ( ! reass )
reass = tcp_content_delivery_ports_orig->Lookup(&dport); reass = tcp_content_delivery_ports_orig->Lookup(dport);
if ( ! reass ) if ( ! reass )
reass = tcp_content_delivery_ports_resp->Lookup(&dport); reass = tcp_content_delivery_ports_resp->Lookup(dport);
Unref(dport);
} }
if ( reass ) if ( reass )

View file

@ -114,7 +114,7 @@ public:
bool DisableAnalyzer(Tag tag); bool DisableAnalyzer(Tag tag);
/** /**
* Enables an analyzer type. Disabled analyzers will not be * Disables an analyzer type. Disabled analyzers will not be
* instantiated for new connections. * instantiated for new connections.
* *
* @param tag The analyzer's tag as an enum of script type \c * @param tag The analyzer's tag as an enum of script type \c

View file

@ -59,6 +59,11 @@ flow AYIYA_Flow
if ( result == 0 ) if ( result == 0 )
connection()->bro_analyzer()->ProtocolConfirmation(); connection()->bro_analyzer()->ProtocolConfirmation();
else if ( result == -2 )
connection()->bro_analyzer()->ProtocolViolation(
"AYIYA next header internal mismatch", (const char*)${pdu.packet}.data(),
${pdu.packet}.length());
else if ( result < 0 ) else if ( result < 0 )
connection()->bro_analyzer()->ProtocolViolation( connection()->bro_analyzer()->ProtocolViolation(
"Truncated AYIYA", (const char*) ${pdu.packet}.data(), "Truncated AYIYA", (const char*) ${pdu.packet}.data(),

View file

@ -482,7 +482,7 @@ void BitTorrentTracker_Analyzer::ResponseBenc(int name_len, char* name,
RecordVal* peer = new RecordVal(bittorrent_peer); RecordVal* peer = new RecordVal(bittorrent_peer);
peer->Assign(0, new AddrVal(ad)); peer->Assign(0, new AddrVal(ad));
peer->Assign(1, new PortVal(pt, TRANSPORT_TCP)); peer->Assign(1, port_mgr->Get(pt, TRANSPORT_TCP));
res_val_peers->Assign(peer, 0); res_val_peers->Assign(peer, 0);
Unref(peer); Unref(peer);

View file

@ -222,7 +222,7 @@ flow BitTorrent_Flow(is_orig: bool) {
connection()->bro_analyzer(), connection()->bro_analyzer(),
connection()->bro_analyzer()->Conn(), connection()->bro_analyzer()->Conn(),
is_orig(), is_orig(),
new PortVal(listen_port, TRANSPORT_TCP)); port_mgr->Get(listen_port, TRANSPORT_TCP));
} }
return true; return true;

View file

@ -5,10 +5,7 @@ static analyzer::Analyzer* GetConnsizeAnalyzer(Val* cid)
{ {
Connection* c = sessions->FindConnection(cid); Connection* c = sessions->FindConnection(cid);
if ( ! c ) if ( ! c )
{
reporter->Error("cannot find connection");
return 0; return 0;
}
analyzer::Analyzer* a = c->FindAnalyzer("CONNSIZE"); analyzer::Analyzer* a = c->FindAnalyzer("CONNSIZE");
if ( ! a ) if ( ! a )

View file

@ -17,9 +17,9 @@ Finger_Analyzer::Finger_Analyzer(Connection* conn)
: tcp::TCP_ApplicationAnalyzer("FINGER", conn) : tcp::TCP_ApplicationAnalyzer("FINGER", conn)
{ {
did_deliver = 0; did_deliver = 0;
content_line_orig = new tcp::ContentLine_Analyzer(conn, true); content_line_orig = new tcp::ContentLine_Analyzer(conn, true, 1000);
content_line_orig->SetIsNULSensitive(true); content_line_orig->SetIsNULSensitive(true);
content_line_resp = new tcp::ContentLine_Analyzer(conn, false); content_line_resp = new tcp::ContentLine_Analyzer(conn, false, 1000);
AddSupportAnalyzer(content_line_orig); AddSupportAnalyzer(content_line_orig);
AddSupportAnalyzer(content_line_resp); AddSupportAnalyzer(content_line_resp);
} }

View file

@ -33,13 +33,13 @@ static Val* parse_port(const char* line)
} }
r->Assign(0, new AddrVal(htonl(addr))); r->Assign(0, new AddrVal(htonl(addr)));
r->Assign(1, new PortVal(port, TRANSPORT_TCP)); r->Assign(1, port_mgr->Get(port, TRANSPORT_TCP));
r->Assign(2, new Val(good, TYPE_BOOL)); r->Assign(2, new Val(good, TYPE_BOOL));
} }
else else
{ {
r->Assign(0, new AddrVal(uint32(0))); r->Assign(0, new AddrVal(uint32(0)));
r->Assign(1, new PortVal(0, TRANSPORT_TCP)); r->Assign(1, port_mgr->Get(0, TRANSPORT_TCP));
r->Assign(2, new Val(0, TYPE_BOOL)); r->Assign(2, new Val(0, TYPE_BOOL));
} }
@ -109,7 +109,7 @@ static Val* parse_eftp(const char* line)
} }
r->Assign(0, new AddrVal(addr)); r->Assign(0, new AddrVal(addr));
r->Assign(1, new PortVal(port, TRANSPORT_TCP)); r->Assign(1, port_mgr->Get(port, TRANSPORT_TCP));
r->Assign(2, new Val(good, TYPE_BOOL)); r->Assign(2, new Val(good, TYPE_BOOL));
return r; return r;

View file

@ -740,6 +740,9 @@ flow GTPv1_Flow(is_orig: bool)
a->ProtocolConfirmation(); a->ProtocolConfirmation();
} }
else if ( result == -2 )
violate("Invalid IP version in wrapped packet", pdu);
else if ( result < 0 ) else if ( result < 0 )
violate("Truncated GTPv1", pdu); violate("Truncated GTPv1", pdu);

View file

@ -352,9 +352,9 @@ RecordVal* ICMP_Analyzer::ExtractICMP4Context(int len, const u_char*& data)
RecordVal* id_val = new RecordVal(conn_id); RecordVal* id_val = new RecordVal(conn_id);
id_val->Assign(0, new AddrVal(src_addr)); id_val->Assign(0, new AddrVal(src_addr));
id_val->Assign(1, new PortVal(src_port, proto)); id_val->Assign(1, port_mgr->Get(src_port, proto));
id_val->Assign(2, new AddrVal(dst_addr)); id_val->Assign(2, new AddrVal(dst_addr));
id_val->Assign(3, new PortVal(dst_port, proto)); id_val->Assign(3, port_mgr->Get(dst_port, proto));
iprec->Assign(0, id_val); iprec->Assign(0, id_val);
iprec->Assign(1, new Val(ip_len, TYPE_COUNT)); iprec->Assign(1, new Val(ip_len, TYPE_COUNT));
@ -411,9 +411,9 @@ RecordVal* ICMP_Analyzer::ExtractICMP6Context(int len, const u_char*& data)
RecordVal* id_val = new RecordVal(conn_id); RecordVal* id_val = new RecordVal(conn_id);
id_val->Assign(0, new AddrVal(src_addr)); id_val->Assign(0, new AddrVal(src_addr));
id_val->Assign(1, new PortVal(src_port, proto)); id_val->Assign(1, port_mgr->Get(src_port, proto));
id_val->Assign(2, new AddrVal(dst_addr)); id_val->Assign(2, new AddrVal(dst_addr));
id_val->Assign(3, new PortVal(dst_port, proto)); id_val->Assign(3, port_mgr->Get(dst_port, proto));
iprec->Assign(0, id_val); iprec->Assign(0, id_val);
iprec->Assign(1, new Val(ip_len, TYPE_COUNT)); iprec->Assign(1, new Val(ip_len, TYPE_COUNT));

View file

@ -17,8 +17,8 @@ Ident_Analyzer::Ident_Analyzer(Connection* conn)
{ {
did_bad_reply = did_deliver = 0; did_bad_reply = did_deliver = 0;
orig_ident = new tcp::ContentLine_Analyzer(conn, true); orig_ident = new tcp::ContentLine_Analyzer(conn, true, 1000);
resp_ident = new tcp::ContentLine_Analyzer(conn, false); resp_ident = new tcp::ContentLine_Analyzer(conn, false, 1000);
orig_ident->SetIsNULSensitive(true); orig_ident->SetIsNULSensitive(true);
resp_ident->SetIsNULSensitive(true); resp_ident->SetIsNULSensitive(true);
@ -82,8 +82,8 @@ void Ident_Analyzer::DeliverStream(int length, const u_char* data, bool is_orig)
val_list* vl = new val_list; val_list* vl = new val_list;
vl->append(BuildConnVal()); vl->append(BuildConnVal());
vl->append(new PortVal(local_port, TRANSPORT_TCP)); vl->append(port_mgr->Get(local_port, TRANSPORT_TCP));
vl->append(new PortVal(remote_port, TRANSPORT_TCP)); vl->append(port_mgr->Get(remote_port, TRANSPORT_TCP));
ConnectionEvent(ident_request, vl); ConnectionEvent(ident_request, vl);
@ -143,8 +143,8 @@ void Ident_Analyzer::DeliverStream(int length, const u_char* data, bool is_orig)
{ {
val_list* vl = new val_list; val_list* vl = new val_list;
vl->append(BuildConnVal()); vl->append(BuildConnVal());
vl->append(new PortVal(local_port, TRANSPORT_TCP)); vl->append(port_mgr->Get(local_port, TRANSPORT_TCP));
vl->append(new PortVal(remote_port, TRANSPORT_TCP)); vl->append(port_mgr->Get(remote_port, TRANSPORT_TCP));
vl->append(new StringVal(end_of_line - line, line)); vl->append(new StringVal(end_of_line - line, line));
ConnectionEvent(ident_error, vl); ConnectionEvent(ident_error, vl);
@ -177,8 +177,8 @@ void Ident_Analyzer::DeliverStream(int length, const u_char* data, bool is_orig)
val_list* vl = new val_list; val_list* vl = new val_list;
vl->append(BuildConnVal()); vl->append(BuildConnVal());
vl->append(new PortVal(local_port, TRANSPORT_TCP)); vl->append(port_mgr->Get(local_port, TRANSPORT_TCP));
vl->append(new PortVal(remote_port, TRANSPORT_TCP)); vl->append(port_mgr->Get(remote_port, TRANSPORT_TCP));
vl->append(new StringVal(end_of_line - line, line)); vl->append(new StringVal(end_of_line - line, line));
vl->append(new StringVal(sys_type_s)); vl->append(new StringVal(sys_type_s));

View file

@ -21,9 +21,9 @@ IRC_Analyzer::IRC_Analyzer(Connection* conn)
orig_zip_status = NO_ZIP; orig_zip_status = NO_ZIP;
resp_zip_status = NO_ZIP; resp_zip_status = NO_ZIP;
starttls = false; starttls = false;
cl_orig = new tcp::ContentLine_Analyzer(conn, true); cl_orig = new tcp::ContentLine_Analyzer(conn, true, 1000);
AddSupportAnalyzer(cl_orig); AddSupportAnalyzer(cl_orig);
cl_resp = new tcp::ContentLine_Analyzer(conn, false); cl_resp = new tcp::ContentLine_Analyzer(conn, false, 1000);
AddSupportAnalyzer(cl_resp); AddSupportAnalyzer(cl_resp);
} }

View file

@ -76,7 +76,7 @@ VectorVal* proc_padata(const KRB_PA_Data_Sequence* data, const BroAnalyzer bro_a
file_mgr->DataIn(reinterpret_cast<const u_char*>(cert.data()), file_mgr->DataIn(reinterpret_cast<const u_char*>(cert.data()),
cert.length(), bro_analyzer->GetAnalyzerTag(), cert.length(), bro_analyzer->GetAnalyzerTag(),
bro_analyzer->Conn(), true, file_id); bro_analyzer->Conn(), true, file_id, "application/x-x509-user-cert");
file_mgr->EndOfFile(file_id); file_mgr->EndOfFile(file_id);
break; break;
@ -100,7 +100,7 @@ VectorVal* proc_padata(const KRB_PA_Data_Sequence* data, const BroAnalyzer bro_a
file_mgr->DataIn(reinterpret_cast<const u_char*>(cert.data()), file_mgr->DataIn(reinterpret_cast<const u_char*>(cert.data()),
cert.length(), bro_analyzer->GetAnalyzerTag(), cert.length(), bro_analyzer->GetAnalyzerTag(),
bro_analyzer->Conn(), false, file_id); bro_analyzer->Conn(), false, file_id, "application/x-x509-user-cert");
file_mgr->EndOfFile(file_id); file_mgr->EndOfFile(file_id);
break; break;

View file

@ -142,7 +142,7 @@ refine flow RDP_Flow += {
connection()->bro_analyzer()->GetAnalyzerTag(), connection()->bro_analyzer()->GetAnalyzerTag(),
connection()->bro_analyzer()->Conn(), connection()->bro_analyzer()->Conn(),
false, // It seems there are only server certs? false, // It seems there are only server certs?
file_id); file_id, "application/x-x509-user-cert");
file_mgr->EndOfFile(file_id); file_mgr->EndOfFile(file_id);
return true; return true;

View file

@ -126,7 +126,7 @@ int PortmapperInterp::RPC_BuildReply(RPC_CallInfo* c, BifEnum::rpc_status status
RecordVal* rv = c->RequestVal()->AsRecordVal(); RecordVal* rv = c->RequestVal()->AsRecordVal();
Val* is_tcp = rv->Lookup(2); Val* is_tcp = rv->Lookup(2);
reply = new PortVal(CheckPort(port), reply = port_mgr->Get(CheckPort(port),
is_tcp->IsOne() ? is_tcp->IsOne() ?
TRANSPORT_TCP : TRANSPORT_UDP); TRANSPORT_TCP : TRANSPORT_UDP);
event = pm_request_getport; event = pm_request_getport;
@ -178,7 +178,7 @@ int PortmapperInterp::RPC_BuildReply(RPC_CallInfo* c, BifEnum::rpc_status status
if ( ! opaque_reply ) if ( ! opaque_reply )
return 0; return 0;
reply = new PortVal(CheckPort(port), TRANSPORT_UDP); reply = port_mgr->Get(CheckPort(port), TRANSPORT_UDP);
event = pm_request_callit; event = pm_request_callit;
} }
else else
@ -202,7 +202,7 @@ Val* PortmapperInterp::ExtractMapping(const u_char*& buf, int& len)
int is_tcp = extract_XDR_uint32(buf, len) == IPPROTO_TCP; int is_tcp = extract_XDR_uint32(buf, len) == IPPROTO_TCP;
uint32 port = extract_XDR_uint32(buf, len); uint32 port = extract_XDR_uint32(buf, len);
mapping->Assign(2, new PortVal(CheckPort(port), mapping->Assign(2, port_mgr->Get(CheckPort(port),
is_tcp ? TRANSPORT_TCP : TRANSPORT_UDP)); is_tcp ? TRANSPORT_TCP : TRANSPORT_UDP));
if ( ! buf ) if ( ! buf )

View file

@ -32,7 +32,7 @@ refine connection SOCKS_Conn += {
4, 4,
${request.command}, ${request.command},
sa, sa,
new PortVal(${request.port} | TCP_PORT_MASK), port_mgr->Get(${request.port} | TCP_PORT_MASK),
array_to_string(${request.user})); array_to_string(${request.user}));
static_cast<analyzer::socks::SOCKS_Analyzer*>(bro_analyzer())->EndpointDone(true); static_cast<analyzer::socks::SOCKS_Analyzer*>(bro_analyzer())->EndpointDone(true);
@ -50,7 +50,7 @@ refine connection SOCKS_Conn += {
4, 4,
${reply.status}, ${reply.status},
sa, sa,
new PortVal(${reply.port} | TCP_PORT_MASK)); port_mgr->Get(${reply.port} | TCP_PORT_MASK));
bro_analyzer()->ProtocolConfirmation(); bro_analyzer()->ProtocolConfirmation();
static_cast<analyzer::socks::SOCKS_Analyzer*>(bro_analyzer())->EndpointDone(false); static_cast<analyzer::socks::SOCKS_Analyzer*>(bro_analyzer())->EndpointDone(false);
@ -102,7 +102,7 @@ refine connection SOCKS_Conn += {
5, 5,
${request.command}, ${request.command},
sa, sa,
new PortVal(${request.port} | TCP_PORT_MASK), port_mgr->Get(${request.port} | TCP_PORT_MASK),
new StringVal("")); new StringVal(""));
static_cast<analyzer::socks::SOCKS_Analyzer*>(bro_analyzer())->EndpointDone(true); static_cast<analyzer::socks::SOCKS_Analyzer*>(bro_analyzer())->EndpointDone(true);
@ -141,7 +141,7 @@ refine connection SOCKS_Conn += {
5, 5,
${reply.reply}, ${reply.reply},
sa, sa,
new PortVal(${reply.port} | TCP_PORT_MASK)); port_mgr->Get(${reply.port} | TCP_PORT_MASK));
bro_analyzer()->ProtocolConfirmation(); bro_analyzer()->ProtocolConfirmation();
static_cast<analyzer::socks::SOCKS_Analyzer*>(bro_analyzer())->EndpointDone(false); static_cast<analyzer::socks::SOCKS_Analyzer*>(bro_analyzer())->EndpointDone(false);

View file

@ -410,7 +410,7 @@ refine connection SSH_Conn += {
return true; return true;
if ( update_kex_state_if_equal("ecmqv-sha2", KEX_ECC) ) if ( update_kex_state_if_equal("ecmqv-sha2", KEX_ECC) )
return true; return true;
if ( update_kex_state_if_equal("curve25519-sha256@libssh.org", KEX_ECC) ) if ( update_kex_state_if_startswith("curve25519-sha256", KEX_ECC) )
return true; return true;

View file

@ -12,6 +12,7 @@ bro_plugin_pac(tls-handshake.pac tls-handshake-protocol.pac tls-handshake-analyz
proc-client-hello.pac proc-client-hello.pac
proc-server-hello.pac proc-server-hello.pac
proc-certificate.pac proc-certificate.pac
tls-handshake-signed_certificate_timestamp.pac
) )
bro_plugin_pac(ssl.pac ssl-dtls-analyzer.pac ssl-analyzer.pac ssl-dtls-protocol.pac ssl-protocol.pac ssl-defs.pac bro_plugin_pac(ssl.pac ssl-dtls-analyzer.pac ssl-analyzer.pac ssl-dtls-protocol.pac ssl-protocol.pac ssl-defs.pac
proc-client-hello.pac proc-client-hello.pac

View file

@ -27,6 +27,8 @@
## .. bro:see:: ssl_alert ssl_established ssl_extension ssl_server_hello ## .. bro:see:: ssl_alert ssl_established ssl_extension ssl_server_hello
## ssl_session_ticket_handshake x509_certificate ssl_handshake_message ## ssl_session_ticket_handshake x509_certificate ssl_handshake_message
## ssl_change_cipher_spec ## ssl_change_cipher_spec
## ssl_dh_client_params ssl_ecdh_server_params ssl_ecdh_client_params
## ssl_rsa_client_pms
event ssl_client_hello%(c: connection, version: count, possible_ts: time, client_random: string, session_id: string, ciphers: index_vec%); event ssl_client_hello%(c: connection, version: count, possible_ts: time, client_random: string, session_id: string, ciphers: index_vec%);
## Generated for an SSL/TLS server's initial *hello* message. SSL/TLS sessions ## Generated for an SSL/TLS server's initial *hello* message. SSL/TLS sessions
@ -64,6 +66,8 @@ event ssl_client_hello%(c: connection, version: count, possible_ts: time, client
## .. bro:see:: ssl_alert ssl_client_hello ssl_established ssl_extension ## .. bro:see:: ssl_alert ssl_client_hello ssl_established ssl_extension
## ssl_session_ticket_handshake x509_certificate ssl_server_curve ## ssl_session_ticket_handshake x509_certificate ssl_server_curve
## ssl_dh_server_params ssl_handshake_message ssl_change_cipher_spec ## ssl_dh_server_params ssl_handshake_message ssl_change_cipher_spec
## ssl_dh_client_params ssl_ecdh_server_params ssl_ecdh_client_params
## ssl_rsa_client_pms
event ssl_server_hello%(c: connection, version: count, possible_ts: time, server_random: string, session_id: string, cipher: count, comp_method: count%); event ssl_server_hello%(c: connection, version: count, possible_ts: time, server_random: string, session_id: string, cipher: count, comp_method: count%);
## Generated for SSL/TLS extensions seen in an initial handshake. SSL/TLS ## Generated for SSL/TLS extensions seen in an initial handshake. SSL/TLS
@ -104,8 +108,9 @@ event ssl_extension%(c: connection, is_orig: bool, code: count, val: string%);
## ssl_session_ticket_handshake ssl_extension ## ssl_session_ticket_handshake ssl_extension
## ssl_extension_ec_point_formats ssl_extension_application_layer_protocol_negotiation ## ssl_extension_ec_point_formats ssl_extension_application_layer_protocol_negotiation
## ssl_extension_server_name ssl_server_curve ssl_extension_signature_algorithm ## ssl_extension_server_name ssl_server_curve ssl_extension_signature_algorithm
## ssl_extension_key_share ## ssl_extension_key_share ssl_rsa_client_pms ssl_server_signature
## ssl_extension_psk_key_exchange_modes ssl_extension_supported_versions ## ssl_extension_psk_key_exchange_modes ssl_extension_supported_versions
## ssl_dh_client_params ssl_ecdh_server_params ssl_ecdh_client_params
event ssl_extension_elliptic_curves%(c: connection, is_orig: bool, curves: index_vec%); event ssl_extension_elliptic_curves%(c: connection, is_orig: bool, curves: index_vec%);
## Generated for an SSL/TLS Supported Point Formats extension. This TLS extension ## Generated for an SSL/TLS Supported Point Formats extension. This TLS extension
@ -125,6 +130,8 @@ event ssl_extension_elliptic_curves%(c: connection, is_orig: bool, curves: index
## ssl_extension_server_name ssl_server_curve ssl_extension_signature_algorithm ## ssl_extension_server_name ssl_server_curve ssl_extension_signature_algorithm
## ssl_extension_key_share ## ssl_extension_key_share
## ssl_extension_psk_key_exchange_modes ssl_extension_supported_versions ## ssl_extension_psk_key_exchange_modes ssl_extension_supported_versions
## ssl_dh_client_params ssl_ecdh_server_params ssl_ecdh_client_params
## ssl_rsa_client_pms ssl_server_signature
event ssl_extension_ec_point_formats%(c: connection, is_orig: bool, point_formats: index_vec%); event ssl_extension_ec_point_formats%(c: connection, is_orig: bool, point_formats: index_vec%);
## Generated for an Signature Algorithms extension. This TLS extension ## Generated for an Signature Algorithms extension. This TLS extension
@ -143,6 +150,8 @@ event ssl_extension_ec_point_formats%(c: connection, is_orig: bool, point_format
## ssl_extension_elliptic_curves ssl_extension_application_layer_protocol_negotiation ## ssl_extension_elliptic_curves ssl_extension_application_layer_protocol_negotiation
## ssl_extension_server_name ssl_server_curve ssl_extension_key_share ## ssl_extension_server_name ssl_server_curve ssl_extension_key_share
## ssl_extension_psk_key_exchange_modes ssl_extension_supported_versions ## ssl_extension_psk_key_exchange_modes ssl_extension_supported_versions
## ssl_dh_client_params ssl_ecdh_server_params ssl_ecdh_client_params
## ssl_rsa_client_pms ssl_server_signature
event ssl_extension_signature_algorithm%(c: connection, is_orig: bool, signature_algorithms: signature_and_hashalgorithm_vec%); event ssl_extension_signature_algorithm%(c: connection, is_orig: bool, signature_algorithms: signature_and_hashalgorithm_vec%);
## Generated for a Key Share extension. This TLS extension is defined in TLS1.3-draft16 ## Generated for a Key Share extension. This TLS extension is defined in TLS1.3-draft16
@ -160,6 +169,8 @@ event ssl_extension_signature_algorithm%(c: connection, is_orig: bool, signature
## ssl_extension_elliptic_curves ssl_extension_application_layer_protocol_negotiation ## ssl_extension_elliptic_curves ssl_extension_application_layer_protocol_negotiation
## ssl_extension_server_name ssl_server_curve ## ssl_extension_server_name ssl_server_curve
## ssl_extension_psk_key_exchange_modes ssl_extension_supported_versions ## ssl_extension_psk_key_exchange_modes ssl_extension_supported_versions
## ssl_dh_client_params ssl_ecdh_server_params ssl_ecdh_client_params
## ssl_rsa_client_pms ssl_server_signature
event ssl_extension_key_share%(c: connection, is_orig: bool, curves: index_vec%); event ssl_extension_key_share%(c: connection, is_orig: bool, curves: index_vec%);
## Generated if a named curve is chosen by the server for an SSL/TLS connection. ## Generated if a named curve is chosen by the server for an SSL/TLS connection.
@ -170,15 +181,35 @@ event ssl_extension_key_share%(c: connection, is_orig: bool, curves: index_vec%)
## ##
## curve: The curve. ## curve: The curve.
## ##
## .. note:: This event is deprecated and superseded by the ssl_ecdh_server_params
## event. This event will be removed in a future version of Bro.
##
## .. bro:see:: ssl_alert ssl_client_hello ssl_established ssl_server_hello ## .. bro:see:: ssl_alert ssl_client_hello ssl_established ssl_server_hello
## ssl_session_ticket_handshake ssl_extension ## ssl_session_ticket_handshake ssl_extension
## ssl_extension_elliptic_curves ssl_extension_application_layer_protocol_negotiation ## ssl_extension_elliptic_curves ssl_extension_application_layer_protocol_negotiation
## ssl_extension_server_name ssl_extension_key_share ## ssl_extension_server_name ssl_extension_key_share
## ssl_extension_psk_key_exchange_modes ssl_extension_supported_versions ## ssl_extension_psk_key_exchange_modes ssl_extension_supported_versions
event ssl_server_curve%(c: connection, curve: count%); ## ssl_dh_client_params ssl_ecdh_server_params ssl_ecdh_client_params
## ssl_rsa_client_pms ssl_server_signature
event ssl_server_curve%(c: connection, curve: count%) &deprecated;
## Generated if a server uses an ECDH-anon or ECDHE cipher suite using a named curve
## This event contains the named curve name and the server ECDH parameters contained
## in the ServerKeyExchange message as defined in :rfc:`4492`.
##
## c: The connection.
##
## curve: The curve parameters.
##
## point: The server's ECDH public key.
##
## .. bro:see:: ssl_alert ssl_client_hello ssl_established ssl_server_hello
## ssl_session_ticket_handshake ssl_server_curve ssl_server_signature
## ssl_dh_client_params ssl_ecdh_client_params ssl_rsa_client_pms
event ssl_ecdh_server_params%(c: connection, curve: count, point: string%);
## Generated if a server uses a DH-anon or DHE cipher suite. This event contains ## Generated if a server uses a DH-anon or DHE cipher suite. This event contains
## the server DH parameters, which are sent in the ServerKeyExchange message as ## the server DH parameters, contained in the ServerKeyExchange message as
## defined in :rfc:`5246`. ## defined in :rfc:`5246`.
## ##
## c: The connection. ## c: The connection.
@ -190,15 +221,71 @@ event ssl_server_curve%(c: connection, curve: count%);
## Ys: The server's DH public key. ## Ys: The server's DH public key.
## ##
## .. bro:see:: ssl_alert ssl_client_hello ssl_established ssl_server_hello ## .. bro:see:: ssl_alert ssl_client_hello ssl_established ssl_server_hello
## ssl_session_ticket_handshake ssl_server_curve ## ssl_session_ticket_handshake ssl_server_curve ssl_server_signature
## ssl_dh_client_params ssl_ecdh_server_params ssl_ecdh_client_params
## ssl_rsa_client_pms
event ssl_dh_server_params%(c: connection, p: string, q: string, Ys: string%); event ssl_dh_server_params%(c: connection, p: string, q: string, Ys: string%);
## Generated if a server uses a non-anonymous DHE or ECDHE cipher suite. This event
## contains the server signature over the key exchange parameters contained in
## the ServerKeyExchange message as defined in :rfc:`4492` and :rfc:`5246`.
##
## c: The connection.
##
## signed_params: A hash of the server params, with the signature appropriate to
## that hash applied. The private key corresponding to the certified
## public key in the server's certificate message is used for signing.
##
## .. bro:see:: ssl_alert ssl_client_hello ssl_established ssl_server_hello
## ssl_session_ticket_handshake ssl_server_curve ssl_rsa_client_pms
## ssl_dh_client_params ssl_ecdh_server_params ssl_ecdh_client_params
event ssl_server_signature%(c: connection, signed_params: string%);
## Generated if a client uses an ECDH-anon or ECDHE cipher suite. This event
## contains the client ECDH public value contained in the ClientKeyExchange
## message as defined in :rfc:`4492`.
##
## c: The connection.
##
## point: The client's ECDH public key.
##
## .. bro:see:: ssl_alert ssl_client_hello ssl_established ssl_server_hello
## ssl_session_ticket_handshake ssl_server_curve ssl_server_signature
## ssl_dh_client_params ssl_ecdh_server_params ssl_rsa_client_pms
event ssl_ecdh_client_params%(c: connection, point: string%);
## Generated if a client uses a DH-anon or DHE cipher suite. This event contains
## the client DH parameters contained in the ClientKeyExchange message as
## defined in :rfc:`5246`.
##
## c: The connection.
##
## Yc: The client's DH public key.
##
## .. bro:see:: ssl_alert ssl_client_hello ssl_established ssl_server_hello
## ssl_session_ticket_handshake ssl_server_curve ssl_server_signature
## ssl_ecdh_server_params ssl_ecdh_client_params ssl_rsa_client_pms
event ssl_dh_client_params%(c: connection, Yc: string%);
## Generated if a client uses RSA key exchange. This event contains the client
## encrypted pre-master secret which is encrypted using the public key of the
## server's certificate as defined in :rfc:`5246`.
##
## c: The connection.
##
## pms: The encrypted pre-master secret.
##
## .. bro:see:: ssl_alert ssl_client_hello ssl_established ssl_server_hello
## ssl_session_ticket_handshake ssl_server_curve ssl_server_signature
## ssl_dh_client_params ssl_ecdh_server_params ssl_ecdh_client_params
event ssl_rsa_client_pms%(c: connection, pms: string%);
## Generated for an SSL/TLS Application-Layer Protocol Negotiation extension. ## Generated for an SSL/TLS Application-Layer Protocol Negotiation extension.
## This TLS extension is defined in draft-ietf-tls-applayerprotoneg and sent in ## This TLS extension is defined in draft-ietf-tls-applayerprotoneg and sent in
## the initial handshake. It contains the list of client supported application ## the initial handshake. It contains the list of client supported application
## protocols by the client or the server, respectively. ## protocols by the client or the server, respectively.
## ##
## At the moment it is mostly used to negotiate the use of SPDY / HTTP2-drafts. ## At the moment it is mostly used to negotiate the use of SPDY / HTTP2.
## ##
## c: The connection. ## c: The connection.
## ##
@ -211,6 +298,7 @@ event ssl_dh_server_params%(c: connection, p: string, q: string, Ys: string%);
## ssl_extension_elliptic_curves ssl_extension_ec_point_formats ## ssl_extension_elliptic_curves ssl_extension_ec_point_formats
## ssl_extension_server_name ssl_extension_key_share ## ssl_extension_server_name ssl_extension_key_share
## ssl_extension_psk_key_exchange_modes ssl_extension_supported_versions ## ssl_extension_psk_key_exchange_modes ssl_extension_supported_versions
## ssl_extension_signed_certificate_timestamp
event ssl_extension_application_layer_protocol_negotiation%(c: connection, is_orig: bool, protocols: string_vec%); event ssl_extension_application_layer_protocol_negotiation%(c: connection, is_orig: bool, protocols: string_vec%);
## Generated for an SSL/TLS Server Name extension. This SSL/TLS extension is ## Generated for an SSL/TLS Server Name extension. This SSL/TLS extension is
@ -231,8 +319,39 @@ event ssl_extension_application_layer_protocol_negotiation%(c: connection, is_or
## ssl_extension_application_layer_protocol_negotiation ## ssl_extension_application_layer_protocol_negotiation
## ssl_extension_key_share ## ssl_extension_key_share
## ssl_extension_psk_key_exchange_modes ssl_extension_supported_versions ## ssl_extension_psk_key_exchange_modes ssl_extension_supported_versions
## ssl_extension_signed_certificate_timestamp
event ssl_extension_server_name%(c: connection, is_orig: bool, names: string_vec%); event ssl_extension_server_name%(c: connection, is_orig: bool, names: string_vec%);
## Generated for the signed_certificate_timestamp TLS extension as defined in
## :rfc:`6962`. The extension is used to transmit signed proofs that are
## used for Certificate Transparency.
##
## c: The connection.
##
## is_orig: True if event is raised for originator side of the connection.
##
## version: the version of the protocol to which the SCT conforms. Always
## should be 0 (representing version 1)
##
## logid: 32 bit key id
##
## timestamp: the NTP Time when the entry was logged measured since
## the epoch, ignoring leap seconds, in milliseconds.
##
## signature_and_hashalgorithm: signature and hash algorithm used for the
## digitally_signed struct
##
## signature: signature part of the digitally_signed struct
##
## .. bro:see:: ssl_alert ssl_client_hello ssl_established ssl_server_hello
## ssl_session_ticket_handshake ssl_extension
## ssl_extension_elliptic_curves ssl_extension_ec_point_formats
## ssl_extension_server_name ssl_extension_key_share
## ssl_extension_psk_key_exchange_modes ssl_extension_supported_versions
## ssl_extension_application_layer_protocol_negotiation
## x509_ocsp_ext_signed_certificate_timestamp sct_verify
event ssl_extension_signed_certificate_timestamp%(c: connection, is_orig: bool, version: count, logid: string, timestamp: count, signature_and_hashalgorithm: SSL::SignatureAndHashAlgorithm, signature: string%);
## Generated for an TLS Supported Versions extension. This TLS extension ## Generated for an TLS Supported Versions extension. This TLS extension
## is defined in the TLS 1.3 rfc and sent by the client in the initial handshake. ## is defined in the TLS 1.3 rfc and sent by the client in the initial handshake.
## It contains the TLS versions that it supports. This informaion can be used by ## It contains the TLS versions that it supports. This informaion can be used by
@ -249,7 +368,7 @@ event ssl_extension_server_name%(c: connection, is_orig: bool, names: string_vec
## ssl_extension_elliptic_curves ssl_extension_ec_point_formats ## ssl_extension_elliptic_curves ssl_extension_ec_point_formats
## ssl_extension_application_layer_protocol_negotiation ## ssl_extension_application_layer_protocol_negotiation
## ssl_extension_key_share ssl_extension_server_name ## ssl_extension_key_share ssl_extension_server_name
## ssl_extension_psk_key_exchange_modes ## ssl_extension_psk_key_exchange_modes ssl_extension_signed_certificate_timestamp
event ssl_extension_supported_versions%(c: connection, is_orig: bool, versions: index_vec%); event ssl_extension_supported_versions%(c: connection, is_orig: bool, versions: index_vec%);
## Generated for an TLS Pre-Shared Key Exchange Modes extension. This TLS extension is defined ## Generated for an TLS Pre-Shared Key Exchange Modes extension. This TLS extension is defined
@ -266,7 +385,7 @@ event ssl_extension_supported_versions%(c: connection, is_orig: bool, versions:
## ssl_extension_elliptic_curves ssl_extension_ec_point_formats ## ssl_extension_elliptic_curves ssl_extension_ec_point_formats
## ssl_extension_application_layer_protocol_negotiation ## ssl_extension_application_layer_protocol_negotiation
## ssl_extension_key_share ssl_extension_server_name ## ssl_extension_key_share ssl_extension_server_name
## ssl_extension_supported_versions ## ssl_extension_supported_versions ssl_extension_signed_certificate_timestamp
event ssl_extension_psk_key_exchange_modes%(c: connection, is_orig: bool, modes: index_vec%); event ssl_extension_psk_key_exchange_modes%(c: connection, is_orig: bool, modes: index_vec%);
## Generated at the end of an SSL/TLS handshake. SSL/TLS sessions start with ## Generated at the end of an SSL/TLS handshake. SSL/TLS sessions start with

View file

@ -1,6 +1,7 @@
%%{ %%{
#include "analyzer/protocol/ssl/SSL.h" #include "analyzer/protocol/ssl/SSL.h"
#include <openssl/x509.h>
%%} %%}
## Sets if the SSL analyzer should consider the connection established (handshake ## Sets if the SSL analyzer should consider the connection established (handshake

View file

@ -9,6 +9,9 @@
common.AddRaw(is_orig ? "T" : "F", 1); common.AddRaw(is_orig ? "T" : "F", 1);
bro_analyzer()->Conn()->IDString(&common); bro_analyzer()->Conn()->IDString(&common);
static const string user_mime = "application/x-x509-user-cert";
static const string ca_mime = "application/x-x509-ca-cert";
for ( unsigned int i = 0; i < certificates->size(); ++i ) for ( unsigned int i = 0; i < certificates->size(); ++i )
{ {
const bytestring& cert = (*certificates)[i]; const bytestring& cert = (*certificates)[i];
@ -21,7 +24,7 @@
file_mgr->DataIn(reinterpret_cast<const u_char*>(cert.data()), file_mgr->DataIn(reinterpret_cast<const u_char*>(cert.data()),
cert.length(), bro_analyzer()->GetAnalyzerTag(), cert.length(), bro_analyzer()->GetAnalyzerTag(),
bro_analyzer()->Conn(), is_orig, file_id); bro_analyzer()->Conn(), is_orig, file_id, i == 0 ? user_mime : ca_mime);
file_mgr->EndOfFile(file_id); file_mgr->EndOfFile(file_id);
} }
return true; return true;

View file

@ -243,27 +243,116 @@ refine connection Handshake_Conn += {
function proc_certificate_status(rec : HandshakeRecord, status_type: uint8, response: bytestring) : bool function proc_certificate_status(rec : HandshakeRecord, status_type: uint8, response: bytestring) : bool
%{ %{
ODesc common;
common.AddRaw("Analyzer::ANALYZER_SSL");
common.Add(bro_analyzer()->Conn()->StartTime());
common.AddRaw("F");
bro_analyzer()->Conn()->IDString(&common);
if ( status_type == 1 ) // ocsp if ( status_type == 1 ) // ocsp
{ {
ODesc file_handle;
file_handle.Add(common.Description());
file_handle.Add("ocsp");
string file_id = file_mgr->HashHandle(file_handle.Description());
file_mgr->DataIn(reinterpret_cast<const u_char*>(response.data()),
response.length(), bro_analyzer()->GetAnalyzerTag(),
bro_analyzer()->Conn(), false, file_id, "application/ocsp-response");
BifEvent::generate_ssl_stapled_ocsp(bro_analyzer(), BifEvent::generate_ssl_stapled_ocsp(bro_analyzer(),
bro_analyzer()->Conn(), ${rec.is_orig}, bro_analyzer()->Conn(), ${rec.is_orig},
new StringVal(response.length(), new StringVal(response.length(),
(const char*) response.data())); (const char*) response.data()));
file_mgr->EndOfFile(file_id);
} }
return true; return true;
%} %}
function proc_ec_server_key_exchange(rec: HandshakeRecord, curve_type: uint8, curve: uint16) : bool function proc_ecdhe_server_key_exchange(kex: EcdheServerKeyExchange) : bool
%{ %{
if ( curve_type == NAMED_CURVE ) if ( ${kex.curve_type} != NAMED_CURVE )
return true;
BifEvent::generate_ssl_server_curve(bro_analyzer(), BifEvent::generate_ssl_server_curve(bro_analyzer(),
bro_analyzer()->Conn(), curve); bro_analyzer()->Conn(), ${kex.params.curve});
BifEvent::generate_ssl_ecdh_server_params(bro_analyzer(),
bro_analyzer()->Conn(), ${kex.params.curve}, new StringVal(${kex.params.point}.length(), (const char*)${kex.params.point}.data()));
BifEvent::generate_ssl_server_signature(bro_analyzer(),
bro_analyzer()->Conn(), new StringVal(${kex.params.signed_params}.length(), (const char*)${kex.params.signed_params}.data()));
return true; return true;
%} %}
function proc_dh_server_key_exchange(rec: HandshakeRecord, p: bytestring, g: bytestring, Ys: bytestring) : bool function proc_ecdh_anon_server_key_exchange(kex: EcdhAnonServerKeyExchange) : bool
%{
if ( ${kex.curve_type} != NAMED_CURVE )
return true;
BifEvent::generate_ssl_server_curve(bro_analyzer(),
bro_analyzer()->Conn(), ${kex.params.curve});
BifEvent::generate_ssl_ecdh_server_params(bro_analyzer(),
bro_analyzer()->Conn(), ${kex.params.curve}, new StringVal(${kex.params.point}.length(), (const char*)${kex.params.point}.data()));
return true;
%}
function proc_rsa_client_key_exchange(rec: HandshakeRecord, rsa_pms: bytestring) : bool
%{
BifEvent::generate_ssl_rsa_client_pms(bro_analyzer(), bro_analyzer()->Conn(), new StringVal(rsa_pms.length(), (const char*)rsa_pms.data()));
return true;
%}
function proc_dh_client_key_exchange(rec: HandshakeRecord, Yc: bytestring) : bool
%{
BifEvent::generate_ssl_dh_client_params(bro_analyzer(), bro_analyzer()->Conn(), new StringVal(Yc.length(), (const char*)Yc.data()));
return true;
%}
function proc_ecdh_client_key_exchange(rec: HandshakeRecord, point: bytestring) : bool
%{
BifEvent::generate_ssl_ecdh_client_params(bro_analyzer(), bro_analyzer()->Conn(), new StringVal(point.length(), (const char*)point.data()));
return true;
%}
function proc_signedcertificatetimestamp(rec: HandshakeRecord, version: uint8, logid: const_bytestring, timestamp: uint64, digitally_signed_algorithms: SignatureAndHashAlgorithm, digitally_signed_signature: const_bytestring) : bool
%{
RecordVal* ha = new RecordVal(BifType::Record::SSL::SignatureAndHashAlgorithm);
ha->Assign(0, new Val(digitally_signed_algorithms->HashAlgorithm(), TYPE_COUNT));
ha->Assign(1, new Val(digitally_signed_algorithms->SignatureAlgorithm(), TYPE_COUNT));
BifEvent::generate_ssl_extension_signed_certificate_timestamp(bro_analyzer(),
bro_analyzer()->Conn(), ${rec.is_orig},
version,
new StringVal(logid.length(), reinterpret_cast<const char*>(logid.begin())),
timestamp,
ha,
new StringVal(digitally_signed_signature.length(), reinterpret_cast<const char*>(digitally_signed_signature.begin()))
);
return true;
%}
function proc_dhe_server_key_exchange(rec: HandshakeRecord, p: bytestring, g: bytestring, Ys: bytestring, signed_params: bytestring) : bool
%{
BifEvent::generate_ssl_dh_server_params(bro_analyzer(),
bro_analyzer()->Conn(),
new StringVal(p.length(), (const char*) p.data()),
new StringVal(g.length(), (const char*) g.data()),
new StringVal(Ys.length(), (const char*) Ys.data())
);
BifEvent::generate_ssl_server_signature(bro_analyzer(),
bro_analyzer()->Conn(),
new StringVal(signed_params.length(), (const char*) signed_params.data())
);
return true;
%}
function proc_dh_anon_server_key_exchange(rec: HandshakeRecord, p: bytestring, g: bytestring, Ys: bytestring) : bool
%{ %{
BifEvent::generate_ssl_dh_server_params(bro_analyzer(), BifEvent::generate_ssl_dh_server_params(bro_analyzer(),
bro_analyzer()->Conn(), bro_analyzer()->Conn(),
@ -283,7 +372,6 @@ refine connection Handshake_Conn += {
return true; return true;
%} %}
}; };
refine typeattr ClientHello += &let { refine typeattr ClientHello += &let {
@ -353,12 +441,32 @@ refine typeattr CertificateStatus += &let {
proc : bool = $context.connection.proc_certificate_status(rec, status_type, response); proc : bool = $context.connection.proc_certificate_status(rec, status_type, response);
}; };
refine typeattr EcServerKeyExchange += &let { refine typeattr EcdheServerKeyExchange += &let {
proc : bool = $context.connection.proc_ec_server_key_exchange(rec, curve_type, curve); proc : bool = $context.connection.proc_ecdhe_server_key_exchange(this);
}; };
refine typeattr DhServerKeyExchange += &let { refine typeattr EcdhAnonServerKeyExchange += &let {
proc : bool = $context.connection.proc_dh_server_key_exchange(rec, dh_p, dh_g, dh_Ys); proc : bool = $context.connection.proc_ecdh_anon_server_key_exchange(this);
};
refine typeattr DheServerKeyExchange += &let {
proc : bool = $context.connection.proc_dhe_server_key_exchange(rec, dh_p, dh_g, dh_Ys, signed_params);
};
refine typeattr DhAnonServerKeyExchange += &let {
proc : bool = $context.connection.proc_dh_anon_server_key_exchange(rec, dh_p, dh_g, dh_Ys);
};
refine typeattr RsaClientKeyExchange += &let {
proc : bool = $context.connection.proc_rsa_client_key_exchange(rec, rsa_pms);
};
refine typeattr DhClientKeyExchange += &let {
proc : bool = $context.connection.proc_dh_client_key_exchange(rec, dh_Yc);
};
refine typeattr EcdhClientKeyExchange += &let {
proc : bool = $context.connection.proc_ecdh_client_key_exchange(rec, point);
}; };
refine typeattr SupportedVersions += &let { refine typeattr SupportedVersions += &let {
@ -373,3 +481,6 @@ refine typeattr Handshake += &let {
proc : bool = $context.connection.proc_handshake(rec.is_orig, rec.msg_type, rec.msg_length); proc : bool = $context.connection.proc_handshake(rec.is_orig, rec.msg_type, rec.msg_length);
}; };
refine typeattr SignedCertificateTimestamp += &let {
proc : bool = $context.connection.proc_signedcertificatetimestamp(rec, version, logid, timestamp, digitally_signed_algorithms, digitally_signed_signature);
};

View file

@ -176,13 +176,333 @@ type CertificateStatus(rec: HandshakeRecord) = record {
# V3 Server Key Exchange Message (7.4.3.) # V3 Server Key Exchange Message (7.4.3.)
###################################################################### ######################################################################
# Usually, the server key exchange does not contain any information # The server key exchange contains the server public key exchange values, and a
# that we are interested in. # signature over those values for non-anonymous exchanges. The server key
# # exchange messages is only sent for ECDHE, ECDH-anon, DHE, and DH-anon cipher
# The exception is when we are using an ECDHE, DHE or DH-Anon suite. # suites.
# In this case, we can extract information about the chosen cipher from
# here.
type ServerKeyExchange(rec: HandshakeRecord) = case $context.connection.chosen_cipher() of { type ServerKeyExchange(rec: HandshakeRecord) = case $context.connection.chosen_cipher() of {
# ECDHE suites
TLS_ECDHE_ECDSA_WITH_NULL_SHA,
TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,
TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA,
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
TLS_ECDHE_RSA_WITH_NULL_SHA,
TLS_ECDHE_RSA_WITH_RC4_128_SHA,
TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384,
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,
TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
TLS_ECDHE_PSK_WITH_RC4_128_SHA,
TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA,
TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA,
TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA,
TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256,
TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384,
TLS_ECDHE_PSK_WITH_NULL_SHA,
TLS_ECDHE_PSK_WITH_NULL_SHA256,
TLS_ECDHE_PSK_WITH_NULL_SHA384,
TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256,
TLS_ECDHE_ECDSA_WITH_ARIA_256_CBC_SHA384,
TLS_ECDHE_RSA_WITH_ARIA_128_CBC_SHA256,
TLS_ECDHE_RSA_WITH_ARIA_256_CBC_SHA384,
TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256,
TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384,
TLS_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256,
TLS_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384,
TLS_ECDHE_PSK_WITH_ARIA_128_CBC_SHA256,
TLS_ECDHE_PSK_WITH_ARIA_256_CBC_SHA384,
TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256,
TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384,
TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256,
TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384,
TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256,
TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384,
TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256,
TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384,
TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256,
TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384,
TLS_ECDHE_ECDSA_WITH_AES_128_CCM,
TLS_ECDHE_ECDSA_WITH_AES_256_CCM,
TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8,
TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8,
TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
-> ecdhe_server_key_exchange : EcdheServerKeyExchange(rec);
# ECDH-anon suites
TLS_ECDH_ANON_WITH_NULL_SHA,
TLS_ECDH_ANON_WITH_RC4_128_SHA,
TLS_ECDH_ANON_WITH_3DES_EDE_CBC_SHA,
TLS_ECDH_ANON_WITH_AES_128_CBC_SHA,
TLS_ECDH_ANON_WITH_AES_256_CBC_SHA
# ECDH non-anon suites do not send a ServerKeyExchange
-> ecdh_anon_server_key_exchange : EcdhAnonServerKeyExchange(rec);
# DHE suites
TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA,
TLS_DHE_DSS_WITH_DES_CBC_SHA,
TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA,
TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA,
TLS_DHE_RSA_WITH_DES_CBC_SHA,
TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA,
TLS_DHE_DSS_WITH_AES_128_CBC_SHA,
TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
TLS_DHE_DSS_WITH_AES_256_CBC_SHA,
TLS_DHE_RSA_WITH_AES_256_CBC_SHA,
TLS_DHE_DSS_WITH_AES_128_CBC_SHA256,
TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA,
TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA,
TLS_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA,
TLS_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA,
TLS_DHE_DSS_WITH_RC4_128_SHA,
TLS_DHE_RSA_WITH_AES_128_CBC_SHA256,
TLS_DHE_DSS_WITH_AES_256_CBC_SHA256,
TLS_DHE_RSA_WITH_AES_256_CBC_SHA256,
TLS_DHE_DSS_WITH_3DES_EDE_CBC_RMD,
TLS_DHE_DSS_WITH_AES_128_CBC_RMD,
TLS_DHE_DSS_WITH_AES_256_CBC_RMD,
TLS_DHE_RSA_WITH_3DES_EDE_CBC_RMD,
TLS_DHE_RSA_WITH_AES_128_CBC_RMD,
TLS_DHE_RSA_WITH_AES_256_CBC_RMD,
TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA,
TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA,
TLS_DHE_PSK_WITH_RC4_128_SHA,
TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA,
TLS_DHE_PSK_WITH_AES_128_CBC_SHA,
TLS_DHE_PSK_WITH_AES_256_CBC_SHA,
TLS_DHE_DSS_WITH_SEED_CBC_SHA,
TLS_DHE_RSA_WITH_SEED_CBC_SHA,
TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,
TLS_DHE_RSA_WITH_AES_256_GCM_SHA384,
TLS_DHE_DSS_WITH_AES_128_GCM_SHA256,
TLS_DHE_DSS_WITH_AES_256_GCM_SHA384,
TLS_DHE_PSK_WITH_AES_128_GCM_SHA256,
TLS_DHE_PSK_WITH_AES_256_GCM_SHA384,
TLS_DHE_PSK_WITH_AES_128_CBC_SHA256,
TLS_DHE_PSK_WITH_AES_256_CBC_SHA384,
TLS_DHE_PSK_WITH_NULL_SHA256,
TLS_DHE_PSK_WITH_NULL_SHA384,
TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256,
TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256,
TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256,
TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256,
TLS_DHE_DSS_WITH_ARIA_128_CBC_SHA256,
TLS_DHE_DSS_WITH_ARIA_256_CBC_SHA384,
TLS_DHE_RSA_WITH_ARIA_128_CBC_SHA256,
TLS_DHE_RSA_WITH_ARIA_256_CBC_SHA384,
TLS_DHE_RSA_WITH_ARIA_128_GCM_SHA256,
TLS_DHE_RSA_WITH_ARIA_256_GCM_SHA384,
TLS_DHE_DSS_WITH_ARIA_128_GCM_SHA256,
TLS_DHE_DSS_WITH_ARIA_256_GCM_SHA384,
TLS_DHE_PSK_WITH_ARIA_128_CBC_SHA256,
TLS_DHE_PSK_WITH_ARIA_256_CBC_SHA384,
TLS_DHE_PSK_WITH_ARIA_128_GCM_SHA256,
TLS_DHE_PSK_WITH_ARIA_256_GCM_SHA384,
TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256,
TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384,
TLS_DHE_DSS_WITH_CAMELLIA_128_GCM_SHA256,
TLS_DHE_DSS_WITH_CAMELLIA_256_GCM_SHA384,
TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256,
TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384,
TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256,
TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384,
TLS_DHE_RSA_WITH_AES_128_CCM,
TLS_DHE_RSA_WITH_AES_256_CCM,
TLS_DHE_RSA_WITH_AES_128_CCM_8,
TLS_DHE_RSA_WITH_AES_256_CCM_8,
TLS_DHE_PSK_WITH_AES_128_CCM,
TLS_DHE_PSK_WITH_AES_256_CCM,
TLS_PSK_DHE_WITH_AES_128_CCM_8,
TLS_PSK_DHE_WITH_AES_256_CCM_8,
TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256
-> dhe_server_key_exchange : DheServerKeyExchange(rec);
# DH-anon suites
TLS_DH_ANON_EXPORT_WITH_RC4_40_MD5,
TLS_DH_ANON_WITH_RC4_128_MD5,
TLS_DH_ANON_EXPORT_WITH_DES40_CBC_SHA,
TLS_DH_ANON_WITH_DES_CBC_SHA,
TLS_DH_ANON_WITH_3DES_EDE_CBC_SHA,
TLS_DH_ANON_WITH_AES_128_CBC_SHA,
TLS_DH_ANON_WITH_AES_256_CBC_SHA,
TLS_DH_ANON_WITH_CAMELLIA_128_CBC_SHA,
TLS_DH_ANON_WITH_AES_128_CBC_SHA256,
TLS_DH_ANON_WITH_AES_256_CBC_SHA256,
TLS_DH_ANON_WITH_CAMELLIA_256_CBC_SHA,
TLS_DH_ANON_WITH_SEED_CBC_SHA,
TLS_DH_ANON_WITH_AES_128_GCM_SHA256,
TLS_DH_ANON_WITH_AES_256_GCM_SHA384,
TLS_DH_ANON_WITH_CAMELLIA_128_CBC_SHA256,
TLS_DH_ANON_WITH_CAMELLIA_256_CBC_SHA256,
TLS_DH_ANON_WITH_ARIA_128_CBC_SHA256,
TLS_DH_ANON_WITH_ARIA_256_CBC_SHA384,
TLS_DH_ANON_WITH_ARIA_128_GCM_SHA256,
TLS_DH_ANON_WITH_ARIA_256_GCM_SHA384,
TLS_DH_ANON_WITH_CAMELLIA_128_GCM_SHA256,
TLS_DH_ANON_WITH_CAMELLIA_256_GCM_SHA384
# DH non-anon suites do not send a ServerKeyExchange
-> dh_anon_server_key_exchange : DhAnonServerKeyExchange(rec);
default
-> key : bytestring &restofdata &transient;
};
# Parse an ECDHE ServerKeyExchange message, which contains a signature over the
# parameters. Parsing explicit curve parameters from the server is not
# currently supported.
type EcdheServerKeyExchange(rec: HandshakeRecord) = record {
curve_type: uint8;
named_curve: case curve_type of {
NAMED_CURVE -> params: ServerEDCHParamsAndSignature;
default -> data: bytestring &restofdata &transient;
};
};
# Parse an ECDH-anon ServerKeyExchange message, which does not contain a
# signature over the parameters. Parsing explicit curve parameters from the
# server is not currently supported.
type EcdhAnonServerKeyExchange(rec: HandshakeRecord) = record {
curve_type: uint8;
named_curve: case curve_type of {
NAMED_CURVE -> params: ServerEDCHParamsAndSignature;
default -> data: bytestring &restofdata &transient;
};
};
type ServerEDCHParamsAndSignature() = record {
curve: uint16;
point_length: uint8;
point: bytestring &length=point_length;
signed_params: bytestring &restofdata; # only present in case of non-anon message
};
# Parse a DHE ServerKeyExchange message, which contains a signature over the
# parameters.
type DheServerKeyExchange(rec: HandshakeRecord) = record {
dh_p_length: uint16;
dh_p: bytestring &length=dh_p_length;
dh_g_length: uint16;
dh_g: bytestring &length=dh_g_length;
dh_Ys_length: uint16;
dh_Ys: bytestring &length=dh_Ys_length;
signed_params: bytestring &restofdata;
};
# Parse a DH-anon ServerKeyExchange message, which does not contain a
# signature over the parameters.
type DhAnonServerKeyExchange(rec: HandshakeRecord) = record {
dh_p_length: uint16;
dh_p: bytestring &length=dh_p_length;
dh_g_length: uint16;
dh_g: bytestring &length=dh_g_length;
dh_Ys_length: uint16;
dh_Ys: bytestring &length=dh_Ys_length;
data: bytestring &restofdata &transient;
};
######################################################################
# V3 Certificate Request (7.4.4.)
######################################################################
# For now, ignore Certificate Request Details; just eat up message.
type CertificateRequest(rec: HandshakeRecord) = record {
cont : bytestring &restofdata &transient;
};
######################################################################
# V3 Server Hello Done (7.4.5.)
######################################################################
# Server Hello Done is empty
type ServerHelloDone(rec: HandshakeRecord) = empty;
######################################################################
# V3 Client Certificate (7.4.6.)
######################################################################
# Client Certificate is identical to Server Certificate;
# no further definition here
######################################################################
# V3 Client Key Exchange Message (7.4.7.)
######################################################################
# Parse a ClientKeyExchange message. For RSA cipher suites, this consists of an
# encrypted pre-master secret. For DH, DH-anon, and DHE cipher suites, this
# consists of the client public finite-field Diffie-Hellman value. For ECDH,
# ECDH-anon, and ECDHE cipher suites, this consists of the client public
# elliptic curve point.
type ClientKeyExchange(rec: HandshakeRecord) = case $context.connection.chosen_cipher() of {
# RSA suites
TLS_RSA_WITH_NULL_MD5,
TLS_RSA_WITH_NULL_SHA,
TLS_RSA_EXPORT_WITH_RC4_40_MD5,
TLS_RSA_WITH_RC4_128_MD5,
TLS_RSA_WITH_RC4_128_SHA,
TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5,
TLS_RSA_WITH_IDEA_CBC_SHA,
TLS_RSA_EXPORT_WITH_DES40_CBC_SHA,
TLS_RSA_WITH_DES_CBC_SHA,
TLS_RSA_WITH_3DES_EDE_CBC_SHA,
TLS_RSA_WITH_AES_128_CBC_SHA,
TLS_RSA_WITH_AES_256_CBC_SHA,
TLS_RSA_WITH_NULL_SHA256,
TLS_RSA_WITH_AES_128_CBC_SHA256,
TLS_RSA_WITH_AES_256_CBC_SHA256,
TLS_RSA_WITH_CAMELLIA_128_CBC_SHA,
TLS_RSA_EXPORT1024_WITH_RC4_56_MD5,
TLS_RSA_EXPORT1024_WITH_RC2_CBC_56_MD5,
TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA,
TLS_RSA_EXPORT1024_WITH_RC4_56_SHA,
TLS_RSA_WITH_3DES_EDE_CBC_RMD,
TLS_RSA_WITH_AES_128_CBC_RMD,
TLS_RSA_WITH_AES_256_CBC_RMD,
TLS_RSA_WITH_CAMELLIA_256_CBC_SHA,
TLS_RSA_PSK_WITH_RC4_128_SHA,
TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA,
TLS_RSA_PSK_WITH_AES_128_CBC_SHA,
TLS_RSA_PSK_WITH_AES_256_CBC_SHA,
TLS_RSA_WITH_SEED_CBC_SHA,
TLS_RSA_WITH_AES_128_GCM_SHA256,
TLS_RSA_WITH_AES_256_GCM_SHA384,
TLS_RSA_PSK_WITH_AES_128_CBC_SHA256,
TLS_RSA_PSK_WITH_AES_256_CBC_SHA384,
TLS_RSA_PSK_WITH_NULL_SHA256,
TLS_RSA_PSK_WITH_NULL_SHA384,
TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256,
TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256,
TLS_RSA_WITH_ARIA_128_CBC_SHA256,
TLS_RSA_WITH_ARIA_256_CBC_SHA384,
TLS_RSA_WITH_ARIA_128_GCM_SHA256,
TLS_RSA_WITH_ARIA_256_GCM_SHA384,
TLS_RSA_PSK_WITH_ARIA_128_CBC_SHA256,
TLS_RSA_PSK_WITH_ARIA_256_CBC_SHA384,
TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256,
TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384,
TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256,
TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384,
TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256,
TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384,
TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256,
TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384,
TLS_RSA_WITH_AES_128_CCM,
TLS_RSA_WITH_AES_256_CCM,
TLS_RSA_WITH_AES_128_CCM_8,
TLS_RSA_WITH_AES_256_CCM_8
-> rsa_client_key_exchange: RsaClientKeyExchange(rec);
#ECHDE
TLS_ECDH_ECDSA_WITH_NULL_SHA, TLS_ECDH_ECDSA_WITH_NULL_SHA,
TLS_ECDH_ECDSA_WITH_RC4_128_SHA, TLS_ECDH_ECDSA_WITH_RC4_128_SHA,
TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA,
@ -275,7 +595,7 @@ type ServerKeyExchange(rec: HandshakeRecord) = case $context.connection.chosen_c
TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8, TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8,
TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
-> ec_server_key_exchange : EcServerKeyExchange(rec); -> ecdh_client_key_exchange : EcdhClientKeyExchange(rec);
# DHE suites # DHE suites
TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA, TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA,
@ -377,72 +697,24 @@ type ServerKeyExchange(rec: HandshakeRecord) = case $context.connection.chosen_c
TLS_DH_ANON_WITH_ARIA_256_GCM_SHA384, TLS_DH_ANON_WITH_ARIA_256_GCM_SHA384,
TLS_DH_ANON_WITH_CAMELLIA_128_GCM_SHA256, TLS_DH_ANON_WITH_CAMELLIA_128_GCM_SHA256,
TLS_DH_ANON_WITH_CAMELLIA_256_GCM_SHA384 TLS_DH_ANON_WITH_CAMELLIA_256_GCM_SHA384
# DH non-anon suites do not send a ServerKeyExchange -> dh_server_key_exchange : DhClientKeyExchange(rec);
-> dh_server_key_exchange : DhServerKeyExchange(rec);
default default
-> key : bytestring &restofdata &transient; -> key : bytestring &restofdata &transient;
}; };
# For the moment, we really only are interested in the curve name. If it type RsaClientKeyExchange(rec: HandshakeRecord) = record {
# is not set (if the server sends explicit parameters), we do not bother. rsa_pms : bytestring &restofdata;
# We also do not parse the actual signature data following the named curve.
type EcServerKeyExchange(rec: HandshakeRecord) = record {
curve_type: uint8;
curve: uint16; # only if curve_type = 3 (NAMED_CURVE)
data: bytestring &restofdata &transient;
}; };
# For both, dh_anon and dhe the ServerKeyExchange starts with a ServerDHParams type DhClientKeyExchange(rec: HandshakeRecord) = record {
# structure. After that, they start to differ, but we do not care about that. dh_Yc : bytestring &restofdata;
type DhServerKeyExchange(rec: HandshakeRecord) = record {
dh_p_length: uint16;
dh_p: bytestring &length=dh_p_length;
dh_g_length: uint16;
dh_g: bytestring &length=dh_g_length;
dh_Ys_length: uint16;
dh_Ys: bytestring &length=dh_Ys_length;
data: bytestring &restofdata &transient;
}; };
type EcdhClientKeyExchange(rec: HandshakeRecord) = record {
###################################################################### point : bytestring &restofdata;
# V3 Certificate Request (7.4.4.)
######################################################################
# For now, ignore Certificate Request Details; just eat up message.
type CertificateRequest(rec: HandshakeRecord) = record {
cont : bytestring &restofdata &transient;
}; };
######################################################################
# V3 Server Hello Done (7.4.5.)
######################################################################
# Server Hello Done is empty
type ServerHelloDone(rec: HandshakeRecord) = empty;
######################################################################
# V3 Client Certificate (7.4.6.)
######################################################################
# Client Certificate is identical to Server Certificate;
# no further definition here
######################################################################
# V3 Client Key Exchange Message (7.4.7.)
######################################################################
# For now ignore details of ClientKeyExchange (most of it is
# encrypted anyway); just eat up message.
type ClientKeyExchange(rec: HandshakeRecord) = record {
key : bytestring &restofdata &transient;
};
###################################################################### ######################################################################
# V3 Certificate Verify (7.4.8.) # V3 Certificate Verify (7.4.8.)
###################################################################### ######################################################################
@ -485,13 +757,21 @@ type SSLExtension(rec: HandshakeRecord) = record {
# EXT_STATUS_REQUEST -> status_request: StatusRequest(rec)[] &until($element == 0 || $element != 0); # EXT_STATUS_REQUEST -> status_request: StatusRequest(rec)[] &until($element == 0 || $element != 0);
EXT_SERVER_NAME -> server_name: ServerNameExt(rec)[] &until($element == 0 || $element != 0); EXT_SERVER_NAME -> server_name: ServerNameExt(rec)[] &until($element == 0 || $element != 0);
EXT_SIGNATURE_ALGORITHMS -> signature_algorithm: SignatureAlgorithm(rec)[] &until($element == 0 || $element != 0); EXT_SIGNATURE_ALGORITHMS -> signature_algorithm: SignatureAlgorithm(rec)[] &until($element == 0 || $element != 0);
EXT_SIGNED_CERTIFICATE_TIMESTAMP -> certificate_timestamp: SignedCertificateTimestampList(rec)[] &until($element == 0 || $element != 0);
EXT_KEY_SHARE -> key_share: KeyShare(rec)[] &until($element == 0 || $element != 0); EXT_KEY_SHARE -> key_share: KeyShare(rec)[] &until($element == 0 || $element != 0);
EXT_SUPPORTED_VERSIONS -> supported_versions: SupportedVersions(rec)[] &until($element == 0 || $element != 0); EXT_SUPPORTED_VERSIONS -> supported_versions_selector: SupportedVersionsSelector(rec, data_len)[] &until($element == 0 || $element != 0);
EXT_PSK_KEY_EXCHANGE_MODES -> psk_key_exchange_modes: PSKKeyExchangeModes(rec)[] &until($element == 0 || $element != 0); EXT_PSK_KEY_EXCHANGE_MODES -> psk_key_exchange_modes: PSKKeyExchangeModes(rec)[] &until($element == 0 || $element != 0);
default -> data: bytestring &restofdata; default -> data: bytestring &restofdata;
}; };
} &length=data_len+4 &exportsourcedata; } &length=data_len+4 &exportsourcedata;
%include tls-handshake-signed_certificate_timestamp.pac
type SupportedVersionsSelector(rec: HandshakeRecord, data_len: uint16) = case rec.is_orig of {
true -> a: SupportedVersions(rec);
false -> b: bytestring &length=data_len &transient;
}
type SupportedVersions(rec: HandshakeRecord) = record { type SupportedVersions(rec: HandshakeRecord) = record {
length: uint8; length: uint8;
versions: uint16[] &until($input.length() == 0); versions: uint16[] &until($input.length() == 0);
@ -563,11 +843,6 @@ type KeyShare(rec: HandshakeRecord) = case rec.msg_type of {
default -> other : bytestring &restofdata &transient; default -> other : bytestring &restofdata &transient;
}; };
type SignatureAndHashAlgorithm() = record {
HashAlgorithm: uint8;
SignatureAlgorithm: uint8;
}
type SignatureAlgorithm(rec: HandshakeRecord) = record { type SignatureAlgorithm(rec: HandshakeRecord) = record {
length: uint16; length: uint16;
supported_signature_algorithms: SignatureAndHashAlgorithm[] &until($input.length() == 0); supported_signature_algorithms: SignatureAndHashAlgorithm[] &until($input.length() == 0);

View file

@ -0,0 +1,28 @@
# We keep this extension separate, because it also can be included in X.509 certificates.
# If included there, it uses the exact same syntax and we just symlink it from the X.509
# file analyzer tree.
type SignatureAndHashAlgorithm() = record {
HashAlgorithm: uint8;
SignatureAlgorithm: uint8;
}
type SignedCertificateTimestampList(rec: HandshakeRecord) = record {
length: uint16;
SCTs: SignedCertificateTimestamp(rec)[] &until($input.length() == 0);
} &length=length+2;
type SignedCertificateTimestamp(rec: HandshakeRecord) = record {
# before - framing
length: uint16;
# from here: SignedCertificateTimestamp
version: uint8;
logid: bytestring &length=32;
timestamp: uint64;
extensions_length: uint16; # extensions are not actually defined yet, so we cannot parse them
extensions: bytestring &length=extensions_length;
digitally_signed_algorithms: SignatureAndHashAlgorithm;
digitally_signed_signature_length: uint16;
digitally_signed_signature: bytestring &length=digitally_signed_signature_length;
} &length=length+2;

View file

@ -7,14 +7,14 @@
using namespace analyzer::tcp; using namespace analyzer::tcp;
ContentLine_Analyzer::ContentLine_Analyzer(Connection* conn, bool orig) ContentLine_Analyzer::ContentLine_Analyzer(Connection* conn, bool orig, int max_line_length)
: TCP_SupportAnalyzer("CONTENTLINE", conn, orig) : TCP_SupportAnalyzer("CONTENTLINE", conn, orig), max_line_length(max_line_length)
{ {
InitState(); InitState();
} }
ContentLine_Analyzer::ContentLine_Analyzer(const char* name, Connection* conn, bool orig) ContentLine_Analyzer::ContentLine_Analyzer(const char* name, Connection* conn, bool orig, int max_line_length)
: TCP_SupportAnalyzer(name, conn, orig) : TCP_SupportAnalyzer(name, conn, orig), max_line_length(max_line_length)
{ {
InitState(); InitState();
} }
@ -229,6 +229,12 @@ int ContentLine_Analyzer::DoDeliverOnce(int len, const u_char* data)
return seq_len; \ return seq_len; \
} }
if ( offset >= max_line_length )
{
Weird("contentline_size_exceeded");
EMIT_LINE
}
switch ( c ) { switch ( c ) {
case '\r': case '\r':
// Look ahead for '\n'. // Look ahead for '\n'.
@ -250,6 +256,16 @@ int ContentLine_Analyzer::DoDeliverOnce(int len, const u_char* data)
case '\n': case '\n':
if ( last_char == '\r' ) if ( last_char == '\r' )
{ {
// Weird corner-case:
// this can happen if we see a \r at the end of a packet where crlf is
// set to CR_as_EOL | LF_as_EOL, with the packet causing crlf to be set to
// 0 and the next packet beginning with a \n. In this case we just swallow
// the character and re-set last_char.
if ( offset == 0 )
{
last_char = c;
break;
}
--offset; // remove '\r' --offset; // remove '\r'
EMIT_LINE EMIT_LINE
} }

View file

@ -10,9 +10,12 @@ namespace analyzer { namespace tcp {
#define CR_as_EOL 1 #define CR_as_EOL 1
#define LF_as_EOL 2 #define LF_as_EOL 2
// Slightly smaller than 16MB so that the buffer is not unnecessarily resized to 32M.
#define DEFAULT_MAX_LINE_LENGTH 16 * 1024 * 1024 - 100
class ContentLine_Analyzer : public TCP_SupportAnalyzer { class ContentLine_Analyzer : public TCP_SupportAnalyzer {
public: public:
ContentLine_Analyzer(Connection* conn, bool orig); ContentLine_Analyzer(Connection* conn, bool orig, int max_line_length=DEFAULT_MAX_LINE_LENGTH);
~ContentLine_Analyzer(); ~ContentLine_Analyzer();
void SupressWeirds(bool enable) void SupressWeirds(bool enable)
@ -60,7 +63,7 @@ public:
{ return seq + length <= seq_to_skip; } { return seq + length <= seq_to_skip; }
protected: protected:
ContentLine_Analyzer(const char* name, Connection* conn, bool orig); ContentLine_Analyzer(const char* name, Connection* conn, bool orig, int max_line_length=DEFAULT_MAX_LINE_LENGTH);
virtual void DeliverStream(int len, const u_char* data, bool is_orig); virtual void DeliverStream(int len, const u_char* data, bool is_orig);
virtual void Undelivered(uint64 seq, int len, bool orig); virtual void Undelivered(uint64 seq, int len, bool orig);
@ -80,6 +83,7 @@ protected:
int offset; // where we are in buf int offset; // where we are in buf
int buf_len; // how big buf is, total int buf_len; // how big buf is, total
unsigned int last_char; // last (non-option) character scanned unsigned int last_char; // last (non-option) character scanned
int max_line_length; // how large of a line to accumulate before emitting and raising a weird
uint64_t seq; // last seq number uint64_t seq; // last seq number
uint64_t seq_to_skip; uint64_t seq_to_skip;

View file

@ -229,7 +229,7 @@ int TCP_Endpoint::DataSent(double t, uint64 seq, int len, int caplen,
if ( fwrite(data, 1, len, f) < unsigned(len) ) if ( fwrite(data, 1, len, f) < unsigned(len) )
{ {
char buf[256]; char buf[256];
strerror_r(errno, buf, sizeof(buf)); bro_strerror_r(errno, buf, sizeof(buf));
reporter->Error("TCP contents write failed: %s", buf); reporter->Error("TCP contents write failed: %s", buf);
if ( contents_file_write_failure ) if ( contents_file_write_failure )

View file

@ -38,18 +38,19 @@ TCP_Reassembler::TCP_Reassembler(analyzer::Analyzer* arg_dst_analyzer,
if ( ::tcp_contents ) if ( ::tcp_contents )
{ {
// Val dst_port_val(ntohs(Conn()->RespPort()), TYPE_PORT); auto dst_port_val = port_mgr->Get(ntohs(tcp_analyzer->Conn()->RespPort()),
PortVal dst_port_val(ntohs(tcp_analyzer->Conn()->RespPort()),
TRANSPORT_TCP); TRANSPORT_TCP);
TableVal* ports = IsOrig() ? TableVal* ports = IsOrig() ?
tcp_content_delivery_ports_orig : tcp_content_delivery_ports_orig :
tcp_content_delivery_ports_resp; tcp_content_delivery_ports_resp;
Val* result = ports->Lookup(&dst_port_val); Val* result = ports->Lookup(dst_port_val);
if ( (IsOrig() && tcp_content_deliver_all_orig) || if ( (IsOrig() && tcp_content_deliver_all_orig) ||
(! IsOrig() && tcp_content_deliver_all_resp) || (! IsOrig() && tcp_content_deliver_all_resp) ||
(result && result->AsBool()) ) (result && result->AsBool()) )
deliver_tcp_contents = 1; deliver_tcp_contents = 1;
Unref(dst_port_val);
} }
} }

View file

@ -130,7 +130,7 @@ RecordVal* TeredoEncapsulation::BuildVal(const IP_Hdr* inner) const
RecordVal* teredo_origin = new RecordVal(teredo_origin_type); RecordVal* teredo_origin = new RecordVal(teredo_origin_type);
uint16 port = ntohs(*((uint16*)(origin_indication + 2))) ^ 0xFFFF; uint16 port = ntohs(*((uint16*)(origin_indication + 2))) ^ 0xFFFF;
uint32 addr = ntohl(*((uint32*)(origin_indication + 4))) ^ 0xFFFFFFFF; uint32 addr = ntohl(*((uint32*)(origin_indication + 4))) ^ 0xFFFFFFFF;
teredo_origin->Assign(0, new PortVal(port, TRANSPORT_UDP)); teredo_origin->Assign(0, port_mgr->Get(port, TRANSPORT_UDP));
teredo_origin->Assign(1, new AddrVal(htonl(addr))); teredo_origin->Assign(1, new AddrVal(htonl(addr)));
teredo_hdr->Assign(1, teredo_origin); teredo_hdr->Assign(1, teredo_origin);
} }
@ -195,7 +195,7 @@ void Teredo_Analyzer::DeliverPacket(int len, const u_char* data, bool orig,
else else
{ {
delete inner; delete inner;
ProtocolViolation("Truncated Teredo", (const char*) data, len); ProtocolViolation("Truncated Teredo or invalid inner IP version", (const char*) data, len);
return; return;
} }

View file

@ -97,14 +97,14 @@ void UDP_Analyzer::DeliverPacket(int len, const u_char* data, bool is_orig,
if ( udp_contents ) if ( udp_contents )
{ {
PortVal port_val(ntohs(up->uh_dport), TRANSPORT_UDP); auto port_val = port_mgr->Get(ntohs(up->uh_dport), TRANSPORT_UDP);
Val* result = 0; Val* result = 0;
bool do_udp_contents = false; bool do_udp_contents = false;
if ( is_orig ) if ( is_orig )
{ {
result = udp_content_delivery_ports_orig->Lookup( result = udp_content_delivery_ports_orig->Lookup(
&port_val); port_val);
if ( udp_content_deliver_all_orig || if ( udp_content_deliver_all_orig ||
(result && result->AsBool()) ) (result && result->AsBool()) )
do_udp_contents = true; do_udp_contents = true;
@ -112,7 +112,7 @@ void UDP_Analyzer::DeliverPacket(int len, const u_char* data, bool is_orig,
else else
{ {
result = udp_content_delivery_ports_resp->Lookup( result = udp_content_delivery_ports_resp->Lookup(
&port_val); port_val);
if ( udp_content_deliver_all_resp || if ( udp_content_deliver_all_resp ||
(result && result->AsBool()) ) (result && result->AsBool()) )
do_udp_contents = true; do_udp_contents = true;
@ -126,6 +126,8 @@ void UDP_Analyzer::DeliverPacket(int len, const u_char* data, bool is_orig,
vl->append(new StringVal(len, (const char*) data)); vl->append(new StringVal(len, (const char*) data));
ConnectionEvent(udp_contents, vl); ConnectionEvent(udp_contents, vl);
} }
Unref(port_val);
} }
if ( is_orig ) if ( is_orig )

View file

@ -2270,7 +2270,7 @@ function port_to_count%(p: port%): count
## .. bro:see:: port_to_count ## .. bro:see:: port_to_count
function count_to_port%(num: count, proto: transport_proto%): port function count_to_port%(num: count, proto: transport_proto%): port
%{ %{
return new PortVal(num, (TransportProto)proto->AsEnum()); return port_mgr->Get(num, (TransportProto)proto->AsEnum());
%} %}
## Converts a :bro:type:`string` to an :bro:type:`addr`. ## Converts a :bro:type:`string` to an :bro:type:`addr`.
@ -2430,16 +2430,16 @@ function to_port%(s: string%): port
{ {
++slash; ++slash;
if ( streq(slash, "tcp") ) if ( streq(slash, "tcp") )
return new PortVal(port, TRANSPORT_TCP); return port_mgr->Get(port, TRANSPORT_TCP);
else if ( streq(slash, "udp") ) else if ( streq(slash, "udp") )
return new PortVal(port, TRANSPORT_UDP); return port_mgr->Get(port, TRANSPORT_UDP);
else if ( streq(slash, "icmp") ) else if ( streq(slash, "icmp") )
return new PortVal(port, TRANSPORT_ICMP); return port_mgr->Get(port, TRANSPORT_ICMP);
} }
} }
builtin_error("wrong port format, must be /[0-9]{1,5}\\/(tcp|udp|icmp)/"); builtin_error("wrong port format, must be /[0-9]{1,5}\\/(tcp|udp|icmp)/");
return new PortVal(port, TRANSPORT_UNKNOWN); return port_mgr->Get(port, TRANSPORT_UNKNOWN);
%} %}
## Converts a string of bytes (in network byte order) to a :bro:type:`double`. ## Converts a string of bytes (in network byte order) to a :bro:type:`double`.
@ -3208,9 +3208,9 @@ function lookup_connection%(cid: conn_id%): connection
RecordVal* id_val = new RecordVal(conn_id); RecordVal* id_val = new RecordVal(conn_id);
id_val->Assign(0, new AddrVal((unsigned int) 0)); id_val->Assign(0, new AddrVal((unsigned int) 0));
id_val->Assign(1, new PortVal(ntohs(0), TRANSPORT_UDP)); id_val->Assign(1, port_mgr->Get(ntohs(0), TRANSPORT_UDP));
id_val->Assign(2, new AddrVal((unsigned int) 0)); id_val->Assign(2, new AddrVal((unsigned int) 0));
id_val->Assign(3, new PortVal(ntohs(0), TRANSPORT_UDP)); id_val->Assign(3, port_mgr->Get(ntohs(0), TRANSPORT_UDP));
c->Assign(0, id_val); c->Assign(0, id_val);
RecordVal* orig_endp = new RecordVal(endpoint); RecordVal* orig_endp = new RecordVal(endpoint);

View file

@ -135,7 +135,7 @@ struct val_converter {
result_type operator()(broker::port& a) result_type operator()(broker::port& a)
{ {
if ( type->Tag() == TYPE_PORT ) if ( type->Tag() == TYPE_PORT )
return new PortVal(a.number(), bro_broker::to_bro_port_proto(a.type())); return port_mgr->Get(a.number(), bro_broker::to_bro_port_proto(a.type()));
return nullptr; return nullptr;
} }

View file

@ -697,7 +697,7 @@ void bro_broker::Manager::Process()
{ {
val_list* vl = new val_list; val_list* vl = new val_list;
vl->append(new StringVal(u.relation.remote_tuple().first)); vl->append(new StringVal(u.relation.remote_tuple().first));
vl->append(new PortVal(u.relation.remote_tuple().second, vl->append(port_mgr->Get(u.relation.remote_tuple().second,
TRANSPORT_TCP)); TRANSPORT_TCP));
vl->append(new StringVal(u.peer_name)); vl->append(new StringVal(u.peer_name));
mgr.QueueEvent(Broker::outgoing_connection_established, vl); mgr.QueueEvent(Broker::outgoing_connection_established, vl);
@ -709,7 +709,7 @@ void bro_broker::Manager::Process()
{ {
val_list* vl = new val_list; val_list* vl = new val_list;
vl->append(new StringVal(u.relation.remote_tuple().first)); vl->append(new StringVal(u.relation.remote_tuple().first));
vl->append(new PortVal(u.relation.remote_tuple().second, vl->append(port_mgr->Get(u.relation.remote_tuple().second,
TRANSPORT_TCP)); TRANSPORT_TCP));
mgr.QueueEvent(Broker::outgoing_connection_broken, vl); mgr.QueueEvent(Broker::outgoing_connection_broken, vl);
} }
@ -720,7 +720,7 @@ void bro_broker::Manager::Process()
{ {
val_list* vl = new val_list; val_list* vl = new val_list;
vl->append(new StringVal(u.relation.remote_tuple().first)); vl->append(new StringVal(u.relation.remote_tuple().first));
vl->append(new PortVal(u.relation.remote_tuple().second, vl->append(port_mgr->Get(u.relation.remote_tuple().second,
TRANSPORT_TCP)); TRANSPORT_TCP));
mgr.QueueEvent(Broker::outgoing_connection_incompatible, vl); mgr.QueueEvent(Broker::outgoing_connection_incompatible, vl);
} }

Some files were not shown because too many files have changed in this diff Show more