From 1bf439cd58a05d724529cbab81bb862861711e54 Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Thu, 11 Jul 2024 13:20:24 -0700 Subject: [PATCH 01/91] Updating CHANGES and VERSION. --- CHANGES | 4 ++++ VERSION | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index 55d064321b..49beb0badc 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,7 @@ +7.0.0-rc1 | 2024-07-11 12:21:02 -0700 + + * Updating submodule(s) [nomail] (Tim Wojtulewicz, Corelight) + 7.0.0-dev.467 | 2024-07-11 12:14:52 -0700 * Update the scripts.base.frameworks.telemetry.internal-metrics test (Christian Kreibich, Corelight) diff --git a/VERSION b/VERSION index 14530a2cf8..8a72a34280 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -7.0.0-dev.467 +7.0.0-rc1 From 92a685df500c51bb4e3bd16e130833583387cdbd Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Thu, 11 Jul 2024 14:20:47 -0700 Subject: [PATCH 02/91] Fix a typo in the 7.0 NEWS --- NEWS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NEWS b/NEWS index e526919b09..e115d2be07 100644 --- a/NEWS +++ b/NEWS @@ -20,7 +20,7 @@ Breaking Changes All of the metrics-related script-level options, type, and methods have been moved to the Telemetry framework: - * Option ``Broker::metrics_port` is now ``Telemetry::metrics_port`` + * Option ``Broker::metrics_port`` is now ``Telemetry::metrics_port`` * Option ``Broker::metrics_export_endpoint_name`` is now ``Telemetry::metrics_endpoint_name`` The following options have been removed: From 962b03a431ff6e66fab8aef3668a131a8006b8b3 Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Fri, 12 Jul 2024 09:46:34 -0700 Subject: [PATCH 03/91] Merge remote-tracking branch 'origin/topic/timw/grealpath-make-dist-warning' * origin/topic/timw/grealpath-make-dist-warning: Fix warning about grealpath when running 'make dist' on Linux (cherry picked from commit e4716b6c912f86cf6b2afd6979c38667c45add95) --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 5c0f8a4b97..394a77ab8e 100644 --- a/Makefile +++ b/Makefile @@ -9,7 +9,7 @@ BUILD=build REPO=$$(cd $(CURDIR) && basename $$(git config --get remote.origin.url | sed 's/^[^:]*://g')) VERSION_FULL=$(REPO)-$$(cd $(CURDIR) && cat VERSION) GITDIR=$$(test -f .git && echo $$(cut -d" " -f2 .git) || echo .git) -REALPATH=$$($$(realpath --relative-to=$(pwd) . >/dev/null 2>&1) && echo 'realpath' || echo 'grealpath') +REALPATH=$$($$(realpath --relative-to=$(shell pwd) . >/dev/null 2>&1) && echo 'realpath' || echo 'grealpath') all: configured $(MAKE) -C $(BUILD) $@ From ac9548438280820801845cb26705a6b7cb636890 Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Fri, 12 Jul 2024 09:47:59 -0700 Subject: [PATCH 04/91] Merge remote-tracking branch 'origin/topic/bbannier/lib-spicy-hooks' * origin/topic/bbannier/lib-spicy-hooks: Do not emit hook files for builtin modules (cherry picked from commit 7a38cee81fd6b4d29f744bb095359d986ebedb95) --- src/spicy/spicyz/driver.cc | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/spicy/spicyz/driver.cc b/src/spicy/spicyz/driver.cc index 8a4eee216a..8e4854c298 100644 --- a/src/spicy/spicyz/driver.cc +++ b/src/spicy/spicyz/driver.cc @@ -4,10 +4,8 @@ #include -#include #include #include -#include #include #include @@ -37,12 +35,15 @@ struct VisitorTypes : public spicy::visitor::PreOrder { : driver(driver), glue(glue), is_resolved(is_resolved) {} void operator()(hilti::declaration::Module* n) final { - if ( n->uid().in_memory ) { - // Ignore modules built by us in memory. + // Ignore modules built by us in memory, or builtin modules which + // never contain implementations of hooks for user types. + if ( n->uid().in_memory || + (module == "hilti" || module == "spicy" || module == "spicy_rt" || module == "zeek_rt") ) { module = {}; return; } + module = n->scopeID(); path = n->uid().path; From 5f6df68463e40d5eb9257d78de0c6779f86c4984 Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Fri, 12 Jul 2024 09:51:39 -0700 Subject: [PATCH 05/91] Merge remote-tracking branch 'origin/topic/bbannier/lib-spicy-hooks' * origin/topic/bbannier/lib-spicy-hooks: Do not emit hook files for builtin modules (cherry picked from commit b935d2f59aea00fdf79216a1b4dfa287136b1b6d) --- src/spicy/spicyz/driver.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/spicy/spicyz/driver.cc b/src/spicy/spicyz/driver.cc index 8e4854c298..82759fbf5e 100644 --- a/src/spicy/spicyz/driver.cc +++ b/src/spicy/spicyz/driver.cc @@ -47,7 +47,7 @@ struct VisitorTypes : public spicy::visitor::PreOrder { module = n->scopeID(); path = n->uid().path; - if ( is_resolved ) + if ( is_resolved && ! n->skipImplementation() ) glue->addSpicyModule(module, path); } From a8c56c1f25d786fc5bfb35ff27f8e0e96b71f9ed Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Fri, 12 Jul 2024 10:00:13 -0700 Subject: [PATCH 06/91] Fix a broken merge I merged an old version of the branch on accident and then merged the right one over top of it, but git ended up including both versions. This fixes that mistake. (cherry picked from commit f3bcf1a55d13986ef7d6146ca26095de32c0176b) --- src/spicy/spicyz/driver.cc | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/spicy/spicyz/driver.cc b/src/spicy/spicyz/driver.cc index 82759fbf5e..75ffd1f6fa 100644 --- a/src/spicy/spicyz/driver.cc +++ b/src/spicy/spicyz/driver.cc @@ -35,15 +35,11 @@ struct VisitorTypes : public spicy::visitor::PreOrder { : driver(driver), glue(glue), is_resolved(is_resolved) {} void operator()(hilti::declaration::Module* n) final { - // Ignore modules built by us in memory, or builtin modules which - // never contain implementations of hooks for user types. - if ( n->uid().in_memory || - (module == "hilti" || module == "spicy" || module == "spicy_rt" || module == "zeek_rt") ) { + if ( n->uid().in_memory ) { + // Ignore modules built by us in memory. module = {}; return; } - - module = n->scopeID(); path = n->uid().path; From 91b23a6e2ec53194ed96b85856c5233d61ede61f Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Fri, 12 Jul 2024 16:13:04 -0700 Subject: [PATCH 07/91] Update broker and cmake submodules [nomail] --- auxil/broker | 2 +- cmake | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/auxil/broker b/auxil/broker index fada26ae50..4679ab3a8c 160000 --- a/auxil/broker +++ b/auxil/broker @@ -1 +1 @@ -Subproject commit fada26ae504981f7f5524bf2a5c82ae49acd556d +Subproject commit 4679ab3a8cc6beadaa65436b47fd79dfbd571a3f diff --git a/cmake b/cmake index 690483f76c..2d42baf8e6 160000 --- a/cmake +++ b/cmake @@ -1 +1 @@ -Subproject commit 690483f76c149ffa8e035b612b406b0964f9886f +Subproject commit 2d42baf8e63a7494224aa9d02afa2cb43ddb96b8 From b8d11f4688c2869daf8e01086fca52315735b89b Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Fri, 12 Jul 2024 13:56:11 -0700 Subject: [PATCH 08/91] CI: Set FETCH_CONTENT_FULLY_DISCONNECTED flag for configure --- .cirrus.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.cirrus.yml b/.cirrus.yml index 1323ce8e95..b96146f230 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -10,7 +10,7 @@ btest_jobs: &BTEST_JOBS 4 btest_retries: &BTEST_RETRIES 2 memory: &MEMORY 16GB -config: &CONFIG --build-type=release --disable-broker-tests --prefix=$CIRRUS_WORKING_DIR/install --ccache --enable-werror +config: &CONFIG --build-type=release --disable-broker-tests --prefix=$CIRRUS_WORKING_DIR/install --ccache --enable-werror -D FETCHCONTENT_FULLY_DISCONNECTED:BOOL=ON no_spicy_config: &NO_SPICY_CONFIG --build-type=release --disable-broker-tests --disable-spicy --prefix=$CIRRUS_WORKING_DIR/install --ccache --enable-werror static_config: &STATIC_CONFIG --build-type=release --disable-broker-tests --enable-static-broker --enable-static-binpac --prefix=$CIRRUS_WORKING_DIR/install --ccache --enable-werror binary_config: &BINARY_CONFIG --prefix=$CIRRUS_WORKING_DIR/install --libdir=$CIRRUS_WORKING_DIR/install/lib --binary-package --enable-static-broker --enable-static-binpac --disable-broker-tests --build-type=Release --ccache --enable-werror From 5cdddd92d55e301fdae474ad6dc85418c170d287 Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Tue, 16 Jul 2024 10:16:02 -0700 Subject: [PATCH 09/91] Merge remote-tracking branch 'origin/topic/bbannier/bump-spicy' * origin/topic/bbannier/bump-spicy: Bump auxil/spicy to latest development snapshot (cherry picked from commit 9ba7c2ddafd73dd2d00ab301d9aa8f501d819f4f) --- auxil/spicy | 2 +- src/analyzer/protocol/finger/finger.spicy | 2 +- src/analyzer/protocol/syslog/syslog.spicy | 2 +- src/spicy/spicyz/glue-compiler.cc | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/auxil/spicy b/auxil/spicy index 6581b1855a..4a1b43ef07 160000 --- a/auxil/spicy +++ b/auxil/spicy @@ -1 +1 @@ -Subproject commit 6581b1855a5ea8cc102c66b4ac6a431fc67484a0 +Subproject commit 4a1b43ef07d1305a7e88a4f0866068dc49de9d06 diff --git a/src/analyzer/protocol/finger/finger.spicy b/src/analyzer/protocol/finger/finger.spicy index dd07dbb7c3..0d6a8da54e 100644 --- a/src/analyzer/protocol/finger/finger.spicy +++ b/src/analyzer/protocol/finger/finger.spicy @@ -15,7 +15,7 @@ public type Request = unit { switch { -> : /\/W/ { self.whois = True; } - -> void; + -> : void; }; : OptionalWhiteSpace; diff --git a/src/analyzer/protocol/syslog/syslog.spicy b/src/analyzer/protocol/syslog/syslog.spicy index fd4c845870..ba8c8a77aa 100644 --- a/src/analyzer/protocol/syslog/syslog.spicy +++ b/src/analyzer/protocol/syslog/syslog.spicy @@ -7,7 +7,7 @@ import spicy; public type Message = unit { switch { -> prio: Priority; - -> void; + -> : void; }; msg: bytes &eod; diff --git a/src/spicy/spicyz/glue-compiler.cc b/src/spicy/spicyz/glue-compiler.cc index cc17312343..e9240ed245 100644 --- a/src/spicy/spicyz/glue-compiler.cc +++ b/src/spicy/spicyz/glue-compiler.cc @@ -1375,7 +1375,7 @@ bool GlueCompiler::CreateSpicyHook(glue::Event* ev) { auto attrs = builder()->attributeSet({builder()->attribute("&priority", builder()->integer(ev->priority))}); auto parameters = hilti::util::transform(ev->parameters, [](const auto& p) { return p.get(); }); - auto unit_hook = builder()->declarationHook(parameters, body.block(), ::spicy::Engine::All, attrs, meta); + auto unit_hook = builder()->declarationHook(parameters, body.block(), attrs, meta); auto hook_decl = builder()->declarationUnitHook(ev->hook, unit_hook, meta); ev->spicy_module->spicy_module->add(context(), hook_decl); From d17a1f9822b9ea651e27e7ae5047a2693e86fc94 Mon Sep 17 00:00:00 2001 From: Christian Kreibich Date: Mon, 15 Jul 2024 17:50:09 -0700 Subject: [PATCH 10/91] Bump zeek-testing-cluster to pull in tee SIGPIPE fix (cherry picked from commit b51a46f94d4012119fd27d5e46328c70af7270a2) --- testing/external/commit-hash.zeek-testing-cluster | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testing/external/commit-hash.zeek-testing-cluster b/testing/external/commit-hash.zeek-testing-cluster index 8b8bfdc2e4..5d84d38106 100644 --- a/testing/external/commit-hash.zeek-testing-cluster +++ b/testing/external/commit-hash.zeek-testing-cluster @@ -1 +1 @@ -45582671c6715e719d91c8afde7ffb480c602441 +ded009fb7a0cdee6f36d5b40a6394788b760fa06 From b13dfa3b16f78897847f1d47729a1989632f2960 Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Thu, 18 Jul 2024 14:31:49 -0700 Subject: [PATCH 11/91] Update docs submodule [nomail] --- doc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc b/doc index f65820ff0f..316ad305b6 160000 --- a/doc +++ b/doc @@ -1 +1 @@ -Subproject commit f65820ff0faf2887799fe691a443b5db39eeed54 +Subproject commit 316ad305b69456fcd424ffaf99d1326822ad9d60 From 5a56ff92d2c9e6d7028f851520b7ece064a22e4f Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Thu, 18 Jul 2024 14:54:47 -0700 Subject: [PATCH 12/91] Updating CHANGES and VERSION. --- CHANGES | 14 ++++++++++++++ VERSION | 2 +- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index 49beb0badc..396fae1710 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,17 @@ +7.0.0-rc2 | 2024-07-18 14:31:49 -0700 + + * Bump zeek-testing-cluster to pull in tee SIGPIPE fix (Christian Kreibich, Corelight) + + (cherry picked from commit b51a46f94d4012119fd27d5e46328c70af7270a2) + + * CI: Set FETCH_CONTENT_FULLY_DISCONNECTED flag for configure (Tim Wojtulewicz, Corelight) + + * Update broker and cmake submodules [nomail] (Tim Wojtulewicz, Corelight) + + * Fix warning about grealpath when running 'make dist' on Linux (Tim Wojtulewicz, Corelight) + + (cherry picked from commit e4716b6c912f86cf6b2afd6979c38667c45add95) + 7.0.0-rc1 | 2024-07-11 12:21:02 -0700 * Updating submodule(s) [nomail] (Tim Wojtulewicz, Corelight) diff --git a/VERSION b/VERSION index 8a72a34280..8e0c129daf 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -7.0.0-rc1 +7.0.0-rc2 From d9dc121e9ad41bc3e7324edb157b7bc206144dca Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Mon, 22 Jul 2024 15:00:22 -0700 Subject: [PATCH 13/91] Update broker submodule [nomail] --- auxil/broker | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/auxil/broker b/auxil/broker index 4679ab3a8c..5b3ed87a93 160000 --- a/auxil/broker +++ b/auxil/broker @@ -1 +1 @@ -Subproject commit 4679ab3a8cc6beadaa65436b47fd79dfbd571a3f +Subproject commit 5b3ed87a93b2ded1f3c95ff1a3b99e2c6ab84ef4 From 8014c4b8c37cce4f7e3c5df9dd1d3b097485b7fe Mon Sep 17 00:00:00 2001 From: Arne Welzel Date: Sun, 21 Jul 2024 17:34:34 +0200 Subject: [PATCH 14/91] telemetry: Deprecate prometheus.zeek policy script With Cluster::Node$metrics_port being optional, there's not really a need for the extra script. New rule, if a metrics_port is set, the node will attempt to listen on it. Users can still redef Telemetry::metrics_port *after* base/frameworks/telemetry was loaded to change the port defined in cluster-layout.zeek. (cherry picked from commit bf9704f3398229c860aca92dd45df1b2fd26f68e) --- NEWS | 5 +++++ .../base/frameworks/telemetry/__load__.zeek | 2 -- scripts/base/frameworks/telemetry/main.zeek | 18 ++++++++++++++++ .../frameworks/telemetry/prometheus.zeek | 21 ++----------------- scripts/site/local.zeek | 4 ---- testing/btest/coverage/bare-mode-errors.test | 2 +- .../coverage/test-all-policy-cluster.test | 2 +- .../frameworks/telemetry/prometheus.zeek | 1 - 8 files changed, 27 insertions(+), 28 deletions(-) diff --git a/NEWS b/NEWS index e115d2be07..2f7422c195 100644 --- a/NEWS +++ b/NEWS @@ -167,6 +167,11 @@ Deprecated Functionality - The ``--disable-archiver`` configure flag no longer does anything and will be removed in 7.1. zeek-archiver has moved into the zeek-aux repository. +- The policy/frameworks/telemetry/prometheus.zeek script has been deprecated + and will be removed with Zeek 7.1. Setting the ``metrics_port`` field on a + ``Cluster::Node`` implies listening on that port and exposing telemetry + in Prometheus format. + Zeek 6.2.0 ========== diff --git a/scripts/base/frameworks/telemetry/__load__.zeek b/scripts/base/frameworks/telemetry/__load__.zeek index 88b6dbf672..a10fe855df 100644 --- a/scripts/base/frameworks/telemetry/__load__.zeek +++ b/scripts/base/frameworks/telemetry/__load__.zeek @@ -1,3 +1 @@ @load ./main - -@load base/frameworks/cluster diff --git a/scripts/base/frameworks/telemetry/main.zeek b/scripts/base/frameworks/telemetry/main.zeek index d71a7d9783..0e5ce1b1f5 100644 --- a/scripts/base/frameworks/telemetry/main.zeek +++ b/scripts/base/frameworks/telemetry/main.zeek @@ -5,10 +5,28 @@ ##! enabled by setting :zeek:see:`Telemetry::metrics_port`. @load base/misc/version +@load base/frameworks/cluster + @load base/frameworks/telemetry/options module Telemetry; +# In a cluster configuration, open the port number for metrics +# from the cluster node configuration for exporting data to +# Prometheus. +# +# The manager node will also provide a ``/services.json`` endpoint +# for the HTTP Service Discovery system in Prometheus to use for +# configuration. This endpoint will include information for all of +# the other nodes in the cluster. +@if ( Cluster::is_enabled() ) +redef Telemetry::metrics_endpoint_name = Cluster::node; + +@if ( Cluster::local_node_metrics_port() != 0/unknown ) +redef Telemetry::metrics_port = Cluster::local_node_metrics_port(); +@endif +@endif + export { ## Alias for a vector of label values. type labels_vector: vector of string; diff --git a/scripts/policy/frameworks/telemetry/prometheus.zeek b/scripts/policy/frameworks/telemetry/prometheus.zeek index 2b2ac4d255..a7d0226d73 100644 --- a/scripts/policy/frameworks/telemetry/prometheus.zeek +++ b/scripts/policy/frameworks/telemetry/prometheus.zeek @@ -1,19 +1,2 @@ -##! In a cluster configuration, open the port number for metrics -##! from the cluster node configuration for exporting data to -##! Prometheus. -##! -##! The manager node will also provide a ``/services.json`` endpoint -##! for the HTTP Service Discovery system in Prometheus to use for -##! configuration. This endpoint will include information for all of -##! the other nodes in the cluster. -@load base/frameworks/cluster - -@if ( Cluster::is_enabled() ) - -redef Telemetry::metrics_endpoint_name = Cluster::node; - -@if ( Cluster::local_node_metrics_port() != 0/unknown ) -redef Telemetry::metrics_port = Cluster::local_node_metrics_port(); -@endif - -@endif +@deprecated "Remove in v7.1: Cluster nodes now implicitly listen on metrics port if set in cluster-layout." +@load base/frameworks/telemetry diff --git a/scripts/site/local.zeek b/scripts/site/local.zeek index 71251c0cb1..d92ccdd5a6 100644 --- a/scripts/site/local.zeek +++ b/scripts/site/local.zeek @@ -94,10 +94,6 @@ redef digest_salt = "Please change this value."; # telemetry_histogram.log. @load frameworks/telemetry/log -# Enable Prometheus metrics scraping in the cluster: each Zeek node will listen -# on the metrics port defined in its Cluster::nodes entry. -# @load frameworks/telemetry/prometheus - # Uncomment the following line to enable detection of the heartbleed attack. Enabling # this might impact performance a bit. # @load policy/protocols/ssl/heartbleed diff --git a/testing/btest/coverage/bare-mode-errors.test b/testing/btest/coverage/bare-mode-errors.test index e477140083..be243bcdc0 100644 --- a/testing/btest/coverage/bare-mode-errors.test +++ b/testing/btest/coverage/bare-mode-errors.test @@ -9,4 +9,4 @@ # # @TEST-EXEC: test -d $DIST/scripts # @TEST-EXEC: for script in `find $DIST/scripts/ -name \*\.zeek`; do zeek -b --parse-only $script >>errors 2>&1; done -# @TEST-EXEC: TEST_DIFF_CANONIFIER="grep -v -e 'load-balancing.zeek.*deprecated script loaded' | $SCRIPTS/diff-remove-abspath | $SCRIPTS/diff-sort" btest-diff errors +# @TEST-EXEC: TEST_DIFF_CANONIFIER="grep -v -e 'load-balancing.zeek.*deprecated script loaded' | grep -v -e 'prometheus.zeek.*deprecated script loaded' | $SCRIPTS/diff-remove-abspath | $SCRIPTS/diff-sort" btest-diff errors diff --git a/testing/btest/coverage/test-all-policy-cluster.test b/testing/btest/coverage/test-all-policy-cluster.test index b213b1ac26..9d88868063 100644 --- a/testing/btest/coverage/test-all-policy-cluster.test +++ b/testing/btest/coverage/test-all-policy-cluster.test @@ -9,7 +9,7 @@ # @TEST-EXEC: CLUSTER_NODE=logger-1 zeek %INPUT # @TEST-EXEC: CLUSTER_NODE=proxy-1 zeek %INPUT # @TEST-EXEC: CLUSTER_NODE=worker-1 zeek %INPUT -# @TEST-EXEC: TEST_DIFF_CANONIFIER='grep -v "load-balancing.zeek.*deprecated script" | $SCRIPTS/diff-remove-abspath' btest-diff .stderr +# @TEST-EXEC: TEST_DIFF_CANONIFIER='grep -v "load-balancing.zeek.*deprecated script" | grep -v "prometheus.zeek.*deprecated script" | $SCRIPTS/diff-remove-abspath' btest-diff .stderr @load base/frameworks/cluster @load misc/loaded-scripts diff --git a/testing/btest/scripts/policy/frameworks/telemetry/prometheus.zeek b/testing/btest/scripts/policy/frameworks/telemetry/prometheus.zeek index 0d6e7794b0..50a6fd8d2c 100644 --- a/testing/btest/scripts/policy/frameworks/telemetry/prometheus.zeek +++ b/testing/btest/scripts/policy/frameworks/telemetry/prometheus.zeek @@ -55,7 +55,6 @@ done @TEST-END-FILE @load policy/frameworks/cluster/experimental -@load policy/frameworks/telemetry/prometheus @load base/frameworks/telemetry # So the cluster nodes don't terminate right away. From a65a339aa8c556410f87b88144bd770720f8ca74 Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Tue, 23 Jul 2024 08:51:11 -0700 Subject: [PATCH 15/91] Merge remote-tracking branch 'origin/topic/bbannier/bump-spicy' * origin/topic/bbannier/bump-spicy: Bump auxil/spicy to latest development snapshot (cherry picked from commit da7c3d91385195a7a4ba957e46743bc52a9d4ecb) --- auxil/spicy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/auxil/spicy b/auxil/spicy index 4a1b43ef07..04c5ed3c27 160000 --- a/auxil/spicy +++ b/auxil/spicy @@ -1 +1 @@ -Subproject commit 4a1b43ef07d1305a7e88a4f0866068dc49de9d06 +Subproject commit 04c5ed3c27879459de69d12efc417c6915f304b9 From 746ae4d2cc53864a156fb185d78b9e757cdacd22 Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Tue, 23 Jul 2024 08:54:23 -0700 Subject: [PATCH 16/91] Merge remote-tracking branch 'origin/topic/johanna/update-the-ct-list-and-the-ca-list-again' * origin/topic/johanna/update-the-ct-list-and-the-ca-list-again: Update Mozilla CA list and CT list (cherry picked from commit cb88f6316c7341da7a2af397932a145be3a0cc29) --- scripts/base/protocols/ssl/ct-list.zeek | 21 +++++++++++++++---- .../base/protocols/ssl/mozilla-ca-list.zeek | 5 +++-- 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/scripts/base/protocols/ssl/ct-list.zeek b/scripts/base/protocols/ssl/ct-list.zeek index c7c2a87ec9..036374d946 100644 --- a/scripts/base/protocols/ssl/ct-list.zeek +++ b/scripts/base/protocols/ssl/ct-list.zeek @@ -1,9 +1,9 @@ # # Do not edit this file. This file is automatically generated by gen-ct-list.pl -# File generated at Fri Feb 23 11:37:01 2024 +# File generated at Tue Jul 23 16:04:45 2024 # File generated from https://www.gstatic.com/ct/log_list/v3/log_list.json -# Source file generated at: 2024-02-22T12:56:21Z -# Source file version: 32.9 +# Source file generated at: 2024-07-23T13:06:08Z +# Source file version: 39.1 # @load base/protocols/ssl @@ -12,21 +12,32 @@ redef ct_logs += { ["\xee\xcd\xd0\x64\xd5\xdb\x1a\xce\xc5\x5c\xb7\x9d\xb4\xcd\x13\xa2\x32\x87\x46\x7c\xbc\xec\xde\xc3\x51\x48\x59\x46\x71\x1f\xb5\x9b"] = CTInfo($description="Google 'Argon2024' log", $operator="Google", $url="https://ct.googleapis.com/logs/us1/argon2024/", $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\x1d\xb9\x6c\xa9\xcb\x69\x94\xc5\x5c\xe6\xb6\xa6\x03\xbb\xd2\xb8\xdc\x54\x43\x17\x28\x99\x0c\x06\x01\x50\x1d\x9d\x64\xc0\x59\x46\x2b\xdc\xc8\x03\x1d\x05\xb4\x2d\xa8\x09\xf7\x99\x41\xed\x04\xfb\xe5\x57\xba\x26\x04\xf6\x11\x52\xce\x14\x65\x3b\x2f\x76\x2b\xc0"), ["\x4e\x75\xa3\x27\x5c\x9a\x10\xc3\x38\x5b\x6c\xd4\xdf\x3f\x52\xeb\x1d\xf0\xe0\x8e\x1b\x8d\x69\xc0\xb1\xfa\x64\xb1\x62\x9a\x39\xdf"] = CTInfo($description="Google 'Argon2025h1' log", $operator="Google", $url="https://ct.googleapis.com/logs/us1/argon2025h1/", $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\x82\xa1\xf9\x67\x68\xa8\xe4\xdb\x94\x98\xe2\xe1\x68\x87\xe4\x09\x6d\x20\x35\x33\x38\x3c\xaf\x14\xaa\xd7\x08\x18\xf0\xfd\x16\x9b\xd3\xff\x7c\x27\x82\xd4\x87\xb7\x4e\x24\x46\x3b\xfb\xae\xbe\xc8\x23\x52\x20\x2b\xaa\x44\x05\xfe\x54\xf9\xd5\xf1\x1d\x45\x9a"), ["\x12\xf1\x4e\x34\xbd\x53\x72\x4c\x84\x06\x19\xc3\x8f\x3f\x7a\x13\xf8\xe7\xb5\x62\x87\x88\x9c\x6d\x30\x05\x84\xeb\xe5\x86\x26\x3a"] = CTInfo($description="Google 'Argon2025h2' log", $operator="Google", $url="https://ct.googleapis.com/logs/us1/argon2025h2/", $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\xaf\xe4\xf3\x94\x2c\xdf\xa6\x27\xb5\xfe\xb2\x61\x83\x19\xc8\x21\x3a\x23\xa8\xa9\x3d\x54\xaf\xbc\x31\x9a\x1c\xd3\xc1\xe3\xb6\xc2\xf3\x0f\xc7\xb9\xca\x3b\x1d\x79\x65\x61\x22\x25\x82\x56\x4e\x98\xe8\xaa\x26\x29\x36\x1e\x28\x60\x6f\xeb\x15\x6e\xf7\x7c\xd0\xba"), +["\x0e\x57\x94\xbc\xf3\xae\xa9\x3e\x33\x1b\x2c\x99\x07\xb3\xf7\x90\xdf\x9b\xc2\x3d\x71\x32\x25\xdd\x21\xa9\x25\xac\x61\xc5\x4e\x21"] = CTInfo($description="Google 'Argon2026h1' log", $operator="Google", $url="https://ct.googleapis.com/logs/us1/argon2026h1/", $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\x07\xfc\x1e\xe8\x63\x8e\xff\x1c\x31\x8a\xfc\xb8\x1e\x19\x2b\x60\x50\x00\x3e\x8e\x9e\xda\x77\x37\xe3\xa5\xa8\xda\x8d\x94\xf8\x6b\xe8\x3d\x64\x8f\x27\x3f\x75\xb3\xfc\x6b\x12\xf0\x37\x06\x4f\x64\x58\x75\x14\x5d\x56\x52\xe6\x6a\x2b\x14\x4c\xec\x81\xd1\xea\x3e"), +["\xd7\x6d\x7d\x10\xd1\xa7\xf5\x77\xc2\xc7\xe9\x5f\xd7\x00\xbf\xf9\x82\xc9\x33\x5a\x65\xe1\xd0\xb3\x01\x73\x17\xc0\xc8\xc5\x69\x77"] = CTInfo($description="Google 'Argon2026h2' log", $operator="Google", $url="https://ct.googleapis.com/logs/us1/argon2026h2/", $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\x2a\x3a\x67\x8b\xfe\xba\x0c\x86\x2b\x4a\x51\x8a\xe9\x17\xfe\x7b\xa1\x76\x73\xfd\xbc\x65\x4b\xc3\x27\xbf\x4d\xf3\x5f\xa0\xca\x29\x80\x11\x20\x32\x78\xd6\x7e\xf9\x34\x60\x8c\x75\xa0\xf5\x35\x50\x9c\xa1\xd3\x49\x4d\x13\xd5\x3b\x6a\x0e\xea\x45\x9d\x24\x13\x22"), ["\x76\xff\x88\x3f\x0a\xb6\xfb\x95\x51\xc2\x61\xcc\xf5\x87\xba\x34\xb4\xa4\xcd\xbb\x29\xdc\x68\x42\x0a\x9f\xe6\x67\x4c\x5a\x3a\x74"] = CTInfo($description="Google 'Xenon2024' log", $operator="Google", $url="https://ct.googleapis.com/logs/eu1/xenon2024/", $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\xb9\x60\xe0\x34\x1e\x35\xe4\x65\x00\x93\x4f\x90\x09\xbd\x5a\xec\x44\xdd\x8c\x0f\xce\xed\x11\x3e\x2a\x59\x46\x9a\x31\xb6\xc7\x99\xf7\xdc\xef\x3d\xcd\x8f\x86\xc2\x35\xa5\x3e\xdc\x29\xba\xbb\xf2\x54\xe2\xa8\x0c\x83\x08\x51\x06\xde\x21\x6d\x36\x50\x8e\x38\x4d"), ["\xcf\x11\x56\xee\xd5\x2e\x7c\xaf\xf3\x87\x5b\xd9\x69\x2e\x9b\xe9\x1a\x71\x67\x4a\xb0\x17\xec\xac\x01\xd2\x5b\x77\xce\xcc\x3b\x08"] = CTInfo($description="Google 'Xenon2025h1' log", $operator="Google", $url="https://ct.googleapis.com/logs/eu1/xenon2025h1/", $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\x82\xe2\xce\x90\x40\x3f\x81\x0e\xdf\xea\xe1\x20\x2b\x5e\x2e\x30\x54\x46\x81\xb9\x58\xed\xaf\xbd\xff\x36\xa7\x9e\x0b\x5f\x6a\x6b\x91\xa5\xc1\x98\xe1\xf2\xcd\xeb\x17\x20\x70\xca\x2a\x12\xe6\x54\x78\x50\xdc\xff\x6d\xfd\x1c\xa7\xb6\x3a\x1f\xf9\x26\xa9\x1b\xbd"), ["\xdd\xdc\xca\x34\x95\xd7\xe1\x16\x05\xe7\x95\x32\xfa\xc7\x9f\xf8\x3d\x1c\x50\xdf\xdb\x00\x3a\x14\x12\x76\x0a\x2c\xac\xbb\xc8\x2a"] = CTInfo($description="Google 'Xenon2025h2' log", $operator="Google", $url="https://ct.googleapis.com/logs/eu1/xenon2025h2/", $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\x6b\xe0\xaf\xed\x06\x7c\x3d\xef\xd9\x0e\xe4\x58\x4b\x04\xd8\x2a\x47\x99\x90\x89\x7a\xb9\x36\xa5\x75\xc8\x04\xb8\xcb\xe2\xaa\x2b\xb5\x68\x9d\x88\x29\xa2\xa5\xcf\xce\x2b\x9a\x15\x9b\xa0\x3e\x9d\x94\x1c\xb2\xb7\x4a\xf2\x51\xec\x40\xed\x62\x47\xa4\x03\x49\x86"), +["\x96\x97\x64\xbf\x55\x58\x97\xad\xf7\x43\x87\x68\x37\x08\x42\x77\xe9\xf0\x3a\xd5\xf6\xa4\xf3\x36\x6e\x46\xa4\x3f\x0f\xca\xa9\xc6"] = CTInfo($description="Google 'Xenon2026h1' log", $operator="Google", $url="https://ct.googleapis.com/logs/eu1/xenon2026h1/", $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\x3a\x1f\xc8\xbb\xce\xd5\x90\x47\x34\xca\xca\x01\x04\x27\x21\x1c\xe2\x29\x3d\x92\xbb\x91\x45\xc7\x5a\x3e\xa5\xd4\xf2\x12\xe6\xe8\xe6\x43\xba\xf3\x7b\xc2\x38\xaf\xfc\x23\x8a\x05\x56\xeb\x03\x0a\x30\xcc\x63\x6c\xd9\x3c\xbe\xf5\x7b\x94\xba\x94\xd3\xbf\x88\x4c"), +["\xd8\x09\x55\x3b\x94\x4f\x7a\xff\xc8\x16\x19\x6f\x94\x4f\x85\xab\xb0\xf8\xfc\x5e\x87\x55\x26\x0f\x15\xd1\x2e\x72\xbb\x45\x4b\x14"] = CTInfo($description="Google 'Xenon2026h2' log", $operator="Google", $url="https://ct.googleapis.com/logs/eu1/xenon2026h2/", $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\xe5\x77\x78\x95\x71\x28\xb3\x95\xc9\xa5\xcc\x7a\x4c\xe8\x32\x03\x96\x7b\xfc\x2e\x1d\xb9\xa4\xdb\x43\xa0\xbd\x69\x72\xf9\x45\xba\x9a\xc3\xe9\x96\xd5\x70\xe7\x0d\x7e\xc9\x95\x15\x27\x8a\x72\x30\x65\x86\x43\x53\xdc\x11\x44\x18\x49\x98\x25\x68\xa7\x3c\x05\xbf"), ["\xda\xb6\xbf\x6b\x3f\xb5\xb6\x22\x9f\x9b\xc2\xbb\x5c\x6b\xe8\x70\x91\x71\x6c\xbb\x51\x84\x85\x34\xbd\xa4\x3d\x30\x48\xd7\xfb\xab"] = CTInfo($description="Cloudflare 'Nimbus2024' Log", $operator="Cloudflare", $url="https://ct.cloudflare.com/logs/nimbus2024/", $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\x77\xb1\x9b\x7b\x8f\xe6\x8b\x35\xfe\x3a\x92\x29\x2d\xac\x8a\x8d\x51\x8a\x25\xfc\x93\xb6\xd7\xa0\x8b\x29\x37\x71\x1d\x33\xca\xcc\x33\xea\x28\xb9\x1f\xe2\xac\xc3\xa9\x5d\xdd\x97\xbe\xf6\x9e\x94\x25\xdd\x36\x81\xd1\xeb\x5d\x29\xc3\x2b\x44\xf1\x5b\xca\x15\x48"), ["\xcc\xfb\x0f\x6a\x85\x71\x09\x65\xfe\x95\x9b\x53\xce\xe9\xb2\x7c\x22\xe9\x85\x5c\x0d\x97\x8d\xb6\xa9\x7e\x54\xc0\xfe\x4c\x0d\xb0"] = CTInfo($description="Cloudflare 'Nimbus2025'", $operator="Cloudflare", $url="https://ct.cloudflare.com/logs/nimbus2025/", $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\x1a\x80\x1a\x15\x19\x19\x23\x79\xb4\xfa\xa0\x79\x8e\x8d\xd5\xc1\xdc\xc2\xb5\x96\x92\x7e\x94\xe0\xc3\x7e\x14\x7c\x0a\x0d\x2d\x46\xa8\x9d\x1b\xb1\x41\x65\x0c\x5f\x98\xc4\x5a\x17\x79\x81\x5b\x4a\x14\x41\xec\xaf\xa9\x5d\x0e\xab\x12\x19\x71\xcd\x43\xef\xbb\x97"), ["\x48\xb0\xe3\x6b\xda\xa6\x47\x34\x0f\xe5\x6a\x02\xfa\x9d\x30\xeb\x1c\x52\x01\xcb\x56\xdd\x2c\x81\xd9\xbb\xbf\xab\x39\xd8\x84\x73"] = CTInfo($description="DigiCert Yeti2024 Log", $operator="DigiCert", $url="https://yeti2024.ct.digicert.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\x57\xb8\xc1\x6f\x30\xa4\x7f\x2e\xe4\xf0\xd0\xd9\x60\x62\x13\x95\xe3\x7a\xe3\x4e\x53\xc3\xb3\xb8\x73\x85\xc1\x18\x0d\x23\x0e\x58\x84\xd2\x78\xef\x9b\xb3\x1e\x2c\x1a\xde\xc1\x8f\x81\x1b\x19\x44\x58\xb7\x00\x77\x60\x20\x1a\x72\xd8\x82\xde\xae\x9e\xb1\xc6\x4b"), ["\x7d\x59\x1e\x12\xe1\x78\x2a\x7b\x1c\x61\x67\x7c\x5e\xfd\xf8\xd0\x87\x5c\x14\xa0\x4e\x95\x9e\xb9\x03\x2f\xd9\x0e\x8c\x2e\x79\xb8"] = CTInfo($description="DigiCert Yeti2025 Log", $operator="DigiCert", $url="https://yeti2025.ct.digicert.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\xdf\x95\x00\x5e\x10\xc1\x01\xf7\x37\xe3\x10\x74\xd1\xff\xb2\xca\x90\xed\x32\x99\x5f\x0c\x39\xfe\xa1\xd1\x13\x11\xac\xd1\xb3\x73\x93\x20\xc2\x13\x3c\x4c\xb5\x7a\x52\x86\x86\x3d\xe3\x95\x24\x7c\xd8\x91\x98\x48\x3b\xf0\xf0\xdf\x21\xf1\xb0\x81\x5a\x59\x25\x43"), ["\x73\xd9\x9e\x89\x1b\x4c\x96\x78\xa0\x20\x7d\x47\x9d\xe6\xb2\xc6\x1c\xd0\x51\x5e\x71\x19\x2a\x8c\x6b\x80\x10\x7a\xc1\x77\x72\xb5"] = CTInfo($description="DigiCert Nessie2024 Log", $operator="DigiCert", $url="https://nessie2024.ct.digicert.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\x2d\xfc\xa2\x7b\x36\xbf\x56\x91\xe9\xfe\x3f\xe8\x3d\xfc\xc3\xa7\xe0\x61\x52\xea\x2c\xe9\x05\xa3\x9f\x27\x17\x81\x05\x70\x6b\x81\x61\x44\x8a\xf8\x3b\x10\x80\x42\xed\x03\x2f\x00\x50\x21\xfc\x41\x54\x84\xa3\x54\xd5\x2e\xb2\x7a\x16\x4b\x2a\x1f\x2b\x66\x04\x2b"), ["\xe6\xd2\x31\x63\x40\x77\x8c\xc1\x10\x41\x06\xd7\x71\xb9\xce\xc1\xd2\x40\xf6\x96\x84\x86\xfb\xba\x87\x32\x1d\xfd\x1e\x37\x8e\x50"] = CTInfo($description="DigiCert Nessie2025 Log", $operator="DigiCert", $url="https://nessie2025.ct.digicert.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\xf2\xf0\xf0\xa7\x8b\x81\x2e\x09\x39\x3b\x9f\x42\xda\x38\x44\x5f\xb4\xcc\xed\x36\xbb\xd8\x43\x7f\x16\x49\x57\x87\x04\x7f\xa5\x01\x34\xf7\xe8\x68\x3f\xb7\x78\x1f\x60\x66\x2d\x67\x9a\x75\x80\xb7\x53\xa7\x85\xd5\xbc\xab\x47\x06\x55\xdb\xb5\xdf\x88\xa1\x6f\x38"), +["\xb6\x9d\xdc\xbc\x3c\x1a\xbd\xef\x6f\x9f\xd6\x0c\x88\xb1\x06\x7b\x77\xf0\x82\x68\x8b\x2d\x78\x65\xd0\x4b\x39\xab\xe9\x27\xa5\x75"] = CTInfo($description="DigiCert 'Wyvern2024h1' Log", $operator="DigiCert", $url="https://wyvern.ct.digicert.com/2024h1/", $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\x68\xa6\x79\x14\xd1\x58\xe7\xab\xaa\x29\x69\x7f\x60\xed\x68\xe8\x10\xf6\x07\x84\xc0\xfb\x59\x04\x5a\x09\xc9\x1d\xe1\x4b\xfb\xcd\xdc\x03\xf3\xa8\x2a\x46\xb9\x84\x4d\x69\x30\xec\x23\x35\xc1\x8e\xfc\x9f\xb4\x20\x24\xd7\x15\xac\x87\xf7\x1e\xc1\x0b\x3c\x76\x1a"), +["\x0c\x2a\xef\x2c\x4a\x5b\x98\x83\xd4\xdd\xa3\x82\xfe\x50\xfb\x51\x88\xb3\xe9\x73\x33\xa1\xec\x53\xa0\x9d\xc9\xa7\x9d\x0d\x08\x20"] = CTInfo($description="DigiCert 'Wyvern2024h2' Log", $operator="DigiCert", $url="https://wyvern.ct.digicert.com/2024h2/", $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\xa8\x73\x12\x9c\x54\xd0\x7a\x7d\xc5\xb5\x17\x2b\x71\x52\x89\x04\x90\xbb\x42\xf1\x9d\xf8\x1c\xde\x4c\xcf\x82\x3c\xbd\x37\x1b\x74\x4c\x3c\xc7\xa3\x13\x87\x01\x51\x13\x14\xda\xa2\x12\x98\x84\xce\x1c\xbe\xcf\x4f\x7a\xef\x15\xfa\xd0\xee\xed\xed\x07\xad\x71\x6d"), +["\x73\x20\x22\x0f\x08\x16\x8a\xf9\xf3\xc4\xa6\x8b\x0a\xb2\x6a\x9a\x4a\x00\xee\xf5\x77\x85\x8a\x08\x4d\x05\x00\xd4\xa5\x42\x44\x59"] = CTInfo($description="DigiCert 'Wyvern2025h1' Log", $operator="DigiCert", $url="https://wyvern.ct.digicert.com/2025h1/", $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\xa7\xcb\x80\x61\x86\x1b\x1f\xb5\xab\x2b\x20\x76\x59\x83\x66\x0e\xce\xae\xb8\x6f\x3b\x88\x02\xeb\x43\xf4\x87\x90\xcb\x8b\xda\xac\x0e\x19\x50\xe0\xf9\x24\x0e\xab\x26\x93\x8c\x3f\x9e\x0d\x96\x58\x44\x9d\x3b\x8a\x80\xc5\xc8\xbe\xe1\x89\x46\x6b\x48\x4c\xd6\x09"), +["\xed\x3c\x4b\xd6\xe8\x06\xc2\xa4\xa2\x00\x57\xdb\xcb\x24\xe2\x38\x01\xdf\x51\x2f\xed\xc4\x86\xc5\x70\x0f\x20\xdd\xb7\x3e\x3f\xe0"] = CTInfo($description="DigiCert 'Wyvern2025h2' Log", $operator="DigiCert", $url="https://wyvern.ct.digicert.com/2025h2/", $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\xe0\xdb\x41\xef\xe4\x04\xbd\xcb\x6b\x2e\x4c\xcc\xf1\x6c\xde\x41\x58\x7f\xfe\x94\xf6\x7a\xf6\x60\xed\x8b\x76\x72\xa3\xa2\x1c\x31\x13\x32\x35\xa1\xf2\x08\xd2\x68\xc5\x34\xa7\x56\x08\x1c\x63\xde\x95\xe2\x81\x69\x97\x8d\x1e\xa8\xb7\x66\x51\x25\x75\x4d\x78\x2e"), +["\xdb\x07\x6c\xde\x6a\x8b\x78\xec\x58\xd6\x05\x64\x96\xeb\x6a\x26\xa8\xc5\x9e\x72\x12\x93\xe8\xac\x03\x27\xdd\xde\x89\xdb\x5a\x2a"] = CTInfo($description="DigiCert 'Sphinx2024h1' Log", $operator="DigiCert", $url="https://sphinx.ct.digicert.com/2024h1/", $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\xc6\xe4\x29\x69\x98\xfe\x28\x92\x57\x12\x4d\x9e\xed\x0e\xe7\x32\xa2\xe6\x9c\x27\x78\xa4\x29\x7c\x99\xd5\xdb\xfa\x22\xc1\xdd\x5e\xa7\xf4\xd8\xea\xc8\xd7\x44\x8d\xe0\xf1\x8c\x0a\x01\x1d\xd8\x22\xa8\xd3\xeb\xc9\x22\x8e\x36\xfb\x4a\xb1\x70\x9c\x5d\xc1\xe8\x33"), +["\xdc\xc9\x5e\x6f\xa2\x99\xb9\xb0\xfd\xbd\x6c\xa6\xa3\x6e\x1d\x72\xc4\x21\x2f\xdd\x1e\x0f\x47\x55\x3a\x36\xd6\xcf\x1a\xd1\x1d\x8d"] = CTInfo($description="DigiCert 'Sphinx2024h2' Log", $operator="DigiCert", $url="https://sphinx.ct.digicert.com/2024h2/", $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\xdb\x09\x41\x84\xe7\xd1\xf1\x5b\x25\x09\x7b\xe8\xc6\x98\x51\x5e\x29\x85\xfd\x81\xde\x89\xd7\xd0\x86\xa4\xb0\xe5\x15\xec\x5d\x7b\x17\x55\x5f\xc9\x79\x8d\xe4\x22\x36\xe7\xe9\xbf\x38\x3f\xd1\xe9\xd4\x09\x84\x81\xbe\xb6\xc1\xed\x1b\x17\xea\x26\x97\xba\xe9\x9a"), +["\xde\x85\x81\xd7\x50\x24\x7c\x6b\xcd\xcb\xaf\x56\x37\xc5\xe7\x81\xc6\x4c\xe4\x6e\xd6\x17\x63\x9f\x8f\x34\xa7\x26\xc9\xe2\xbd\x37"] = CTInfo($description="DigiCert 'Sphinx2025h1' Log", $operator="DigiCert", $url="https://sphinx.ct.digicert.com/2025h1/", $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\xe3\x2f\x1f\x4d\x89\x05\x75\x29\x78\xbb\x22\x3d\x07\x62\x51\x14\x70\x94\xe7\x3c\xea\xf5\xee\xae\xa6\x48\x9a\x86\x52\x4e\x9e\x5c\xe3\x95\x97\x28\xbb\x52\x4b\x2a\xfd\xc8\xc9\x89\x4e\x45\x31\x17\xd3\x8d\xf2\xe7\xce\x18\x11\x58\x98\x2c\x60\x6f\x58\x20\x36\x6e"), +["\xa4\x42\xc5\x06\x49\x60\x61\x54\x8f\x0f\xd4\xea\x9c\xfb\x7a\x2d\x26\x45\x4d\x87\xa9\x7f\x2f\xdf\x45\x59\xf6\x27\x4f\x3a\x84\x54"] = CTInfo($description="DigiCert 'Sphinx2025h2' Log", $operator="DigiCert", $url="https://sphinx.ct.digicert.com/2025h2/", $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\x41\x8c\x50\x13\x54\xb1\x19\x05\xb7\x7f\x4a\x20\x6e\xa3\x75\x63\xca\x34\xf4\xcc\x74\xea\x32\x3b\xb6\x8b\x03\x14\xa8\x52\x7f\x32\x87\x5e\x59\x9e\x0f\xab\x18\x9e\x29\x6c\xb5\x72\x77\x1a\x27\x54\x85\x5d\xc1\x7b\x24\xa8\x34\xe3\xcd\x88\xce\xd4\x50\x1b\xbe\x69"), ["\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="Sectigo 'Sabre' CT log", $operator="Sectigo", $url="https://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"), ["\xa2\xe2\xbf\xd6\x1e\xde\x2f\x2f\x07\xa0\xd6\x4e\x6d\x37\xa7\xdc\x65\x43\xb0\xc6\xb5\x2e\xa2\xda\xb7\x8a\xf8\x9a\x6d\xf5\x17\xd8"] = CTInfo($description="Sectigo 'Sabre2024h1'", $operator="Sectigo", $url="https://sabre2024h1.ct.sectigo.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\x01\xf6\xce\x31\xbc\xaa\x14\x61\x51\xfe\x6b\x7a\x87\xae\xa6\xd3\x9b\xc7\x87\x2d\x0a\x5a\xc8\x4f\xb5\x54\xdc\xc9\x93\xa0\x00\xee\xca\x1c\xb9\xa7\xb6\x7b\x47\x3b\xe5\x4f\xaa\x6c\x16\x1c\x70\x2e\xc8\xec\x53\x5a\x4c\x21\x4c\x7e\x27\x0b\x13\x14\x5e\xfc\x85"), ["\x19\x98\x10\x71\x09\xf0\xd6\x52\x2e\x30\x80\xd2\x9e\x3f\x64\xbb\x83\x6e\x28\xcc\xf9\x0f\x52\x8e\xee\xdf\xce\x4a\x3f\x16\xb4\xca"] = CTInfo($description="Sectigo 'Sabre2024h2'", $operator="Sectigo", $url="https://sabre2024h2.ct.sectigo.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\x7a\x10\x4c\x8a\xe7\x22\x7b\x6d\x2a\xba\x8e\xfa\x6b\x4a\x81\xd5\x85\xae\x03\xef\xff\x4b\xfc\x4d\x53\x3d\xb7\x8c\xbb\x75\x09\xc9\xea\x16\x7e\xc1\x77\x16\xd2\xc2\x45\x74\x6d\x8d\xc4\xe1\x88\x37\xdf\xd4\xf3\x60\x65\xfc\xa0\x75\xf0\x20\x66\x8e\x4a\xcc\x19\xda"), ["\xe0\x92\xb3\xfc\x0c\x1d\xc8\xe7\x68\x36\x1f\xde\x61\xb9\x96\x4d\x0a\x52\x78\x19\x8a\x72\xd6\x72\xc4\xb0\x4d\xa5\x6d\x6f\x54\x04"] = CTInfo($description="Sectigo 'Sabre2025h1'", $operator="Sectigo", $url="https://sabre2025h1.ct.sectigo.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\x7e\x2f\x39\xf1\xe8\x23\x8e\xb3\x32\x04\xaf\x4d\x57\xf6\xdb\xc5\x74\xa4\x7a\x6d\x3b\x07\x51\x0c\x5a\xfb\x80\x30\x05\xc6\x5a\x0c\xc4\x76\xd6\x06\xa8\x57\x4d\xfb\xdf\xe4\x82\x90\xc2\x41\xae\x70\xb3\x31\xa2\xe3\xfa\x3d\x5f\x2c\x5d\x04\xcd\xb4\x9d\x55\xab\x41"), ["\x1a\x04\xff\x49\xd0\x54\x1d\x40\xaf\xf6\xa0\xc3\xbf\xf1\xd8\xc4\x67\x2f\x4e\xec\xee\x23\x40\x68\x98\x6b\x17\x40\x2e\xdc\x89\x7d"] = CTInfo($description="Sectigo 'Sabre2025h2'", $operator="Sectigo", $url="https://sabre2025h2.ct.sectigo.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\x85\x13\x11\x2d\x7b\xf3\x93\x81\xe4\xb9\x7c\xd9\x64\x3b\xe7\xb5\x83\x99\x66\x79\x59\x47\x6a\x42\x5e\xd6\xbd\x63\x2e\xb7\x91\x4b\xae\xbc\x56\xc4\xc5\x6e\x09\xa0\xd7\x64\x1a\xc8\xc1\xaf\x89\x8b\xf5\x58\xd8\xba\xeb\x7b\x83\x52\xe9\xf4\xe0\xa5\xcd\xcd\x92\xcc"), -["\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="Sectigo 'Mammoth' CT log", $operator="Sectigo", $url="https://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"), ["\x29\xd0\x3a\x1b\xb6\x74\xaa\x71\x1c\xd3\x03\x5b\x65\x57\xc1\x4f\x8a\xa7\x8b\x4f\xe8\x38\x94\x49\xec\xa4\x53\xf9\x44\xbd\x24\x68"] = CTInfo($description="Sectigo 'Mammoth2024h1'", $operator="Sectigo", $url="https://mammoth2024h1.ct.sectigo.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\xa4\x59\x90\xf3\x71\x24\x24\xf7\xc3\x55\x27\x56\x9c\xa3\x59\x1e\xf7\xb7\x9f\xce\xab\x4e\x19\x66\x4d\xd0\x8a\xfa\x9d\x62\xa4\x24\xf0\x3b\x20\xe4\x1d\x14\x67\xc8\xfc\xe4\x37\xf2\x4b\x38\x54\x5a\xcf\x9f\x6b\x07\x90\xd0\x0e\x7e\x3d\x4c\x87\xb2\xe8\x3f\x07\xcc"), ["\x50\x85\x01\x58\xdc\xb6\x05\x95\xc0\x0e\x92\xa8\x11\x02\xec\xcd\xfe\x3f\x6b\x78\x58\x42\x9f\x57\x98\x35\x38\xc9\xda\x52\x50\x63"] = CTInfo($description="Sectigo 'Mammoth2024h1b'", $operator="Sectigo", $url="https://mammoth2024h1b.ct.sectigo.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\xd5\x07\x28\x7a\x04\x34\xae\xca\xbe\x80\x79\x4f\x3e\xf6\x41\xf4\x24\x04\xe1\xd6\x36\x5a\x1a\x09\xf2\xd1\xba\x84\x17\xae\x1e\xa1\x7c\x00\x1d\x54\x73\x90\x75\x21\xa8\xd1\xda\x5e\x10\xe1\x8c\xec\xb2\x8a\x8c\xc8\xe7\xdd\xcd\xe2\x07\xf0\x4e\x16\x02\x57\x37"), ["\xdf\xe1\x56\xeb\xaa\x05\xaf\xb5\x9c\x0f\x86\x71\x8d\xa8\xc0\x32\x4e\xae\x56\xd9\x6e\xa7\xf5\xa5\x6a\x01\xd1\xc1\x3b\xbe\x52\x5c"] = CTInfo($description="Sectigo 'Mammoth2024h2'", $operator="Sectigo", $url="https://mammoth2024h2.ct.sectigo.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\x85\x66\x22\x24\x6e\xbe\x52\x62\x0a\xa0\xaf\xc3\x25\x1a\x36\x2e\xa7\x60\x89\xa2\x65\xbf\xa4\x5f\xbd\x85\x6a\x94\x05\x81\x35\x90\x54\x31\x95\xe7\x11\x9e\xa3\x2e\x0f\x85\xef\xa7\x88\x57\x8b\x63\x1a\x81\xc1\x41\x9d\x7d\xec\x01\x3a\xdb\xb9\xc1\x27\xf4\x65\x1e"), @@ -39,4 +50,6 @@ redef ct_logs += { ["\x87\x4f\xb5\x0d\xc0\x29\xd9\x93\x1d\xe5\x73\xe9\xf2\x89\x9e\x8e\x45\x33\xb3\x92\xd3\x8b\x0a\x46\x25\x74\xbf\x0f\xee\xb2\xfc\x1e"] = CTInfo($description="Trust Asia Log2024-2", $operator="TrustAsia", $url="https://ct2024.trustasia.com/log2024/", $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\xa7\x64\xe2\x79\x81\x3f\x61\xd7\xec\xc6\xf8\x65\x28\x1d\xa0\xb4\x66\x33\xc3\x25\xd5\x0a\x95\x78\x9c\x8f\xfe\xa4\x2a\xd8\x8f\x7e\x72\xe0\xfe\xa8\x7f\xf8\xb1\x2d\x85\xc0\x8e\x12\x74\x0d\x2f\x8c\xab\xd7\x7f\x7a\x1e\xd9\x84\x33\x39\xe8\xfd\x89\x5f\x96\x48\x08"), ["\x28\xe2\x81\x38\xfd\x83\x21\x45\xe9\xa9\xd6\xaa\x75\x37\x6d\x83\x77\xa8\x85\x12\xb3\xc0\x7f\x72\x41\x48\x21\xdc\xbd\xe9\x8c\x66"] = CTInfo($description="TrustAsia Log2025a", $operator="TrustAsia", $url="https://ct2025-a.trustasia.com/log2025a/", $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\x70\xe5\xb1\xa4\x09\x79\x2b\x9d\xf8\xa3\xa0\xdf\x18\xef\x95\x5d\x03\x6c\x7b\xa1\x91\xa9\xb8\x80\x7d\xec\x5c\x02\x08\xe2\x6e\x2f\x7c\x32\x70\xbd\x96\x84\x5f\xa6\x62\xe9\x65\xb5\x7c\x90\x58\xba\x22\xd5\xf9\xf5\x69\x54\xb7\xa8\x94\x4e\x32\x09\xae\x26\x11\x4d"), ["\x28\x2c\x8b\xdd\x81\x0f\xf9\x09\x12\x0a\xce\x16\xd6\xe0\xec\x20\x1b\xea\x82\xa3\xa4\xaf\x19\xd9\xef\xfb\x59\xe8\x3f\xdc\x42\x68"] = CTInfo($description="TrustAsia Log2025b", $operator="TrustAsia", $url="https://ct2025-b.trustasia.com/log2025b/", $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\xaa\xa0\x8b\xdb\x67\x14\x5d\x97\x89\x1d\x08\x8d\x06\xd7\xc1\x94\x8e\xb0\xfa\x4c\x46\xd5\x53\x08\x78\x2b\x04\x53\x6c\xf3\xde\xb1\xd1\x53\x40\xda\x90\x57\xe6\x1a\x9e\x3c\xc7\x03\xb8\xbd\x2f\xa9\xcf\xe8\x7b\x5e\xe1\x4b\x60\xe5\x38\x43\x60\x97\xc1\x5b\x2f\x65"), +["\x74\xdb\x9d\x58\xf7\xd4\x7e\x9d\xfd\x78\x7a\x16\x2a\x99\x1c\x18\xcf\x69\x8d\xa7\xc7\x29\x91\x8c\x9a\x18\xb0\x45\x0d\xba\x44\xbc"] = CTInfo($description="TrustAsia 'log2026a'", $operator="TrustAsia", $url="https://ct2026-a.trustasia.com/log2026a/", $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\xa7\x4e\x7a\xc9\xa6\x07\xf9\xff\x74\xec\x98\xcb\x49\xe1\x00\x24\xb3\x59\x2e\x83\xfd\xc0\x70\x35\x33\x4c\x63\xca\x74\x83\xc0\x3c\x5b\x53\x40\x7c\x31\x1f\x35\xa4\x5f\x0f\xe4\xee\x4f\x89\x17\xe8\x5b\x2e\xc5\xac\x00\x05\xc9\x76\x37\x45\x97\x03\x15\xff\x60\x59"), +["\x25\xb7\xef\xde\xa1\x13\x01\x93\xed\x93\x07\x97\x70\xaa\x32\x2a\x26\x62\x0d\xe3\x5a\xc8\xaa\x7c\x75\x19\x7d\xe0\xb1\xa9\xe0\x65"] = CTInfo($description="TrustAsia 'log2026b'", $operator="TrustAsia", $url="https://ct2026-b.trustasia.com/log2026b/", $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\x0f\x12\x8c\xa9\xe6\xe3\xec\x62\xee\xdf\x58\xc8\x50\xe6\x26\x70\x76\x10\xb7\x04\x39\xb3\xa7\xf8\x4c\x73\x3b\xc3\x38\x5a\x12\x00\x4c\xe0\xda\x0e\x16\x8a\x45\x32\x0a\x31\xaa\x22\xc7\x9d\x7d\x05\x53\xc7\x9e\x94\xea\x9b\x57\x46\xbf\x4f\xa4\x7e\xfb\xdf\xfa\x85"), }; diff --git a/scripts/base/protocols/ssl/mozilla-ca-list.zeek b/scripts/base/protocols/ssl/mozilla-ca-list.zeek index 1206908a10..e308f1fb75 100644 --- a/scripts/base/protocols/ssl/mozilla-ca-list.zeek +++ b/scripts/base/protocols/ssl/mozilla-ca-list.zeek @@ -1,6 +1,6 @@ # Don't edit! This file is automatically generated. -# Generated at: 2024-02-23 11:28:07 +0000 -# Generated from: NSS 3.98 +# Generated at: 2024-07-23 16:04:06 +0100 +# Generated from: NSS 3.102 # # The original source file comes with this licensing statement: # @@ -158,4 +158,5 @@ redef root_certs += { ["CN=CommScope Public Trust RSA Root-02,O=CommScope,C=US"] = "\x30\x82\x05\x6C\x30\x82\x03\x54\xA0\x03\x02\x01\x02\x02\x14\x54\x16\xBF\x3B\x7E\x39\x95\x71\x8D\xD1\xAA\x00\xA5\x86\x0D\x2B\x8F\x7A\x05\x4E\x30\x0D\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x01\x0B\x05\x00\x30\x4E\x31\x0B\x30\x09\x06\x03\x55\x04\x06\x13\x02\x55\x53\x31\x12\x30\x10\x06\x03\x55\x04\x0A\x0C\x09\x43\x6F\x6D\x6D\x53\x63\x6F\x70\x65\x31\x2B\x30\x29\x06\x03\x55\x04\x03\x0C\x22\x43\x6F\x6D\x6D\x53\x63\x6F\x70\x65\x20\x50\x75\x62\x6C\x69\x63\x20\x54\x72\x75\x73\x74\x20\x52\x53\x41\x20\x52\x6F\x6F\x74\x2D\x30\x32\x30\x1E\x17\x0D\x32\x31\x30\x34\x32\x38\x31\x37\x31\x36\x34\x33\x5A\x17\x0D\x34\x36\x30\x34\x32\x38\x31\x37\x31\x36\x34\x32\x5A\x30\x4E\x31\x0B\x30\x09\x06\x03\x55\x04\x06\x13\x02\x55\x53\x31\x12\x30\x10\x06\x03\x55\x04\x0A\x0C\x09\x43\x6F\x6D\x6D\x53\x63\x6F\x70\x65\x31\x2B\x30\x29\x06\x03\x55\x04\x03\x0C\x22\x43\x6F\x6D\x6D\x53\x63\x6F\x70\x65\x20\x50\x75\x62\x6C\x69\x63\x20\x54\x72\x75\x73\x74\x20\x52\x53\x41\x20\x52\x6F\x6F\x74\x2D\x30\x32\x30\x82\x02\x22\x30\x0D\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x01\x01\x05\x00\x03\x82\x02\x0F\x00\x30\x82\x02\x0A\x02\x82\x02\x01\x00\xE1\xFA\x0E\xFB\x68\x00\x12\xC8\x4D\xD5\xAC\x22\xC4\x35\x01\x3B\xC5\x54\xE5\x59\x76\x63\xA5\x7F\xEB\xC1\xC4\x6A\x98\xBD\x32\x8D\x17\x80\xEB\x5D\xBA\xD1\x62\x3D\x25\x23\x19\x35\x14\xE9\x7F\x89\xA7\x1B\x62\x3C\xD6\x50\xE7\x34\x95\x03\x32\xB1\xB4\x93\x22\x3D\xA7\xE2\xB1\xED\xE6\x7B\x4E\x2E\x87\x9B\x0D\x33\x75\x0A\xDE\xAA\x35\xE7\x7E\xE5\x36\x98\xA2\xAE\x25\x9E\x95\xB3\x32\x96\xA4\x2B\x58\x1E\xEF\x3F\xFE\x62\x34\x48\x51\xD1\xB4\x8D\x42\xAD\x60\xDA\x49\x6A\x95\x70\xDD\xD2\x00\xE2\xCC\x57\x63\x02\x7B\x96\xDD\x49\x97\x5B\x92\x4E\x95\xD3\xF9\xCB\x29\x1F\x18\x4A\xF8\x01\x2A\xD2\x63\x09\x6E\x24\xE9\x89\xD2\xE5\xC7\x22\x4C\xDC\x73\x86\x47\x00\xAA\x0D\x88\x8E\xAE\x85\x7D\x4A\xE9\xBB\x33\x4F\x0E\x52\x70\x9D\x95\xE3\x7C\x6D\x96\x5B\x2D\x3D\x5F\xA1\x83\x46\x5D\xB6\xE3\x25\xB8\x7C\xA7\x19\x80\x1C\xEA\x65\x43\xDC\x91\x79\x36\x2C\x74\x7C\xF2\x67\x06\xC9\x89\xC9\xDB\xBF\xDA\x68\xBF\x23\xED\xDC\x6B\xAD\x28\x83\x79\x2F\xEC\x38\xA5\x0D\x37\x01\x67\x27\x9A\xE9\x33\xD9\x33\x5F\x37\xA1\xC5\xF0\xAB\x3D\xFA\x78\xB0\xE7\x2C\x9F\xF6\x3E\x9F\x60\xE0\xEF\x48\xE9\x90\x45\x1E\x05\x51\x78\x1A\x2C\x12\x2C\x5C\x28\xAC\x0D\xA2\x23\x9E\x34\x8F\x05\xE6\xA2\x33\xCE\x11\x77\x13\xD4\x0E\xA4\x1E\x42\x1F\x86\xCD\x70\xFE\xD9\x2E\x15\x3D\x1D\xBB\xB8\xF2\x53\x57\xDB\xCC\xC6\x74\x29\x9C\x18\xB3\x36\x75\x38\x2E\x0F\x54\xA1\xF8\x92\x1F\x89\x96\x4F\xBB\xD4\xEE\x9D\xE9\x3B\x36\x42\xB5\x0A\x3B\x2A\xD4\x64\x79\x36\x10\xE1\xF9\x91\x03\x2B\x7B\x20\x54\xCD\x0D\x19\x1A\xC8\x41\x32\x34\xD1\xB0\x99\xE1\x90\x1E\x01\x40\x36\xB5\xB7\xFA\xA9\xE5\x77\x75\xA4\x22\x81\x5D\xB0\x8B\xE4\x27\x12\x0F\x54\x88\xC6\xDB\x85\x74\xE6\xB7\xC0\xD7\xA6\x29\xFA\xDB\xDE\xF3\x93\x97\x27\x04\x55\x2F\x0A\x6F\x37\xC5\x3D\x13\xAF\x0A\x00\xA9\x2C\x8B\x1C\x81\x28\xD7\xEF\x86\x31\xA9\xAE\xF2\x6E\xB8\xCA\x6A\x2C\x54\x47\xD8\x2A\x88\x2E\xAF\xC1\x07\x10\x78\xAC\x11\xA2\x2F\x42\xF0\x37\xC5\xF2\xB8\x56\xDD\x0E\x62\x2D\xCE\x2D\x56\x7E\x55\xF2\xA7\x44\xF6\x2B\x32\xF4\x23\xA8\x47\xE8\xD4\x2A\x01\x78\xCF\x6A\xC3\x37\xA8\x9E\x65\xD2\x2C\xE5\xFA\xBA\x33\xC1\x06\x44\xF6\xE6\xCF\xA5\x0D\xA7\x66\x08\x34\x8A\x2C\xF3\x02\x03\x01\x00\x01\xA3\x42\x30\x40\x30\x0F\x06\x03\x55\x1D\x13\x01\x01\xFF\x04\x05\x30\x03\x01\x01\xFF\x30\x0E\x06\x03\x55\x1D\x0F\x01\x01\xFF\x04\x04\x03\x02\x01\x06\x30\x1D\x06\x03\x55\x1D\x0E\x04\x16\x04\x14\x47\xD0\xE7\xB1\x22\xFF\x9D\x2C\xF5\xD9\x57\x60\xB3\xB1\xB1\x70\x95\xEF\x61\x7A\x30\x0D\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x01\x0B\x05\x00\x03\x82\x02\x01\x00\x86\x69\xB1\x4D\x2F\xE9\x9F\x4F\x22\x93\x68\x8E\xE4\x21\x99\xA3\xCE\x45\x53\x1B\x73\x44\x53\x00\x81\x61\xCD\x31\xE3\x08\xBA\x81\x28\x28\x7A\x92\xB9\xB6\xA8\xC8\x43\x9E\xC7\x13\x26\x4D\xC2\xD8\xE5\x55\x9C\x92\x5D\x50\xD8\xC2\x2B\xDB\xFE\xE6\xA8\x97\xCF\x52\x3A\x24\xC3\x65\x64\x5C\x47\x31\xA3\x65\x35\x13\xC3\x93\xB9\xF7\xF9\x51\x97\xBB\xA4\xF0\x62\x87\xC5\xD6\x06\xD3\x97\x83\x20\xA9\x7E\xBB\xB6\x21\xC2\xA5\x0D\x84\x00\xE1\xF2\x27\x10\x83\xBA\xDD\x03\x81\xD5\xDD\x68\xC3\x66\x10\xC8\xD1\x76\xB4\xB3\x6F\x29\x9E\x00\xF9\xC2\x29\xF5\xB1\x93\x19\x52\x69\x1A\x2C\x4C\xA0\x8B\xE0\x15\x9A\x31\x2F\xD3\x88\x95\x59\x6E\xE5\xC4\xB3\x50\xC8\x14\x08\x4A\x9B\x8B\x13\x83\xB1\xA4\x72\xB2\x3B\x76\x33\x41\xDC\xDC\xAA\xA6\x07\x6F\x1D\x24\x12\x9F\xC8\x76\xBD\x2F\xD9\x8E\xF4\x2C\xEE\xB7\xD2\x38\x10\x24\x36\x51\x2F\xE3\x5C\x5D\x81\x21\xA7\xDA\xBB\x4E\xFF\xE6\x07\xA8\xFE\xB9\x0D\x27\x6C\xBB\x70\x5A\x55\x7A\x13\xE9\xF1\x2A\x49\x69\xC7\x5F\x87\x57\x4C\x43\x79\x6D\x3A\x65\xE9\x30\x5C\x41\xEE\xEB\x77\xA5\x73\x12\x88\xE8\xBF\x7D\xAE\xE5\xC4\xA8\x1F\x0D\x8E\x1C\x6D\x50\x02\x4F\x26\x18\x43\xDE\x8F\x55\x85\xB1\x0B\x37\x05\x60\xC9\x55\x39\x12\x04\xA1\x2A\xCF\x71\x16\x9F\x36\x51\x49\xBF\x70\x3B\x9E\x67\x9C\xFB\x7B\x79\xC9\x39\x1C\x78\xAC\x77\x91\x54\x9A\xB8\x75\x0A\x81\x52\x97\xE3\x66\x61\x6B\xED\x3E\x38\x1E\x96\x61\x55\xE1\x91\x54\x8C\xED\x8C\x24\x1F\x81\xC9\x10\x9A\x73\x99\x2B\x16\x4E\x72\x00\x3F\x54\x1B\xF8\x8D\xBA\x8B\xE7\x14\xD6\xB6\x45\x4F\x60\xEC\x96\xAE\xC3\x2F\x02\x4E\x5D\x9D\x96\x49\x72\x00\xB2\xAB\x75\x5C\x0F\x68\x5B\x1D\x65\xC2\x5F\x33\x0F\x1E\x0F\xF0\x3B\x86\xF5\xB0\x4E\xBB\x9C\xF7\xEA\x25\x05\xDC\xAD\xA2\x9B\x4B\x17\x01\xBE\x42\xDF\x35\x21\x1D\xAD\xAB\xAE\xF4\xBF\xAE\x1F\x1B\xD3\xE2\x3B\xFC\xB3\x72\x73\x1C\x9B\x28\x90\x89\x13\x3D\x1D\xC1\x00\x47\x09\x96\x9A\x38\x1B\xDD\xB1\xCF\x0D\xC2\xB4\x44\xF3\x96\x95\xCE\x32\x3A\x8F\x34\x9C\xE0\x17\xC7\x5E\xCE\xAE\x0D\xDB\x87\x38\xE5\x3F\x5B\xFD\x9B\x19\xE1\x31\x41\x7A\x70\xAA\x23\x6B\x01\xE1\x45\x4C\xCD\x94\xCE\x3B\x9E\x2D\xE7\x88\x02\x22\xF4\x6E\xE8\xC8\xEC\xD6\x3C\xF3\xB9\xB2\xD7\x77\x7A\xAC\x7B", ["CN=Telekom Security TLS ECC Root 2020,O=Deutsche Telekom Security GmbH,C=DE"] = "\x30\x82\x02\x42\x30\x82\x01\xC9\xA0\x03\x02\x01\x02\x02\x10\x36\x3A\x96\x8C\xC9\x5C\xB2\x58\xCD\xD0\x01\x5D\xC5\xE5\x57\x00\x30\x0A\x06\x08\x2A\x86\x48\xCE\x3D\x04\x03\x03\x30\x63\x31\x0B\x30\x09\x06\x03\x55\x04\x06\x13\x02\x44\x45\x31\x27\x30\x25\x06\x03\x55\x04\x0A\x0C\x1E\x44\x65\x75\x74\x73\x63\x68\x65\x20\x54\x65\x6C\x65\x6B\x6F\x6D\x20\x53\x65\x63\x75\x72\x69\x74\x79\x20\x47\x6D\x62\x48\x31\x2B\x30\x29\x06\x03\x55\x04\x03\x0C\x22\x54\x65\x6C\x65\x6B\x6F\x6D\x20\x53\x65\x63\x75\x72\x69\x74\x79\x20\x54\x4C\x53\x20\x45\x43\x43\x20\x52\x6F\x6F\x74\x20\x32\x30\x32\x30\x30\x1E\x17\x0D\x32\x30\x30\x38\x32\x35\x30\x37\x34\x38\x32\x30\x5A\x17\x0D\x34\x35\x30\x38\x32\x35\x32\x33\x35\x39\x35\x39\x5A\x30\x63\x31\x0B\x30\x09\x06\x03\x55\x04\x06\x13\x02\x44\x45\x31\x27\x30\x25\x06\x03\x55\x04\x0A\x0C\x1E\x44\x65\x75\x74\x73\x63\x68\x65\x20\x54\x65\x6C\x65\x6B\x6F\x6D\x20\x53\x65\x63\x75\x72\x69\x74\x79\x20\x47\x6D\x62\x48\x31\x2B\x30\x29\x06\x03\x55\x04\x03\x0C\x22\x54\x65\x6C\x65\x6B\x6F\x6D\x20\x53\x65\x63\x75\x72\x69\x74\x79\x20\x54\x4C\x53\x20\x45\x43\x43\x20\x52\x6F\x6F\x74\x20\x32\x30\x32\x30\x30\x76\x30\x10\x06\x07\x2A\x86\x48\xCE\x3D\x02\x01\x06\x05\x2B\x81\x04\x00\x22\x03\x62\x00\x04\xCE\xBF\xFE\x57\xA8\xBF\xD5\xAA\xF7\x10\x9A\xCD\xBC\xD1\x11\xA2\xBD\x67\x42\xCC\x90\xEB\x15\x18\x90\xD9\xA2\xCD\x0C\x2A\x25\xEB\x3E\x4F\xCE\xB5\xD2\x8F\x0F\xF3\x35\xDA\x43\x8B\x02\x80\xBE\x6F\x51\x24\x1D\x0F\x6B\x2B\xCA\x9F\xC2\x6F\x50\x32\xE5\x37\x20\xB6\x20\xFF\x88\x0D\x0F\x6D\x49\xBB\xDB\x06\xA4\x87\x90\x92\x94\xF4\x09\xD0\xCF\x7F\xC8\x80\x0B\xC1\x97\xB3\xBB\x35\x27\xC9\xC2\x1B\xA3\x42\x30\x40\x30\x1D\x06\x03\x55\x1D\x0E\x04\x16\x04\x14\xE3\x72\xCC\x6E\x95\x99\x47\xB1\xE6\xB3\x61\x4C\xD1\xCB\xAB\xE3\xBA\xCD\xDE\x9F\x30\x0F\x06\x03\x55\x1D\x13\x01\x01\xFF\x04\x05\x30\x03\x01\x01\xFF\x30\x0E\x06\x03\x55\x1D\x0F\x01\x01\xFF\x04\x04\x03\x02\x01\x06\x30\x0A\x06\x08\x2A\x86\x48\xCE\x3D\x04\x03\x03\x03\x67\x00\x30\x64\x02\x30\x75\x52\x8B\xB7\xA4\x10\x4F\xAE\x4A\x10\x8B\xB2\x84\x5B\x42\xE1\xE6\x2A\x36\x02\xDA\xA0\x6E\x19\x3F\x25\xBF\xDA\x59\x32\x8E\xE4\xFB\x90\xDC\x93\x64\xCE\xAD\xB4\x41\x47\x60\xE2\xCF\xA7\xCB\x1E\x02\x30\x37\x41\x8C\x66\xDF\x41\x6B\xD6\x83\x00\x41\xFD\x2F\x5A\xF7\x50\xB4\x67\xD1\x2C\xA8\x71\xD7\x43\xCA\x9C\x27\x24\x91\x83\x48\x0D\xCF\xCD\xF7\x54\x81\xAF\xEC\x7F\xE4\x67\xDB\xB8\x90\xEE\xDD\x25", ["CN=Telekom Security TLS RSA Root 2023,O=Deutsche Telekom Security GmbH,C=DE"] = "\x30\x82\x05\xB3\x30\x82\x03\x9B\xA0\x03\x02\x01\x02\x02\x10\x21\x9C\x54\x2D\xE8\xF6\xEC\x71\x77\xFA\x4E\xE8\xC3\x70\x57\x97\x30\x0D\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x01\x0C\x05\x00\x30\x63\x31\x0B\x30\x09\x06\x03\x55\x04\x06\x13\x02\x44\x45\x31\x27\x30\x25\x06\x03\x55\x04\x0A\x0C\x1E\x44\x65\x75\x74\x73\x63\x68\x65\x20\x54\x65\x6C\x65\x6B\x6F\x6D\x20\x53\x65\x63\x75\x72\x69\x74\x79\x20\x47\x6D\x62\x48\x31\x2B\x30\x29\x06\x03\x55\x04\x03\x0C\x22\x54\x65\x6C\x65\x6B\x6F\x6D\x20\x53\x65\x63\x75\x72\x69\x74\x79\x20\x54\x4C\x53\x20\x52\x53\x41\x20\x52\x6F\x6F\x74\x20\x32\x30\x32\x33\x30\x1E\x17\x0D\x32\x33\x30\x33\x32\x38\x31\x32\x31\x36\x34\x35\x5A\x17\x0D\x34\x38\x30\x33\x32\x37\x32\x33\x35\x39\x35\x39\x5A\x30\x63\x31\x0B\x30\x09\x06\x03\x55\x04\x06\x13\x02\x44\x45\x31\x27\x30\x25\x06\x03\x55\x04\x0A\x0C\x1E\x44\x65\x75\x74\x73\x63\x68\x65\x20\x54\x65\x6C\x65\x6B\x6F\x6D\x20\x53\x65\x63\x75\x72\x69\x74\x79\x20\x47\x6D\x62\x48\x31\x2B\x30\x29\x06\x03\x55\x04\x03\x0C\x22\x54\x65\x6C\x65\x6B\x6F\x6D\x20\x53\x65\x63\x75\x72\x69\x74\x79\x20\x54\x4C\x53\x20\x52\x53\x41\x20\x52\x6F\x6F\x74\x20\x32\x30\x32\x33\x30\x82\x02\x22\x30\x0D\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x01\x01\x05\x00\x03\x82\x02\x0F\x00\x30\x82\x02\x0A\x02\x82\x02\x01\x00\xED\x35\xA1\x81\x80\xF3\xCB\x4A\x69\x5B\xC2\xFB\x51\x83\xAE\x26\xFD\xE1\x6E\xF3\x81\x12\x7D\x71\x40\xFF\x87\x75\x42\x29\x21\xED\x81\x52\x2C\xDF\x12\xC1\x19\x84\x89\xC1\xBD\xC5\x28\xD5\xD5\x4B\x6C\x44\xD6\x4C\xDB\x07\x96\x4A\x55\x7A\xCA\x36\x82\x04\x36\xA8\xA5\xFC\x27\xF6\x49\xF1\xD5\x72\x9E\x91\xF9\x23\xD6\x70\x7B\xBB\xF5\x9B\xC1\xEC\x93\xCF\x19\xEA\x65\x7E\x88\x70\xA0\x73\xFC\xF6\xFF\xB5\x56\x62\xE1\x73\x6A\x34\x98\x3E\x82\xB8\xAC\x95\x53\xF4\x01\xA0\x27\x07\x72\xA3\x00\x53\xA0\xE4\xB2\xAB\x83\x38\x57\x33\x25\x94\x9F\xBE\x48\x1D\x98\xE1\xA3\xBA\x9E\x5C\xCD\x04\x71\x51\x7D\x75\x78\xAB\xF3\x59\xAA\xC4\xE0\x60\xBE\x8F\x83\x52\xB8\x75\x1A\x41\x35\xED\xBC\xF3\x3A\x63\xE9\xA9\x14\x45\xD7\xE6\x52\xD1\x6E\xD2\xDE\xBC\xE3\xF5\x0B\x3B\xE6\xE0\xC4\xBD\x43\x64\x13\xA6\xCE\xF4\x98\x37\x6C\x8A\x95\xA8\x97\xC8\x47\x0F\xF0\x5E\x10\x8B\xE7\x1D\x1C\xFE\xB1\x3B\xA0\x05\x33\x68\x05\x41\x82\xC1\x03\x2B\x01\xC8\xE7\x8F\x4D\xAB\xE8\xB5\xF6\xCD\x6B\x44\xB5\xE7\xDD\x8B\xEC\xEA\x25\xB4\x00\x22\x57\x4D\xB0\xB1\xB2\x31\xC1\x16\xCE\xFF\xFD\x14\x84\xB7\x47\xFA\xB2\xF1\x70\xDE\xDB\x8B\x6C\x36\x58\xA4\x7C\xB3\x11\xD1\xC3\x77\x7F\x5F\xB6\x25\xE0\x0D\xC5\xD2\xB3\xF9\xB8\xB8\x77\xDB\x37\x71\x71\x47\xE3\x60\x18\x4F\x24\xB6\x75\x37\x78\xB9\xA3\x62\xAF\xBD\xC9\x72\x8E\x2F\xCC\xBB\xAE\xDB\xE4\x15\x52\x19\x07\x33\xFB\x6A\xB7\x2D\x4B\x90\x28\x82\x73\xFE\x18\x8B\x35\x8D\xDB\xA7\x04\x6A\xBE\xEA\xC1\x4D\x36\x3B\x16\x36\x91\x32\xEF\xB6\x40\x89\x91\x43\xE0\xF2\xA2\xAB\x04\x2E\xE6\xF2\x4C\x0E\x16\x34\x20\xAC\x87\xC1\x2D\x7E\xC9\x66\x47\x17\x14\x11\xA4\xF3\xF7\xA1\x24\x89\xAB\xD8\x1A\xC8\xA1\x5C\xB1\xA3\xF7\x8C\x6D\xC8\x01\xC9\x4F\xC9\xEC\xC4\xFC\xAC\x51\x33\xD1\xC8\x83\xD1\xC9\x9F\x1D\xD4\x47\x34\x29\x3E\xCB\xB0\x0E\xFA\x83\x0B\x28\x58\xE5\x29\xDC\x3F\x7C\xA8\x9F\xC9\xB6\x0A\xBB\xA6\xE8\x46\x16\x0F\x96\xE5\x7B\xE4\x6A\x7A\x48\x6D\x76\x98\x05\xA5\xDC\x6D\x1E\x42\x1E\x42\xDA\x1A\xE0\x52\xF7\xB5\x83\xC0\x1A\x7B\x78\x35\x2C\x38\xF5\x1F\xFD\x49\xA3\x2E\xD2\x59\x63\xBF\x80\xB0\x8C\x93\x73\xCB\x35\xA6\x99\x95\x22\x61\x65\x03\x60\xFB\x2F\x93\x4B\xFA\x9A\x9C\x80\x3B\x02\x03\x01\x00\x01\xA3\x63\x30\x61\x30\x0E\x06\x03\x55\x1D\x0F\x01\x01\xFF\x04\x04\x03\x02\x01\x06\x30\x1D\x06\x03\x55\x1D\x0E\x04\x16\x04\x14\xB6\xA7\x97\x82\x3D\x74\x85\x9B\xF7\x3C\x9F\x93\x9A\x95\x79\x75\x52\x8C\x6D\x47\x30\x0F\x06\x03\x55\x1D\x13\x01\x01\xFF\x04\x05\x30\x03\x01\x01\xFF\x30\x1F\x06\x03\x55\x1D\x23\x04\x18\x30\x16\x80\x14\xB6\xA7\x97\x82\x3D\x74\x85\x9B\xF7\x3C\x9F\x93\x9A\x95\x79\x75\x52\x8C\x6D\x47\x30\x0D\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x01\x0C\x05\x00\x03\x82\x02\x01\x00\xA8\xCC\x61\xA6\xBE\x75\x9E\x15\x50\xA4\x6B\xFB\xA8\x70\x45\x7C\xBA\x7E\xB1\x5A\xFC\x5B\x23\xFA\x0A\x77\xF8\x98\x71\x82\x0C\x6D\xE0\x5E\x46\xAA\x93\xF4\x1E\xA0\xC3\xE1\x93\xDB\x4B\xAD\xB2\xA6\x5D\xAB\xB0\xD4\x62\xCB\x5E\xBB\x66\xF5\x2D\xEE\x97\x40\x3C\x62\xEB\x5E\xD6\x14\xD6\x8C\xE2\x96\x8B\x41\x69\x93\x35\xE6\xB9\x99\x6B\x62\xB4\xA1\x17\x66\x34\xA6\x6B\x63\xC6\xB9\x4E\xF2\x22\xE9\x58\x0D\x56\x41\xD1\xFA\x0C\x4A\xF0\x33\xCD\x3B\xBB\x6D\x21\x3A\xAE\x8E\x72\xB5\xC3\x4A\xFB\xE9\x7D\xE5\xB1\x9B\x86\xEE\xE2\xE0\x7D\xB4\xF7\x32\xFD\x22\x84\xF1\x85\xC9\x37\x79\xE9\xB5\x3F\xBF\x5C\xE4\x74\xB2\x8F\x11\x62\x00\xDD\x18\x66\xA1\xD9\x7B\x23\x5F\xF1\x8E\xD5\x67\xE8\x54\xDA\x5B\x3A\x6B\x36\x6F\xF9\x81\xB1\x33\x47\x33\x77\x40\xF9\x52\xAA\xDD\xD4\x83\xCF\x85\x78\x99\x9A\x93\xB9\x73\x67\x42\x46\x11\x21\xEA\xFE\x0A\xA9\x1B\x1A\x65\x69\xB3\x8F\xAE\x16\xB6\xF6\x4B\x56\xB2\x2D\xF9\xA5\xC8\xEC\x3B\x62\xA3\xED\x6B\xD0\x4E\xD5\x40\x09\xA4\x1F\x98\xD7\x3A\xA5\x92\x59\x20\xE4\xB0\x7D\xCD\x5B\x73\x68\xBD\x6D\xC4\xA2\x13\x0E\x67\x19\xB8\x8D\x42\x7E\x6C\x0C\x9A\x6E\xA0\x24\x2D\xD5\x45\x1B\xDC\xC4\x02\x14\xFE\x85\x5B\x65\x97\xCA\x4E\x90\x50\x08\x7A\x42\x35\xF9\xEA\xC2\x66\xD4\xF8\x01\xAE\x1E\xB4\xBE\xC3\xA8\xEF\xFE\x76\x9A\xA2\xA6\x1F\x46\xF6\x84\xED\xFC\xDB\xCE\xC4\x02\xCE\x77\x48\x2C\x8C\xB2\xEC\xC3\x00\xA3\xEC\x2C\x55\x18\xC1\x7E\x19\xEE\xE1\x2F\xF2\xAD\x83\x9B\x9E\xAB\x19\xDF\xC6\x8A\x2F\x8C\x77\xE5\xB7\x05\xEC\x3B\xC1\xEC\xBE\x86\xB3\x86\xBC\xC0\xF7\xDC\xE7\xEA\x5B\xAE\xB2\xCC\xB5\x35\x86\x4B\xD0\xE2\x3F\xB6\xD8\xF8\x0E\x00\xEE\x5D\xE3\xF7\x8D\x58\xFF\xCF\x8B\x37\xE9\x63\x5F\x6E\xF7\x09\x71\x36\xC2\x12\x5D\x57\xF2\xC8\xB4\xCD\xF3\xEE\x02\xDF\x11\xDC\x6A\xB9\x57\x84\x1D\x59\x4D\x8C\xCE\xC8\x0E\x23\xC2\xB7\x26\x9A\x10\x14\x71\xFE\x93\xB2\x8A\xB8\x80\xF0\x0E\x10\x9E\xD3\xA8\x50\x0C\x37\x82\x2F\xEA\xE0\x8A\x9D\xE1\x2C\x39\xFF\xB5\xB4\x73\x00\xE4\xF7\x48\xA6\x73\xAC\xBF\xB2\xDE\x77\x04\x87\xB4\xA3\xCD\x9B\x35\x24\x37\xFA\x90\x93\x13\x81\x42\xC6\x98\x26\x75\x37\x66\x41\x10\xAC\xBB\xF5\x94\xE3\xC2\x31\x2B\xAD\xE7\x23\x56\xCC\x35\x25\x92\xB3\x50", + ["CN=FIRMAPROFESIONAL CA ROOT-A WEB,organizationIdentifier=VATES-A62634068,O=Firmaprofesional SA,C=ES"] = "\x30\x82\x02\x7A\x30\x82\x02\x00\xA0\x03\x02\x01\x02\x02\x10\x31\x97\x21\xED\xAF\x89\x42\x7F\x35\x41\x87\xA1\x67\x56\x4C\x6D\x30\x0A\x06\x08\x2A\x86\x48\xCE\x3D\x04\x03\x03\x30\x6E\x31\x0B\x30\x09\x06\x03\x55\x04\x06\x13\x02\x45\x53\x31\x1C\x30\x1A\x06\x03\x55\x04\x0A\x0C\x13\x46\x69\x72\x6D\x61\x70\x72\x6F\x66\x65\x73\x69\x6F\x6E\x61\x6C\x20\x53\x41\x31\x18\x30\x16\x06\x03\x55\x04\x61\x0C\x0F\x56\x41\x54\x45\x53\x2D\x41\x36\x32\x36\x33\x34\x30\x36\x38\x31\x27\x30\x25\x06\x03\x55\x04\x03\x0C\x1E\x46\x49\x52\x4D\x41\x50\x52\x4F\x46\x45\x53\x49\x4F\x4E\x41\x4C\x20\x43\x41\x20\x52\x4F\x4F\x54\x2D\x41\x20\x57\x45\x42\x30\x1E\x17\x0D\x32\x32\x30\x34\x30\x36\x30\x39\x30\x31\x33\x36\x5A\x17\x0D\x34\x37\x30\x33\x33\x31\x30\x39\x30\x31\x33\x36\x5A\x30\x6E\x31\x0B\x30\x09\x06\x03\x55\x04\x06\x13\x02\x45\x53\x31\x1C\x30\x1A\x06\x03\x55\x04\x0A\x0C\x13\x46\x69\x72\x6D\x61\x70\x72\x6F\x66\x65\x73\x69\x6F\x6E\x61\x6C\x20\x53\x41\x31\x18\x30\x16\x06\x03\x55\x04\x61\x0C\x0F\x56\x41\x54\x45\x53\x2D\x41\x36\x32\x36\x33\x34\x30\x36\x38\x31\x27\x30\x25\x06\x03\x55\x04\x03\x0C\x1E\x46\x49\x52\x4D\x41\x50\x52\x4F\x46\x45\x53\x49\x4F\x4E\x41\x4C\x20\x43\x41\x20\x52\x4F\x4F\x54\x2D\x41\x20\x57\x45\x42\x30\x76\x30\x10\x06\x07\x2A\x86\x48\xCE\x3D\x02\x01\x06\x05\x2B\x81\x04\x00\x22\x03\x62\x00\x04\x47\x53\xEA\x2C\x11\xA4\x77\xC7\x2A\xEA\xF3\xD6\x5F\x7B\xD3\x04\x91\x5C\xFA\x88\xC6\x22\xB9\x83\x10\x62\x77\x84\x33\x2D\xE9\x03\x88\xD4\xE0\x33\xF7\xED\x77\x2C\x4A\x60\xEA\xE4\x6F\xAD\x6D\xB4\xF8\x4C\x8A\xA4\xE4\x1F\xCA\xEA\x4F\x38\x4A\x2E\x82\x73\x2B\xC7\x66\x9B\x0A\x8C\x40\x9C\x7C\x8A\xF6\xF2\x39\x60\xB2\xDE\xCB\xEC\xB8\xE4\x6F\xEA\x9B\x5D\xB7\x53\x90\x18\x32\x55\xC5\x20\xB7\x94\xA3\x63\x30\x61\x30\x0F\x06\x03\x55\x1D\x13\x01\x01\xFF\x04\x05\x30\x03\x01\x01\xFF\x30\x1F\x06\x03\x55\x1D\x23\x04\x18\x30\x16\x80\x14\x93\xE1\x43\x63\x5C\x3C\x9D\xD6\x27\xF3\x52\xEC\x17\xB2\xA9\xAF\x2C\xF7\x76\xF8\x30\x1D\x06\x03\x55\x1D\x0E\x04\x16\x04\x14\x93\xE1\x43\x63\x5C\x3C\x9D\xD6\x27\xF3\x52\xEC\x17\xB2\xA9\xAF\x2C\xF7\x76\xF8\x30\x0E\x06\x03\x55\x1D\x0F\x01\x01\xFF\x04\x04\x03\x02\x01\x06\x30\x0A\x06\x08\x2A\x86\x48\xCE\x3D\x04\x03\x03\x03\x68\x00\x30\x65\x02\x30\x1D\x7C\xA4\x7B\xC3\x89\x75\x33\xE1\x3B\xA9\x45\xBF\x46\xE9\xE9\xA1\xDD\xC9\x22\x16\xB7\x47\x11\x0B\xD8\x9A\xBA\xF1\xC8\x0B\x70\x50\x53\x02\x91\x70\x85\x59\xA9\x1E\xA4\xE6\xEA\x23\x31\xA0\x00\x02\x31\x00\xFD\xE2\xF8\xB3\xAF\x16\xB9\x1E\x73\xC4\x96\xE3\xC1\x30\x19\xD8\x7E\xE6\xC3\x97\xDE\x1C\x4F\xB8\x89\x2F\x33\xEB\x48\x0F\x19\xF7\x87\x46\x5D\x26\x90\xA5\x85\xC5\xB9\x7A\x94\x3E\x87\xA8\xBD\x00", }; From a4b746e5e843ab8792cbd3070c0ae7b637270193 Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Wed, 24 Jul 2024 13:25:52 -0700 Subject: [PATCH 17/91] Merge remote-tracking branch 'origin/topic/timw/smb2-ioctl-errors' * origin/topic/timw/smb2-ioctl-errors: Update 7.0 NEWS with blurb about multi-PDU parsing causing increased load [nomail] [skip ci] Fix handling of zero-length SMB2 error responses (cherry picked from commit bd208f4c54f66074315479071c810d792e69f96b) --- NEWS | 3 ++- src/analyzer/protocol/smb/smb2-protocol.pac | 2 +- .../out | 13 +++++++++++++ .../Traces/smb/smb2-zero-byte-error-ioctl.pcap | Bin 0 -> 29460 bytes .../smb/smb2-zero-byte-error-ioctl.test | 16 ++++++++++++++++ 5 files changed, 32 insertions(+), 2 deletions(-) create mode 100644 testing/btest/Baseline/scripts.base.protocols.smb.smb2-zero-byte-error-ioctl/out create mode 100644 testing/btest/Traces/smb/smb2-zero-byte-error-ioctl.pcap create mode 100644 testing/btest/scripts/base/protocols/smb/smb2-zero-byte-error-ioctl.test diff --git a/NEWS b/NEWS index 2f7422c195..13c25977f9 100644 --- a/NEWS +++ b/NEWS @@ -85,7 +85,8 @@ New Functionality environment variable configures the addition. - SMB2 packets containing multiple PDUs now correctly parse all of the headers, - instead of just the first one and ignoring the rest. + instead of just the first one and ignoring the rest. This may cause increased + CPU load on SMB2-heavy networks. - The new built-in function ``lookup_connection_analyzer_id()`` retrieves the numeric identifier of an analyzer associated with a connection. This enables diff --git a/src/analyzer/protocol/smb/smb2-protocol.pac b/src/analyzer/protocol/smb/smb2-protocol.pac index b922c62f2b..5e7bf673b1 100644 --- a/src/analyzer/protocol/smb/smb2-protocol.pac +++ b/src/analyzer/protocol/smb/smb2-protocol.pac @@ -413,7 +413,7 @@ type SMB2_error_response(header: SMB2_Header) = record { byte_count : uint32; # This is implemented incorrectly and is disabled for now. #error_data : SMB2_error_data(header, byte_count); - stuff : bytestring &restofdata &transient; + stuff : bytestring &length=byte_count &transient; } &byteorder = littleendian; type SMB2_logoff_request(header: SMB2_Header) = record { diff --git a/testing/btest/Baseline/scripts.base.protocols.smb.smb2-zero-byte-error-ioctl/out b/testing/btest/Baseline/scripts.base.protocols.smb.smb2-zero-byte-error-ioctl/out new file mode 100644 index 0000000000..f803db64f2 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.smb.smb2-zero-byte-error-ioctl/out @@ -0,0 +1,13 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +smb2_close_request, [credit_charge=1, status=0, command=6, credits=256, flags=0, message_id=8, process_id=65279, tree_id=3905704575, session_id=66137014, signature=\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00] +smb2_close_response, [credit_charge=1, status=0, command=6, credits=256, flags=1, message_id=8, process_id=65279, tree_id=3905704575, session_id=66137014, signature=\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00], [alloc_size=0, eof=0, times=[modified=0.0, modified_raw=116444736000000000, accessed=0.0, accessed_raw=116444736000000000, created=0.0, created_raw=116444736000000000, changed=0.0, changed_raw=116444736000000000], attrs=[read_only=F, hidden=F, system=F, directory=F, archive=F, normal=F, temporary=F, sparse_file=F, reparse_point=F, compressed=F, offline=F, not_content_indexed=F, encrypted=F, integrity_stream=F, no_scrub_data=F]] +smb2_close_request, [credit_charge=1, status=0, command=6, credits=256, flags=0, message_id=21, process_id=65279, tree_id=900627714, session_id=66137014, signature=\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00] +smb2_close_response, [credit_charge=1, status=0, command=6, credits=256, flags=1, message_id=21, process_id=65279, tree_id=900627714, session_id=66137014, signature=\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00], [alloc_size=0, eof=0, times=[modified=0.0, modified_raw=116444736000000000, accessed=0.0, accessed_raw=116444736000000000, created=0.0, created_raw=116444736000000000, changed=0.0, changed_raw=116444736000000000], attrs=[read_only=F, hidden=F, system=F, directory=F, archive=F, normal=F, temporary=F, sparse_file=F, reparse_point=F, compressed=F, offline=F, not_content_indexed=F, encrypted=F, integrity_stream=F, no_scrub_data=F]] +smb2_close_request, [credit_charge=1, status=0, command=6, credits=256, flags=4, message_id=25, process_id=65279, tree_id=1248644238, session_id=66137014, signature=\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00] +smb2_close_response, [credit_charge=1, status=0, command=6, credits=768, flags=5, message_id=25, process_id=65279, tree_id=1248644238, session_id=66137014, signature=\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00], [alloc_size=0, eof=0, times=[modified=0.0, modified_raw=116444736000000000, accessed=0.0, accessed_raw=116444736000000000, created=0.0, created_raw=116444736000000000, changed=0.0, changed_raw=116444736000000000], attrs=[read_only=F, hidden=F, system=F, directory=F, archive=F, normal=F, temporary=F, sparse_file=F, reparse_point=F, compressed=F, offline=F, not_content_indexed=F, encrypted=F, integrity_stream=F, no_scrub_data=F]] +smb2_close_request, [credit_charge=1, status=0, command=6, credits=256, flags=4, message_id=28, process_id=65279, tree_id=1248644238, session_id=66137014, signature=\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00] +smb2_close_response, [credit_charge=1, status=0, command=6, credits=768, flags=5, message_id=28, process_id=65279, tree_id=1248644238, session_id=66137014, signature=\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00], [alloc_size=0, eof=0, times=[modified=0.0, modified_raw=116444736000000000, accessed=0.0, accessed_raw=116444736000000000, created=0.0, created_raw=116444736000000000, changed=0.0, changed_raw=116444736000000000], attrs=[read_only=F, hidden=F, system=F, directory=F, archive=F, normal=F, temporary=F, sparse_file=F, reparse_point=F, compressed=F, offline=F, not_content_indexed=F, encrypted=F, integrity_stream=F, no_scrub_data=F]] +smb2_close_request, [credit_charge=1, status=0, command=6, credits=256, flags=4, message_id=31, process_id=65279, tree_id=1248644238, session_id=66137014, signature=\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00] +smb2_close_response, [credit_charge=1, status=0, command=6, credits=768, flags=5, message_id=31, process_id=65279, tree_id=1248644238, session_id=66137014, signature=\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00], [alloc_size=0, eof=0, times=[modified=0.0, modified_raw=116444736000000000, accessed=0.0, accessed_raw=116444736000000000, created=0.0, created_raw=116444736000000000, changed=0.0, changed_raw=116444736000000000], attrs=[read_only=F, hidden=F, system=F, directory=F, archive=F, normal=F, temporary=F, sparse_file=F, reparse_point=F, compressed=F, offline=F, not_content_indexed=F, encrypted=F, integrity_stream=F, no_scrub_data=F]] +smb2_close_request, [credit_charge=1, status=0, command=6, credits=256, flags=4, message_id=34, process_id=65279, tree_id=1248644238, session_id=66137014, signature=\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00] +smb2_close_response, [credit_charge=1, status=0, command=6, credits=768, flags=5, message_id=34, process_id=65279, tree_id=1248644238, session_id=66137014, signature=\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00], [alloc_size=0, eof=0, times=[modified=0.0, modified_raw=116444736000000000, accessed=0.0, accessed_raw=116444736000000000, created=0.0, created_raw=116444736000000000, changed=0.0, changed_raw=116444736000000000], attrs=[read_only=F, hidden=F, system=F, directory=F, archive=F, normal=F, temporary=F, sparse_file=F, reparse_point=F, compressed=F, offline=F, not_content_indexed=F, encrypted=F, integrity_stream=F, no_scrub_data=F]] diff --git a/testing/btest/Traces/smb/smb2-zero-byte-error-ioctl.pcap b/testing/btest/Traces/smb/smb2-zero-byte-error-ioctl.pcap new file mode 100644 index 0000000000000000000000000000000000000000..3ffab0867ad80a375de55e06141ffe9dc358dc1e GIT binary patch literal 29460 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 >out +# @TEST-EXEC: ! test -f analyzer.log +# @TEST-EXEC: btest-diff out + +@load base/protocols/smb + +event smb2_close_request(c: connection, hdr: SMB2::Header, file_id: SMB2::GUID) +{ + print "smb2_close_request", hdr; +} + +event smb2_close_response(c: connection, hdr: SMB2::Header, response: SMB2::CloseResponse) +{ + print "smb2_close_response", hdr, response; +} From b46aeefbabd514e8863e908170e99930a5ebd01d Mon Sep 17 00:00:00 2001 From: Christian Kreibich Date: Wed, 24 Jul 2024 16:48:06 -0700 Subject: [PATCH 18/91] Add contributors to 7.0.0 NEWS entry [skip ci] --- NEWS | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/NEWS b/NEWS index 13c25977f9..57a02b61a0 100644 --- a/NEWS +++ b/NEWS @@ -6,6 +6,13 @@ release. For an exhaustive list of changes, see the ``CHANGES`` file Zeek 7.0.0 ========== +We would like to thank the following people for their contributions to this +release: Christopher Knill (cknill), Jan Grashöfer (J-Gras), Martin van +Hensbergen (mvhensbergen), Matti Bispham (mbispham), Mike Dopheide +(dopheide-esnet), Oleksandr Pastushkov (opastushkov), Peter Cullen (pbcullen), +Steve Smoot (stevesmoot), Tanner Kvarfordt (Kardbord), Victor Dvornikov +(lydiym). + Breaking Changes ---------------- From 3a44bda957280e6c3eda0557a32adabc2b4fd60f Mon Sep 17 00:00:00 2001 From: Christian Kreibich Date: Tue, 23 Jul 2024 16:58:52 -0700 Subject: [PATCH 19/91] Bump zeek-testing-cluster to reflect deprecation of prometheus.zeek (cherry picked from commit 146cf99ff62d729705c155b44199a674911ade09) --- testing/external/commit-hash.zeek-testing-cluster | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testing/external/commit-hash.zeek-testing-cluster b/testing/external/commit-hash.zeek-testing-cluster index 5d84d38106..b8df5d15d0 100644 --- a/testing/external/commit-hash.zeek-testing-cluster +++ b/testing/external/commit-hash.zeek-testing-cluster @@ -1 +1 @@ -ded009fb7a0cdee6f36d5b40a6394788b760fa06 +9f875d86000602661fbfc9bb471d1c598917ebc9 From 5974613cae0d097fbfae9622b346a6cc6441405d Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Thu, 25 Jul 2024 10:52:29 -0700 Subject: [PATCH 20/91] Generate docs for 7.0.0-rc3 --- doc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc b/doc index 316ad305b6..2329974428 160000 --- a/doc +++ b/doc @@ -1 +1 @@ -Subproject commit 316ad305b69456fcd424ffaf99d1326822ad9d60 +Subproject commit 2329974428148b8bf2122745bb7b58494b394efa From b9e4669632b8bf0a1351d2dd4ab5942eb2d849b4 Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Thu, 25 Jul 2024 11:06:51 -0700 Subject: [PATCH 21/91] Updating CHANGES and VERSION. --- CHANGES | 24 ++++++++++++++++++++++++ VERSION | 2 +- 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index 859b7f0d30..bbc39852e1 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,27 @@ +7.0.0-rc3 | 2024-07-25 10:52:29 -0700 + + * Generate docs for 7.0.0-rc3 (Tim Wojtulewicz) + + * Bump zeek-testing-cluster to reflect deprecation of prometheus.zeek (Christian Kreibich, Corelight) + + (cherry picked from commit 146cf99ff62d729705c155b44199a674911ade09) + + * Update 7.0 NEWS with blurb about multi-PDU parsing causing increased load [nomail] [skip ci] (Tim Wojtulewicz, Corelight) + + (cherry picked from commit bd208f4c54f66074315479071c810d792e69f96b) + + * Fix handling of zero-length SMB2 error responses (Tim Wojtulewicz, Corelight) + + (cherry picked from commit bd208f4c54f66074315479071c810d792e69f96b) + + * Update Mozilla CA list and CT list (Johanna Amann, Corelight) + + (cherry picked from commit cb88f6316c7341da7a2af397932a145be3a0cc29) + + * Bump auxil/spicy to latest development snapshot (Benjamin Bannier, Corelight) + + (cherry picked from commit da7c3d91385195a7a4ba957e46743bc52a9d4ecb) + 7.0.0-rc2.7 | 2024-07-24 17:00:51 -0700 * Add contributors to 7.0.0 NEWS entry (Christian Kreibich, Corelight) diff --git a/VERSION b/VERSION index 625920dc5e..0761c39a86 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -7.0.0-rc2.7 +7.0.0-rc3 From b76096a9eef6aa039e30b8dbef8df1f4870e2408 Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Fri, 26 Jul 2024 10:09:48 -0700 Subject: [PATCH 22/91] Merge remote-tracking branch 'origin/topic/bbannier/bump-spicy' * origin/topic/bbannier/bump-spicy: Bump auxil/spicy to latest development snapshot (cherry picked from commit 4c0c7581c835b4dcd5339a4b34c2b82fcfc40dc3) --- CHANGES | 8 ++++++++ VERSION | 2 +- auxil/spicy | 2 +- 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/CHANGES b/CHANGES index bbc39852e1..4f14dba6d2 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,11 @@ +7.0.0-rc4 | 2024-07-26 10:12:34 -0700 + + * Bump auxil/spicy to latest development snapshot (Benjamin Bannier, Corelight) + + This in particular pulls in a fix for zeek/spicy#1808. + + (cherry picked from commit 4c0c7581c835b4dcd5339a4b34c2b82fcfc40dc3) + 7.0.0-rc3 | 2024-07-25 10:52:29 -0700 * Generate docs for 7.0.0-rc3 (Tim Wojtulewicz) diff --git a/VERSION b/VERSION index 0761c39a86..12751eb9a9 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -7.0.0-rc3 +7.0.0-rc4 diff --git a/auxil/spicy b/auxil/spicy index 04c5ed3c27..4c5c26bf34 160000 --- a/auxil/spicy +++ b/auxil/spicy @@ -1 +1 @@ -Subproject commit 04c5ed3c27879459de69d12efc417c6915f304b9 +Subproject commit 4c5c26bf34c2cf2cedf56270e84f1271fcf94465 From 72ff343f175f35e9373d1fb412d534453b8459cf Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Mon, 29 Jul 2024 11:40:28 -0700 Subject: [PATCH 23/91] Update docs submodule [nomail] [skip ci] --- doc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc b/doc index 2329974428..3cd0dd2315 160000 --- a/doc +++ b/doc @@ -1 +1 @@ -Subproject commit 2329974428148b8bf2122745bb7b58494b394efa +Subproject commit 3cd0dd2315663b0dcb38ac30b874492fd5071e6b From f8fbeca504f6b32b67ee9d02320eb22e11a3c31b Mon Sep 17 00:00:00 2001 From: Benjamin Bannier Date: Wed, 31 Jul 2024 14:57:53 +0200 Subject: [PATCH 24/91] Bump Spicy to latest release --- auxil/spicy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/auxil/spicy b/auxil/spicy index 4c5c26bf34..7ddf6ce441 160000 --- a/auxil/spicy +++ b/auxil/spicy @@ -1 +1 @@ -Subproject commit 4c5c26bf34c2cf2cedf56270e84f1271fcf94465 +Subproject commit 7ddf6ce441d63aa5894dd11d9a5047ddc761de9a From 55d36fc2cdbada347478f771231cca6bcdf4028a Mon Sep 17 00:00:00 2001 From: Benjamin Bannier Date: Wed, 31 Jul 2024 15:06:47 +0200 Subject: [PATCH 25/91] Allowlist a name for typos check --- .typos.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/.typos.toml b/.typos.toml index dfa60bd504..d162b1d842 100644 --- a/.typos.toml +++ b/.typos.toml @@ -30,6 +30,7 @@ extend-ignore-re = [ "\"BaR\"", "\"xFoObar\"", "\"FoO\"", + "Steve Smoot", ] extend-ignore-identifiers-re = [ From d1f6e91988c0eacf2c7a75ef7817f6c128be8445 Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Thu, 1 Aug 2024 10:42:25 -0700 Subject: [PATCH 26/91] Updating CHANGES and VERSION. --- CHANGES | 4 ++++ VERSION | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index 34feb74a85..bcfa60229b 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,7 @@ +7.0.0 | 2024-07-31 09:37:03 -0700 + + * Release 7.0.0. + 7.0.0-rc4.4 | 2024-07-31 09:36:51 -0700 * Allowlist a name for typos check (Benjamin Bannier, Corelight) diff --git a/VERSION b/VERSION index a0664e5d3d..66ce77b7ea 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -7.0.0-rc4.4 +7.0.0 From f6b88645847235b9cf7fa92edd3a75df99bb5d29 Mon Sep 17 00:00:00 2001 From: Christian Kreibich Date: Mon, 12 Aug 2024 17:54:52 -0700 Subject: [PATCH 27/91] Update docs submodule [nomail] [skip ci] --- doc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc b/doc index 3cd0dd2315..4e2413e2fb 160000 --- a/doc +++ b/doc @@ -1 +1 @@ -Subproject commit 3cd0dd2315663b0dcb38ac30b874492fd5071e6b +Subproject commit 4e2413e2fb2f98298430b3e2cb384fc5f18cbde4 From 056bbe04ea48d311201e62a5578d1d18682bb5e3 Mon Sep 17 00:00:00 2001 From: Arne Welzel Date: Thu, 1 Aug 2024 11:14:46 +0200 Subject: [PATCH 28/91] Merge remote-tracking branch 'origin/topic/timw/use-more-memory-for-freebsd-builds' * origin/topic/timw/use-more-memory-for-freebsd-builds: CI: Use 16GB of memory for FreeBSD builds (cherry picked from commit 9d9cc51e9dd93668cd332aa1aef283c9dc23a677) --- .cirrus.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.cirrus.yml b/.cirrus.yml index b96146f230..88ffb16c76 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -35,8 +35,7 @@ macos_environment: &MACOS_ENVIRONMENT freebsd_resources_template: &FREEBSD_RESOURCES_TEMPLATE cpu: 8 - # Not allowed to request less than 8GB for an 8 CPU FreeBSD VM. - memory: 8GB + memory: *MEMORY # For greediness, see https://medium.com/cirruslabs/introducing-greedy-container-instances-29aad06dc2b4 greedy: true From dd4597865a0b6c640fcccd1482de70b6af8df37f Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Fri, 2 Aug 2024 15:49:40 -0700 Subject: [PATCH 29/91] Merge remote-tracking branch 'origin/topic/timw/telemetry-threading' * origin/topic/timw/telemetry-threading: Process metric callbacks from the main-loop thread (cherry picked from commit 3c3853dc7da9aad94a9b2d5a143cc7bd9476ea7a) --- auxil/prometheus-cpp | 2 +- scripts/base/init-bare.zeek | 7 ++ src/telemetry/CMakeLists.txt | 1 + src/telemetry/Manager.cc | 79 ++++++++++++++++++- src/telemetry/Manager.h | 40 ++++++++-- src/telemetry/consts.bif | 2 + src/zeek-setup.cc | 2 + .../canonified_loaded_scripts.log | 1 + .../canonified_loaded_scripts.log | 1 + testing/btest/Baseline/plugins.hooks/output | 6 ++ 10 files changed, 130 insertions(+), 11 deletions(-) create mode 100644 src/telemetry/consts.bif diff --git a/auxil/prometheus-cpp b/auxil/prometheus-cpp index 2fec7205d1..4649065e2a 160000 --- a/auxil/prometheus-cpp +++ b/auxil/prometheus-cpp @@ -1 +1 @@ -Subproject commit 2fec7205d1a9cb4829b86c943d599696d53de85c +Subproject commit 4649065e2a1dd21c81e41cd6007dce5486b77fc0 diff --git a/scripts/base/init-bare.zeek b/scripts/base/init-bare.zeek index 30b49def26..85a1dc0f20 100644 --- a/scripts/base/init-bare.zeek +++ b/scripts/base/init-bare.zeek @@ -5883,6 +5883,13 @@ export { type MetricVector : vector of Metric; type HistogramMetricVector : vector of HistogramMetric; + + ## Maximum amount of time for CivetWeb HTTP threads to + ## wait for metric callbacks to complete on the IO loop. + const callback_timeout: interval = 5sec &redef; + + ## Number of CivetWeb threads to use. + const civetweb_threads: count = 2 &redef; } module GLOBAL; diff --git a/src/telemetry/CMakeLists.txt b/src/telemetry/CMakeLists.txt index d61cbdb671..a760dcd13c 100644 --- a/src/telemetry/CMakeLists.txt +++ b/src/telemetry/CMakeLists.txt @@ -9,6 +9,7 @@ zeek_add_subdir_library( ProcessStats.cc Utils.cc BIFS + consts.bif telemetry.bif) # We don't need to include the civetweb headers across the whole project, only diff --git a/src/telemetry/Manager.cc b/src/telemetry/Manager.cc index 04c47ba3ef..6ae4e06ec6 100644 --- a/src/telemetry/Manager.cc +++ b/src/telemetry/Manager.cc @@ -6,6 +6,7 @@ // CivetServer is from the civetweb submodule in prometheus-cpp #include +#include #include #include #include @@ -16,19 +17,32 @@ #include "zeek/3rdparty/doctest.h" #include "zeek/ID.h" +#include "zeek/RunState.h" #include "zeek/ZeekString.h" #include "zeek/broker/Manager.h" +#include "zeek/iosource/Manager.h" #include "zeek/telemetry/ProcessStats.h" #include "zeek/telemetry/Timer.h" +#include "zeek/telemetry/consts.bif.h" #include "zeek/telemetry/telemetry.bif.h" #include "zeek/threading/formatters/detail/json.h" namespace zeek::telemetry { -Manager::Manager() { prometheus_registry = std::make_shared(); } +/** + * Prometheus Collectable interface used to insert Zeek callback processing + * before the Prometheus registry's collection of metric data. + */ +class ZeekCollectable : public prometheus::Collectable { +public: + std::vector Collect() const override { + telemetry_mgr->WaitForPrometheusCallbacks(); + return {}; + } +}; + +Manager::Manager() : IOSource(true) { prometheus_registry = std::make_shared(); } -// This can't be defined as =default because of the use of unique_ptr with a forward-declared type -// in Manager.h Manager::~Manager() {} void Manager::InitPostScript() { @@ -75,7 +89,9 @@ void Manager::InitPostScript() { if ( ! getenv("ZEEKCTL_CHECK_CONFIG") ) { try { - prometheus_exposer = std::make_unique(prometheus_url, 2, callbacks); + prometheus_exposer = + std::make_unique(prometheus_url, BifConst::Telemetry::civetweb_threads, + callbacks); // CivetWeb stores a copy of the callbacks, so we're safe to delete the pointer here delete callbacks; @@ -84,6 +100,13 @@ void Manager::InitPostScript() { prometheus_url.c_str()); } + // This has to be inserted before the registry below. The exposer + // processes the collectors in order of insertion. We want to make + // sure that the callbacks get called and the values in the metrics + // are updated before prometheus-cpp scrapes them. + zeek_collectable = std::make_shared(); + prometheus_exposer->RegisterCollectable(zeek_collectable); + prometheus_exposer->RegisterCollectable(prometheus_registry); } } @@ -130,6 +153,21 @@ void Manager::InitPostScript() { return metric; }); #endif + + iosource_mgr->RegisterFd(collector_flare.FD(), this); +} + +void Manager::Terminate() { + // Notify the collector condition so that it doesn't hang waiting for + // a collector request to complete. + collector_cv.notify_all(); + + // Shut down the exposer first of all so we stop getting requests for + // data. This keeps us from getting a request on another thread while + // we're shutting down. + prometheus_exposer.reset(); + + iosource_mgr->UnregisterFd(collector_flare.FD(), this); } // -- collect metric stuff ----------------------------------------------------- @@ -545,6 +583,39 @@ HistogramPtr Manager::HistogramInstance(std::string_view prefix, std::string_vie return HistogramInstance(prefix, name, lbls, bounds_span, helptext, unit); } +void Manager::ProcessFd(int fd, int flags) { + std::unique_lock lk(collector_cv_mtx); + + collector_flare.Extinguish(); + + prometheus_registry->UpdateViaCallbacks(); + collector_response_idx = collector_request_idx; + + lk.unlock(); + collector_cv.notify_all(); +} + +void Manager::WaitForPrometheusCallbacks() { + std::unique_lock lk(collector_cv_mtx); + + ++collector_request_idx; + uint64_t expected_idx = collector_request_idx; + collector_flare.Fire(); + + // It should *not* take 5 seconds to go through all of the callbacks, but + // set this to have a timeout anyways just to avoid a deadlock. + bool res = collector_cv.wait_for(lk, + std::chrono::microseconds( + static_cast(BifConst::Telemetry::callback_timeout * 1000000)), + [expected_idx]() { + return telemetry_mgr->collector_response_idx >= expected_idx || + zeek::run_state::terminating; + }); + + if ( ! res ) + fprintf(stderr, "Timeout waiting for prometheus callbacks\n"); +} + } // namespace zeek::telemetry // -- unit tests --------------------------------------------------------------- diff --git a/src/telemetry/Manager.h b/src/telemetry/Manager.h index c4c2537f1a..d967fe43c0 100644 --- a/src/telemetry/Manager.h +++ b/src/telemetry/Manager.h @@ -9,8 +9,10 @@ #include #include +#include "zeek/Flare.h" #include "zeek/IntrusivePtr.h" #include "zeek/Span.h" +#include "zeek/iosource/IOSource.h" #include "zeek/telemetry/Counter.h" #include "zeek/telemetry/Gauge.h" #include "zeek/telemetry/Histogram.h" @@ -29,15 +31,16 @@ class Registry; namespace zeek::telemetry { +class ZeekCollectable; + /** * Manages a collection of metric families. */ -class Manager final { +class Manager final : public iosource::IOSource { public: Manager(); Manager(const Manager&) = delete; - Manager& operator=(const Manager&) = delete; ~Manager(); @@ -50,6 +53,8 @@ public: */ void InitPostScript(); + void Terminate(); + /** * @return A VectorVal containing all counter and gauge metrics and their values matching prefix and name. * @param prefix The prefix pattern to use for filtering. Supports globbing. @@ -88,8 +93,8 @@ public: * @param labels Values for all label dimensions of the metric. * @param helptext Short explanation of the metric. * @param unit Unit of measurement. - * @param callback Passing a callback method will enable asynchronous mode. The callback method will be called by - * the metrics subsystem whenever data is requested. + * @param callback Passing a callback method will enable asynchronous mode. The callback method will be called + * by the metrics subsystem whenever data is requested. */ CounterPtr CounterInstance(std::string_view prefix, std::string_view name, Span labels, std::string_view helptext, std::string_view unit = "", @@ -124,8 +129,8 @@ public: * @param labels Values for all label dimensions of the metric. * @param helptext Short explanation of the metric. * @param unit Unit of measurement. - * @param callback Passing a callback method will enable asynchronous mode. The callback method will be called by - * the metrics subsystem whenever data is requested. + * @param callback Passing a callback method will enable asynchronous mode. The callback method will be called + * by the metrics subsystem whenever data is requested. */ GaugePtr GaugeInstance(std::string_view prefix, std::string_view name, Span labels, std::string_view helptext, std::string_view unit = "", @@ -212,6 +217,12 @@ public: */ std::shared_ptr GetRegistry() const { return prometheus_registry; } + // IOSource interface + double GetNextTimeout() override { return -1.0; } + void Process() override {} + const char* Tag() override { return "Telemetry::Manager"; } + void ProcessFd(int fd, int flags) override; + protected: template static auto WithLabelNames(Span xs, F continuation) { @@ -231,6 +242,15 @@ protected: } } + friend class ZeekCollectable; + + /** + * Fires the flare for prometheus-cpp callback handling and waits for it to complete. + * This can be called from other threads to ensure the callback handling happens on + * the main thread. + */ + void WaitForPrometheusCallbacks(); + private: RecordValPtr GetMetricOptsRecord(const prometheus::MetricFamily& metric_family); void BuildClusterJson(); @@ -250,6 +270,14 @@ private: std::unique_ptr prometheus_exposer; std::string cluster_json; + + std::shared_ptr zeek_collectable; + zeek::detail::Flare collector_flare; + std::condition_variable collector_cv; + std::mutex collector_cv_mtx; + // Only modified under collector_cv_mtx! + uint64_t collector_request_idx = 0; + uint64_t collector_response_idx = 0; }; } // namespace zeek::telemetry diff --git a/src/telemetry/consts.bif b/src/telemetry/consts.bif new file mode 100644 index 0000000000..76c256dfa1 --- /dev/null +++ b/src/telemetry/consts.bif @@ -0,0 +1,2 @@ +const Telemetry::callback_timeout: interval; +const Telemetry::civetweb_threads: count; diff --git a/src/zeek-setup.cc b/src/zeek-setup.cc index b05af74f20..3f5549b78a 100644 --- a/src/zeek-setup.cc +++ b/src/zeek-setup.cc @@ -376,6 +376,7 @@ static void terminate_zeek() { input_mgr->Terminate(); thread_mgr->Terminate(); broker_mgr->Terminate(); + telemetry_mgr->Terminate(); event_mgr.Drain(); @@ -716,6 +717,7 @@ SetupResult setup(int argc, char** argv, Options* zopts) { // when that variable is defined. auto early_shutdown = [] { broker_mgr->Terminate(); + telemetry_mgr->Terminate(); delete iosource_mgr; delete telemetry_mgr; }; diff --git a/testing/btest/Baseline/coverage.bare-load-baseline/canonified_loaded_scripts.log b/testing/btest/Baseline/coverage.bare-load-baseline/canonified_loaded_scripts.log index aee483157a..5466f0ea13 100644 --- a/testing/btest/Baseline/coverage.bare-load-baseline/canonified_loaded_scripts.log +++ b/testing/btest/Baseline/coverage.bare-load-baseline/canonified_loaded_scripts.log @@ -146,6 +146,7 @@ scripts/base/init-frameworks-and-bifs.zeek scripts/base/frameworks/files/magic/__load__.zeek scripts/base/frameworks/telemetry/options.zeek build/scripts/base/bif/__load__.zeek + build/scripts/base/bif/consts.bif.zeek build/scripts/base/bif/telemetry.bif.zeek build/scripts/base/bif/zeekygen.bif.zeek build/scripts/base/bif/pcap.bif.zeek diff --git a/testing/btest/Baseline/coverage.default-load-baseline/canonified_loaded_scripts.log b/testing/btest/Baseline/coverage.default-load-baseline/canonified_loaded_scripts.log index 40a1c5b84c..07dc32da6d 100644 --- a/testing/btest/Baseline/coverage.default-load-baseline/canonified_loaded_scripts.log +++ b/testing/btest/Baseline/coverage.default-load-baseline/canonified_loaded_scripts.log @@ -146,6 +146,7 @@ scripts/base/init-frameworks-and-bifs.zeek scripts/base/frameworks/files/magic/__load__.zeek scripts/base/frameworks/telemetry/options.zeek build/scripts/base/bif/__load__.zeek + build/scripts/base/bif/consts.bif.zeek build/scripts/base/bif/telemetry.bif.zeek build/scripts/base/bif/zeekygen.bif.zeek build/scripts/base/bif/pcap.bif.zeek diff --git a/testing/btest/Baseline/plugins.hooks/output b/testing/btest/Baseline/plugins.hooks/output index c3b551dc84..2514d98015 100644 --- a/testing/btest/Baseline/plugins.hooks/output +++ b/testing/btest/Baseline/plugins.hooks/output @@ -464,6 +464,7 @@ 0.000000 MetaHookPost LoadFile(0, ./comm.bif.zeek, <...>/comm.bif.zeek) -> -1 0.000000 MetaHookPost LoadFile(0, ./communityid.bif.zeek, <...>/communityid.bif.zeek) -> -1 0.000000 MetaHookPost LoadFile(0, ./const.bif.zeek, <...>/const.bif.zeek) -> -1 +0.000000 MetaHookPost LoadFile(0, ./consts.bif.zeek, <...>/consts.bif.zeek) -> -1 0.000000 MetaHookPost LoadFile(0, ./contents, <...>/contents.zeek) -> -1 0.000000 MetaHookPost LoadFile(0, ./control, <...>/control.zeek) -> -1 0.000000 MetaHookPost LoadFile(0, ./data.bif.zeek, <...>/data.bif.zeek) -> -1 @@ -758,6 +759,7 @@ 0.000000 MetaHookPost LoadFileExtended(0, ./comm.bif.zeek, <...>/comm.bif.zeek) -> (-1, ) 0.000000 MetaHookPost LoadFileExtended(0, ./communityid.bif.zeek, <...>/communityid.bif.zeek) -> (-1, ) 0.000000 MetaHookPost LoadFileExtended(0, ./const.bif.zeek, <...>/const.bif.zeek) -> (-1, ) +0.000000 MetaHookPost LoadFileExtended(0, ./consts.bif.zeek, <...>/consts.bif.zeek) -> (-1, ) 0.000000 MetaHookPost LoadFileExtended(0, ./contents, <...>/contents.zeek) -> (-1, ) 0.000000 MetaHookPost LoadFileExtended(0, ./control, <...>/control.zeek) -> (-1, ) 0.000000 MetaHookPost LoadFileExtended(0, ./data.bif.zeek, <...>/data.bif.zeek) -> (-1, ) @@ -1384,6 +1386,7 @@ 0.000000 MetaHookPre LoadFile(0, ./comm.bif.zeek, <...>/comm.bif.zeek) 0.000000 MetaHookPre LoadFile(0, ./communityid.bif.zeek, <...>/communityid.bif.zeek) 0.000000 MetaHookPre LoadFile(0, ./const.bif.zeek, <...>/const.bif.zeek) +0.000000 MetaHookPre LoadFile(0, ./consts.bif.zeek, <...>/consts.bif.zeek) 0.000000 MetaHookPre LoadFile(0, ./contents, <...>/contents.zeek) 0.000000 MetaHookPre LoadFile(0, ./control, <...>/control.zeek) 0.000000 MetaHookPre LoadFile(0, ./data.bif.zeek, <...>/data.bif.zeek) @@ -1678,6 +1681,7 @@ 0.000000 MetaHookPre LoadFileExtended(0, ./comm.bif.zeek, <...>/comm.bif.zeek) 0.000000 MetaHookPre LoadFileExtended(0, ./communityid.bif.zeek, <...>/communityid.bif.zeek) 0.000000 MetaHookPre LoadFileExtended(0, ./const.bif.zeek, <...>/const.bif.zeek) +0.000000 MetaHookPre LoadFileExtended(0, ./consts.bif.zeek, <...>/consts.bif.zeek) 0.000000 MetaHookPre LoadFileExtended(0, ./contents, <...>/contents.zeek) 0.000000 MetaHookPre LoadFileExtended(0, ./control, <...>/control.zeek) 0.000000 MetaHookPre LoadFileExtended(0, ./data.bif.zeek, <...>/data.bif.zeek) @@ -2305,6 +2309,7 @@ 0.000000 | HookLoadFile ./comm.bif.zeek <...>/comm.bif.zeek 0.000000 | HookLoadFile ./communityid.bif.zeek <...>/communityid.bif.zeek 0.000000 | HookLoadFile ./const.bif.zeek <...>/const.bif.zeek +0.000000 | HookLoadFile ./consts.bif.zeek <...>/consts.bif.zeek 0.000000 | HookLoadFile ./contents <...>/contents.zeek 0.000000 | HookLoadFile ./control <...>/control.zeek 0.000000 | HookLoadFile ./data.bif.zeek <...>/data.bif.zeek @@ -2599,6 +2604,7 @@ 0.000000 | HookLoadFileExtended ./comm.bif.zeek <...>/comm.bif.zeek 0.000000 | HookLoadFileExtended ./communityid.bif.zeek <...>/communityid.bif.zeek 0.000000 | HookLoadFileExtended ./const.bif.zeek <...>/const.bif.zeek +0.000000 | HookLoadFileExtended ./consts.bif.zeek <...>/consts.bif.zeek 0.000000 | HookLoadFileExtended ./contents <...>/contents.zeek 0.000000 | HookLoadFileExtended ./control <...>/control.zeek 0.000000 | HookLoadFileExtended ./data.bif.zeek <...>/data.bif.zeek From 8a92b150a581bfd58261bd489045ac8f6cf5089f Mon Sep 17 00:00:00 2001 From: Arne Welzel Date: Fri, 23 Aug 2024 09:40:53 +0200 Subject: [PATCH 30/91] Merge remote-tracking branch 'origin/topic/awelzel/tcp-reassembler-undelivered-data-match-bool-bool-bool-confusion' * origin/topic/awelzel/tcp-reassembler-undelivered-data-match-bool-bool-bool-confusion: TCP_Reassembler: Fix IsOrig() position in Match() call (cherry picked from commit 4a4cbf25765f387f0aa20277afd133918292b9c4) --- src/analyzer/protocol/tcp/TCP_Reassembler.cc | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/analyzer/protocol/tcp/TCP_Reassembler.cc b/src/analyzer/protocol/tcp/TCP_Reassembler.cc index e9c2a1f2f6..9a63962db2 100644 --- a/src/analyzer/protocol/tcp/TCP_Reassembler.cc +++ b/src/analyzer/protocol/tcp/TCP_Reassembler.cc @@ -273,7 +273,12 @@ void TCP_Reassembler::MatchUndelivered(uint64_t up_to_seq, bool use_last_upper) if ( b.upper > last_reassem_seq ) break; - tcp_analyzer->Conn()->Match(zeek::detail::Rule::PAYLOAD, b.block, b.Size(), false, false, IsOrig(), false); + // Note: Even though this passes bol=false, at the point where + // this code runs, the matcher is re-initialized resulting in + // undelivered data implicitly being bol-anchored. It's unclear + // if that was intended, but there's hardly a right way here, + // so that seems ok. + tcp_analyzer->Conn()->Match(zeek::detail::Rule::PAYLOAD, b.block, b.Size(), IsOrig(), false, false, false); } } From e7ab18b343e115207af95caaa35bf09333f1b1bf Mon Sep 17 00:00:00 2001 From: Arne Welzel Date: Fri, 23 Aug 2024 14:18:35 +0200 Subject: [PATCH 31/91] Merge remote-tracking branch 'origin/topic/awelzel/no-child-analyzer-on-finished-connections' * origin/topic/awelzel/no-child-analyzer-on-finished-connections: Analyzer: Do not add child analyzers when finished (cherry picked from commit 45b33bf5c17d5e8cf6c777a9bd57e4a803dfad19) --- src/Conn.h | 3 +++ src/analyzer/Analyzer.cc | 38 +++++++++++++++++++++++++------------- 2 files changed, 28 insertions(+), 13 deletions(-) diff --git a/src/Conn.h b/src/Conn.h index f6ec77e59a..269f432409 100644 --- a/src/Conn.h +++ b/src/Conn.h @@ -201,6 +201,9 @@ public: bool PermitWeird(const char* name, uint64_t threshold, uint64_t rate, double duration); + // Returns true once Done() is called. + bool IsFinished() { return finished; } + private: friend class session::detail::Timer; diff --git a/src/analyzer/Analyzer.cc b/src/analyzer/Analyzer.cc index e8f2b65d28..5db65b44a2 100644 --- a/src/analyzer/Analyzer.cc +++ b/src/analyzer/Analyzer.cc @@ -113,19 +113,7 @@ void Analyzer::CtorInit(const zeek::Tag& arg_tag, Connection* arg_conn) { Analyzer::~Analyzer() { assert(finished); - - // Make sure any late entries into the analyzer tree are handled (e.g. - // from some Done() implementation). - LOOP_OVER_GIVEN_CHILDREN(i, new_children) { - if ( ! (*i)->finished ) - (*i)->Done(); - } - - // Deletion of new_children done in separate loop in case a Done() - // implementation tries to inspect analyzer tree w/ assumption that - // all analyzers are still valid. - LOOP_OVER_GIVEN_CHILDREN(i, new_children) - delete *i; + assert(new_children.empty()); LOOP_OVER_CHILDREN(i) delete *i; @@ -330,6 +318,30 @@ void Analyzer::ForwardEndOfData(bool orig) { bool Analyzer::AddChildAnalyzer(Analyzer* analyzer, bool init) { auto t = analyzer->GetAnalyzerTag(); + // Prevent attaching child analyzers to analyzer subtrees where + // either the parent has finished or is being removed. Further, + // don't attach analyzers when the connection has finished or is + // currently being finished (executing Done()). + // + // Scenarios in which analyzers have been observed that late in + // analyzer / connection lifetime are: + // + // * A DPD signature match on undelivered TCP data that is flushed + // during Connection::Done(). The PIA analyzer activates a new + // analyzer adding it to the TCP analyzer. + // + // * Analyzers flushing buffered state during Done(), resulting + // in new analyzers being created. + // + // Analyzers added during Done() are problematic as calling Done() + // within the parent's destructor isn't safe, so we prevent these + // situations. + if ( Removing() || IsFinished() || Conn()->IsFinished() ) { + analyzer->Done(); + delete analyzer; + return false; + } + if ( HasChildAnalyzer(t) || IsPreventedChildAnalyzer(t) ) { analyzer->Done(); delete analyzer; From 0fd6672ddeef497dcf04456bf43f97b90ee8a215 Mon Sep 17 00:00:00 2001 From: Arne Welzel Date: Fri, 30 Aug 2024 18:56:24 +0200 Subject: [PATCH 32/91] Merge branch 'fix-http-password-capture' of https://github.com/p-l-/zeek * 'fix-http-password-capture' of https://github.com/p-l-/zeek: http: fix password capture when enabled (cherry picked from commit c27e18631c5d9c6f04c230bd421c9750a1f02342) --- scripts/base/protocols/http/main.zeek | 4 ++-- .../http.log | 11 +++++++++++ .../Traces/http/basic-auth-with-colon.trace | Bin 0 -> 1840 bytes .../protocols/http/http-basic-auth-colon.zeek | 8 ++++++++ 4 files changed, 21 insertions(+), 2 deletions(-) create mode 100644 testing/btest/Baseline/scripts.base.protocols.http.http-basic-auth-colon/http.log create mode 100644 testing/btest/Traces/http/basic-auth-with-colon.trace create mode 100644 testing/btest/scripts/base/protocols/http/http-basic-auth-colon.zeek diff --git a/scripts/base/protocols/http/main.zeek b/scripts/base/protocols/http/main.zeek index 0f65c6b984..e334a83253 100644 --- a/scripts/base/protocols/http/main.zeek +++ b/scripts/base/protocols/http/main.zeek @@ -338,8 +338,8 @@ event http_header(c: connection, is_orig: bool, name: string, value: string) &pr if ( /^[bB][aA][sS][iI][cC] / in value ) { local userpass = decode_base64_conn(c$id, sub(value, /[bB][aA][sS][iI][cC][[:blank:]]+/, "")); - local up = split_string(userpass, /:/); - if ( |up| >= 2 ) + local up = split_string1(userpass, /:/); + if ( |up| == 2 ) { c$http$username = up[0]; if ( c$http$capture_password ) diff --git a/testing/btest/Baseline/scripts.base.protocols.http.http-basic-auth-colon/http.log b/testing/btest/Baseline/scripts.base.protocols.http.http-basic-auth-colon/http.log new file mode 100644 index 0000000000..e386f15fb5 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.http.http-basic-auth-colon/http.log @@ -0,0 +1,11 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path http +#open XXXX-XX-XX-XX-XX-XX +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p trans_depth method host uri referrer version user_agent origin request_body_len response_body_len status_code status_msg info_code info_msg tags username password proxied orig_fuids orig_filenames orig_mime_types resp_fuids resp_filenames resp_mime_types +#types time string addr port addr port count string string string string string string string count count count string count string set[enum] string string set[string] vector[string] vector[string] vector[string] vector[string] vector[string] vector[string] +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 172.24.133.205 43090 172.24.133.205 8000 1 GET 172.24.133.205:8000 / - 1.0 python-requests/2.31.0 - 0 643 200 OK - - (empty) test 1:34 - - - - FM4Ls72L4REzbA61lg - text/html +#close XXXX-XX-XX-XX-XX-XX diff --git a/testing/btest/Traces/http/basic-auth-with-colon.trace b/testing/btest/Traces/http/basic-auth-with-colon.trace new file mode 100644 index 0000000000000000000000000000000000000000..c1b03b6ecbad02a99d58e70d607337d0279a05fd GIT binary patch literal 1840 zcmZ{lO>Epm6vroSC}hP-El3dH(7^|Us;tNR(WG&lRnmBsLb6GeZ27twdv@2vv5h^O zbfZ0l11EYxLgiX+Edo&?RTXDcI8;q8g(6X@2M`=URga|~THcJ;X}#^PG&|#+H$VU9 zKkv<6|MB~;Bs7eYPq&NEpYV|TZMVMk(g@OF%v%LI}8#@qSTBQxmI zXTS5c=cMk9A6`UA8t&d0mY&Phf8Nyi??VR;Jj+=>^|27*tY7aWtRpk$SFZ%)-vRID zxfi-uZ~dEQabCh2eR%|xfXy4|DjEL?UEPG$({&Sg7k3Ux=->s=F%)a!9InR(#%);7 z8!&Dg_XNXuDq~ba|J+J5<|{Q!@X1*THRaMPq zPDM1#%{Hh90YRHJeJ>Z%k6Sci5h*CeyaF+^mPG@Wt9X`gJ6=P>jcq3w!#1tECZox` zhL4h?+02~pdDLQ#?`e3Q(jaHL&L$6P0X%fJ&3NjB895fl_WV2Bw&9;%{-_Es%4YcP z$41i*b{6>VKlnD;eeX0bqDyDa?i?EGK659%d(QX-7<=FzZ{XlwXHhT?Ka~LvJ`Z`) zJB2BJ3O(;sTu@cKypYYT(QuQ78eVfY0+)(uRT;-C!ZK1+^6-?+7~qG7tG+je3*-3h zmIvz#MVwc)V?_-}^VOPgh=JcZ)(#+;(bJ4H*@ioXt)>}9lufr-J$L+3+#>ZFtf}Gg zQZcdUk3Nfx`yxReCfkdX?9ACK!Nh{FXf3t9DQ*#YWdvQ8kZ2VoUG7vlQdyF*++-}! z2-(`&QnreUA2vvBRqVY)A{IIpQ*36-<&4h#;2kw>=r$-bF<+a5%yc%VWymq%U=19U zu@yf}%Y&@sMCLG;mJKI_-1NgXcAbbpF5|i%Vxp6HI-`@`D?jw@HW!c|yaeVTAcU_L z*XlZD9aM(2J}oN^hY`6fI-QthoxtpqAx^{dLmJ1$;{m~z+lm;}sZ9gdZz~(%(Gx!n zSXysc>q=mmfn44n4hRiQYu#*65T1+%1-h+<=MEEP5CcSeJNmCZL#TSsqsr&YUD1`?}8b2z9$z3Rgd(toIH0Gu7cORp(ByNkZ z6GmJLle?l64ogV7w$ISvwh-m?*QDU7uU-JKse#ZY7z(KtL literal 0 HcmV?d00001 diff --git a/testing/btest/scripts/base/protocols/http/http-basic-auth-colon.zeek b/testing/btest/scripts/base/protocols/http/http-basic-auth-colon.zeek new file mode 100644 index 0000000000..6cef93eba7 --- /dev/null +++ b/testing/btest/scripts/base/protocols/http/http-basic-auth-colon.zeek @@ -0,0 +1,8 @@ +# Authorization: Basic password has a colon in its value +# +# @TEST-EXEC: zeek -b -r $TRACES/http/basic-auth-with-colon.trace %INPUT +# @TEST-EXEC: btest-diff http.log + +@load base/protocols/http + +redef HTTP::default_capture_password = T; From cfe47f40a4b01a75f38a4578600c4e8ce3eb3cb9 Mon Sep 17 00:00:00 2001 From: Arne Welzel Date: Wed, 17 Jul 2024 16:45:13 +0200 Subject: [PATCH 33/91] Merge remote-tracking branch 'origin/topic/awelzel/spicy-ldap-krb-wrap-tokens' * origin/topic/awelzel/spicy-ldap-krb-wrap-tokens: ldap: Remove MessageWrapper with magic 0x30 searching ldap: Harden parsing a bit ldap: Handle integrity-only KRB wrap tokens (cherry picked from commit 2ea3a651bd83b0dfa15924417e4667241531b57b) --- src/analyzer/protocol/ldap/ldap.spicy | 313 ++++++++++++------ .../scripts.base.protocols.ldap.add/conn.log | 11 + .../scripts.base.protocols.ldap.add/ldap.log | 14 + .../conn.log | 11 + .../ldap.log | 12 + .../ldap_search.log | 14 + .../conn.log | 13 + .../ldap.log | 15 + .../ldap_search.log | 27 ++ testing/btest/Traces/ldap/ldap-add.pcap | Bin 0 -> 2012 bytes .../ldap/missing_krbtgt_ldap_request.pcapng | Bin 0 -> 101144 bytes .../Traces/ldap/missing_ldap_logs.pcapng | Bin 0 -> 443684 bytes .../scripts/base/protocols/ldap/add.zeek | 11 + .../protocols/ldap/sasl-signed-clear-2.zeek | 11 + .../protocols/ldap/sasl-signed-clear.zeek | 11 + 15 files changed, 357 insertions(+), 106 deletions(-) create mode 100644 testing/btest/Baseline/scripts.base.protocols.ldap.add/conn.log create mode 100644 testing/btest/Baseline/scripts.base.protocols.ldap.add/ldap.log create mode 100644 testing/btest/Baseline/scripts.base.protocols.ldap.sasl-signed-clear-2/conn.log create mode 100644 testing/btest/Baseline/scripts.base.protocols.ldap.sasl-signed-clear-2/ldap.log create mode 100644 testing/btest/Baseline/scripts.base.protocols.ldap.sasl-signed-clear-2/ldap_search.log create mode 100644 testing/btest/Baseline/scripts.base.protocols.ldap.sasl-signed-clear/conn.log create mode 100644 testing/btest/Baseline/scripts.base.protocols.ldap.sasl-signed-clear/ldap.log create mode 100644 testing/btest/Baseline/scripts.base.protocols.ldap.sasl-signed-clear/ldap_search.log create mode 100644 testing/btest/Traces/ldap/ldap-add.pcap create mode 100644 testing/btest/Traces/ldap/missing_krbtgt_ldap_request.pcapng create mode 100644 testing/btest/Traces/ldap/missing_ldap_logs.pcapng create mode 100644 testing/btest/scripts/base/protocols/ldap/add.zeek create mode 100644 testing/btest/scripts/base/protocols/ldap/sasl-signed-clear-2.zeek create mode 100644 testing/btest/scripts/base/protocols/ldap/sasl-signed-clear.zeek diff --git a/src/analyzer/protocol/ldap/ldap.spicy b/src/analyzer/protocol/ldap/ldap.spicy index 8d74b85237..2d4f821d78 100644 --- a/src/analyzer/protocol/ldap/ldap.spicy +++ b/src/analyzer/protocol/ldap/ldap.spicy @@ -126,125 +126,126 @@ public type Result = unit { # https://tools.ietf.org/html/rfc4511#section-4.1.10 }; +# 1.2.840.48018.1.2.2 (MS KRB5 - Microsoft Kerberos 5) +const GSSAPI_MECH_MS_KRB5 = "1.2.840.48018.1.2.2"; + +# Supported SASL stripping modes. +type SaslStripping = enum { + MS_KRB5 = 1, # Payload starts with a 4 byte length followed by a wrap token that may or may not be sealed. +}; + +type Ctx = struct { + saslStripping: SaslStripping; # Which mode of SASL stripping to use. +}; + #----------------------------------------------------------------------------- public type Messages = unit { - : MessageWrapper[]; + %context = Ctx; + : SASLStrip(self.context())[]; }; #----------------------------------------------------------------------------- -type SASLLayer = unit { - # For the time being (before we support parsing the SASL layer) this unit - # is used by MessageWrapper below to strip it (SASL) so that the parser - # can attempt to resume parsing afterward. It also sets the success flag - # if '\x30' is found, otherwise backtracks so that we can deal with encrypted - # SASL payloads without raising a parse error. - var success: bool = False; - : bytes &until=b"\x30" { - self.success = True; +public type SASLStrip = unit(ctx: Ctx&) { + switch( ctx.saslStripping ) { + SaslStripping::Undef -> : Message(ctx); + SaslStripping::MS_KRB5 -> : SaslMsKrb5Stripper(ctx); + }; +}; + + +type KrbWrapToken = unit { + # https://datatracker.ietf.org/doc/html/rfc4121#section-4.2.6.2 + + # Number of bytes to expect *after* the payload. + var trailer_ec: uint64; + var header_ec: uint64; + + ctx_flags: bitfield(8) { + send_by_acceptor: 0; + sealed: 1; + acceptor_subkey: 2; + }; + filler: skip b"\xff"; + ec: uint16; # extra count + rrc: uint16 { # right rotation count + # Handle rrc == ec or rrc == 0. + if ( self.rrc == self.ec ) { + self.header_ec = self.ec; + } else if ( self.rrc == 0 ) { + self.trailer_ec = self.ec; + } else { + throw "Unhandled rc %s and ec %s" % (self.ec, self.rrc); + } } - on %error { - self.backtrack(); - } + snd_seq: uint64; + header_e: skip bytes &size=self.header_ec; }; #----------------------------------------------------------------------------- -public type MessageWrapper = unit { - # A wrapper around 'Message'. First, we try to parse a Message unit. - # There are two possible outcomes: - # (1) Success -> We consumed all bytes and successfully parsed a Message unit - # (2) No success -> self.backtrack() is called in the Message unit, - # so effectively we didn't consume any bytes yet. - # The outcome can be determined by checking the `success` variable of the Message unit +type SaslMsKrb5Stripper = unit(ctx: Ctx&) { + # This is based on Wireshark output and example traffic we have. There's always + # a 4 byte length field followed by the krb5_tok_id field in messages after + # MS_KRB5 was selected. I haven't read enough specs to understand if it's + # just this one case that works, or others could use the same stripping. + var switch_size: uint64; - # This success variable is different, because this keeps track of the status for the MessageWrapper object - var success: bool = False; - var message: Message; + len: uint32; + krb5_tok_id: uint16; - # Here, we try to parse the message... - : Message &try { + switch ( self.krb5_tok_id ) { + 0x0504 -> krb_wrap_token: KrbWrapToken; + * -> : void; + }; - # ... and only if the Message unit successfully parsed, we can set - # the status of this MessageWrapper's success to 'True' - if ( $$.success == True ) { - self.success = True; - self.message = $$; - } + : skip bytes &size=0 { + self.switch_size = self.len - (self.offset() - 4); + if ( self?.krb_wrap_token ) + self.switch_size -= self.krb_wrap_token.trailer_ec; } - # If we failed to parse the message, then we're going to scan the remaining bytes for the '\x30' - # start byte and try to parse a Message starting from that byte. This effectively - # strips the SASL layer if SASL Signing was enabled. Until now, I haven't found A - # better way to scan / determine the exact SASL header length yet, so we'll stick with this - # for the time being. If the entire LDAP packet was encrypted with SASL, then we skip parsing for - # now (in the long run we need to be parsing SASL/GSSAPI instead, in which case encrypted payloads - # are just another message type). + switch ( self?.krb_wrap_token && ! self.krb_wrap_token.ctx_flags.sealed ) { + True -> : Message(ctx)[] &eod; + * -> : skip bytes &eod; + } &size=self.switch_size; - # SASLLayer (see unit above) just consumes bytes &until=b"\x30" or backtracks if it isn't found - # and sets a success flag we can use later to decide if those bytes contain a parsable message. - var sasl_success: bool = False; - : SASLLayer &try if ( self.success == False ) { - if ( $$.success == True ) { - self.sasl_success = True; - } - } - var remainder: bytes; - - # SASLLayer consumes the delimiter ('\x30'), and because this is the first byte of a valid LDAP message - # we should re-add it to the remainder if the delimiter was found. If the delimiter was not found, we - # leave the remainder empty, but note that the bytes must be consumed either way to avoid stalling the - # parser and causing an infinite loop error. - : bytes &eod if ( self.success == False ) { - if ( self.sasl_success == True ) { - self.remainder = b"\x30" + $$; - } - } - - # Again, try to parse a Message unit. Be aware that in this will sometimes fail if the '\x30' byte is - # also present in the SASL header. - - # Also, we could try to do this recursively or try a few iterations, but for now I would suggest - # to try this extra parsing once to get the best cost/benefit tradeoff. - : Message &try &parse-from=self.remainder if ( self.success == False && self.sasl_success == True ) { - if ( $$.success == True ) { - self.success = True; - self.message = $$; - } - } - - # If we still didn't manage to parse a message (so the &try resulted in another backtrack()) then - # this is probably an encrypted LDAP message, so skip it - -} &convert=self.message; + # Consume the wrap token trailer, if any. + trailer_e: skip bytes &size=self.krb_wrap_token.trailer_ec if (self?.krb_wrap_token); +}; #----------------------------------------------------------------------------- -public type Message = unit { +public type Message = unit(ctx: Ctx&) { var messageID: int64; var opcode: ProtocolOpcode = ProtocolOpcode::Undef; - var applicationBytes: bytes; var unsetResultDefault: Result; var result_: Result& = self.unsetResultDefault; var obj: string = ""; var arg: string = ""; - var success: bool = False; + var seqHeaderLen: uint64; + var msgLen: uint64; - : ASN1::ASN1Message(True) { - if (($$.head.tag.type_ == ASN1::ASN1Type::Sequence) && - ($$.body?.seq) && - (|$$.body.seq.submessages| >= 2)) { - if ($$.body.seq.submessages[0].body?.num_value) { - self.messageID = $$.body.seq.submessages[0].body.num_value; - } - if ($$.body.seq.submessages[1]?.application_id) { - self.opcode = cast(cast($$.body.seq.submessages[1].application_id)); - self.applicationBytes = $$.body.seq.submessages[1].application_data; - } - } + seqHeader: ASN1::ASN1Header &requires=($$.tag.class == ASN1::ASN1Class::Universal && $$.tag.type_ == ASN1::ASN1Type::Sequence) { + self.msgLen = $$.len.len; + } + + # Use offset() to determine how many bytes the seqHeader took. This + # needs to be done after the seqHeader field hook. + : void { + self.seqHeaderLen = self.offset(); + } + + messageID_header: ASN1::ASN1Header &requires=($$.tag.class == ASN1::ASN1Class::Universal && $$.tag.type_ == ASN1::ASN1Type::Integer); + : ASN1::ASN1Body(self.messageID_header, False) { + self.messageID = $$.num_value; + } + + protocolOp: ASN1::ASN1Header &requires=($$.tag.class == ASN1::ASN1Class::Application) { + self.opcode = cast(cast($$.tag.type_)); } switch ( self.opcode ) { ProtocolOpcode::BIND_REQUEST -> BIND_REQUEST: BindRequest(self); - ProtocolOpcode::BIND_RESPONSE -> BIND_RESPONSE: BindResponse(self); + ProtocolOpcode::BIND_RESPONSE -> BIND_RESPONSE: BindResponse(self, ctx); ProtocolOpcode::UNBIND_REQUEST -> UNBIND_REQUEST: UnbindRequest(self); ProtocolOpcode::SEARCH_REQUEST -> SEARCH_REQUEST: SearchRequest(self); ProtocolOpcode::SEARCH_RESULT_ENTRY -> SEARCH_RESULT_ENTRY: SearchResultEntry(self); @@ -267,17 +268,15 @@ public type Message = unit { ProtocolOpcode::INTERMEDIATE_RESPONSE -> INTERMEDIATE_RESPONSE: NotImplemented(self); ProtocolOpcode::MOD_DN_REQUEST -> MOD_DN_REQUEST: NotImplemented(self); ProtocolOpcode::SEARCH_RESULT_REFERENCE -> SEARCH_RESULT_REFERENCE: NotImplemented(self); - } &parse-from=self.applicationBytes if ( self.opcode ); + } &size=self.protocolOp.len.len; - on %error { - self.backtrack(); - } + # Ensure some invariants hold after parsing the command. + : void &requires=(self.offset() >= self.seqHeaderLen); + : void &requires=(self.msgLen >= (self.offset() - self.seqHeaderLen)); - on %done { - self.success = True; - } - -} &requires=((self?.messageID) && (self?.opcode) && (self.opcode != ProtocolOpcode::Undef)); + # Eat the controls field if it exists. + : skip bytes &size=self.msgLen - (self.offset() - self.seqHeaderLen); +}; #----------------------------------------------------------------------------- # Bind Operation @@ -288,15 +287,99 @@ public type BindAuthType = enum { BIND_AUTH_SASL = 3, }; +type GSS_SPNEGO_negTokenInit = unit { + oidHeader: ASN1::ASN1Header &requires=($$.tag.class == ASN1::ASN1Class::Universal && $$.tag.type_ == ASN1::ASN1Type::ObjectIdentifier); + oid: ASN1::ASN1ObjectIdentifier(self.oidHeader.len.len) &requires=(self.oid.oidstring == "1.3.6.1.5.5.2"); + + # TODO: Parse the rest of negTokenInit. + : skip bytes &eod; +}; + +# Peak into GSS-SPNEGO payload and ensure it is indeed GSS-SPNEGO. +type GSS_SPNEGO = unit { + # This is the optional octet string in SaslCredentials. + credentialsHeader: ASN1::ASN1Header &requires=($$.tag.type_ == ASN1::ASN1Type::OctetString); + + # Now we either have the initial message as specified in RFC2743 or + # a continuation from RFC4178 + # + # 60 -> APPLICATION [0] https://datatracker.ietf.org/doc/html/rfc2743#page-81) + # a1 -> CHOICE [1] https://www.rfc-editor.org/rfc/rfc4178#section-4.2 + # + gssapiHeader: ASN1::ASN1Header &requires=( + $$.tag.class == ASN1::ASN1Class::Application && $$.tag.type_ == ASN1::ASN1Type(0) + || $$.tag.class == ASN1::ASN1Class::ContextSpecific && $$.tag.type_ == ASN1::ASN1Type(1) + ); + + switch ( self.gssapiHeader.tag.type_ ) { + ASN1::ASN1Type(0) -> initial: GSS_SPNEGO_negTokenInit; + * -> : skip bytes &eod; + } &size=self.gssapiHeader.len.len; +}; + type SaslCredentials = unit() { - mechanism: ASN1::ASN1Message(True) &convert=$$.body.str_value; - # TODO: if we want to parse the (optional) credentials string + mechanism: ASN1::ASN1Message(False) &convert=$$.body.str_value; + + # Peak into GSS-SPNEGO payload if we have any. + switch ( self.mechanism ) { + "GSS-SPNEGO" -> gss_spnego: GSS_SPNEGO; + * -> : skip bytes &eod; + }; +}; + +type NegTokenResp = unit { + var accepted: bool; + var supportedMech: ASN1::ASN1Message; + + # Parse the contained Sequence. + seq: ASN1::ASN1Message(True) { + for ( msg in $$.body.seq.submessages ) { + # https://www.rfc-editor.org/rfc/rfc4178#section-4.2.2 + if ( msg.application_id == 0 ) { + self.accepted = msg.application_data == b"\x0a\x01\x00"; + } else if ( msg.application_id == 1 ) { + self.supportedMech = msg; + } else if ( msg.application_id == 2 ) { + # ignore responseToken + } else if ( msg.application_id == 3 ) { + # ignore mechListMec + } else { + throw "unhandled NegTokenResp id %s" % msg.application_id; + } + } + } + + switch ( self?.supportedMech ) { + True -> supportedMechOid: ASN1::ASN1Message(False) &convert=$$.body.str_value; + * -> : void; + } &parse-from=self.supportedMech.application_data; +}; + +type ServerSaslCreds = unit { + serverSaslCreds: ASN1::ASN1Header &requires=($$.tag.class == ASN1::ASN1Class::ContextSpecific && $$.tag.type_ == ASN1::ASN1Type(7)); + + # The PCAP missing_ldap_logs.pcapng has a1 81 b6 here for the GSS-SPNEGO response. + # + # This is context-specific ID 1, constructed, and a length of 182 as + # specified by in 4.2 of RFC4178. + # + # https://www.rfc-editor.org/rfc/rfc4178#section-4.2 + # + # TODO: This is only valid for a GSS-SPNEGO negTokenResp. + # If you want to support something else, remove the requires + # and add more to the switch below. + choice: ASN1::ASN1Header &requires=($$.tag.class == ASN1::ASN1Class::ContextSpecific); + + switch ( self.choice.tag.type_ ) { + ASN1::ASN1Type(1) -> negTokenResp: NegTokenResp; + # ... + } &size=self.choice.len.len; }; # TODO(fox-ds): A helper unit for requests for which no handling has been implemented. # Eventually all uses of this unit should be replaced with actual parsers so this unit can be removed. type NotImplemented = unit(inout message: Message) { - # Do nothing + : skip bytes &eod; }; type BindRequest = unit(inout message: Message) { @@ -324,14 +407,32 @@ type BindRequest = unit(inout message: Message) { (|self.authData| > 0)) { message.arg = self.saslCreds.mechanism; } -} &requires=((self?.authType) && (self.authType != BindAuthType::Undef)); +} &requires=(self?.authType && (self.authType != BindAuthType::Undef)); -type BindResponse = unit(inout message: Message) { +type BindResponse = unit(inout message: Message, ctx: Ctx&) { : Result { message.result_ = $$; } - # TODO: if we want to parse SASL credentials returned + # Try to parse serverSaslCreds if there's any input remaining. This + # unit is parsed with &size, so &eod here works. + # + # Technically we should be able to tell from the ASN.1 structure + # if the serverSaslCreds field exists or not. But, not sure we can + # check if there's any bytes left at this point outside of passing + # in the length and playing with offset(). + serverSaslCreds: ServerSaslCreds[] &eod { + if ( |self.serverSaslCreds| > 0 ) { + if ( self.serverSaslCreds[0]?.negTokenResp ) { + local token = self.serverSaslCreds[0].negTokenResp; + if ( token.accepted && token?.supportedMechOid ) { + if ( token.supportedMechOid == GSSAPI_MECH_MS_KRB5 ) { + ctx.saslStripping = SaslStripping::MS_KRB5; + } + } + } + } + } }; #----------------------------------------------------------------------------- @@ -899,6 +1000,6 @@ type AbandonRequest = unit(inout message: Message) { # # }; -on LDAP::MessageWrapper::%done { +on LDAP::Message::%done { spicy::accept_input(); } diff --git a/testing/btest/Baseline/scripts.base.protocols.ldap.add/conn.log b/testing/btest/Baseline/scripts.base.protocols.ldap.add/conn.log new file mode 100644 index 0000000000..09b5614986 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.ldap.add/conn.log @@ -0,0 +1,11 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path conn +#open XXXX-XX-XX-XX-XX-XX +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p proto service duration orig_bytes resp_bytes conn_state missed_bytes history orig_pkts orig_ip_bytes resp_pkts resp_ip_bytes tunnel_parents +#types time string addr port addr port enum string interval count count string count string count count count count set[string] +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 46160 127.0.1.1 389 tcp ldap_tcp 3.537413 536 42 SF 0 ShADadFf 11 1116 6 362 - +#close XXXX-XX-XX-XX-XX-XX diff --git a/testing/btest/Baseline/scripts.base.protocols.ldap.add/ldap.log b/testing/btest/Baseline/scripts.base.protocols.ldap.add/ldap.log new file mode 100644 index 0000000000..b6de5febd9 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.ldap.add/ldap.log @@ -0,0 +1,14 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path ldap +#open XXXX-XX-XX-XX-XX-XX +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p message_id version opcode result diagnostic_message object argument +#types time string addr port addr port int int string string string string string +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 46160 127.0.1.1 389 1 3 bind simple success - cn=admin,dc=example,dc=com REDACTED +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 46160 127.0.1.1 389 2 - add success - - - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 46160 127.0.1.1 389 3 - add success - - - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 46160 127.0.1.1 389 4 - unbind - - - - +#close XXXX-XX-XX-XX-XX-XX diff --git a/testing/btest/Baseline/scripts.base.protocols.ldap.sasl-signed-clear-2/conn.log b/testing/btest/Baseline/scripts.base.protocols.ldap.sasl-signed-clear-2/conn.log new file mode 100644 index 0000000000..8b4c3fa573 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.ldap.sasl-signed-clear-2/conn.log @@ -0,0 +1,11 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path conn +#open XXXX-XX-XX-XX-XX-XX +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p proto service duration orig_bytes resp_bytes conn_state missed_bytes history orig_pkts orig_ip_bytes resp_pkts resp_ip_bytes tunnel_parents +#types time string addr port addr port enum string interval count count string count string count count count count set[string] +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 192.168.10.138 63815 192.168.10.186 389 tcp ldap_tcp 0.033404 3046 90400 RSTR 0 ShADdar 14 1733 68 93132 - +#close XXXX-XX-XX-XX-XX-XX diff --git a/testing/btest/Baseline/scripts.base.protocols.ldap.sasl-signed-clear-2/ldap.log b/testing/btest/Baseline/scripts.base.protocols.ldap.sasl-signed-clear-2/ldap.log new file mode 100644 index 0000000000..cce0806fc6 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.ldap.sasl-signed-clear-2/ldap.log @@ -0,0 +1,12 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path ldap +#open XXXX-XX-XX-XX-XX-XX +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p message_id version opcode result diagnostic_message object argument +#types time string addr port addr port int int string string string string string +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 192.168.10.138 63815 192.168.10.186 389 3 3 bind SASL success - - GSS-SPNEGO +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 192.168.10.138 63815 192.168.10.186 389 9 - unbind - - - - +#close XXXX-XX-XX-XX-XX-XX diff --git a/testing/btest/Baseline/scripts.base.protocols.ldap.sasl-signed-clear-2/ldap_search.log b/testing/btest/Baseline/scripts.base.protocols.ldap.sasl-signed-clear-2/ldap_search.log new file mode 100644 index 0000000000..0caeba4973 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.ldap.sasl-signed-clear-2/ldap_search.log @@ -0,0 +1,14 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path ldap_search +#open XXXX-XX-XX-XX-XX-XX +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p message_id scope deref_aliases base_object result_count result diagnostic_message filter attributes +#types time string addr port addr port int string string string count string string string vector[string] +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 192.168.10.138 63815 192.168.10.186 389 1 base never - 1 success - (objectclass=*) - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 192.168.10.138 63815 192.168.10.186 389 4 base never - 1 success - (objectClass=*) - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 192.168.10.138 63815 192.168.10.186 389 6 single never CN=Schema,CN=Configuration,DC=matrix,DC=local 424 success - (&(!(isdefunct=TRUE))(|(|(|(|(|(attributeSyntax=2.5.5.17)(attributeSyntax=2.5.5.10))(attributeSyntax=2.5.5.15))(attributeSyntax=2.5.5.1))(attributeSyntax=2.5.5.7))(attributeSyntax=2.5.5.14))) - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 192.168.10.138 63815 192.168.10.186 389 8 tree never DC=matrix,DC=local 1 success - (samaccountname=krbtgt) - +#close XXXX-XX-XX-XX-XX-XX diff --git a/testing/btest/Baseline/scripts.base.protocols.ldap.sasl-signed-clear/conn.log b/testing/btest/Baseline/scripts.base.protocols.ldap.sasl-signed-clear/conn.log new file mode 100644 index 0000000000..d4b1e6e630 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.ldap.sasl-signed-clear/conn.log @@ -0,0 +1,13 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path conn +#open XXXX-XX-XX-XX-XX-XX +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p proto service duration orig_bytes resp_bytes conn_state missed_bytes history orig_pkts orig_ip_bytes resp_pkts resp_ip_bytes tunnel_parents +#types time string addr port addr port enum string interval count count string count string count count count count set[string] +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 10.199.2.121 59327 10.199.2.111 389 tcp ldap_tcp 63.273503 3963 400107 OTH 0 Dd 12 2595 282 411387 - +XXXXXXXXXX.XXXXXX ClEkJM2Vm5giqnMf4h 10.199.2.121 59355 10.199.2.111 389 tcp ldap_tcp 0.007979 2630 3327 OTH 0 Dd 6 990 6 3567 - +XXXXXXXXXX.XXXXXX C4J4Th3PJpwUYZZ6gc 10.199.2.121 59356 10.199.2.111 389 tcp ldap_tcp 0.001925 2183 3436 OTH 0 Dd 4 463 5 3636 - +#close XXXX-XX-XX-XX-XX-XX diff --git a/testing/btest/Baseline/scripts.base.protocols.ldap.sasl-signed-clear/ldap.log b/testing/btest/Baseline/scripts.base.protocols.ldap.sasl-signed-clear/ldap.log new file mode 100644 index 0000000000..6e6fe79fd9 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.ldap.sasl-signed-clear/ldap.log @@ -0,0 +1,15 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path ldap +#open XXXX-XX-XX-XX-XX-XX +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p message_id version opcode result diagnostic_message object argument +#types time string addr port addr port int int string string string string string +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 10.199.2.121 59327 10.199.2.111 389 3 3 bind SASL success - - GSS-SPNEGO +XXXXXXXXXX.XXXXXX ClEkJM2Vm5giqnMf4h 10.199.2.121 59355 10.199.2.111 389 3 3 bind SASL success - - GSS-SPNEGO +XXXXXXXXXX.XXXXXX C4J4Th3PJpwUYZZ6gc 10.199.2.121 59356 10.199.2.111 389 9 3 bind SASL success - - GSS-SPNEGO +XXXXXXXXXX.XXXXXX C4J4Th3PJpwUYZZ6gc 10.199.2.121 59356 10.199.2.111 389 12 - unbind - - - - +XXXXXXXXXX.XXXXXX ClEkJM2Vm5giqnMf4h 10.199.2.121 59355 10.199.2.111 389 13 - unbind - - - - +#close XXXX-XX-XX-XX-XX-XX diff --git a/testing/btest/Baseline/scripts.base.protocols.ldap.sasl-signed-clear/ldap_search.log b/testing/btest/Baseline/scripts.base.protocols.ldap.sasl-signed-clear/ldap_search.log new file mode 100644 index 0000000000..3ef959bcf1 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.ldap.sasl-signed-clear/ldap_search.log @@ -0,0 +1,27 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path ldap_search +#open XXXX-XX-XX-XX-XX-XX +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p message_id scope deref_aliases base_object result_count result diagnostic_message filter attributes +#types time string addr port addr port int string string string count string string string vector[string] +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 10.199.2.121 59327 10.199.2.111 389 1 base never - 1 success - (objectclass=*) - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 10.199.2.121 59327 10.199.2.111 389 4 base never - 1 success - (objectClass=*) - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 10.199.2.121 59327 10.199.2.111 389 5 base never CN=Enrollment Services,CN=Public Key Services,CN=Services,CN=Configuration,DC=DMC,DC=local 1 success - (objectClass=*) - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 10.199.2.121 59327 10.199.2.111 389 6 base never - 1 success - (objectClass=*) - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 10.199.2.121 59327 10.199.2.111 389 7 tree never CN=Enrollment Services,CN=Public Key Services,CN=Services,CN=Configuration,DC=DMC,DC=local 2 success - (objectCategory=pKIEnrollmentService) - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 10.199.2.121 59327 10.199.2.111 389 8 base never - 1 success - (objectClass=*) - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 10.199.2.121 59327 10.199.2.111 389 9 base never CN=Schema,CN=Configuration,DC=DMC,DC=local 1 success - (objectClass=dMD) - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 10.199.2.121 59327 10.199.2.111 389 10 base never CN=Schema,CN=Configuration,DC=DMC,DC=local 1 success - (objectClass=dMD) - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 10.199.2.121 59327 10.199.2.111 389 11 base never CN=Aggregate,CN=Schema,CN=Configuration,DC=DMC,DC=local 1 success - (objectClass=*) - +XXXXXXXXXX.XXXXXX ClEkJM2Vm5giqnMf4h 10.199.2.121 59355 10.199.2.111 389 1 base never - 1 success - (objectclass=*) - +XXXXXXXXXX.XXXXXX ClEkJM2Vm5giqnMf4h 10.199.2.121 59355 10.199.2.111 389 4 base never CN=WS01,CN=Computers,DC=DMC,DC=local 1 success - (objectclass=*) - +XXXXXXXXXX.XXXXXX ClEkJM2Vm5giqnMf4h 10.199.2.121 59355 10.199.2.111 389 5 base never CN=WS01,CN=Computers,DC=DMC,DC=local 1 success - (objectclass=*) - +XXXXXXXXXX.XXXXXX ClEkJM2Vm5giqnMf4h 10.199.2.121 59355 10.199.2.111 389 6 base never CN=WS01,CN=Computers,DC=DMC,DC=local 1 success - (objectclass=*) - +XXXXXXXXXX.XXXXXX C4J4Th3PJpwUYZZ6gc 10.199.2.121 59356 10.199.2.111 389 10 base never - 1 success - (ObjectClass=*) - +XXXXXXXXXX.XXXXXX C4J4Th3PJpwUYZZ6gc 10.199.2.121 59356 10.199.2.111 389 11 base never CN=62a0ff2e-97b9-4513-943f-0d221bd30080,CN=Device Registration Configuration,CN=services,CN=Configuration,DC=DMC,DC=local 0 no such object 0000208D: NameErr: DSID-0310028B, problem 2001 (NO_OBJECT), data 0, best match of:??'CN=Services,CN=Configuration,DC=DMC,DC=local'?? (ObjectClass=*) - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 10.199.2.121 59327 10.199.2.111 389 12 base never CN=Certificate Templates,CN=Public Key Services,CN=Services,CN=Configuration,DC=DMC,DC=local 1 success - (objectClass=*) - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 10.199.2.121 59327 10.199.2.111 389 13 tree never CN=Certificate Templates,CN=Public Key Services,CN=Services,CN=Configuration,DC=DMC,DC=local 38 success - (objectclass=pKICertificateTemplate) - +#close XXXX-XX-XX-XX-XX-XX diff --git a/testing/btest/Traces/ldap/ldap-add.pcap b/testing/btest/Traces/ldap/ldap-add.pcap new file mode 100644 index 0000000000000000000000000000000000000000..118a8c42a53f9039231ee0181f5c5e1adcfe2071 GIT binary patch literal 2012 zcmaKsPiz}S7{zCIC$a0e!EFGULQn*15?WJcO`?K|MPdjM1w~d0YPof@p2SP-S+lz) zQAO0mQb7ik3kPW7P&hR=K;cpegs22nPqkVJT2Lv0CU8R)mncQy`^JCpTG4*eNbB|b zH*em1>uVRk{8S~BG-hjy5CuNmzVP96&yNvu7_M=(PMC}l@=WFC2pQ@8;^$NFgHuFN zRx--z*qwj(KpoQ9onwT{$0RQXkEUTxEy0Q%j97}@+dirdxnA{n(h zKoo$&)jE=RymCttzuJ}3p-JbxPVS}{Go_d{| zo|!jXSAT$No?WE7ZD+<1)=9&&Y+>YI6_&@kscM(>Fzu|-*nZlT<*w;iMSMtqi0*mL z7M@`V?(|LDPG8A|3obmz;w~QW!1ZuYB(98P#2<+sfsof1Ad-pAMkGsX)#Y3iBT=nJ zB*;Gk{D4S)mj>Q!GjJUuiDM)moM;;ONGQ3q_7@Plg+@Mt{|Q{JgOMojR{lWZ=kIJw zgh;L)Z4jMVB(kzH32#KMth_`AN>(-nwhNbwL{LCwWPDE27>9i6qEEDChF>2MEo>iAv@YL+LP^=wGJLvj{I^YK* xF@7nCI9`(GzT9SRKbSkVu#0TW5BkhqLgHv3vGS+Xc)d;I7-$@jcJ})<{s*}!1=0Wj literal 0 HcmV?d00001 diff --git a/testing/btest/Traces/ldap/missing_krbtgt_ldap_request.pcapng b/testing/btest/Traces/ldap/missing_krbtgt_ldap_request.pcapng new file mode 100644 index 0000000000000000000000000000000000000000..52c52d7424acb0bc08e375854d1342398cc3885f GIT binary patch literal 101144 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 j`n=HsM{l~f*M961(J7OBN9XYo|QIa4UvySObS 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 z zpMLsR_%eCjtZx?`xJ$v{mx~_Wulw=GoOi8w`rk9(y!Ou3OU8;foiXj9r>4ErykXD# z#+-QUsxw}EcID+G2b?negXQOaz3d-*+_-2)|Bp_;{>aV=M}NHVtk46C-+X_^c{iW1 z|5dKqqc`l``AYEImX~~Q7k~Wh=YhpL9_pz2_^&much3CahWih8|LK#n`M{JxA1;xa z4k$k5fG2hu^V0J(Q%i*aM+qDCx1Wo{M|;cdj9F6&WTfBIP2`iFaOXs z@|7FExaX*k;w!ty%|G?z$u(DAw*0TLOV0RYr%&G%JU_p6&7nU<&Mr7;_JgZjUrl&t z*xkDgIX@u8&-!}Z>DM0H^0)uK^U(bF_kOIhYT;7p-CGCk>iOo$)nD#(*b@t0ud3bk z><5p&V8qIrU5?o8Vqxg)v-iFCruMs9*Ea3Y_3ZV*=slNAC>Z_h9$lkOyz+)=W9QCa zxZSX&;W2G%{&G;stFO;k`iASumk$^;Wa;Pku37k+^2nr7HI8fVY5!`%Eg!sGzw?`O z*9eck_VS+9<+DHN79ZOFPvv{>vBxhLJ^ance|cu#a7X_kKVN<3yr%L$-~8rt_j#X^ zZdpCF6t$?AZ9sKhNE+^_j^l-Wxyu^EvyU_sl=`4gYWdqq`^X*?#@_ z^`D$vT(xq{key2Qer&<0#;X?a*YEYu#y4jEJ9gQ9r_cDSe8uvD%bm*$F2Tpo%H;*; z@XHI%EWBU+sk6J|@QGg^{=adP{`&n%FE4%J{ju?H&l>r}+K--j?ZL+nxN6OSex-8R z&letcVC{-uzK(t<{BpZA`lu6*SP-1`T*oWUcedZL`G6z8c;>hVZYn4}egD(`v|-pA z;;h=yFL}S;J={>&+&JX(F*ojf%JgTyNDlMe8=By_@81{rS5Cd@?!d3dx>`P)eQ9*J ziw?YV7iY`sbH00T=Dq%PbIYFJZ)Mx-HynIU^Oy~hux53K&nE#vCfty_C; z!G7bP|Mc(U-)e?|`#TdjE$Tx+Zhyoc!wQZ~glnv||430Sn$69Dm}1BO=RAI;G~` z({H=z`aK3;`knaT=*1t*d?R&L)OlCn_WzBp+t<1MzsG;`{@sU8Ib^>Lw|5`^&#{lL z=%1)x^vaByL(aeC^kiveTm9!7 zuLx(Sf?o>#K{z|%jirMI!q4a{(+1&wh+T?sHvYcZ26^a`iPQE_0B8I0M`<|AJr3|H zB20f+$Mh4Ib9Y{L>}}3tZ@#o2ymZ+R1DLKn_8${SHMxl-2JXpErI~*Uz_9pT9hI=~S%! zl@=E8$QR2^Hu_=<3lA|kWBtS#i>`w15#1}YFVP=#uP=VNQ6J-F=w2iJ&2#$jLYUKs z!N=IIaW8b8A*=fH{nPjQpR(ci?ey!-16I5=@Zq(cU!i*)qQbp~&^HS-ALNiW{0O`7 zBSTmdu1UqPgGdB#Xg5|I`|$;uzYjjsj#c4}d}b;?LAwsv3CO7%krEsEbZ&M}pFDuz zGz2$Zc-2EAKsn0Grzs8qKIQhLWw~*FoYFBqk6O(Ke9s(cYt5iuS6lV24Vcx zKm-2RK)wiKRb>!9Mk?`^;~DK;>^BE5_8$C@U@DP-crA*jVp)vjM?eV0;}jq?Raxe7 zc}ku0uvl2W`!p6@3W7s_h+P1b6b^l5*?LOsa)bp7<7O;a5Ai0z0GR#=;o*~>EJi-x z@w3pcad%|cSPO@YO+EA9gAzxbx!so^VS)V}+_2cj`WrtF{MgkoWL!i+*5F&mBo^#j zZ%VZRKcsk;)NOj%_>qkUFu>@A{}GeM%6i+5*V#4Lpo3dSvOqF1+UKtpE*n&YUPp4m z>>f=r*bn|)>d9A3H(7=JpD5k53$dG!Vjmd zom(rH4SEHBMqgQL=ZUooSZim>QLuJCNA~&nGJL7aGS*IF(uy+IC*=zcN}MxbS9~`| z7Zw!ZwbNzCK0lZdLCKEz8@L=s&JHt>#-V3MYvd=0nV>&t-yFTqvOzDy&*&?2jr4y! zb|rfD$cT(J^7+JRQ+I=BFF0o&x=#N~GuFrs{SW&1Rql)H&+zU4^aAwk{X5{<(HiN0 zxMuJ7pMyoRN%8Ivs={nD=C&DgY;xT;!iAY`2uuvNK@4wLkRi5g!o_c8ya4VMW#Aq< z^U>K~XV97I_FXn;Pxu*qW#V4J&TBhaxHomT;gg;_8|zF6@;UDF4BS(nzx}R3(vtli zJN?STHNW)w!h!)9_b&b|^@G6$g(jWpa&&up@Y`!7WN@-dVIbh~qvEq_(^{LZkzp+2 zE=9jF5r03PN#DU#F!&6TA(ExhZ~pzCmTioidlkk}#HTiJbDukV;2Q%rN zeN{)%$OCW0f+@{by~b;*m$hKW@P)w`*3v+0HQX_}V83Jd?SekPl+ekQ*k0+^$)mR< z=kk7{b9rGcisTd)4zCz-ZtJ069dv5rb+`K8JM6W+oZIO!pzR6@hVE(XFl5mZ3?oiaPmG3vwbW6o!wu8gO>jK(wS%pwO zZ|pF^CAjblz;lBaHpwW<3nm$FzMwzXZ+XEm4g#Tr3ztK*=Bn3rx+Hqcf#)AOe!^u_ zcKlc3!vFTeQFr|WO^zccFo@!!r(zIf|SueSZ|<>UUZVEqgCKKJe`gH9Xv zw|iFJbx7#$alhPh@%6Lge;(<*f97#7Oyd5!|FajyJAW>|=i1$C7k?7iZ`tdgExO>J z`<{K>OS+NT=J3EajiQjyZGv2X!wW64~$R1J?B$@bvKS53IiRx{q(W>!-_4 z?Kk4-`LC}z{j^_yURQCS`phcV+Fy=6epcYnihnjtiESUL8+zA!H$0ly@#+14zEgQH z^!|%iEV!xb*|qOT9k+e@f6u>mLwwxV_nmRgZbv&u50L+JQ1RI1w+7bypFCp5@+Y5J ze$$T5(QmK2dc=U+?%em(+pn4Y@!$UY%RvQ^x8z5BPX-3wcs<_M$MYjXvWmE2DOv51 zLWmHLcWmcoK4!Qv{7^ZjCdF7#YUz$^HvyqPji3mwjYS<&%n!_T@bust)La|dmc=`i zxHiaVAt57d{;bO>l(~d5uhUCDTMT@BS&c`;Zu;QaM-?}YADjv_7zYP_8R6#k0t>E2 zSkU>a84F&SNw6TcH{=ZUca?j*nCH#yqz!9$4sdM=PN&zYy}vuZquQY?s*U+VT}W)9 z*|M~#F&4=VCXVCz7@1hc^X<+L*1&Q`Yi$)4?hgF$@Hvxjy>0Gybr4C0Lgm6Z;s(d8&3R;#0D=v%yjlwX`VaHHDvg;y^D1| zB>FdheYRo2cz#qc4NWMOAOZ_dd+cBN;ne}Z zr&W~_2pDlkrqC<8v<4=LY*DGI)`EsbmK~4)PcvJp#0qYRFfLG)r-C zCgHpTNG`$A@pM!h{Q~?Rd4I=QQld>tC~C&*L#k^6kcFW@MoKr|4}Rc>XI_aPG)HPf za)PXl0rg_A1H33ak8YCh56N17AHSV11UXo6OhAH_qB&TW@uNcll!@1rP~svGIw7Y6 zWrX0FI2?N&0X+@dE&Y-z)WNxO00={i3&n zRWFyzSqTbPna8cGUfK%+dZEuF^rUuO`Q*qoPyX$j`imx<|J3j+Uz>FP=$gG>J@4v| zCcONn@BFc6y!G9^j_RKtzGdnWtA>xOzj0aHx*fl)dvN~Ad);~UKD+L;UrtzX4aS0B z%vkWoPXr6z-;U#6{Nb$))26<9)ZO>&?>KSYYy3W!pCzgHzw0YIfBCJiTzJPt`#%|3 z{pQ^}{%!kR&sg@;F_VUt9kHO{xFh$C9Q}s)TwHL@XFq>dHfrki|8Z5k{Z-+R$f@P?e`=jS!clYO+|g%EfB&1L zYt@vNQ+5-Jo>Wem_0FLFp4n4dPe14LKWplo>z8fPbmH7vK^1T zEq2SYL8l%v<}ESw?q52OKl-%#WedJOdFhI$p1t?M9p1X2yZ=6(OTOs(HF3u&ho+*< zT}RCDeZ5cgtaCm~E&Km)Y_M(7=_}+5Uw!Glg7+7!K4{jQ)4eBuc<2M_a@Thk z?S1ov9UOmZe>YGaJ?n`3f4cbB75{l7^2iUzbbR5Qc-Rqps_(dl$}^7{UA6D**Y3W! z-+-&$IrqM4A8RR|$5^R(;mvrA<*MSPPXcoGZ$!m&xdAHN@HhGF&ebPQ}>(=R~FI{|O^tkT#@NgD7 z*raS7Y#6^CfK!I|k1(Ep?Y^@9&kORyPNF)awdqU3+e^Bgc_5mA>yG4;aGGn$SV}?)K zAY=a{JMNZzp#K?fUa;!=_5b+3`%%18AnrDBi;KIpAGp!D+jZ#KBSXz=VS@~7;a+%l z?#CJ=!~U6Zw^8oq+I0;l6;`Ynb)kr!9mU-ShR`?L;%=m90Vy1?E$+50?zS!NW~kfOz|%p^b)*=zOrQ=SJph=w^m`z^PbHx&o^QHW-|IU?u?9i?s~pu;CEMr?kPF; zn6n!2tt*8EgYi7K_vYDqHP1t##t!zI*2dZuyq3{CKZS2ld)8$2vOzb%&*&>_o-c`A zkLS6Xsti^*g{ZUZMY3aY65c6wACWrM+w!$L9;Xrba(EZLlj zNUAOiBokv?{T_Q7~z0aaQ>% zC~bu*wUie(`0A^Rr$p5%@SQvK3rs2YwH{JDwODh^2jw{O+86I$99L9%@r;C$io*|b z9K}H38&!;IZg%)S)D5v0IoOD6qM`RXM5sdN3kH=GzJivo)-0h2Lx_G#mLv%(uV}^N z;J5HN>0fGts%EIT5q)2kAx0quBwzqT;vBtfE~-*-NePxy>r^PKS5^w5@#ta+;c|9)CywHJ-`wJ zQ}{}GCv|NRj%7-U$O+c17QM<-=}cxy$K_3*V_K99R$)9LtCFKp4%rfwh5^0Af`4Kx z$na%-^$Nj)sZiBw>pLa)U`{~=idL4n_3a#l;H=s#wIe*iM0Hzpu=UAmB$AaIAqxIa zD6P;1B*z=1wHAR=;*t!^Lg?fs4Dw*Aw+sjoZkd=c<14p33 zVj`g=ur8LTg4&ZQD1n|qQMG1vwS(|MkV%(_;^oz&ymG>V8!;AqYqkr%KaF6)1#>uV z>(rWeWzR!7S+G&HHY$dJbmwRaG^srbf9n(yTW=A(UaJ3snG(Rp6186PR8*zx^;G7f zqH;i`a0jv(9bh!NTn>B+;sU?jc`CD=m@;#@D|MNP{s6GsKx}y`pV3VDc!;{%-cr?W zaWdtE1vgx;Q#6Zr4D-{KL^FgE^Qc^C zp03=z7{YGRVJ~rvkIkpS{GT7gha@^$zebC82V; z5`$u~c`7Iimz*c9w}DD>a0*oTlg!+3`$AU@-!rjg3cqxRc6H-!4bi;2(((=#)(H5$i zkX8&@pc9g#8POS_|BwXvkiXwf_?=d)W;?RXBNSIoOA5u61DG$Md5B0FW1b4kf(ufK zn*O;6#7EUYO{?1pA*xz?(bKIja>q6!Jp``fVz3j=yk;p32V72Aa0|wQugq95{BVK= zw>-gdT8qCtU8rn*$>k<95CQU$FBYl+Vo^S>(P>Owi4vEBwE3K7_>}NY<}VPFDT_L# zYpvs$zvc1}S01!~lj`JHzJ{^cTnHf1(pUx3Re*j7q5e>QYxe~#OB8!D)2M^;`5B%} z3)lP>=|ay53vR_&@TD0Gb{t8tpzA`g3pOFoksYyhJBd?3^O)4?1xoT1e;n+SuZ*0S ziDqBGP$~kIgpjpn4iMPLPyQ@RWO#=Y3!WLP$mhUq(QAkYmEA%Ub>P;B*-)P(*_a4} zVXZ2$yjxegTSCEf@&M)|tG;@j8IGzL5qHHVaYg9#@!AlC(x3}2CNiVW*AWTTK87A9 z2?@U?MiAvWk#RdH=Kx+-YpZ60O#pRmigUt(+b|YY6h(F z<+bNS?YH4}lS-!)!vu$Fi$a_#;M@`f3 zp+dBt$)0v5#pK1U;4vY(5nP|)p4p_%o1iHPz(-O=Tx4jA_k|wbclYqVr-%2;dU(IQ zhxaRbc)zlT_q{#5?{fC^fu1A?ZUudIEkx|Sll8L2j?4c2ti5dEm4u8Bx3AK>BlSOavvW3m>GI4OhK5 z4t2ul`!!IIjil>9f>KsmQ&}k`%CJS+m4A)3auQTB`;j@!0O(%?S(cz*z8^84IRNBUo_9K*%rH z+7fahONfE+ZW7!>&gVQlEm2B0TlW!!^vcvD#ChsCDB&xZYp0y(CnA{jdOg_yEFo3K~K7muUT4()O{mDe$4Ry5NMYNswM2%6?~wlXW4scSso z1*!CuS@V&Lvpzu@377y~2bqRU8nOW3?GEn!3q+o#pxf9ex zoQ4rs5{P)2*HFRsB0#lW9VX;hNLn1geHNf8l?YDaJY8DjnP!NWm?3f;m{)o0C55zH zt>6|}HqhNv_v!7(l$)ElO}msxD!MfTMow68H^zdG%~()5i(r9#FYt&qQvYlsQ|1B{ zx@Jo(X^cyGZAENPRxNQ&hfzhm#&#U4%hO}df~`y3QD9l+z46Jm7%B)7fHw-2Cya$n z?x_4ElCiy;Prni@c=3#@Qyg@>ZC3KKm_rF# zipJV`G(E{oanKi@h4Nyk`v6q@bX+rEIl30bR)}5=#a0?1S20gFBpafkw;y$W;%q`F zG7T^-X$5aLv#4^yf_pI*d}zi3|1AUypfnv5UG6b!#Aq!dbdW(uwqT<-M$IVlGg!Ni$$JmUghI%9mjK-)OZF-Pu^u zMmO19%ta}b6Jvx;AX4)^_QteQa>9c9F&4aU#)8K21PeZVljEQ&h?&x$vAA$ao8LXD z;&&mdBl;!Vigptx7fSzw>L7V%kzn#9U&Y+kloqIEhEz2K@=iP&+5~-OtZ7ThP@^ga z$)%Vj*&;($E2QyguhuIel!+Sh>;03UYLxL)#w;6cW5TaOnaH42r-YUEcK9hIwTr1p zvQ7z#5iQV6KNwMhok}WMrIP~T!|0X9RI;%R5K$v-&Vfk2vIxBu@MYX0ypnl)`W0I` zpe;~`64CkxEpA#A@`ceuMdet=_jOV%oa{hv86VV_L@8w8U5>&#vFeuTwT%Is?F&Ca zJ*{S(c^h98(*4g`CM*1`=cUq%0<{R9LW2BLxK2XCjNbtEJj2h5A*ooYt~WFYfH%?e z1LY$LzYRa7d;z}_jf=S36@CZ#WZ@0c&I(@{el|S?{EYOfghGn)%HfVAN~04~(1{EV zPi;Ej1*s-LzYj@jCxpS_(NF>#ycuh$mlsQ+Dh0Z6p(MIQZI$N#NI-)Xt@szbnoLNN zE~0o&SnvSGf(>RYXnB%gf%k5XlRE1lvl#}9OPwH7Eyb@Eabvo0vTwKvv54UPa8qL( zaRar)MF;lS;HJ*Hs|Ht^~UlyIs7JuUB5V|Ha= z!B8xn_9B7uVS%6+gL4)YOy6o36&nkZvp3q~ay7<+_sm!@?>K@5*FMW}8}FoOv8ySe zGOFsQ2z2krTlO0=Bv^??Wu;zn`l+~SN4^`p7OTli&;?@zQb=fhmaTR>Z+zPUp};DS zn)p;gN)U*Xd07e_?YDu1yGP^!{FS^ZtdtWLJczO2T{9LOQ9-caJm}wzEfZrST?-hl zFa>clNkGW9$kTnx=DP_M#CM7hILf-(dX*LH(+%gEn#>WMl3{8vy-_NVtAg+cqk;N^ z>*X+zn4tR6?q!J?pzm!i;-?%+B{W1X)lfSn$BC@0+dMO$}Jiv&`F${``r z3E#M&T#3E}O+C-`CCJ{- zqVDc4%>)uELfFI37Zg_!JD(+set7KI+68- zvbRvIFi%Cqjz798(;~u_7g%4L-SEl@3;u<%;4L#2EDR7VxOyA`w+ zDU-OGQK>S}=#u$sqLYTh8I6G}$N>fYfSc+a2F8*`>Dtuc|D3Sk5sU?Inz3Nf0D=X@ zZ5)SbRJgi#x@Rzw6^H6yCdf_4XBaCJ2+N)k8# zd1_IxRa(JKyt+D#u0>RHw7GJ^f=4kHykW+IW%m#)czGW1h~Shr1yJB;Q%n!Nk9ShD zWMB_&G1yS_3zO|GP=5fHJZ`YFEo)iD{hDy6X(Rjk57g2LEly=oZA|avY^!1Qw$@7) zS;;*$4%(Kr496TkKdc1UlLUX8)=N2I!5WMOubZ)8xk9ku(p4O%Ldrlo=eVbw@@*}h zz}tDwU%~h%Fh+b#s?RT zG~yc6+5*jUeBdr&YJr5lq>_@iQ?zmn=4uH>x72S_6hJp^*dPWSFe%Fll`CE13qj2U zJ>5S~4;^*~1p#_O8~JF>sk}vb3&Ng(tBmQl&5fIL0p)}R|HfGGsu>H;I)z}tJ+)fw zc#EbH36<$6J#67BsS66bZ%)Z?K}0LIzCh17;5@64f~7HT^HfA*ty6Z1@tsiemTOB} zZIHv>$R^0s6~itWAXHFpo(jhfO%~k}gp?B&tixFFiWv*eKY(Dt!*iidX_`K?xiSgZ zggO3en6bM3Nggn>73r1#o?}-X7$C3Lre_=7pflp318I}D?DnTW(C2ZT@ zVS51@GScoU$?k&O3hV*SQ|YjKqS5-CntON)mrYJs@HobTm(5sk@mB;3jxB(A!Ecm0 z#+JE2JgAVFmdM*oVpdum@EOz9wjfIY>gP!bsKcnHTde1&1J5Eh=}fC_h(la2CBhPl zSm?fHDH=ztw=H~A|3;gy=zS&}xM+E-sM<8E)&ZdkSpwMU@7B~81wgSls z3!cDO@RAt|uDF_D!IR@TPA>xsapG-cJtzvft;I-NDk=5U!eU#C5hSH;q`Iw$RF@7l zSycsuzAai1r9A;On^2@1*BMXz4p|gAVZnNg1uvSh;JQNz7PN%6ka|QGSuC{X4sd*p zX`)?1e(HM#Y-7ty0xDWH)I609o694>fvxReFI0`HoZfkx+*BUnUDedVZ}5l@|Ivc<%9)KVk~&Uj0HChBUo_aY?NQ{ zJGeC2(Rr7fME69$-uod>w<{YPDP=pD)j=aq57Svh6kN=Y z%e$qc`-Ori%hpJ3V`p3@rHB;ofbgZBg#(RmAg0hHs_G&ofqMC%AI;5+pm?1EZ-m7} z8#KJ~D-o38FDtn5kBYL{eX0roBgT??bDAiAwN7k`hDxYI+znyZIfA@GT+}h7|*LL&0U;&Iu+IRfW!1d3Tm;ZGc#r3VIc# zv?c)Fgk}gOp@q0Li76*6cp78Db7m~KXA!}IpZ5d1028KcRT5>9ub_A`5q(HIKJ&bI zGD}s39Zcvy!3by+fnbLe6}P6<*^5=gPUa9Oi_Da6l-D8P0yc%%RZgq+0>>cFQ-iXy z9%WhF#M*ub8JiyJj6uM zik-#dD5-htJpFn+rP%#vDu@aOMA`r@CQyxhEL(!lzc0sAPFV0P#)4{RY_eTU}+8$K31-;LJ`Gd%=}4x4{KU!)M0=Twb!VAy(2Xskni6og9^u`Pc~! z$!RbNm}g<3>g7jlbCLL*po?UxxRJz zPDG84s|M)%h?T=U_p7isA+6R8 zrkW&&V}Z=xRC&4y**q5yvGp~lZxUp-`Q(!m7CeWs;At}!JTrq}!A_3=r*undW&_T4 zD|RpO1B$_*0w?n36Z{q>AXdZ-u#~8Y>3&^Xg)N-3&C1sH1Q%IET1*0R)Mhko)o}2dDFCdL|bxyf&!Mthq`i^bB+15;Fpkh4M}?f6UC% zJYekohO|7ZZUdNp2V5D8_x~{M8gjyd7cdq)X~u&8-bk>(ds^K`~7kn50HlX&CAoAd+$_CNG|;M5QV@0Y;XhQBjq!91Czz~w4aNN( zs23f5sa{4TaP94SaWVaVj+ltau`vC)HYNfGwJZIL)r;dW7=6DcB8CaI)xu_=bU0A- zAg>WM`pw&vMt0hsi^i&f8v+z$XouXA5MydwN#v`UZqbLpUFs<%J|w)HnjIS5o7fF~ z)W~wef)_CstT$u9+d+Z_Yj5E=IjD8wp!+6Wt8R-n7c3gd5gnMYn-GPwkCOkRN{C&# z*_DnqfcyO5I!9xjuPM)~>W?E~YMP`RloCm~T{kj)sU&nm&d;bdisG{p9l$bo(&J8o zjGS0FPq$em(-s%fehU=I)`EJ?QkW8HP~=LZU-mwBpA#0mgt6cWGZuU>hG4;(4>%6g zE>d(J;NXwk?XqAO=B!i@NtoYm}yGT}-T)p*moLFMVXVx`rTmD0M;Xz%H#U!DqR2gc##E+wjKsJ^Nfa>)q` zUdCAPxETvRT}QCsYSh}(SA)-Av$vb$)vH$8lXtSx`4Z8MTfwkVDR+sh<4)AUwUT(%XQP2e_x z)g(rHaTIPXM;12RjZ9%udNg!`!r%Mv zcjrK^n(O~+>=ld!>&#g2_0a?ij%??+>f$N5EJ#`Y1)rN^>UXUPuW--(RHaKvCO#b*!+->jL%EVcU!( z(?QpnIP%PIla{%qG&%8TOKB~pR}ZZQ^0}=vJM8ar6MiR9s()iPCn5#^{$bRd?1KMd zEO^X}1;1_}Sm6DU0(bP=Gz!Y#;h2rk;G(bbEcDR)Z>>E7QBYBV66!YcJF^7 z!Gcv|fm4byw*U<`SLQLRT4hI&%v7r<)OBHDA5c>UT7c|_1o^qt6T<<%|<%9*VV=P!>#)2V@1PgXvj(S{f zEi@uF(7P%~yedAcwmJq0lo8#JlgG`1S&kgoX>~j6MLFV&$Z$a9 ztJ{msktrj4JP9@3>*Tfs)bP&JQ;-!Y)**vzKAmRYqQsSm63$mav7KB3?c1WU_?F;K z?;BZ5Ibp#Y7z-XXW5I}i1Pi`(Kz_kuY>k6upw+oDI*j1^KQzgd&9JW^HVC9BLr^mT z0G+1&Ze#|wW=XN#T@)6AN;J*J&1Wl(ZGU(PETsMW^)1ymk;Hc0 zEn#ttl#xrLoYzPM3b-Z`N+RHI%EPHbF&GQW4rRO&N$ILMCIM4ld9knc5O6z2jnldH z?|TcEK_y+?TG}O~UV^t(fg>0+#4UJX<%9)qVJ!HU84GsqBv^36dWaX`Ono^D&C^I_ z!gL~XW~oA0HQ0>tn+jK02A^qXRRVNMA}q$_C74|(Mw*p~0qhKC&DOs-hiZgj0q7&- z_)N9sb&DH|8eo;gh{Nm7GJSIk-nhTz24e@4sLb^4Qh_)m!l5>ac`7BA3k%YYT!bm9 zaXhqQ-n#a(WkY68SnxK+f``pmFlkqU1$#_D@q*t52iQ+E zqGla~sNQlp!HKAfNasr&ejuzSpowKL2rLqu){wt!Og72QAT#Lsb#O{b<*T;Ah6xvS zXGK+iW4!|<4a$frlczAju4Ln)spUABUL!}K{?ZmCp`5Vb9gGDJnXzEXvjhv~S7~)h zHy4L!5J{gSh>S^0TeLa0`L#MPDZm=<=vJX3P6QeG`MX_<-eWLQ-KB2gUV>0YJhf$Q z)y+f8+g5-TKukhDiF7mYjGwZKE9wRBQ9f%ZKu#`l1?A~>Wm7DK3X(&F!w0j)NJ?q}N@t!5i4{NwM|iq`sEVup#5!Zj zqF7!hSFp|^>mnyC*nqL%0W%gp9i67_jT;bt|@Y{>YWI{&zJ38o87kYI%-^p;60Ba{4u0>4xa{BIW!e+2lU)Z>JY)i%tit9H!x)wNa^m+*(P z2dgk-Z-M2kc~WWaD*%^`(OhLyEC(nrBe}H^DJ%xNs}~1xM}w*cu8OAR?#%$)NX&=$j% z=oqV4WDM&mt)yXqctQ!Kf=Ry;vNt=7A?BkY(qS8Q z#NJxX5>P{%VJ5NYed7?a+?e6UJd{ItC} zfOb6Y#G*u_V$9wOE^}vz5HGK+bIw&+MttK~8HRKn+f&&+Yk1;TN{T1?|2=pe5)OYJaFENF9PKyW2I8)95;>a&QT+ORtP zu1Z$p5wW}0-m_%wq7t5cPP)ns2~WtH2!J*c3xnk)hp_o&Z`W=dGtG*G=7doj+cTglAzU^pc?)G$gf)sYp^UYGP-U$3 zSg&k##Z~Dsor)U&E0^6DWNdDslxTNqstqn`Qzq8OAZrj%PCP{Or6`qo4reZk~tDr!ve(c6K6ldcKM=_&TsGGn?x1!vdob5WVbJCvki zYlEY`QoWftrr1+gNBG54tk@EcB*@1?Z%Q32ogkLmn(`7$(F`ldbTC zpk1ASS~s-ao3@^9p7M;fz{V88)6+G1$Rv>HXV zfvSdHX#b1}v%r9Ift*BoMYF050p^4SA7U)H*Ng=R4Ix-?`BaWWE`n^Y0prHmN|@j@ zlwxZMXuSoYO_l`v&c>_==woK@gylF?*;9?Wj5?JEzRV*ND1+G&f@Ddjklh55zyAG*uPQh-wH$Q4{01LcyM7`C33aS|xZ zX9dh5(llVsOi}IdMIgIhPIf?#g4~45!d8K1=D@;BieQOpfumeTun?-1GM9c#-Q^IF zm)P62jD^DjaNNui%%>2@5{LSa6RS3mP9FSg`m!j+4-X)W&AD87GQi zp~DW&IJA*UdLnaKl$VopJC69vz=$WV>?$b&{qU5SZ8I>-qOzDb)^Y(=%t@;eMFBy; zk*>r-VxqfBQah7MyzhsL#C(32*PB-UTLQS6E2u7Y0i%q2qy4j=&P{bNC>iUEAWs64 zZIhyyTst-<(?X~VnNL?vu98-4jQ%% zFSvdqwl+L|HF9T8@(H5c8N*w{s@tTqN@b~w{*UpoUlEe3Ma#xJ5j(4fS? zeG0u$r4ZI0GgS^72YU%`F;KZc)I?fM8x|SzrP_KT#rbW8L_~jJeF#9%nO$bGh9_b262W)KV&Y7zErsCHxWW>sA=rs6i+U74yaN?3EUw z8Q@ksio$~!f|H>hwvw!Zx*JRqjim{KdiLyPZJ-%stx=hzK++_IK^I0&SnvtPg1gLE zaOf0*1ut&kxSkm%R%eR<{vo}90zUk)`CA|G=`o=W*#w!4#ggr|V~f0ujstPp0O=WR zKTOMjvlb+BS2=j^oyb9k!i`Q~1;DrZ69vUY9jGrcDBo*W^(*0J=9(0oMu#nEl`Uc- zEG3a?WK*%s(rVd55z~^KSTHL!foABt4YrsR((J$b-rIldNpY3a5?UIvXiwE7+B|a^ zlY%u&qX&l^5t;`FN9QrC$kvoFpldF3eq0qa*oD_Iz_GrBZH7!hM-)3u0nSn&X$f7p!sF!nav z3*holu0l>&@F~WEJIz>d#47{~#ti1Tj9hdmVuc7KwgiQCfraA6b}5#*h^q~2z6q-A z^xauw5oYpIe+Kdq%~YZijnvtD#B9Qp#oBhKJ>7btD-E=CidL?pu??a!$}os2F+w3F z$uTzVVyh@>84Um_Z3{rd@uLP8wr-zs`YvFfzHUld)R{grngVr7EG#EeHd%fQC}CUn zE{}mAgPawC6c8I!DI_^sB&fn=`()GfHa6MMRpB%Mu%?1izi19>DBJH+PAOmDHULdR zv^g(~s4RPb0=}nBdrT%$Qi-6{Xs9A)YauWuhZTK7@e~hn|KTGPG0GgicI*&=;&3)r zvW7S8sTb%f!%iJ!(Lf(xduy5T2y7z?9w99=us)g+h)D(!I>!vZ13ize$6!nmTX89? z1UF(%SnwIff;-Gu(0&@hf>R*Z%vTQ`kE0TJ@nhlXK!{u>jy5IH8{^4h^;S5EixrOpp{iOONsrOw;~IwgD^ zv2z8o2EfGtXBT31_C`h4_Bq=D0REu##3O%@KLM?$q)e5PG2_{;3-%@#(wQ5uv>dO-% zAJ}rH79hB&{|WC`tubPV_&{>ir7gCwg+=R01GlEOwRFe{xQ9g29{yw-3+%W|8TDWz z)fc=B(`9fd#=^C+b|n$T9!7gWfx{+-5K~TA@HxhU+s#-I@e?dKZz0Elf254K-#t`s zj~Zy-)r)Q4afUH!5m@lhGeR>;(9)wtvU+QnWDLpH5L|9bZ8lUNF_$8+^^n@}#A0m- zrDa}n^hH&aBQ;Y2S6^)iP7b|DqzyHPadfaPMrfC0(x@ydZU`ugtY`WYV_3t|Gc1v` zYd5GJioGLsqPsDM14?+9FDp7KO+xGdbFQgFiP==KvQ0VmVGkM|@d)B`$u9;wK%HZ| zI4y%)3>%;2D%AaVhO`&09T*xiWs^I`7>d2z%c+A3XFedcA$O8Z3D0JDms4^y@@OLm zlC7o2c!*XeY`DvbsRgCv8=&Vp1Zhy;KAX$gDvFTqGlmXmDUlh(vYcqf9$`a(H=PfJ zPEid8OggFM7!1prb=KsB1z%t+xXp|O3%?~;;QE2%5D`6n^QgzCR+FMJ&>NC9Ls0Bx z>UI-1VVj&tcJ%cqVIP#R%MFnX)u9!Gb|6A`FVZQ{sSMnjlvRB9UVEY%u{o7(#K7Aa#RVf`mlnQ@|+ySJ2BCt&_0x?5W8r2v?hHeP~k)dA8A z$pG+F&Gin=&PsM00-3gthZ3H(&WXlOEk_s#h1`KRiVL9T64YXk1ZR&IxqCIYEX1$o zD2dKK$FE{+%q=%Wf>D^nATWn7j@x6S4Xk?{ZOIVnC{|WNMcSpH1|ikduD8dNvF5EJ z+hx?E$}Hd8H?(8tG?q~?*S+UJ3rZ?MGgmuvL(q~gnw*Ye%nO_j^vZfP4pBz^06wU} zqODngy^|9be1);#7Bdzcc{ss>hu1(23OmQo#;jfgu%aylr_UlK5wZuV3=Nn)Ih8bL zCy4#Rb08x>5duBfmiV;EVMjJ-lK`OScS1m;u?^Xd80hAJdrw(p9Kjacu>*e<)c6V~ zlvKPgNQd09$1+wLip81v64Rv)u}fAGj@)$+IH)Z!i5*b!rbD&Z&lrx`wNe-$#J0b@ zH2YYDq>4olgdpiF_EsGNU5jU89jrh&qwcCypuvx+Or{)d8_U9CJa#a|P0iW_1lE$O z?b1Aq{WOQMP@t|16}|JqmGCTm3s#^z9l(S6CtPxS`aDBLV7p;}5Rk^y zOr#^l%xoAC+QDG?Bs7#_coLWKJg|fV#*}bJ@G@q)q*+R3*2@Af)Sa7o$ z3yvE}uwcSch!>d4lrdHlTT~FdBPLH&MZvp19XD1>tCF5=dgdf@Dn%lo>;jD<0x7AD zfnGRXN_e*C*h^iLTAU;tGiXt2y_|DK0n2hgPC07MV-?=Q*YEP$T6T;XvmDmsAGaD7 znI}1g7%Yb+zL||aEi$z?>990GWTV5PQ1Yf7mYyKU;c6vh6x7(X!LASeA5n_ zJ_I)MwC+tltU&{{7P37AVr-x#3;>0F3$#vZ)uBK;X7E9sXH-WK8Cifr(D6Flw}LKK zyNEJMqiRlA@IQ` zQW{HmOF2<&-Pr!iIgZNK-dts5`)N@qt!1Z;XJIG}iGMYH9f~%IM`t~+)h8=$f*CW}<#4d8j@Y%K*s%qakY+0pWh)x=oL%nd*GbX{} zgz*|OhKz-T?9Fwy-*N_JM(QF$Rp7xA2}8vWCMS%&a!Ys%M+Z%clu$@JB!zIcIl8v3 zJ4OeV#m-|xmzS2kBqTALaSVpQ`(;85y=oA z+tT(>Iy|IQqEG@-G5eajmnGhEqS|WH(U$?()MOyXriF$M6-tgp-`QK+pwO4_Dnmaa zhden<$RUrCqhVk6{e*9342t4B`WXO~&b4itSuRd1KLt)&Q!#jLaY4E@JFyko*y`6s zRIH|1{s4yW9u2pgu;5#a1vi?p;OuDx3wC}IYSU>NH`|%+q6bz&ibASm0Oy|c#n%l9 zzl;!j1#Q29Oa?^5f^;BT%SKD;PcW}qNxfLGxiqRERjm3BcF1dgG;>@*pg{=ip3sO{ zy`oHIsdN^{ek1b+(kY!vOzt!n3)twHWmO+kpdnAJ?bJ&lS!|ZXkiBS^wj(e?X`@5b z8U07hDj6AxI5gKcCBb413)F)R+Iu3Yt*%TJ)KVh&OcyxTwe9bV1woFso{b?q3vJhF zwoGc(RyZBe(T<7}`jX8`C}?X$#lANNuu1|c$Z}iUE1$EKSxo>Jm!`7|4RWf4gBP@R!h zqX|KR5hyn)89WUk`@1jm(iU5VtzAL71OZ#9eaIn6O4wog;^&UIfWBz_;*3dD0XbgC}YhYKGMWu7XYAiDHMD1sXO3 zE`^lr1rRXK81`zYtRx#AGTp#z5F;8C*g97jv%_X{3QkIGz~>5h9uVb@WKe<1Y8)?1 zRrflx^WRw6?YdG-AXL|hk*NYzm!Lef%^XpN@YsY6pe!5o?|@@^H*hTz3DF+LX-keR zFxaHJLQIQ&0c|6!z%DXM$`YU%Gs6ze0$<(~zR@bSqohaNZer68R!%kNg;2PoTic#} zS2`DG>3cb0!S@&oZZKoPCFc?>IPrRf1z-YE%_*U|2sH)3mZY*)mc_}M<-G~xXU(6L!^B-qVi%}81;omrW<2gs)W^}-r-dMxD;=UE95OdsX0+7F z?T{pIZn|XacxA6Zu@XJ8piAo_Edjk|n|=i3%uIj^C2R`_ zEEN(8CUyOLd)$=p;LEhSI=MKM+_zUZm2q5J3W}VUsQi&xP&socEXN|dF?%dzS@r03 zEM+_wTY)d5^WUXJQcanmBZUB-IeGi6)T$G|u%XO)-42JizxbU=<$A6##A(0ss-DDlomi z3Vg?zrC@raH?b4}=weGf$_SzlPD!NExs7vF(7y){&v5y({2i6Jqow<<}-h^*BC_9^xMhvWp*0tEIBL^bRy zp%!*HdrJv4x{vLJ#)J$xf|w5pq_j91*k&V8q(@jqm&(#oml*X)3 zfIZLwo$^98N+cvD8c}MDt!dHL6pHYk#8wrd<4pPt3pg^%WTAF;Id@#Jcv_2+1zvN$ zL9LO|2j$7^J+8HkS%!svic^%*ozLhPud&^(mw_1U_-zG^Jtq@lOhso-Rb5?QP?ya? z@X#p@Y8$v-ilyv{51(xoC`7%9BC1RP&aqxbYBDf^MeNk)gL+={`Djt1ZIC~XN}0rE z)MK#^BuKXI0Nu!lUaHrO&BdqAFfm)LEpuWdq0NnHIlY)7_ES_)e;cAHi;Gc#c4(vw zWigXp-Q zEljXRKf;Y&jB>E$r(&bM;4;u}VN$Vg1rZLhf-R{nN-qw5n4A)xMRWjaCJh?Mu`a!l zpWS*FnUxVO6t-o|>4pFnJ(*El$q>;*$BbUlu+H)A9@}sf;E&OSwa6;==K7$Pqo&Uv zIQ=X}%{fioa#XSwv5IFgDpEXhiilZ_N>d0nHmW^x3ByRT95sESSW6hKOw+UGgayB1 zEV$Z?1rI(+us~?kc|@!ni43)i?aV2sOnMnLeB0 zY!*g&nlOrKwxM45!ZO5W`B=nxxUr>Y4>TE%WjQM4NNhxy_8_!3qY{I9W6x?2P#L4L zlibVFTAb#y?oC(UG7!8~RTPhxY+qa%3v6DkHdf|-#r!-Q`^qA0;idX-RBiTE)wTv4 zHGnZvs5ahJj{2p@i*1dF+N5PHNtU%nG!O&iAO!?@SKtf0rM3oR%uWpri(P`N zH(e~;@B~(oiE_#~pvKNj>`JzGyV(970r?v2a`3H<~sG}>Z(D|sl1tmPx2dWwa zw#H!KJ^LgTs9~=5SjRjUEKoR%1y`A|V9jv^3rcP<#f};G&32#y@rrB+lPAlbnwO0O z7AG<}LL#VhGIRs5n|_vQ3tAPCtxQ|_YICy>qES$bExO0k=?UY_+v68D@e7XgH0vupxmMdG=L^t?TU=lHDj`XU-q) zjp<JLa!&TQ%Cz0QfCu~D!oLd4ma8F z6PRt9un4z^T}c!q+}Z&ueT$La9IuQsn|(mJX;D5ID*Ixy2PjZlRn6X2k72p_!Q(?B zcBtkbE;?zV?b`5JS@?M%Si$m>m62J&75VCcNZ6*>!&Gf~v9=4qXeDG$x@kLys2Zqg zbvqjZ^}ePWS&D?36gAzqzNh~34Dilc1UX?r0mgzW%~LI1s(?^d4_vX0bGleW9^`$e4BUE%FzNNOLcL(WWy;Zt9bHM8 z*HR2f_Yv$6Nhn>A^=1>L8D|h%*(j$K^40EGkfO6`HCnC6?`kC4o3q+xjmLIC^qV5JdD%pF$>+>=ZBn(HefCGBD>NA5jkN&A;y9$ z%vkWuM+6I;Cv#jKt{!heZNPw+&Pvq)59-h+L=1QVDGtt25T9{!EcYm55wPdT?I8{n zXl2xyR8Wb6cDq~v#wb7?V<-t!<$)R_xU_CN(tCSTXM|0-6{uqzM`3~ZaR}7b21l|j zAu$dz_Ap>+lSB!~+Es!LE&6$4YZ!(J*us=jc?D6WqNw5})bA5j8=BAohw=|KimJ_xgpN48NUV~9h|>zOI;&$r zXl@p2Z0@5C#3q+}Dv7ZLN?TuP(X4`bFjbW_Q3tO>UH#~FC)1p;pdZG9%gtEu;w1zN z&RM~6px#(0)D~w@r9jRgI2|NOs&s;@%VBfw87DP63|K*pY|28kT?UB(+3b>2>3$yx z;8M1r-DB${)pSA&=54uw-;W~9gu2of1|{qE!KX>}4Y3=MphcTS7ZGK-glDsrpfWsl z|EZ`le6vq$cVgEipg{neO;AC#N?`s~cL6>E;}7d&w#3fBN$hRXv=3b3sFWOwslHY~ z#3^ycD-$$PJ4EPeQ5zG18rNl?!Ij~(XX_{4vl*uu`-_Fm!PMV?#>Ba1MbO zsSQ*$^gD)tJ0X4^LGb3mYGHP);GaWD%2acr#@#$m&T z0fE+{#)Cj{(TLqd?d<1Z`5^!X(mo_qM=^lP{{r_Fl`66IET*-e6Bh6o3s#!3;I#n3 zg6r-ib^+TYET^SER}I9Ns}1#-UxbMbAJRS;QR)J;WFwE2h9T?fpv0Jwg*3qr?P1CQBKPbL{*GMVj`Mz zY~6AU63a=C0q#OG+re)1lwI)&2+C{u;Acb55L@Czr5Q6&#%juFu@~s1g)mr& zArdcy8lrLIP_}$7R$~|faAfI$u9@4iV7o-!G%XB0Mr%9-hju`M`aiLtJ&7>@f*rmp zrvlSkdjmlXoeMsD4}@KaZ0A=w&9(_P*X7cdEhjAKkFnq~GZwrvfMCHV-*a5GW42FQ zu$B`{?6ma0&zbbWszVD3E*T-Lbb$_|+B7m)DS52aIkqz3DmVBk(8>izQKf$57^mCT z=CGh@Qau=lzkdUGsi6Eu(6qG-s6N^snpR1T0}%>C;TlTK5}|Y3_7WjApoF(DmjznR zO;)Sp9T1mH*eqL+dAeJewd`4UQ@@6uW^UWsWS}uCln5%Ihf?{Y*tBXvEmh&na)7@O zddz_&Wfgoz#zki7SY?dLu3iZB@rX@?Ym(%aN?~OJP`V&i(~!Z^mt|)41nFE>Ff{7Y zPhkJJv7(8%+%&rzm0ZI<;hYmmwJ_1COrNUYq@gY>s%F3`NGA_zDKwL`XTx!OG5AGpY@VuYn9IVrmol6GkRn#kiIEgbP#jij= zOJH0<<)%6%7M7E#kO`h`9i%7#w}LHMSGxQ%PVmrr8n!5qyVe*(l8v-Cw&Pr6(g@eM z!x*F6JV@|rHF^jr5k+$mpdheuq~7dhmTyT9W~Vh_z2&Y}f)Zs>LdvPBUOwa5vSVg! zyW33-uvkky6zSC$YOc>?kqQWkHVv7{V_>3y+LD0mW7-6w7g@Xv_aA$$x+)Dh zX5i~;R>UY6wn!BQkG5GAwwyeMP0NlCLe4?jP(nEepxr~CR0-;2)Jd_h%>tr~bDw21 zfk8n5O$>z+&~Bs}Rme7y9&ODfwhIvw9_cv#K!Xx%mLRax zC54(Ku`{#0o~`xI)568NZY3DkuNBWuO5Gzy?!937t|Q*_pTLJ6So z-FqE|#7n-e9z222@U}Jyjn=88(MAnq0!x}er=6H58gaj2yv9BeGNwe*iW?%1h>G#H zGuja^(|B>T-#9~+ugE?N$`R9{@tQCG zU-YBU1;xFjQ>Lq18*X+CSai{zTqo!iPk?^ZG#Si57nd7y>c+E6lw+rYhlmn&;tC!q z7EZui+!j5@49sIxtArFur%O^3^yRK@NsDnaWuVJM_E}W6ln$UG)gxzrTQ#;6Pey~c zAxyHIA_^;?Huu-WOo-Y6%3JA?s#;xY!Lu4L!K35-W1^`A2KDcfefVN!Cr~RWM;coy9a+rhX@WGNE&-*> z7n~qF=<8HFsJbf+=y+T(P|!>a$Rar}rF6lku`c-jye{~SpLM$6=$}?9gzQE$? zHY*wx*ge^W`# z;c9~s8@)k79X-*cHRqN$Qv;yBg35bzo&wbeJ?++<ye+x_Gui?x#g(vnrEvjbL+7f2zHH(jLyn z7sx$Em#^j!gxyZ8$EGY>AQf^eQ=kheLMY_c8xwzJ4aZ~9o)%;%j;MvG?=ri5VSfwUSnh@&=WZ5_9&K)E*Y!RwyXoMDt29z z+do$I@s^yY!A-h2lQ~owY*$nvp+wE$IRpZ>n%UlwhlrU8x`_#N$op*M|GT)#eu5r| zFqSUjn<$5RIHF~aQ|Gpz<-(3Dh? zS^95Y@vW}tj2IL-wUfvF$(DgV1HR}^hPaB2ZBi%=7O{U4wGWh|ug}`1m@AZEV4Hej z!y&~!Y9M991<3^t-I^m8wAh_`Y0_&cUGV9w3qFz81)uU>rwjhkFH|Zxe0Mc4&~0#E zBcE}7U}<|JXtKByr07dMFLc+l7cAQvdNP4M616ng&#Nl|(YcdHAe81GQ9~FwIH2r3 zX}NoHPQ@Z97-dLs(KinmpKpZA0Xq{P-q$d)(K!1IfoR@tKFaoJa(Qt*J&L|{(LB?S zA&?9aUZ$wr86kyejXH^&t0K@D*tqKwo@7@6kPzAF`!j0PmZ$baSG^gcCE?l(&+@7BGe%VIW>})PI2d1k%5897h%g% z1E%++5Izm6c13CgY}0L-eO}^h?%h%ucOl!Y}z18!FkQ7BqX< zOA#Bp=2XQ=54Au_>4MK-UGRN*UGVAu!s&u9_@qiD>a3Y zc0$``Zj>M|>j-hR?g36CRyigDypg-hM=iHvO6kULttvShgOq}}FV>C#Pl(y;)@Omx zk21E7yNG|t$e9^osTv;vP_XVpu4X>5K{e%t^H1{VB;|btQ05DV@akM6@Rk&^Pzg zb;`Ct=^#?S0w#t&iubM9=P^q?XD&3x4AhRF9~}7RMckGNiqeTvpmQ`n`7CK2eS~qPj$4M@1(mY6nCBxLu6zSHlL( zDUg5-t)K8(Jp*jP_mnbk1dzj6ELe%bRaah6Hy}{`L}rm4cR25l4&J6N50h@(WReB8 zx&p62A%E4^T?qNvWrDWrkvv9v{M8k3;7neD)9NE;1Tgy}N_*VF7}G-D7741kM~28F zBxwICUFgAc>mMqkRNe6SoXe!9KC=vVN4=bKu(g+>=(^Ab0hcz;IO&{KaCr)iZh+O+ zcN{u{QfOyqYs^BjO;w{_O0nj_R#Y}tRahM+Ak6yqpd_g#a7cC24@|4fi2;r422FiH z^&omgd&rr2QLm~TQQeN(t-49=w1=Z1NG1IOR(}_!9(X%F(`8#+VbYRN0`WtY(gpt( z>w-U-*9GtVfYSwk_OmOMqKT}7TnI5bV0Dm!K|M$Ym#FG80Z|-9_##QB1gZokEP&>S zTgl29*7I~&9yicUm))9R?G}n!L^A6r!OoVuXWM%(HU%OUOEY3xZ=3G>fCESA_Zd!q zK0RKniqz1e0zOG%Xaa?w!03^RFy%E_-I6(=u3DVWTX5j)yQKK0! zQ+pMsmHpW^ZA#I!mTKlj-M#2{=<9;~0q577?qgJep|$^*(r2;*MeQp+zOW&wGZ}AD z5Zde@VdIWAV4l+vP*uob5z+<99Jks?g`lcT%aolnX}KMzs$2JVHr9zR07R+2P9@d+nhCvqfx0zDZRx@+L!-B< zHeTA#oypJuLQ%2!IW*Ky;i=&@|%0C*kV5lvZ3#gHlshq2%SUBjEs*;V;1YBN&YA=PF zmeK{kgLT1wl-C8n@5h}kc>DvE%8KS0qAY|MwkR!*txYg6{Fw7(fHDy|B1eQ456Jd_ zqqdbj+T8K}edt|)ZW2pHe)Q9|C4~b~(qv*&8VqPx)`$q8kGn#7r4j)TM}uUa$hC2! z6rDHCU4SN*0#bwY;CbifsC@|{QTOqAGkTmL)KV9yW&EfKwm>sYXP`nMH7XL0Qbb0LfiT{X9h0QfxoZI~-6w`cRYQacqdUm#Z$T1BD)hK*i0o*mm&B%mw16C=@BC zDrTQ znL?c|vFm|LSQf8B^5{vgXbS3FOM~+5wcb2>M8F5qOrSZs2v5Q*S6{A_F8H0S3%)0> z3%=l)(*-}*rFg-{R+dYotWba`Q}r=pv|chUlJzRi7D?SwmPxP9i%fqHFe}{!h3WjV z*h?lxGG|-pX41Bl?Y7XKi&e*ll9Wl+_>FJ{WKL&iC#~5P+E*>$Ppz(mGVBENWt<^n z)EM*13l1*~u~LsK986TLW715TQDg zG6kzaa(vO_J3Bv$t5iG$y8qzINZ=4;O0rx$FVr+uMk!V#(nF7EOy_2Y@*OhS4p^7C zSt<%8P2ysAt!GO0Q1kg7dbkkriyBibpSkIY2u`q@B;J2BM1<3M40*1@<|ro#fDvAYN{yhaUZeF)MfGRzRqLqcUq>GWn%+ z!S7~W@LhRbQ2zy|3*P&Au4Z*WeAmUg$V(;^Tx4Yd{HsjdN2gc$j9zxr7j|p)Bq;zV z&a#}22AAm+T!f?E75E5)ocsyZHKBq0#XL66c>UlVGYz0y0sZe>i@0vCQptU4RA*euLwf zntblx@<6!O#wgMNk zj@kz1t@PkOnw)tn7%Y}GlYM#I{@`e`h|j2OHJxm-DIMWJflG`uU0#Uln?hXf;laiI z=4opooMTS5>HsE;O}DKFY-|!63zjUgqodZQuq#$qG|>o9&B@#Wnm!S-wOI3{_c<*i z$K+-NsLUWhSG@)3flPv)Lnj^hj>IgW0MXM-?%CWl>oz^g?usi7NPNHfxV2WEXQKtm zoSGB`WYy#`LbVCXno$v zNpF#IN;%1a`i?tUVgSgkJXJ~eex#8H_DDbk>NWXl;!Af7unU+MWrELp*Ee~CKWN1m z;7`|2NcwgLnB#Mq9kwWoE3kuQV@+UxpzQ~u@a3C+5Y6VBbuG1<3FSaZ5!K)j9cq&< zlTl3%FlnHY6;TmxQee4s;alC!OemftQ^qvuHm3V~*};QLX28xvkzUq`0lEpecL5~G z7>K%+wJGKLaa#gSIh`X~iYeBuJ|i%Jyso91f*!bbmAr`#mortARjCtls=o=2h~LB) zt>gBPi}@V2COks!)X`;ZbWj-~kONlD?kc6Y5%mQryYN~V2H{%C z+8NI#o#FA;gsfS zU_o(M3<&5{EZGm&2~t0hSK5WiIHbzv`I-(345XX$JHqO8#me^1mN)11{0F30Iz!X0 zRw*!47irM{R=04jDQn9Gn{CgTvOr@($5qm^yQ9vG>US+(-6NF8u_e)x?g^N22$!HD zM%lxuZ!YX(VHFakjQ4S4*g=1#sDTupM;FVxbr<6x_=8@gHNB1GJ`_)iu9SBK9YUdx zMLgblAyY~hypwgox94@i`~ITS1z-A;$S+u32}Cia-ZJ3t{nq_sfRYnbSBzQ%#mWb> zUCC;ciu)jmT=Y6ml4;{Qx1SUXrRdh__eO4u7(`fLN~(VVS(P65;*fS@9P0P>-TaWB z_#~OwMj{KHhEUHh(39o4ZDog7T-8BS#6Z)Xh`MPb|Ch;amT`2lm$Mp!V*L&(X8<2U zZfTYTd9ive@16pVSz@SZ(V+G`nq)q;(x>IrTU%d@>@zoT(-Ms&tT@D;!xClDH2d;%83%X z8o^~J-}&k)JAyJnrF6mPurB!Hd0lYUak}6g-;UaJ7&o6~r%_0$my$D-#+3Jns;Z{m z`m5-sq!S$kR-_8NQFBy$7Y&y~t$=NB^`(R(yfEyt19WB^CVOpE3tXagMaaUDhL^Z$tDb7u$mJuKjv4>b%hmY&)r;{$Q z;TdK2#|>9RB?!;^xVn1Pt^7_zd!EVY`C1cIf4h`0C!GqThAvEKU@`SjI1005{8wax zNp+AW7=~l=El;nm(Cnq$vzTs_-=t0hnzcEJW)I{U3f1;d#GLcgsk>PkTLyVvM+fFW zr!9GI5g0kox)HW;DP8dIvM%^zd0p`4JDo20{(r``>GG;T%lB}5HX~(t&z|&b9s0PX zD#~iz=&o){aUEONr8!>&RHEzB-cfAWb>2cm>P4InF^-v_U6f~K1Yhc1=NsJkI>@w~t>#rsUX3Qojt4)-8! z(C68Npp3P?fNv72kiISSzuuUO_{43CqC(N^@fvbIoZ;`1g_p@k4#d&6>dxXY&1!(8 z?SQ_ReG|oEE=m|3^gv>@SHIW?&2*Vw7Qy_?-He0JHYc|@LGQZQxV|EG06~}11^*uF zf^W;~f)D(p(*=KWruMi*2Q$BcsVltcV8$RCl}XI5N7ynd?kwH>-;rF*E67VEdzK)m z=qhDf9J~=*7-cfVR#$XD*|TjYw!8HnjN@xCYa&Iy2`FnZcn~%=9a>|H^(>GIrTFq> zB7RN4Hu5MM_nx>I4>Dyqft|P%iUlN8z$nrWB^cN4T?c8i32w&484+R1?lIjd+mxyy zw!rPf9=dd2#}_J^H~d1D#;!j(KqdEpp+~()!MNsaXUYXiCrlfUfvNn)tljS|#JrjF zQFNl%mUPJLnFctm4)TfPEEr>c@mVn)vl5$Xf#5 z09q_qRc>y6^r4U{kYXsG8i5Dr$o%)2B0{ zkiq13n60%=>ir?Q^~Exr&574vW=HB@T%YY7&W0R3hRmAYE)phFUWQcJM|D*OI%+oB zFm9ts#I%bS8b(Jk=TB!qlj+j4x+QUdWOsw31#P%-EVrWAwM|~XogP^HGpCa>tYbVcSNndePj{^~|m$byJkzG)^nsY)Er_DfvLkWI-;2<$f{k zKP5r&a!#BgzXE|MaT#qvg(U(}fmrN%7JtQCP~RDs!%v$n@|6_tLO<^tQZxhHi2W8| zj<}Uq<}84+tP60@`tq!urj!Iq4og3I4pp<9cdrNZs*;Lgxwsj2cf^h`a$bwjBdb+# zF_cAirOFI&w7l~LD-#?5rSzcms+ry(3^4@Vmm+Xc+gsTS0q@HL@Ftdvu;Oe2^;{lG z&>3X_F1!suzy+$7O>P%XPR+@^5QQewcNn6F%cCuYCF;@#VH5FgFbvlb3)clNr3>E0 zy5L*#x}g8dP8WPf6R~5&0;I8-qLDSEm$sX=$A)|Hp~*-SO!u0QQsZKVCZ*=l{vpUN z?YKHv%6``2{!OXLXYuRFVdh1|&=k#_cGlQg!)qLDaII|fXUmRH~> zro90Gw+j@e8!yM!ADdBsEvF5ra5JixAlP>> z>`ZPM23$@r=+-BK@p4W%7*EhO;H6&I1R1jeRfn)wS9FcD?Ma!)YsLJ{6(iH{Hn+P1 z9?MSVq2XB&aTOhVv(FmzSZHNzI#=Nd(9OUB?d_BEsM{$!O1CUQe%Vgr zEOKQW*e@Zjtso3zu&m?eMHwJq^6yF&EtfR3mMsEJ>@g-0$Cb4x;0&d7!N1SC;G6Th zVDbs43%>KJQVG^@s_#0S#4@ax2@vV#{-%`5w}LlbuN0#Z`f;m@gv=)N5GEeAk4cAw zj)f4bxB?EGp?NR6aFDbf;{in>;0JL$ZndHrQFqttKWs@`@#!Q<%1?U0htxfY9qA8t zeTLS%n6Ee_TG1K0wUFt@3DYW@V-~g4MISXlLfgnR6Xw*d1oYc0idfwcm&o+_1>*jcW(_KE zsY%oMIVefyEY=)?6g7W_U!ljiwxmgdl_@APQvMLFt^`;dQWdF}?xA@j6)!MVU{6cw zg3o1L@J)GL@ch*2g3tMmN`)I(MNLofuxJJ&*r!4Qx^7P{p>=_x_Q5RfjUv@xaUlKh z*QBv2Z{y>}-jZ8bcNGA$I|Dx5H|fSg_m7%5<;ZL25;G^+7C@g9#P7OjBr{2ES(~V_ zV&_iWc`BIs7EV9v1jfr}#X<^Y*ooSKMFIO1xN!inj#gLxfb(u8{bMwX+VJM*I%}*}^Nt2_ z$6F@9o6H1Td^2u{c|c=zMZcBP?N~)R17pB@zd9i=j zR#9Dg>po7G+@&W;<6HRYBfq6K0Gmt@ISWJcZgdrIko-^aS(>+`zcTb?*w@YXLu7tF1bhV0kw zZAdMcXK%elO}V0bGAU+>ZYOVxcbLwQ+RWVMGJ)F=^&25T34pi|U?2i`=i0BXu$D64 zu`FsENWV@xqd3J>2nQLb@EdfAv@ZRl_>dU1z1_EszLp^G2CQy9T|@d^UjYw~e9fXm z5s1&$q$<7jVp`3^=w>(uCtx(BAm+A&=+tREPGOtGJ-NB%T?VvsT|YQZu0d{|#vvj` zp6db%)~9Hk)B?iCn?tyM7t}Tj48rL>2x7`K+oqAz0_|txZ-Wun3t}ew#9bm ziqBl|VgVe|*lrpavvF_NQ*NPBkp`3Wu5?*Iznwaz+C9x0HIdwZ??J; z*tB(_#7Z^~S0o{lNg~)-nJf5N4G>4a{4$?irKDa^Re15v_ zel1-a)v8(B3JLL82vY_1%fZE2_D}+w zVrvF*JsahF#TBfCB9kMqF9Pn8crl2N7$AGeL>iqYj%*Nb!*Vvrekon>d8`Y*F0Tu| z`|mnkaQk;El^znqTv^F^BFrM|6^OfTZ8))EQprsU^HO_T7v!75p`)-HGFKgSJ1Z`f z{ZKrgx)D{~5Ug;J?wua5v5QAA|GWntoHfEcR#%Q)luYO-qh~1anSIPV?=a`b>Dn5U z4KGa`*=3E2yi!6A#Z=?QD+VWY02eT)9}gxi&VDn_ASfLDz=70w3djoa`QL0MxHRe5 z(jo;lp#vo@EGU+)4GTu=a>WnS`|;Hz%7YRqWO?>`myt7RT$zw|5e}s}hs?+?y9abI zy(-!Avj)oVp;u7pr0bA|$s9q_FcbuitbwKI$N<@CS0E6Bb|XmwE#A=!-6pn_oivD* zP>@E7@MDNkr-u{T-DgNOFjgsD@cFC@zBaE5zVDlyF8JY(qQ_+}!GQK`sOZ_YOcM3& zTBMUn;k<{2*z}c_O}0ulVsd9>Ls@G*9Jehwm$n>%wKA~)s2~xSAg=(~0f(mU6XXqJ z8a$dQ((wX|oL>y(ope35B?TLq-dg^603bBE3Q~Bg;|Y`C^IMaPFp8)*P(-b+$+slj zM0i5&sZkZ6A4tWtU8+i0#OdK^&O84pd@3Lrjfod15-FhAU2?E~0nD zIEJZ5HY;&DaG0)o*WlWr;aJpYn{|9GUw#dwsE~*j-PWFUdy7DT1rS*ZI1M;ffHH0; z$&@=nMLo8W%3eX1(gnYtb-~xvWx|!Wx?Up@8tWuKWy9bd9R@Ea=3^BS5d{ADUd9Sfy8au;=$I}2(<$wa>qH|Etq#){hoX* z>O~%z9<5BBZULZJL@u=IoW?b7w?s7_CT(Krr0GIfpgtHHh&yPIofWEn_X>E7T08`f zu7kBvG&V=$Jnc-AX$v%1lF9*RD}a^Pg>%}4fj_|s9U&u&vHs{?UE2tb8kjXe^bU*T zXo=~yv5+~g*d8pG3wXembVDCaZ<5LJVy#$0wdhc=$nR?}3C{X6)IW|oLdu3dDjGMX zbisRA7ko6Y3;x{y>2$%n*P#nG?rjSZa5jmnAYg>C4h#7jqh#W_4tC42CUueuDtb8B z+GrI%%;oK$Kv~^&k&r!5U^=%Q&~Bm@c3w0F4x}Ebt%)sR{TF_@1q#wIAf-w{&HypR5Yw6gQ%Lnb;?1Lr3-9aYXR)$M{c-~rjIJ>mb*Qmu(d_CRfu6oAK z_)!z^I!C0V#!y7nS@ERb165x)`?BQZlPMqrTjd-y-UM5uyuzIHm?PX_H__uzS_Kcn91STQOMUrHBz0qcT~ z<&6jUM z^pk-Raw=dA$31yb7U;7Mrk-QhSQ-T7$^jCicCB$^DX0$}ps!PRS#?XS0oG}pfwD#j z!rH}XZNC=>9FPT@bDIJ?O@jf6Vdq}Czu!13)6yt6_UeibGof6T>^b8~p~=RejezXZ zO`+NFG$ATOi}MM4yt^MqQbEiX46vnlq*E-fRO7`ds0Qq5M4BMV#?Tc~UG@a*4#s^W z<1Gb=6DkSrSA5iYGMY{IXXZ_^he^@Y#mcJzeJ6+LYLdDD7rCT4l1AgbE8$(1z(-l1%K%+rwiWoX>t9IVPXc( z2WZ&_V3rW^^Ud}3*{}zh>s*4!xF{`!?tEFTna%Mbt+{N-LbsWB#Cz-wk&BD^_Prw% zzKQdflntv%5JIxDC`r18S~SJtHo*|GGK@r|ok5vWd5Jjrt2n0mE=4td2SX2R!!@M< zf8^m-j-ECuvazl6_v|Ja8f-YuEsK@$IzWx+yBpXPOn}%$@?oC~Cd@;oi>#E6oTA^F zpIQXpeZRHy(E{l#t1DX75qp5Dp0G&jiQBbJE!_4+?9fV#9w{mSP=vo0bJ3mT0{snCD#QUv>8v)n>=6*hCD=Hjop$a2sI*@ z1IIUR%%V3M0CB;F_kjkmW5Mvl`9+|Rqe2O2+=&TxM2%a71CV8+bmv8!)sD(ttM8-d z12j;a7jFgaEA8d)(M!BR2egJGb`4+ zzL~2#Qi;ww&_t4G4oq^({oV^|f<+P4xVI^up#bbqlQaP{EIRyM50maI2y-4fcTvtu zH(89LV@`{nn6@h@00~U4@0*<&Md=i$MBm1>^?c&YNvAxeDX@)o0f1Vp83+hzX6@&_ z!EE3Hr;R*MMtQ@cZ53Sf+(7Q2yn;p7Gp(yT!ky+_M!F!LyAJqnbw!JSAmc=sMZ*h6 z1#r2kd1<3eS5e^W6yI&xY8+#3F4!hce|EqEbzfk>sLK1ZUO&>^4dorb1S9$))&(!} zy5O&;P8YnW74wcYwgQY=Nt!~Y_HZG&q~ktB^Q*efDs-gXrli9cuH2m?z$%&wc{L%1 zn54~m5^p>c2P$fHMYkN03*yZZ>1%E>k(O#}u6g@diCU%+7?fY5D8XC3ejEc%iI?ga zEONFz4TqTB$D_EIpt3}|yI&WGgsm)Yg#mw??7F8GP}I9>3wf3H$GU3=U*IA1$H-EST?_Zkb?Lxh!98b3)ZQd8ht^Lzh)QMG)Cw=pYg+3T{srP0#Q_K>4)Le@Z#YivuG`dA1 zWb{G1bJH85hgoDKML9)*sEsdiPl{m=;liX#JL z%)v2wlXIR{q`tnR$bk+vNw)@e27wCqhNVh5>ufkj8gsf7?lJ}Ma7IaNQx(62`aC~v zcj6@Lyr~eZ7E+UWG&qo#dP_|TILll{CL1<$0pC7tnAS}a+t#fp|8z0CEop>^ zSL{IsGQa}zO4JJ|GpWT9Kr5Fx1%cG4DKkmBhYK9Tv!<%5j95%^=UUz}A zsLFcTZ<%c**=ITF8>O8zyM?eG8#1^A#Do00rK&pV8=xkJF!{2P+jSlwW#d=|RPs6eHosZzTxEw$Z6|p;}{eW@^BbtV<^jyVMWP zS`Vo}QQRvjxPl%FtF3#Lo;C+<9Q^CGv(}l*<%#TjIQLQ-5K46woOjIA2lQeP4`vk) zC16}b^^!>M^wqRG3!J_!!7NxdpHeOlD#uSL6*YGT!yY7FLN~9SFv-+#V`0)_4`M-| z%Rm$$_|x>DPk~b@U|`KUQ}6`)HYJ@>(4s^y86c}G`k~m8lmQ4^O0l#JP@)48%3cl8 z2%NwVt zau7@i3ym9GK3LpK7=fxkceO4|bx0*L*iA}M)NV324w+-#{V>nnI(vWgUFQ_?N7PN~ zgL^1^cFZ3Avee4}93QfBJR)LWaiMC;iZE;`FA8RnFZxGXo9Yio(mYsW>xq)p9jTDW zgj`#g!dKDGZ7#(yuai>MTo^}>^&vWTu$KZ7^{_EoSUEN1%h%_gJ7~-pNu>wIkQ3vd zokDNUmso&cRZ16BSr^Rmy5Q&kAEyhx?Hei;9HD%H4(%1NWt{lCX{TsM0Y1$usObyLTPV*a2nMW4FI$D7gh}cRwW8MLE_-EDYNcCO>3)B7 z8Fg3X+2>ZflrE^TE|}(Z!Tjf3nvCEfjz#qK46{mK!)AyRQgTq?T_hLfC0kICD{HCeG1O|(wuQY*E+m8^$j_4Q#fSpTHr|jN z&ILq+Lo4T6XQP2s>huK<4UmOWT2C(tQDRf&EfCm8&$6qki1MOJ)L9_#ZN($xm1~0D zLWJV%{ey2cuNgzsNg%7amwGrtV?=|HSx;f1E)1G>M~MTe$kaJM;@A{z3_1_5qLiXu zhh#&d^_uJz$ZWUZg7t~o7qyTUwKhSQu$=KDGtL_ZoY?)MdO}$O)*`l{v*|71*XE0$JUgfjFWz zwNdQ4po6XL5M(}`Y-B?^#2pvKlw(8NoG;q~#~sJs*v2;(37-{@y$+vkijd)ob_SG_ zl=ir3DpJ67zYA*0J3_rANp{w2)#@7D-*z-EuFRY+&$gs)ZhAZHyajO1;QO!kmC!gL zqwiX450cT|2!LP@DmOv7{Gvg#jEEMu_3{>X$H_;wGctptUP+m_5X9y-_INV70u5vt zo8{DnqXc*FQ180Tp+9R!);%IAV|qG$qizK4*4%^hi9}WbYyxBxJ(^rzTu&D{JoDNt zU;^nv4go!Pa?Nv0C!^st(G(Uyyp`3`I(HC>JcGBv^n)@jr3*G#7fkZH;Mab)(*-~H z&np!QV`VsX3n=Qq{OJKvWD_`arhC%57!5AdDQWMhT|U2ZdSH>VD%}{|5@7jv2@uqG zvqlv;;!l${$Y=YlMx3&{gH@%U-kNXw#k-H(=46sNZ*k+A!=|eYG{Ny=oNBvWj8IZ; zbbX8Tz1W_V#lUr7Gf1^R)A`aO8Bu#dG4cbn`)uh7N_vglYz4zDu+Q}^}p&S9b@c;zn6zTvH!(zG9rAGocg&1ZXnA1rQR3su-l|9CqVGeC5 zgpTxP^sG5-be|H`+I_Q^Jfp7nQKQW-^XiH=*v7q0NjGtBSr?w{w3nhr2%0fQjirco zM3F-If`axFhmTVJ7uqmE;w_MHDPrJAVklv7BV>TGuM&Wwa)p6hM|)xfq zJxW_@15!e4_J9MjJU`sqL_#-0Ge||~Q%9OOo2mGQdKro>IRICa9tz9!Z)rcqjbR`O zU0k5{wcn7w_O-ayrF6j->wA;yux3a>-<|jw<@4lbhL0=%3c`K-dWOqav!B-pY^)=vm3Rq zLAJ7-PZu%+yoQupOq^?od7PksQ=AJ$%eA_q#eLBw)@N8!v76aw+KxK>$`;TkCKDq? z#so~_rRW_x3#~5akNVLwe=F)G%+~slx~;aQRFv^k7OXo~n4iFI(kS;E_jV*y2YVlZ z5C9H++rITaW)ZGg)cYw)RX?Y@KIaX);B+=UM_hsgGxNOS&M7&zt1FuIic|%m3F374 z9yiCxd&7=E;tpwns8=eAWZh%h^wCIL&J7uMoyqMu))iFdPCG#``JF1A5Od-PfuuNF zuCPNwL4sO6BNv{QlRz*y)0IU!yi%(7B`2GY8x2 z(Hm6P5H-f^1?=dQ^uVxlyLSTvj?)k`?-CwUnKa$YKv9gGRyeq(BukDIr>1}b@q{Ug zv;c-jTYT<~1D0JaKe{WR@k+rq9fa7Ca4pqHZgf$S@u)ZGMW%5XYeYZ92#|Om9s5v# zJk}bAC_NqN#VCuY>kjIoWDRoEwOzJ)`a`Ew7%I)e0j0eWwg1fg=nSX&x|^QS zm^N129hJ$@aKIY6h}fyrhbYlf*S!!gl4<<1e-d>}6^lcoc_Zj9)}gJs9(y>A z^wNDz)a`S!))3~-8*7>H`Wmar#Rk&W9MqV!+-88`pA7%5+qZU~?8oGo*&2R5IlilzFv8Hr1L%|D}Ps=f*G%`NrElQY< zH*b>*;se8u%r7mP=AjI5cQ~C!vxn0%Xi2h>LWT;J#w^Q$vHE7&mLi{UN~i?h>D7Ka z4jEOBs#aZ!g1J5@lu|Gk%mw3AJzl64*oE$+R-Lp-XCQ1d+B$!TO6h`K)&+ySF8GY^ zb-LhR{(b6ksTRTI0)ZMO7X3VM0O?Tan2m1<4yg zWI#O&g&jmbx)xO=mm{4Xqqf8ck=N*C`EpUKU^bF2Z??SIi{^ljxgQAdg6w@2ld4E9 z(?J!KQ*;7nkX|5Daxj{bHX?W`J46sNP@J8!@N~P7!3|Du)a}jA(d`>VnB5t(DMGC` zj~=z2%p!MXVf%y#u^Yl4!%15{kf^gLP-Zz}*>Zj7e4%Bvz;h{G@FlDZ`gvXOyB;}R zaQoSn3XD34uzdYbMgw)}AfD_1g=U_08zqYA>T8UiSYlF`90c4VQqn0`e*F>RTE1Dy1S`v?tfebl#r|o=iow>sb4i zY&?UD?=8T43I<-m8kN8+tfaHnDZ3t#tQ``qfyvU;EvY9v8n;-d>g16rDvJCH*a?z( z-ydL$KLpx2ifqea#Jgtc;K9X5wI7f2>U=q6A_lr}LmO|z-7Rw-TZrK}5{>UL64}E`F$)5l zyCzMO$a39J#vls7%s0iT$tMIEH|ouzPq5U5W?_L`TLKXJ2<(A)F&mq122mp_tEI&) zf#->2gUQ@B&5&p|d$5kz(##1I$+Z~9LO7z;dtL5kpy&QF{jT+9F=K2xZ6q6gA7@zRvS<+0+EApP&sF9kR>fk8KUeb}FOywU4o0I8AYdXu( zt8zn>(gk0}y5NI(UGT2|+UbIojYJM4m1~qtS0f?+DgpTVo#8@=;XSjvY6Pj7${z9E!-Hp?20*}TTo=12hVj^eIwsQ%TCoN?;#6TKab zFekU|Yt`GLQM)s|_-%lWyh%-jM#E*6E8u=SaPmsxT&5WR@uID)bs=8e&L_e*UYMqQ z1ZIQ4lU@JZd7nR*b0JU7V5O9Fu~>QH6k9oJK(j!)7rV3WFrNuyOE!xlI*6mlM=dxA zN2)HCgWCnnx+>pn?aF4ow5hOlreNl5oGP@ zbke&-re!9NO3F`0&6QC*nyv4YLZ*`mEBwP=((g(!)u=&~chQ}gP01tYND#IcN;ObS zwd^oDtl`srjZ7XsSx_$Pkw*~3#PK({-NN-J=eAeCDsqU%a9RqK(aSoxQ#}OMSZ=xl z+CztaQFP1+Nhzc>S4U|PVXq5fUrElI!kjmJ0Hi<899A~2?i$qAGq@$}nfs^>hAQ<* z8z+To45srL_=+1+C(APM9=qb*r|p3W0-8b&aZromiRxQ;XU8oHNDW-Jq}}I^Md(Xl zeEUUH0(AC-AUeR#FM3phz6^XG+F72bNswQ;UN(P_b-_(u7p(psrwh&=R4RL}e$|>g z=W(myZM$y_*>+xi-~|qzCmqOmV-z_6GwO&I);(}UHTjQXWNt4E;LW_^q&jW;S=}$A z8r8oXY!Dzgi6M)?t_d$5HSb5hq9PO|9x9F+aWYS@t^kJJAH^k^(rs5)zFOT8NDj#u zM6ESq={*`EL;SofDJ!rM0^+AGo^7}FxXEl>$ZBdO8MO@+w@`CKVVq~#LMCn3ChUR& z98Ygm#tXdIw&y>Rs36Y+T!>|emb$--FhuT1qdrEq5$AGY2%TP6mB0tXqu@B^zIsGUgEmQW6nmIF^nfwQSb+yrb%oFUmO@Y!RlSo# zBGcphk&bO)q`Q=M@tw`VIQT)^r&OjZJveyGo`AB}U0O<){ZTv)A+eoSO{sHc+?0WH)i%DQFjqg=2~~maZ+f zcjVZEue+qrABaC! zC9{2yn(RKq2{@nile9V9gT;sjb|{AiwZCA6f>8SPu20_w8HQ5GGr`X|yR%xd*Nl1~2 z{=wB%!d!m90=Jz$_i>Hd>#>C-b?S>x#YKWIF(~6+(RdBIHSYVIp*vzaMSZc}bHMCr zB+XTk?xf&8swy~iD{+BVYnQOQ+#Dbm1O6TDoFx9begl;b|fZKNGB_cv-S?x0WVaRzBq z1jbWQmePKdK99O_{gct@)gd~m!M-B~yU&dV#s6|N8+Mm0x28dE;5$1cet5yrMPvHKO&hJx>WYpv?1=E~ zw1|YLJ%_h}`PR1E)TvNgisUW`QYxlN#-Ne zcyZBApEOfSa6{D%PHl;7v{bag*aI-f-1Iq-`dYoQ3DA_%1^cWEF7vwJQOoIqPyWA9 zj|f2ibkxav*I|K!9l5%q^IA5fHyuQPjVmux9td`6$l?;PsT7+-MmX?MBY41aMR@3D9MKT$nUU`4PYN$qOY03~}IjKxy`fR;vvN5vTHn^+E zhFD$EXgoDkwzXm(fi=`XBI|>An=wm6S!TXjyW~Wu8^ejv zJ3+1AXRpjif`_oXM$Z zNlpm`PqVqPZh!8G0Xl1)6hp63vQuA&U1=*udD%#nT&h5|?);(jm1s5M{+IxApwj;W z`iC3kSxM~{nrf%v5VLw-B)+jxFKFnH*DOs=cvGRX?!|~V6S1<&3J;BGMzl%yT34;( zQ!-aipG7Cj7EKP_9zbBz!%AzzWV%K^!y0gUZ`MhIgl1{_Mxw9E!*?&f41@eMwfU3^4`h_^(1~Z3#A;-wbr>uNV;Aspyu{GY5chvw>94M{`Q1eoU87P#B-0sg} z4Gnf@b!-lWuw*VxLLJppN-o;{NcjvTXwHTVa6+~O1>{ZV`qINSTr-6p)((4=2qJBv>cKkI zO~YE%*CA#hYMs$Py_pRzhu|li-2mT+5)+Cv*4!-$b7v^D)M@R}ajV&ldw%1_=~80b z=hm|EoGm3npm6prG;6JtE_lGY;4AaG;44N>7ktV&_dCvK9%~30)`MYTL4iSi z!-{-6fsSZZ>&2Sg8i*%>Cvbv&STh^=3ndroznOl+tw9o2_=EP9s z*h#BS+^JS(qbajt1z%?v_5RAO^yS-?X(oTjHcf$QiW)@`L)w%hg{0x|o}A4tFG#tuB^lgNrF6kV z)&+kguL~~U?R3G{d`{jkQ07a6ZK0~%ne7d)BKK0!deRO7rD}OLVoF6jIf*iQC6q&; zAL*(%?4yI@CSJp~z6mY>M4}XKQby4eWOl`VA;EFlimpAXSbMso?#sJ^S$UE?pPok^ zj=~55MXjG0Faw?Xgpo_kK;Rq%_eQb;l^N7+C^Q<+I3g%VX%aU_aV^=DVf1N4W?gO= z2zR&#sL2i#0+p6v{BY@7iccUER-%rSj^+3w=adJtWWlA?6+I%mx$cbU(eXv}Nm7J? z9%B<1bx6A}GOx0*`&L)w-U=*9F%<>vX{v|5T--Vh~{FyX`{-&hJmC9wKNu zLt=rBh7JC2l+-N7BDH`L+%ZuvtP*kF#-JcwFIJzkIGE;fI6F7D#nAkCxn@Tfs8rc*Kno3m}O&T{sF>IhCDVsaa(Xef=Q8<+&%8?YsP_s-_^^+S@un0jrOAuSY z1r4l?Zg*@;)+z#@`>p%OXG<2S(_x5BVM`6#of{A>UCNUos&H!K(|ihW9w{oN3*N`N z;4AXFVDPO@7d-wY#E#JicfH70(>5}~HWHG85ekr9;OR(!1KTUGIJ()iE4^XJtUekI zua7{mjU#g^mPdeNS(8x^|GEUL`nWflpo$zs8^ylkP7d=2wJqi(niywRqMaw{tdH(I zwisXJ4Dv8fRRvzFdGvzv*ayrNJ-yh1-yojqY>fFtp8*d2mSPv_JJ9#s0drt-Y|d`k^u*PbTV>^_ zbhyQ{1YSq4tZ6&01QfBObCVW0VLG&5mj>dbDxw3uiqoL`Bs=16b;y`!?p$(_3{cO0 z8X4>%%Yp5B)!4o#{;9MHKLYh{hTh6?+r6k%HJibmV$aYsm8|!ut@0xM$cv&jKwsI- zRHc9>L^uS}3EeeOP`;Edc*MHk19@GLzSrr3FZo{dFIcX}z@bASB~dL++LO)=xuS84 zLE9=sQ$;(u9CNXm+T`J=WiGl2kCmec$s#_9HEbA`iW_)377CmsZ!EB+sl=1ELEPZjppbKA7kkrlkI()1~t!3u$O^ zv&rVWW_=QX?i3D?hy?w#QNVhU0;GD30=Ws^s!h*PpGuT-+!H%FRhSMZJR}ljO@I^I zrjMdhCEE1q#{ZV|DdWD;XK29dgbD=VR zC`GBb0Q>?QRxt?!V3bt&V`So(ayJ))C5$l8k|-f#gicOmb=c68B)!RQvApFUu+S|* zt&}b}VqNg%d0p`QUpQTG@24vjj?nw$zuEk@_B1E|N#q@Ar%=aN1hPR{3gOByRXzE=x?I{?)Bvdz^ynz%<*# zi?e-H=zbb)_AP8YG2LRpt6R+%}Sh!c!DPXKvc z+|cG8^-KF~x&u)4Z8I4AdSiwpJX3Qx-qOff&8sWgW^|HUO21mk-Aut&>U9_EV4{d0 zeKY!Ub#^l@W0waea67+T`$Hr|jiwE>JdQI%6v>^c+kRL28nCj)o)fi7;kc;dOoIi? z92Ve44%iGVXC#AW0lJ5@415uTa-Wgr0wiDqfNIOqC=+2 z&LgAyTh-lHTbI(0JaPHb7F_ZNYHS`b2zRd+MV za2KuS5O7tykH8}m?{f6F;C@hEOSk#91ZU}6#aJc-4(?DewbB`AAcMlc1f@QD%~w}6 z+!DC3TM6VnzmnFM`YLS82{oxlXG#0X{r0f?tk<31p!i1&gA(tWXFBTM@3wFZhVU0# zra8eKq;ZMxHqT|=KrN*UPFNSbKd%eE z{sT@IeE0vsJR&$GYDUEBiVm=&8m8Mx6j??R)@azp1_kl$$#gW1v^N+J&^IdBR(=5D z_3lxB>$6CTf^vp+3tHUw%eGXkn-|_uu3I1+4x`pCEvu>r$!Kphn!phts1#K_d(&AS zM~fPabmJcn=te2)%LAS#Uo|6K3jJS!rQc6(+St02MMx3_dnTYxbZ!oEk^C}-a*>t^ zIBRGUY%3w2u(N-^$6!+Au4K$dgDj|?k!PD5e=kEndwhNrCkl$7jAmY0fF#>5fB+IH zQU~V}c52xXpQ+oYDn_tLUT*G}cT)oUM2E(aEt7LKIlv{vKCU8H_D#P`>>TGs#5*V< zHM%Jk!P4ZbI5ET)5Quun!jW2CdFUR}*E3XSa{#i~JeDRl{HXV1j zROF`?L4o<}p0}G^wGsPdTin2R%W)KRt$^A&&L(2<)_8Hh_kwmu)VwQil`Z$@k+EGl z1{9;-?_EQ7#t9D-?a){-6cTikb(8d|IPX&ZMRZeQL-IaMJNvf~rda?@HIFZw(Q(>K zSM~@Ub_wud6_KEZ|2;Z*n|c*Y&|YeKaS4nfnID|8oS zo#owoi6z2f4x#Ud2obuipJ67 z18jVqYfu%}o}40z+C^?Nw#L$n%D%lGuig>Ud1h+I0R`&LI@4%?%g6_vnFYtjTOv8f zrdoY9RTcti&$65wbe4blOn_QAYp}li~)_%97*~{V48;2TQff44#7> zIskk`qJ0);h$&}8cj@ZVB+>?EEOmnHvt?=^>GD!kY`@iT#kluSm@ya5k61Z9^%MAB zDP8ae>w?F5UGP26oG$ohpIWJSt}86!`|T99>XvKztUI6xiii=CLJl*HfE=O zQF$V}*MnegL0YY@=Ex8ExMZ+mp2GH8BDoeNHBI>+K}4^?ab1iFlv7Tt zD*@KCBy^0qM%Z2>lg|VGb}!D3QMOk=@9k!D1zJeyc$&1Ka%q3(1e&rC^FSGFo5%yw~j| zjvV+uEg7b8q4xSJ&N)5Re_^&P9>gKNU0A~0)Jz%taqHssFX#;MYkm%_KB7~`hQ%0t z{BK16o6&!$G8F#5P5Z{b9K{TA4*wU2_mk9LIO(OvJ$${CE;wghaFN#qpZG$j3%=nW zS1O@7Vd`y$IQ;uOMd&6u@`Zmd;HOHu4LqRfrJNg9wUK6fG?&{uIEB7}^7Oq*- zF`LEyngP1ri=@ko$J-u>xw(>O@@hY$zS{Qs`uaTyx^*U_6uoY)vb34NyUor{S~Ijl zer|Uwl#&ZbtXUz&Z-DEq;#W=9o#}n;zNR+BmJf&ROGwzm1UBQu@6-R0Udl)%BA3+e zIeViwK1rs}MiVM2q`ZMUxu5sCe9@j;dzR_&c75Fk`~{9QJxqHD$DU5|qUYBRH9&1+ z5fR0c_l`{`f!xl{_dY<6L$WSIuLN0RU!a3Wq?bsi{2%IsO8@YDZ~Qgi1p$`~Yruvq z>twpn*P4IO#zkn!P0|UgztYhND%iGcwTS5*$roYspt@!LJfDGWH z=fJf6<1xDj;WtQq)O~I3pU7a74MjK=xgR`J5i23OO6Ms)Tm091uXzr zm;+A8;#XC7r_rwem3p(9h@X6y+e|P{z2~u2C)v)pnI+2Kj8Yuj(J-I*$|AHl++P>A zF15PG0q1vb>W?c#kwMxVw84P6UOQ`@k==(=iO4w>XM=>uSShP3ntud+DlBGpAzI9b zgDW=d^v0ZO7&_+K*U>^-UXT;Z_#Mco`7!-H?t(n1KB`0-l&3J-?M|eGXEpc@iW1-b zjdN5Ag+iy7;@$I(A5ve#7jy!&+nQa%g4K5mJ+k4i%vb-ybA*X4^5Oo>w@#VF8I&C%jtrD@_$z<7{SStC&?{LsV=!Cvy(k%YqBLo z`i$Q4P<=y*kpdV$K+`y)ycr>Bi&k**%j=E%5SEQSjJE=L^^PA^?=} zUadlLq5Lq@n*C=y%)@qiBfpcM@kemd5LRxr5$8{a*VCK)r%l*SELHpsi-BGFiF-s7 z@0H7vIoCvEa4zLx+Pe8K@Z=NA_nHU8;psyZK*pk@nEw{05m)h+V5D(Vw$a2t77b!P z_1ChG>aQA(AEv~txgSAlhqPk|ZT`TX_t$=hvV*~6 zLcB!$NYhs_*Gkb+9|G#uh)gpn=Eu?ikY5K?(~ZXF$1~rc*BPP7XYdPzR=)f;knG$~ z8g5~i6UH+`nCcJV&XD(yoB~%NpUq4p!c_Xmn!EZLH^v8<$MRik7n?g+U_t-TAOcM> zD=L3OSu2=kf?2Yy#px?A@rs>KX&o^BoqZJkx!E?YwTsc<5}EMBgs&n9YP=9Xjx31# z1%DB{&z=an#n@hRwyI&ymC^-|Sr@#K*9HIO1E&jq^FydXkxMqi?D!;H!u2_9mF8oS zycZ!&)g@eA`G`8}RS6JVl}7~wt{o59WlG|JkZA~5u0iD)q1CNrMwygZyPHwD+?|L3 z=l0`k-=jW*WA6$^MDY>-7LCX6Zyq%p=WiR#Z+PL(mKRM}HZZ(do>?IR?pucpz0uVb zK7`3gnODxBv{#@FPA}=b_=j)xAe^81FH4#hE)Ckx(J-w6F9rXG!IA&B7v{D-EJvgo zQ#$I92Lt@b)(6ACKpeMP%qYHjB00X|r~vqvBfh%YKQ+~pTzxz z{)y!2(+3Qay6aSb-Tm7b(xQCR8LSM>a;Go&zw!f*SiNf3vi<=-v#F_NpTZ*Z_-l}M zV9!7@+UK?_Nk7T$5xM{q*iWi2q2<=^9sfXGzqv~PoFgTueMVBuoiUb-9ZIN@FAHi~ z;T#e7^CL&o^K4`PNH5-+syGJ1_ZsH~4ueUGOIBg0s9X_)EX(biwz$ zzfzg>EukoXhQH32%XjjH*UsO&x{C_ni7a%M<+cn^lge4(FG7y2@q6P`&Q z{zq@zyE6!9)hyeI7%2Ov6}tJc37FD2PB1Qn^@?N^w47Z#2gzr61t=Fz#2xb9eme*B z@$VtMxDg+VHv27q$NOl)%q#FAeKsT@ZUR)T9!ld_7Oo5Gn1?c-8ynnxl3NgqS5jQd z6qPf!s1us%bRZJBgRn+T3dXsxLjuODJ{iV5=B5qKRX3$@AhAsg2i~&g3ld(`!ho;+ zQ*}xt&1P)C(sPE|jSY6!BlS$Yhj=)6g3jqN>mH7W;SYrRk_mwS#9hF$UGu*QV(XjB zwl-S>MQfliI~)r_V5Kt}`n%G0>-R2swE?Gf4aRRC)o#T!na;+RhJ;74?_p=l{^jfg z7&X2g?86?up1X2HkpL=kWkXs>(V=~ci+;b8gy<1eXAvlv8Ps*!m|R6V8~rx5lZAiJ zw@bw(iZI|@JJt@aj6EAJ`*ZtBrF6kttP4)_y5NWZqSFQ6vRtkx=Fa`3edWO>V~p22OYAa8QgM-xBBZKYw64-VeKoW708d6Ufa*012n;N#pA%lIO>!o3ak0+Ie%A z1NSX{aqfv}hlX5H7fPnOYlJW8yOS5udoAhV1x`iWC*GN)pSe5ba*f>rx(~_i zL!1|IR2H$y{F>NO5UJQOwtoXWr@5~J^d}El^N0D(?B^K|I(s?iD`%hEP23q00O)K$ zOlQHGv(_mW&P~u6kXPnRSrvxy97Zrm12A63naTL2CJOrJl)G-;tFK#Vki2C;8%+|W zV(`p~v!Yqi^#oqpc;+5XzuK2H`N*Yo!TVVkoaA-Ef7@}o;2j5*iu05CjLyA;J=r{| zT6qMZfI>l=P+hMauCw3cbPba+A3#S3To3F`R`=o@9#F`^ow3TFQRbaj)7iV~Y8rb^ zKWfI(QnrBk5gRY=rZ2-u-DAG?gG2x+c3^@HXg3I=%hS^dVdN<%XkbQWnD5-4peG~4 zL}7T)cQf=zd`VcD__u3{ihn-eTwk9tev(r$`JG0EB1gB0CwaIFR=?bg1~8V%D)2B0 zJ;8j{b&Tf-Ha*e_lhJ4(Tn^Akrt~&OEfZyfZ%gD7{2PkU)Kj2uj4loN0w_K!#P+P) zqo00ooLqyV%eU#Y5en>}EFJy2n~d9&DQQeU+=MzEL3_G7mG~Mx^Vy@l7JIGz_9Y?~ z-N)xmUbTH?V}Y6G){Bfa(jUM_J5La(Q1=pxhSzl1MB1Yp>@2$@*`mov7)CtXo>>ji z>M1386w=aDAWBhDV+2p~*199F7@%xFKc{|zR{OM{U-UXplIhFQOLVx)d@};5gbDoo z_NaG-+Kn8iP7Yhq=#H1?+M?brV@bE;k&>U$7LM#c6h*f7y(oOwx=GU^`7I5bb949bd1^ zD0GQr9gH6}GosEp<$jF$larTiSN--iS!}qAjpJYgwZ;jBk#P-waAh|07mTfDn$B>( z_hAl`gG+-WTuTJG90r5yT=U8VJYA#{S5ILV_1j|!e)1RdRp4?@vj^6Zxo|L?AaF`T zjI8n0SjlH#n4UM*BnFGG4pO@4zr99Iu3U$=LX7`4yjcE&%p9(f6`uc;jmdVOe`fta zGme{YbPl>n2JIXzl%7LA#~nr!V$pNXp*&BRIEzw`(0(xCFXTd}kKBW=JfzUZ}wOt?Vh4o8T!ijq@bq5;j@PAUawB^M+g#ufb`0gM( zQ84^6Bq1!^#NW-dzGOd+>2U0M(VeVqA|lTl#jlE2|4YhS!RB>IcjP~*bHZYd@E^-> zLT05YQ4Pgr!IZ4b)tQvYaiZ{wF~{%++Gw|?vrAfA`w;}<7Zh&H^yctSF`%dSr;7Tb-_>kq|*hH-vW=wfz*s?0A`$DLV6jX!LR*QWsjiq zsI$)7t`NVGCjLdTLY((JARQnP?(4kl@|UUGj?a7G>I|>@2_vE$&^(sU`umMDThz=x zbhdyB&OA@qgi;@lkjzE~DgW_!46#I;2&lC|E@AfZKSsw!y|G7zZx|l7gBTNA>l3L; zlawfhNRXp1vDoA<9Z*Vye+dgOaWos>y9LpCa60T$l(PdYGR;3c(mQOY0j5O26nArj zU4fqf15U1H!;bm)!5G3C+#id~q)vM0bQrtaI2Qm}-SU00vV7S3k|PPj28Exf^stF= z&+GfbGMXQ7rKr}EnFa5CQ&>EB<{PLbHFp74y{Q#PS;A0hZrRL_*uCzf#ytc{=GGJz z=-CEznah}4cwOFUF!$h;zxj)N2Xw)3{)HV5rU7~L?z)|{%HPr_&F5zld;!I?W^QXK zsAlhHPq>38vy;d^piMh^atF3~|8|-*CX+Vp9$r^)a}&>g0<8_myvupO2C{n> zjpSHI@h0oG0>UuN=(|s@JzQq*JKTWWG_FX)=cff$2)S-jo>1)IX}e?BobF`@U%`qdKinfuF_w)fRP`=8JyShK42!!8nPDANlNNp>p56~Tn64SZ_ z*>Ph_1#$MS75l>}LdGCYVW;D$kx};4x(d{e6`^5Q8zOrdcc+l`+@-mjWF0Y>00Z*y zGrwq&u%N?9&uZ^R@2bTu0EZ zSpEFZ`9=Kq4}RHS`P9lm<&%GI^cAcN-j~+}f3NOz!C(HHl?t-AjmP_^Rk>T0fC!k7 zSWFg~d&nBdMSdLRueqCLFZATxU!_@zi!AI zVy|U(iT7ZknTtuyS||P|eVv3n zNald(F@QV;{-BcwX>pzq`(`hBX8oo4@;CS{1Ibo0@|G~)$;}G8 zY^>C=P0Zl?t%e^GdQo$lmEKvQ^tQosKR)9$$>ef`1eA7*?NG7RJmFd7oV-2n#bx zdDS{TC2Foymd2TM#wa}k<`B2yDK>_SY*W5Agxa_MsBts-sy$+TgcbPjXUGzLG{j<= zyU|PcQcTHH*eQTg(0_tGXNtwZYZK*e98?SO_@B;yjW-jNgN1}<6LMbR2v2!Pc)gID zxN^z3&5htT^mX$NrmbLW?~MQKr4G0?O3e(68(d9N3U7n|ILS`}cy@Cj8s7-Ju;mzW z<^Io!C`hJ(h|zdDKj7wjfMnC z+mlRty_a;&8`^8>{(0~EW}0U2)dihz`@GUue7l6XO2KFMg_AuT99|Ny=>*{74Sq-~24Bp53dX^4j!e|Q02y8n>=(yq__D1S%) zqwICGxy(;~5kc_dl8ofsXS);a3!CaXkgqaAVE|7HsSPS$Pq`cdoi+ntUh*|yI-J<^O}DRVz^K}AdxTp9zriMNEK~^ zj@8lpdA@Fkf3ITkDjunaLLHsk4u)|LMkaD!4y}`kStKX_4g34t7o5yI-#>A;wWxzF zz2V;yf~z-Rrz=H-pCyf?0 z?7%8_myGn!Uo*0{HKP1?q%HxS1gzILSDg*VrYnPRa1ICLeQ}=5Ev=QilFlv-6b_-} z6bsPC!^ib?tVi#;nfO!6IKtx*#AB`$CXqgJv!4CXxlP}q+P|fA!5?8=@G!3ne&G{N z7yQb{D-|gz`4phSU{SEe+WPPfsAd$Ze1M5Iy!Mzn83p9*xDRo9+-vIf1+qPRNgKQn z8F&X+$lD?FRm1@7gXL{&`@KwL(W*ap12(;!iX+X@c<}&iib=1-U!+F|5tgc~ZQXNW z^=m5LaC$`|RHvZ{@f91xRf^z<23gr$txBN{v7JpjHc1-&)bQg7&HEa4a|m4>3vt!E z&f(Vc;Vu`mu`{H{@aWxP7n6aVDSF3ir38l>|KjFMuGRHdn@VVXLfS}e|QAgo1_^tR>O^y*aptDUXwR4%o%yVzX zvVa(Yo(D6wo-UsVhERl%)zWMWlKJKyN2HxG2eTh#?7dRD;44`d zJjm;UUp#fX;JNr6ku0%@zt12}S+n$t~ZXEA%(VKVoErz6;9{k`?X* zrilJ#q}`s0cj(AlO^WTB{Iq#f&pn%`*BHEk-_MP!{jdRx zm1=dUKg?V_Knp}9Z;O$gS(1~Bqhp7x`?UcK;SP@*-}v<}|N3+?8eY@aEJulUl@31c zIJzLpnVg{hn10q-I^~L?z~m?X9Du1@`4apkRSCR76et3j37`6!-vDa(U^wYXpPWl= zNKIz?-&%5=mzVw{NY!4~coi(wwQdANGH@gjUiM>Cna0h&Nl7se*0JbK_JIrv{k^JS zl{N=tP@+4nAodAH4n^llf_u6ge%ZXb@m|8_U~PI^D;7nSbW8LES~?3YxFL znB#b*`3qJXBeW*RnvRRRVggUuD|H#heP=_i;K&aAJ?Jn0d-}`&mj3d;<6sH9B_yJr zs?#IQj8W@^ig>sK7>=5=+5+;{*r*0%MmK-v zjw%l-rL5Rh4p%a@dJgxSuYIccCiY%=_=Kk(zKrR5>&{ntI&1;^nC`VFU5ZQC6Yb4D zu5&t9O?va*uA>zqcx}=PP}Gp20Q0(Pc7S{rCMfbI@IY|1FUSIFcAwkug1ch>M1ib{ zEu_z+s3}kgjAWuMxB>kQ;9!DA()eqxi59MmOni#LSXwwVE6s~DX^qoMl4NJS7GsMc z71%|u>7JcC2T%2R(JJUS;*(CRX;{n zM+6M<+%K~*sP+8uL=EJ$aM;KW#gc*-rZ~2bqZL0}+=|{)-@Pi-9deYj619{rXtORj z$m@b%`(dXGe&DAo6{Y^I(c*treZX3#?v|A7q?Q1PhQKc+#=O2p#(>I6pj^?xoPe2a9fVn5`=eP8Le;pN~>W#JM%sKHaCCk58Fo#oEA5p+zKKW2gp z#=m4uaJ}G{S^xRXGB<<9s!#bww2wuln@b><(gN|vV7tk`-)c{&nUp{fV;Jd!MQjv}LmsR;wl?FtV>~Y*f=WytBa&E#)Z0r?N z=gg#tTn{r_jH8ganQbMBx6Cw_#0d5RC0=EJk+d5mq{AFskP)ytrKkOhZ={Xg^UbsI4Nr7K!t@XwcDq$GJ z$9UD5>yA-rf0hxOXr=4F#{$Gq`Eu92II=g$5I*e{h+V^(rjyN`V2n!)MmNZ9TgZ}H z$3LpOk}2IaRbP!`=9hcUJ?4|hR`VK#*HBy$ZFva*MT}^2i}sanhrPC@uai`17+z43 zrkJ!W@I}rUOEerD{A$XT#F>=iObH(az}J0|H55j`!{O2)^=QR~`Fr5W3{@6ir}<$qk-fdYNTD7pL7aBbOFUI;E?6~b z?gKjVYm>E*Sy|u<DH@xRX3fk%kEB70#KiJk{MX*w~&4e8SiLf#ckwHtX=AN z=(?60jBGd?km6$Cag@>p9o7YVd0p`Tey-C6|9x7im>0^1^+Jg;H*NI1AyUxE9-RvO z34|lV2r-wt$NL!@s5g9S_aQr5FpD9MT-giU#K-C|eVOA;aymm8!#DdF`aXEivoUNB zf=7tiOy>xny)4cLpPhQZ6LSSKDcQZOlu{rIp)M>adu(co;4Ps6%?q;Zvm_XLhJ*2_ zV+%pI*6<7C`{uqYqo3>*2cMf(d;3gxEW99J#1}Jcoy-6yR2{|;XgE{V{lHv09quEO zc-YN-)Jq@ixvzm0bGk2oQM}UWJ(?Si!cC}pJ>eaV>G=rgxQ^4%uGTtoQF^&^^?Sps z30BfjI1(eF!)K~{BIFA5RnaT&R78>#25^H}YKK`7(yrl=>{nad>_uEReo>}}n4M2z zKI5wLC#MteFvS$l4QVzQf9vf`iBtO>SceZXc(A|vxOlahGOVvW*xuxJJO!`q2F1Uv zSb43kOb$$VX$NW$(bj07&xiFU2@$o<9sQFxg*cXUMVudVKcmLrOq)n3eS_J{I3u}> zhTwy8EbU?Mg?AF^`wnjP0IR#=K~{IA&Wn@%l?Pi1diD39zx?m%FaKNmYlA0Fcj|W> zUWju1aCWFLiJ3H4o|{7ez53C@6`$n-1zDBmp9XglxdBq-?@Ml8u`Lh!sIZ>=nzi zVE5U3FFY&uj*Z{;RP4Q@@PFsrd#CKqY?6f}pvilSyLax)+WXh8g=d9}FN2V->J|Hkv+Lj-Mx-{wkAHRL12J{Xm0PgN8J7^bN90iXu3(m4F4 zQPWp+pz)(5rzpS3_(}E;{*uyaHpmqXn*-llF=>JWQGiswgaD~HP%G5d6!$r?AXAHc zGq6<~8aZ#1d5>c+hk@r=plA+NwZ<>R zTY`IlOnq=?G$LKguo&aTwYv`a}Zy`yQgrfxkAL? zL{xGdEwgX7ZOUVkX{s{^5sr%rl1zu6kbju0pI7lgP`Jc@tIG@xMNwV6ufthR-nL566H5JsDE4cp`q>L*D8 zTlE9Mi|mNHfE~m^xKD>gu7kM+1y&Ua|LBLvcsMy|_Eg3CA-C+vY>3-e?n8&DfK_CE z%s_V*g+;3j@OGaUY^;|au(E_5cuL^p$2lM|)LcLwZgf0w{zN169+x0nL@k~0Vmg#= zSKi3(aWddvO+B{NylD}y6mwl#tu!5E)dKTTOYA{w&PElikf~g`@UKM+D&UqzyBc4) z)yUC;SYIM*3$VJHSIQ$Me1~Fl_H-%|T(Y9#_H{`DsM=e|BtHPkYU3tx@b*4|NT(vcUii&C_P|$N_VyHN* zq+USEK*dnF?1(za5RB8B7PAGl5q0MrlHv#}S3e_8F)13H91JcXDo$9YN(5LILQDpa zlxY=l_OKjOo$%X;5sSEw3N1J4NwVW+*i#1G;=ZPSI{aq<`xnw10o0;^B35pS8>Z(@ z(KD4vR-K+B%v7@B&%<%8?Wzc!0$yYaS1g*KQrL%GknIAyAd*m0WrfCQ$Ix#nXc1Og zQ~9=uR&r$p6NE8R|j~9yAsdw$dO}S?QrQ@=j%^ z#b@|Jj@xaR_J`F`{SPZP>~q2{C{2b@LA2SIEtSmk0(E?vZ~}C*5vW39B8#;B!eGvW zH<=~ZG`HT&At=ip@)BnP7D-2X&Mo z7x$?%CH!cxJH(nhG3@TKJyg_*)8bQ6okDRoW1)+o71UPqmG3JkMG6fPHrNjXOBwXU zBf41zGu)zhO2A)@2#Nq0(o0D`8@nu2>U2>Ewe22P?5~Ho$?ghTYGTmD3iB0Y7x6oQ z5JgTy8istEA%HKL+wD$HRfloCka>hr=`c%|ahkn7a+b3H(9JMmNC`JbRt1WItOU>` zajJ?JZ6^Cd4wPZrN>8S0p_EiXNJ%GanI(UndCv+#5DV4R{u7cj?wi>N0EAB{f#su3 z+@(c}pKA${AuDHB2TFyUMab_&7GQZXT&gY_K*UHW$gCngDu{ zO6ZAAZv!eYj0Qk9;wIY;o>wBxnw#kkWjjt%OMA#R28xa=KeA91@o8|>}RC~!>&@a zplOE7Rb6eoilGAz*G7t+mc;ZJ7TY+LDAgrmafw3=_y92%2%t7wPaHq`kzp8izimH? zx{$GooO#7!)bAE6vfPm^sFd~{5JC_atMjT=MLAO_%qMf8=$N8TK>xUcQwPybB;-SZ zH2BsfhIB$uzi|mjIAm9Tz^obaoRuV{OT2CO)DqECY#Mtk%r?giQ6M$QHrZ35DP=HC z!unE2hy>=cR0ZAQ^p~hyZcWKqVG8yxa1AXn5oMATEn5~7-`80vl_*gnbPWb^C%3nT}NZ)lg$$?6!K zmLkzfJi4k#N=Wg&2CN$acVq~w^-JSOU9CZ^j$y0YR9kL(nh=!uL$ta}LQrp6?t+|x zE+ETo_?05lExH$7y|`IHD|@w~H$_(~3LZ?Jcr1)C_Cz?zwr&c^8wz%nwt%n?lf@$C zS{@WzwSKaD@GH401|s_?aWXY&uWC2mzNxoc>ZPKtEp5#0$R~N ziW112oC5?gS!%JBRB@qbfi#+m#DQPh50UO1%JUHJOJiP5+!txwCO4f^4lsUJe!Vg{ zlhdi&^Ky5kB#XnueYcc`Leyny}X%u z?$Ek?7=zKKV{JA)j6=EDms*3lh;|m_78nSb?$3v|1wyxg5ZiKBsel59nS2by&3vLL zbtm0SN1g5?!6%$LM!vJ1aQzg4B@&eK(qT!g9a|T$dWl#}?kf=X(amH9lMfHZ8l37F z94-@DDIpH$0?4i!paf9YiGf-SMMyn6lj)CvlDG;9x%J1$9*XPAaG&N|P~w~rVhDi{ zpaA$q$)aUCqOfL}N=7;}cq6TI;;jurM*%gbae_iQ(F$k*;sx zuf*=4VLXp|SW&5##=ub5^p%@0q7kuazg-X*+xh;sW>KtSn*wZp32T-p`-~;Adc`7`cA@#k zZ)K8Ydnzaq9}Y?GGYiaEh$BzAFd40q@-l)@ht~Dstyc#HbeQt(%{O1w)DNGQ3XogV zT6hjeWC}p$Z8dGMjbs6UXsw;4BsU5dX4Z2>j2ZtBKo^=UH6#ua6Lp4Tw}E4~9~6?* z;kwyRPEvKKt1&yZL(OR%2}T%Hj$ubCAIWF&UfM!)YU-_ha$c{JPXd3y zie2>77NC&BIaJPk1YkHJb7_DmN%Hq#R6(q*KSfP7&^N_I3l=afm}sR1;~rJC;F-}b zm+eaN7~aJ&ZG)=AA3_tMENoWzMfQ3$TfT-Sp`s(xIA4*PK>Q+;#2K(A5oVSJvrJGJ zR~7TBtZLP7p{liC*Iu`AQWJkt;15;#$r@ftJf*H!OpZksDz8}C5SZfFY#xv9J}i=K z0nsA8S2=$@ z?)!t~Z?@=bLG*VUYd(gFhM`{s4~$EO|4vx2c$#@OCKSk^rNQJ&8mdiE;U#@VUIkO3 zU_)t}qtIa1&=~L~GORpppE}zi%2L(}!W-QAj52{niUptx)*Pbvs}1{{?OVMb_1aPx z1xwkm+ySBqrgF90EDL~+O%=Fsfl>s7C2+_2qGyT6`ZOe_4!PdV=PKSWR)E@?)Z12n#mjUXs}8_o~$2mfL)SyO(&L+J?}6)iZ;ImGoZX&{0-o82r*NV#U~&ce047 zf--gZN;-@Z^g?eEwOaPZ(jxBWT2o&zOQ_TAn;~SYDkd!}yW{t=U8M?2vVJVe!}vNc2u1Y7 z(@7n{Xk8lFpqs>%5_hZ=Mx~U5T>aqZ=*%ZAB`z^cbfDisVdQvI)ksxHc+Lb=GSd~{ zM+$|_4diu2*NL&tK57PBLkzhyij1)DMy0K0^|b|NTC&C1Zsw@os*Q&H!5r_7MnM>4 zMz;#0XEPJZvPUrq`j)UWTu(1!;RIT5v*w%ca7=p|iCO08(eFKq2K)wi;!hu)Lr)N4^!J z3Nn#YK+zET*IM<9VH!P_?Sd!)=3t)dDM>F_HAG9}hp`+{$WzrSaPn2A5c@&{32mLp zq=UAA$y*s~A4C($ipi=OlH6>{-DKo3w5dtK8T@d{!YoBp_vPx$v{0t0R_2P)V3~p{ zb4UW9FT&StPA%!nqtFR+8!9M!l&O*Rl>R_(q?#SEUW{Vic;wlmtLR0esR)diu!hkq z**oGGcUW9cNG$b*P0tWNLG>yuR6>+~8EYRg9P3D-m_kO!@Wz3%vb5S9BcZ^TTj;|z z$n$}tp@c$U4)b+fqGyl|gCg1vHPw^UE5Tyezf#R)+$XmE)!mQF$sj~90nz(P8={P* zk{pu1ikRWrdNyFe9|^SU^u;+q-qd_Q+_?(Z$xow zpv#dmM*3BXtO{&Xjvv^MI8XS!rHzXN&`}}h0=*j7oD$#iBH>+e5xvo?ONQ;lEKwGdbczy|=_JFE z-4^9DDOwrenqOoVqUo|OX8eVPA{t+A0%a(S5EEHM zKNzT1$%NF4=@^xpQ5GRxDjilPds#eNUIQ?)R+a^df3*`XO|o5_O1C0S-voTIoiq{E z;UU|ncvBT%PAE_hc625i^9TyNHzEVZ(X1Rq=V#q>1g*}5_dMuK0fjfM!(C^izw zzr<7Yvv!2uO{K3Qa9po6ds4>_23i%A;qmG-K^0zx)o_) zR<4H7d>lYqDK!<8eN>!F*V=bQ54hyu+8*WI;toNGO@Ul>R70-vzR&{r%9PA&tSMvW z8iQ3zno>Qb~F_6>YbwU0`|m23+k8_q+4mh zlpIA1W~CwDaRD*~l$w)KgslZ0L)!m(7y|1-pw1YTi(wuP6Mg4gW;?w)G6IpoW~&5$ z+%keF2$v0^!om>YGUN_o>ZKmdUVf6uW!EC>g;iGlfqfhG92)}Kg9VscBrRXVM~Dw( zGwUMQ8GSc*H2Yv50@0hQ$PJ$hY#C0+0u1V-Y%eAU#tp)NQ5fVv3dRq~uF*s4`|QUy zP3>=fkTT{{$4GN$6JhSNY#;2&R7xVl*US{z)xKMTEwXVpGi+ytCzoRSh0UpagW?fo z73tVUXSFEdKmyswZrg-Wfk2|HzC0A*IG08pZX!pow%#Vv1S5N>{cZecP5?`x6FJrt zFnyG|5YRUw$Z%Z+HbB&hzS`0{q^9O1QuR|xigKZ?t`3$G%V4y+WL_XtLApMjQ1-sp zc2*SmA+riG1!k*ExU|?So9Vo<(J0eXto}9*Awd?Wx!p+o0NRVYOb#VeC}wCM?YNF7w<-|%vwO++_= zStDVnG%F(dL9QW{WP&Vz#6$~@WLl7Br3KS}RkUE$qUMz%kyMop4J z5hgJ4Xxol}w&ATni8*npn}WoAAcM?*ANT%gl38x5Td9ZlLcA44zP z#JyDrT5|4~x&?5!k!y%*0BOSjcZ$kr9$tjVCcN5Flb9JDXvyb+a}hds`5WWProwt7 zNI*pK&rCa$29Jtki$`8Rvxv_(3O>x?-fK{jQ(BE5Rdg`p5EgQi?OR*&lX^mj+RKwPqah54HP z5<9E^oWcT%@IlL2*i?W>O7AkJo$NeSAyeqqQ%nZx11NFC1rbFYLnrd~QXP`GC1qD~ z5DeY^pWc=vPcx3_20TF4SmY(br-D3?I503ay?k7LzAp)sLaNk|VnqDLK_^;NjM!gn zXw=YTS|h5p!s1yd5oG?0qUrg?!BVWUDq6)xyHTE7ggAsES}a%!UT5_vR!6Yzq#~|} zsY{X*p$j?Kb`dj33nYnWF=`EYv2I~HB4bnrD6*DXE0()$D;PKHlWq5A+-qE?`GIX> zZ3Pq|BCoh<`Qjo8y`eCSi57&I7NlBf!K@n;_ZR;>J1=hQ-0dgpcP& zcEzl0tY(ld(l6k2hck)@Bh71*YEnX1Y(1I|hg$YE)G5mkic%%J!P*{f1W#HCG5ExD zNOAzC8V1T%nyi;ex=g?MI5Iz`7-3EuNUTecSw0#jIZ*mw+N7#o?{*1U>!7Y}c|PJd znQD?vs;Y?iQxb2Y36n!)v}8QRa#0qGaFe;zaIyYNeDVq%>KJazrCg!ADhVR87m^Nf z1=$s%$7Y;DV~}49!!97UP!I_#L=+(&PN?`AnjnCoO<^h!nvoKO`maN9a1}EFHD=%x zt*!Sf`$TbD0hxwlzt8aTbFjw6$tUm-KZ7%kn+_v-oAGe3hVzX)!lbRHIvHs> z)a#?pFbG@-$mS|x~NqvE8!somT=_Hyd z-~km&<0B&(s?F`{Rvh0t)G%&9snJz4wbOAQspXXk2A;)erXar{&q`X9jFN44Ox|Ju zgfci<4SOSm@Ce5BGQwItI|AU`rDldlTO;ps>iYaTf0c@{R$dyCD+d>h_<{O?t+(6c zhf8fPnx5lB#$N*VW$?kOm|dJtuZ(VGB&Anzvm%(Sm}o&g(}EN$EjZu^MGIc2cDX!A zXLAMUKUtc_>EQ<_}zET>4F}ptfrJ?e9 z%GEcTS1gPO1r|1S7UK;k+6L?|Hf%JJqM}mfg6s|Eg@3pppMn9x6YAJnF((^ep^!4U zQhr^DQZ8D!~bPWCq#lbC2h1JeSpl@=T}P|<=v<4HzD2$tV*K;C4rf?)Hnx4b-? z(;U*wgX(cIq#Sd69KL|S=)ifAb>l2(Wfx0GUSgMH=_5{l0hWCn6#=qj^!*XpN}B zhqNLuqDY7@#P_hxCko}3K@;UeOo&I8pv8I;196j*M~h#k70BFSQCsV zLYD;)J6Ggz755hkt4GM-jN56QgJn~}2V})XBJ_fMph%q{F0p5^aeH0Yh*%Cm zoKY?hBXJKr88EEIMT+oIPFYxl%b~19@glHN%1uv!oWKZ$DyrqxDp{&*oLMEWia^r% zus_sx!o7xGf#fDag(`w}2>S+~BtkSa2x(*QE-RGDPujjALn*H*s)})PMgvOGob<+6i+BY6^p-9hG@6(SU?4l2|dVu6%0SN7M>%t2UnatkA> zXzy0;)h#dVI0O5DYfcJ%ukKmN{uv_kDfw##>L{Ut{hkxJ1MVDpy(9$8Kt5Et0mU4= zV?PJV1(oJN&ZzTSkcPDk!s%KBMXbajz)tBEzG;30U85j?bh1>HhRU$da&Wvr#}PpG zAc4I~f^|WNjGM4n5sp1?G1jqU^6QIcA}VAZ);`_OW5|+Oh=N4OI#mjbatOC&wrITt z3Tv{DzG2xJ6D??DTHvwLg0iO-Ex0Yo{uq76# z20bG-DXYyqIhmkLeE$@F@O5>(TXEgB?9 zf1=sMh1$gUNF=jWxdbXKkuXK55<~heeyh+Wt@Y0QyM!1~>*W{Q_2SWErAi!3pg*Uv zEZW)-5LhmHd7C7ow4udioCcO)rmY72twQ!zEFX@}U08~Cd&R9B+=R8mY%r}jnXnK` zWt<;TUfhx-8&dR$)z9pyxD$IB7W9D%Hlx>Zm}rjK5Lg}6Sh0b{?2u+`O*;cN>$+#z zi`27X0-%swJR7{9QoW+6%A6mLee-4q^o{B|Pv>2fy#Z_P3M-MB3i@W6XnR_xr!(P~ zqN?sBCRlX5nLVnl&9%{jEBA3_eWTXw!}jx*rpBu#CR(tNX@T2H3+5fIXhGJ+@HOP?}=oMAH7XhZ5O zur(yCVULp{TOLo`PJ6*rLlsN8yWJ&;mTYb^6_Ic_kE|WxT&!rG%RZhWB1=m0rc=Ej>5Uf#5lVG0{Jynf=MJ44ZY9@P`z?G*v6L1|Q1V}(dN*Yh36e26v9V|K$@hY|w2W=SnHWLZn z2@ZGg8LLd(xb|Tylev9g!G|PVNvqR592{>r>tCx#1dY7r)1=)`WDRrHnyg``p&l z)-1}G3!ttsBm}Y|5ra-%>|IqdICFwJlEH8*fwf|@jdK|ZqDqRhb4mnAHC2^p9_GX% zKnljz9Ii|~NpHy;wqxKm{P&2=3r$FA^%R8ugq+f7hTW!!sIG&i$S0|zP(p1wv0#o) z8M}p7mU4Nw>=~mHWGDzY7+#6awo=<}WhntEVKC_WZG3!0-{f`7x*nSVJcapCXUZB^ zWBVG99yN@!$jdVYLvKHD#1m5vbQwh)vD(1WV?&}$_FImiNhpSEmd%UbksFr^$v}=M zHNH#oLkdL1kr8FaOXWLIj~xZrFG<#+!$=0f6(zdvjO7TX(0RC99SZnLk^l(z2y5{( z#m!R1FIf!2%2SFVqmaTUSO9QXTTwbKCR(tVX+g4;7S#Vw(Sp5^Ev>Ok8mH+SVTJ8f zdfkRKI@!w`ETsKhO3FZ0C2}!xzEPp@;1!1W)ODjw(hY&w&aiC^pAWi`x(+&xmRL^( zfl+}wFz)=FMf?1X*c8PK5JHt~3twaRpL#16g>8HMMK*1cMAR4~CM#xJZ=-Q`X9W=) zI$9ZdHW*o~>_{Rs83-tnTUk%~da+`R4oaeGZHXhLg=oA&#vhQcW(!QgL>dnT zDo`<^_<9&lfFcHQ2=i<0u0`Z!wVX?;zqPrD&QM#SlljQQO4SrfcWH4%lPo7C2m15c z#<~)yevlP2zZRlv7;6cip7}OQ6S{b>u`bC@2?vkN*`T5;qEk*1d)~+-kTIz=^|Qjk z>0Qt1S2sOBPgmc`W7mEousqbPD8!stRjU?7^43u!(yF8ZG1@3S=7d<7F0lmqp zfuaSs{15q#Ey>=-Y4x_NDNQY=22kf2fwB+`v7*drVF4fVeB_oF7C?Y#@?u7T5XsHR zpUh?+;?zIe=Ed@aH3Xb|rYUOa+yJ?qY);7Ljv{$B=@~3tx7sudyGxIJhgVUoEmoY` zH%ReIdNsMS81`9(it=G54Y4j#Q15CF<~FBLy<&sONv$ex9f;sl3<_uh=$Bj}lr=##JqxLAyN&gjS_C zXwD3gY6A62D8oT^z1Y8mlTpU%POeV{0T^#^qy+Ns;DrSF6v{)Ad9f4AG*@kTB^)_>6#RP%h_45u$|{$3zQ` zVp=fXN(+vku4uuYd%IlhR}&EGT{}Iw$fixE!}VkaExBz`I>T%&3qQq0`L$AqNfHDs z57h&FrIgd>BAO~}TuvMe{1pfMLA1m5AXvGu zQ8rl*)B3bG%}~n|H*#J$@n+Ks(FGmG0vV^J+pIQ_B)62#(;05_2(eNxx4qYsrdk3< z-w%JTnm{Oo$muyn;z1Y%2Z=$%4#EVM0nW>$S_FqBSeF;rV`HX&k#LEib3Sd#0;=1Gvb+Ok!&(nHMk(1N084o zuCsfiEG1xr(JJ84D)jL&C@+;j@@#4|o%+?)5J6(+5Sg-87H5+p-*G)`CP_jeHBS=Z z@MD!&%b0XCw<*vj11F0h$$^DzF+kF}I})iNNU7i+t(=+VQY53;0_KJyPQ7e19Dol- z?kcIPpEUyl9ZJ!PJsf2$TBP`&jC_G~065qIm_|}O&J26>yG)^+^utA;SgHC8 z%gY<Pw2oGm_T4d9 zA2JqY(@5G=#4?E|>0nslc)FBdUyp2gCeZ_RgKsj!T}#SEkO_*CZN8pg3xn9eLc}uH z?fm!|;_1RJ$L<|6pBpuy*-ENUl9!09vK>Qx2&In1R|k7ZO66ofXtW04j9)8{Qa}ne zeK-JNwL=WZX~Gvb6!>c!F)kc>T1i_engI#S6HR(z=bSG2_lg!2% z_Bi2Y6~NaH7RlAXWY(V0V3*krG(sWCZ6;*PB9c`&s4^2rxj+p;w5ZI7biVC7beF42 zKpPfOl71bCf!PAv86BtDg*O^GNc zrbet+dOEj=gTF>!#VP$Pjx=JeLc?Ev3e3g$jYFT~kgmf}F6EfE|iMwZ^n77hYNR zoz7DBc;T5{MB}On8RL|W;3TY~1FUxKN}Gd;9d1tx z)O5+9DgyDV^GSvVVSFvF$ddupJwW0b!l86=Wv z$U0>8gQr3n(}XOYz)N^4}430)uo5Fsr1;m|^nolHige6xt%K&Lm_z$HkE;)js4Vm4L{wUi5I zq7b|!U156|RW6E@?#Jemzrt*GU_Qty%+VWKo<0o}5OEDK=8D(jrcgveasH77pRkJ; z7kouA(Sl={7L2pfg0rd=EqD}`suEP_j`E5&L+dX`Ex(=yk+fw5__7;{gB9iK8qK0y zqH@k;d*KjNN4aryd3T9V6)E~bVFhHZqUuJdDpgm7*E~2d^0AlplqFF314B`uj<5?D zvy!?R6Ke)L3h=3Xa;Rn+9@5f@A-{%oqe({O$7!W3v_()Ad5H>iA2vKluJzp6EJ(EV zACIQ*3D?UIBm6m?e`bqo#X3TVGt=L|_RjW{#L6>{g*?+7@hrM;J58(5M#)#uBw`r{ zA=VUgV7W?@Z@$Wg+B1y?($E;cpwWahS(L%agm4J;`%xL<)XkKsSwHZ^;|V{5HKfIi zpb3gT;ED1=er*}f-U{;66=>PGge=98*VIXiY7u57a6#jaqoW)KaM4?3en0U$=BLx1aEMQx zp$y6RAZO17I!B_siz|ZX4%Fzi@j9cl^_gDv^RNhM4+1y~g#!g_d}x%FAjoAO@ziVh zv$CDc?Aisja4-lr!4Zs(QEEXvin}pr!IC%(8U7CK-_7;&p~v)?i{JEd^&U57*eCdR zzkTlO?#gq;6$g(aS`fU$N()vEXIe09*G-o{;&Q>HCwdA26E~G(yP4CKibQxz8Pj7J z^Kd6XL1>+q=*vl|=PG>C3f;7>#A3IM1f2vlexUGV%3)ATdaAuiwnrDJGknhXWlt|C z5>QYy(;ij3X;JozkL%^9F9|*4TpIpIzxeI9<(M~u9f1s?yC)}Bq{ z?{Z=Mn`jO;yc@SXf64xnM_=;Ln?=L4_~GBUT=cHE1LNc3%IQm?=EB?X|9JZU;uQ57r92a0jov#gv@cv3g?qRn!)TZ2%p5bsIBg9iXo&$^(^qK$Et4_n);3%VOc2+>S}@!@#^>hj zn_G}W|6z8K-3hZ3L<&bG-?8V^yF!siJ)JBr2Ryn3Fw&Zysw|9(?0qZJ^%Z zWc?9bJKu4Y@tu2W-KP3{h<~T`#D9~JmN#!|q1HX`z>>V;nb|Y6p1Ju`^L!;q1-WVT zxVVc=^GqvTtz~*x+_BmY4P z75icRTw4HwO+rR~5hN>s*Nwv6UK>Dd5$)518?cbZ`b!umt?eo*T_Rq<3I)PGB96FGZYI^{AQc|)UE~MI@Oo-r=q7C&T z6OV9vA;*`D6gPOM)Z{E}nEeHh!?V)df(8&7*qP3K{3%-Sr{;3eC!7{&-vrMiT2M{& zJ4iG%b~lOX&oVS_2dh{hv&m!Jtr(*<8PS`U(uFG6d)P#}vqPec3 zuR|;#YiUBaxl0q`yLH>ETU^(!@vE11`^CMq+YhVV?&NMg_B?6Y(q9L}#mDp4lf>7a zsHw#*&4`a5(areY^U9^&9@3U}yKnB&Zg-ig$GK{kcDo9XynJ<+__(fD;GZ3?Oz6_p zm57dAwN!h)bg8!1y;OTbT<$fzhmJF^^tkt?()cUJx_2M05zrfMhcLx0j92l%qw%ms zblU)WSFbCVY5{Gj=D&B^ldmla{PxRH-u^$mn(;yM?o0Ri@Vbo`{$8^pciHZhu74*U zaltER-*bIlvH#PggU)y|`MLMwzJ2b8r@mP^^ow&BZaN`p@#FRTUAL;=jK-w{KYjP~ zy1Pz(b=qNR`oWHy(+(K%4z>uJouRR z*PQa$w`=-ee&2y-=I{CDRny-1a^_*{)`mvpC-iya#tZVxZcBV><(2=M{Aclo_pd!< zMBugG&Kr=MS2}FT`TKu4EGx&i=B+tHt!RS9PdHSKJ?tMBt^X$)m-D%KUfic%Tx$?9p6Zg1npNw^1PWf@?Q;z?k z{JP&?{OzR8f4urm*Kbbmd-1zdHhtds(4fmRr>+|`dsNyZ&)$5{;f;r^O?~0(>I=Wp zg8L2rV@&_l<$X&J9P(*kpQ}A@y?#QM?92Lmxjgx^vmZLFdePKFe(Zht<#`DUK7P5# zdupHcrQeJRET2Am_L14wT(jnho1Uz?;^ehW6aO#g)W<&Ay!n#}uiy5+Gp-pmY@fA( zfxkTTz`v(71&;N+c++XVUB-<3c>ay&taeYxed6$4dwhP)hV&<&J#_BAX@xs}G4i#a zf7o}g;g|RC(|gpHU6;@3GGg_J*N;4V{f6H+1b6(vGpy|BckZn?^tSBJ|M+3=)AKGK zz2b+H7vJ{uiM7AnT`}>?yep14Vbyb^x?Z=Y_w9Z5y85zyJ8wRA$~jf9?tAL98$TTR z{tGAXKK1967mqxsYvL70KAG3=nlI{Sb*cLO*kd+*e9Zj&56r*E{pn>lxDQ!z>_;D- ze!+Xe=g05A^Ti{Er51eu;cL5p`2MXa&uzGJ)LEkzoqXWi>(97r+(SbO2VXRH-FG|n z8hZ8dr*_@jySZS$sYPckslK9M!Fl)nIrD`(uln$v=?|Pdazfz7b?ayBdT#N#-Flx3 ztC)(Q$cb|J{++BS9T)8yvMr~=_b=UvAk4?owhu4V*bHZ z?+wZ+xV87(Yv%O%?5@f?7hPE7%ghMeSeKE#*ZdFm`g!6G`P1Gx`GY|t9`8BiyL)Gj zTtDEn9gZ)}yz_^9zk2fLeoH^=`c=+d)7<+kn_1KArvKg&{OQ3}eFh!6_W5hF;_mqB z(Aj-WzO&${#yCOwWU9N`rU+? z??1V*_rTDqh2LD&s#{T}$nwh^fJe-pD>sMzLp8xosZ~Ob+wELWA_j_;dhTm6Y z-gS51x1SlU9s2Ye|N3D5@{zLz{Utg)p5%%6BRYKD6U%z{z;F75^C+&3!Bxbg1i!cP zC{NGIUsC*X(XhlWSAHkxu*?HdJPN-&6#`W%Ea$?yR#|ybNMe>s}9(Z|6}lwy+3_w>W9a^aN#}`mnGi$N%m`( z+?|k7hJMf((O9j=hyG}+Zg_H8@B8tcJ`tGZ#aFz@VqP*Hz;mfj)VH7Tp+D-|rl*$meg)s@6R{2+4_-ihs~c-w z2Wv;?FY)=X4&w8h=r-2{UA3-8->$6rW@fJ^&Kmhp-OS399v{wqI|6;HpuWv%S>O1k zJ^A0!=3X#P9ia6qJaby{e>dJcV|85ds}DcDVIkK90M#r26z`+HQlCG-hyJL~M?bx+ zHn&RwX7e_&QmX~huC+>Ye@Z}e*H;p!5^)^x@VX5roG5#OqhPn^$cPxP-CdDpu`M!ov(^L?|?J-!K(+RZYl)Mx6ung6@!wW$2x#ngAxoUV^s zp8oO1wD-ra=^M`f_2}gPI{Cj&{;!k&>*W7BhW{(P>+Anq{rGjg$5y@8<4WJTAI>}N zsg3uPzH{6yqfT5trS{ey1>b&m>dX7Q^~t*I30L;rT>jGIV^*Bnqt6r9>{1l`GXIF% z4ml*Hc*XK}?w+&a$sxc0HtpXpzxLwymu|Rc1@5>a<_h zoqEl*$F5knGvl0J80>hS6sW#85>4kU-!ws&b{Jk_vt4*e&Wi0m%65n z%w2P7{t0~!JMHj)uRr^~!{6|J^Yr{b_CD_8->28#bHuQJAF^oU<{5*1y?&i@{2s?8 z^!X^5vFX~CPfXeG!hQaD;;m)R{FrxmuVY`XPCV+7P|57{+3P1Pnl!kiHhbOUPmaF+ zwdI@UPQIZqbx_gde#hULymCW9-?SYEzjDiCDR)%vcjmmClfSPz`ux<<`}Ff5k<=5B#;y zS8rc`@L!v5K5F3VvZWiY&wg#eeLb(;|D?TcyL$MUn(Q3{-@$>8&tCTaC~dd< z&es}V{ou|;r+o8&-YK~cFWeaFHekk=dp$qp`Nm%}d+oGt#WycqIeN@q<1^#V{AuO< zwRcz43?6t|H~+DHH$Ut?{*IR}^#mW>@zp24TvD-N<(%%9U3RK#=Xs}3IRC6g{s;Sg zcF@PW_1L`R;1ddfRTTes6TZ_Q;k5~GF6(_7zSAcHhaR_<$0`i7V4N^s9}&N>)2DQs zt2hjYZanAEYi5in%spcHBXM6desagh^<*5nhheXy^LD~uiao!$au+RbPiiCKE3+NS z?Qcc3L%EdZbwQ7?dHo3U`XKC3x-2=Dn%e6|3%0zvU;1B1rY`^MxXFtqm5v`zukTfl zwi34NHDB1N^eW?4jnD=Pd#x#rwbIuD)`g59(O_W{f;zCWf)j3(I%Bn6#B-oaB74bd ze<(`r*mPrCWF-Pa0N7}AY8^y1AS?D_SY(KvcGI+y;@NpTAY0cy#MMIkgHAgVWi_&G z+L3hHhaeR}YVzOTKE&Pz!L!xvI0Ox7B`vs&X+d`@EqH2`q6Ix?xm;mUep8b@S)KMF zmUy{v*4!rSL$+57(Y7*1=orh>t!gE+-J87ZtnCn}C#%$XA;jB42rveMW_YxlHgH~` zY97EKIot#qkR%5wVYpg%tsCqa(_msuYJ+XZdZu;u!7*4m?XLBb0l~;Fm&anD)*ohe zsctXK7cg|Khpy6 zdxZ;JF5SYPo77UfF$jfwT7<%Q{c3!OR+;sY#cwa`-5a_$`b6+po7OU|ir}#xe1H7& zXOmobcqQ&~xn2$9vHm=;;gt3F9ai_^=u>ulkq7KHSk5qyb)D7(9b3A$)LmKW^(SRz zlw~EQrg>75vQkqjliU?vucxdc#f{}hIye!NBGDX0BGGE*hDzi&01w;djnpF)2;t0K zPp$g`nSoL9qmyV{@JDlb?mNqRC*n7K!sjw>KyWq9W$@*&xjZ}llP(ym#Q1CvKj_mi z9xr3g{bTNXvvAxOm;CIX%VYI~@>O}TXI!GDOwn4@Lyh+=;&!{?Bak~Gk(?>=LZJzX zxd&gD4e{1UQWrl@rf1SsuJDf6U%Tmz_A); z=83_|2|au4fq^E6ffhAmkDe|XH(G1dAo`>68}aV4-lh0XpNO^QTg!VPe64jk`~C4R z9L@avgLIo~kFd4&*GHd!I_suGa!x<2Y?lo@eqH0^dc&_nygR%NA4PA&6*PyYHn5LR z$zjlKtwS4JJK4A4<%fS3#QSMo;25p-D2J4VGa+(C9NE1s zM>dTQjZ=eZoPL^|-N%RD^a)=(ad~U6vs*jkkLb6@g+nn;1Bc&?yIgTQhOM2Zb3Ukk zX5*^3xUp|~?&P-o8Xwn(*Usf_J5D|0;<0?lKTfQjt7vYHZTD#m% z*J`>UpT7^cwJ&F11u^-f9E|uqadDfqu5K8?bmg(8F*nQhE-%dP6UE2u8XEHjan`kY z;n0zLCmlmRW?%nILq6f>u(i44gtx|KAJY4;gwMd=MBnhbQiHkqYZvPExx>#D+60nbNN}vYyA;ciDG3m1`xZb zf@ly|s%*b*xrS=J0~Fa0X-~<^nBNacsIch=(p!W;HtYy4!LdMkUUwFpOyRuYO;<=y z)#bpL0!Ta7-4QNqMxe}yf!R^(+31^Tertl()svnEYE6q+UN*hRa(T2iLsySQ*(91 za|XH2LkB>)=&x%p{NwaYs?U=(K+|f~x;8Ie8xuo<7WUdb-D*&Q}I%-6_R0<)Pt=Shp#B;c#sSVc!DLH;0Sn%hR+eM8pv# z-E>GMsZ)~SV=J5qcGmjixRw5(fCLm8O|`0M4)xoq^uRmA8y*rRYz(4P_+;qrq!i&VfB_=+jH}Kn?=2YPqK%d-?aYfeQ5|wm_hzf=t*{K zux&JI=hfo0p*(X@?%<(yYlABgDkH@C&q}L!CdkW`=K<%TC*AGg{}JoqR%a&`gNW>3 zoQ(+nGOM_CF^tp(M+E<;*cx05%PLi@IZ$p!AU3hPt)kqMmsx5CJkO z1B)hMZDnPpW~HWz6^Wx&+y%eaKuu{iKb!6tSDh2B zj;xIr1VczFWZm7OcBMAdXuH0DlM3^5`KeR2JhfCH4(27~^&}(Tfya}Xk(vUBO0Op? z4dVS&H-2Vd|DDo5KBz7;CkW<=5Mmng8!r_TJX--E*HWow@UhAK|+@CXbBRs+|cF&*fB^5lGkt~ z)KA+%?|CAvo#-G)Y-L9fBrdlc1nnM0GSibKGa5-|J|j7V{1cLy*CCaOO~MkZWM*3f z9r~>4lV%G#HXeQ6m`8V-HtEDOmz??h%V!GfNE^_RCiuBQVWJjroF0K}I~sL}R@kGC zzl*G;MY0c*L`Jc_Zc6eePvka|OC&~ZyIq!mrvo>B`xN_eo*Z=j@Gkftavw<&COKk&R#3|b;)IbuyEjJ*U;tVqo z&OZWXY?~4cfpoX7mf{~w)Y)1o;WI_l-`C1P>GG!d#^=Pu7u>|O;14S;Skpz(g27j~ zTo7cmsby%x79fPaIzs5Gb-^g`qmFZe1%6|&+PG64g9S!J(rnndK}ibhEHyZe)LNLq zIZ|tJx#iTlQ$W%70*d}7DsNiQaW1H$d^Ux8_h|4V(n{>jN=HQG0J9adQ zKWsLRE$C>9d+UlD<6p|T=FO&a&h?H_)|ufhvhFNL&>=2t%b=s9#2_QC{>=YJ>s(~h zoI%G<+AyWzP=1I)3?f_$|Cw&8NFzvgLtDj7H6~hc8`FYcth8X=Yl;^9_@T=sd}{yU zf)GAf68=ztjxj<1;A=#W7W9Y@F@E_XtPC?Pk5(?|^AG{PW*X|3{<*+PaZ*5>Ek`q8GmGfIEH z%G;&Bl50lFDG*7Huh_^bwhhfmG~3IVXu<7F3x2lJg7qsDEjZ?6m+Nn9(U3g)X%xE`Qv4Rh|*kFa#(L`@FKe0JS6TSA|6jaztBT7Pz z2#+}f%CnY13*j#22rb0rW}rn(wBQb=1wUD7!ABDnEpT56Uo$;xLR_bmqvcYLa4!^n zBk;DdMJ(ss@!RAV4my424gFS+9yjEahq>n846$rS$RY+?4`Jof2`@U~g%&5)LRIvr zT?oz>E-i~KY8Raq-3KWHj+kh{olFaUw9fh)31b5%fr z|K?mfGTfk~44GsH_~~am z;g7`~+4YWrA(J9uNRqZ!-r{nOdY)*EqQE1GW92|5hWtl1A|r{&s30Lo$d54CA{4ZU zlrBRzIU*Esmj0~~3g<0orQh-0ObfoZ(t;lkP_*EebfCTt3$#AkgnXj!Gg|=k`h&Za zY`Xub84s<$=jx(U^KNhgK&e6mXQL$Q1VD8GcnBaudzk0!HUohE89=4Eh-9tu=iR;e zIO#B&)z8aqAUb+Gp%Z2_x@ReL;${+EP+C3@aKxZa?IaetV~fy9OnkvTObfoV(t_W6 zDO&KrSeHxXe8FjKKQJvpJ@$9DIpFIU)C0j*xbS5cZMdfGBuTKY%+9{b$J3oTO3 zw9Vrh!SLGSn$_D+5R=xWdhtevEED4})i%|ON88(+Lax}Co#@Mf__o$x?GS=Qp7L!J zseS93qI4pLX41zoNa|jy1SAJ)bwCWc!5XA7Mv~|TG8}1-ge)J(MHLHl*ja}TFo6hf zIzRVRCkzqlnC`Y2n23oM+|RV&Yb!12xrd?!S$m7j>yBx1ky1BY9D=%HA`*>7#53WD zRs>jgL@PR$Z(+ESN1|kAxl#jP5O)b>W?2#k4nh8j%q-P$-SL~yLqA-j%Pq~B`vWS+ zf;wW&=%Q@_%IWGF>zorTUfM5(nDiT`YLJis)ujcclpVS zKjxKZ17Fe{osY$G>u9k|CwvhpbpKB9MTR74VVu?$!WU0gY6=1h3YC!(c*H~t9$;GV zm6aCseOJ+fK_9wYNgbM1x1IDxBK+$EN|189762?dz+dL`hY;ta?L{e*wg3+e*6|R8 zVS1bSfhRfvp#|;S!8SucLeAdb>-KuxSsr}c8Qyf2zP)o&LM!&vN-EQO;8|WQQKmGuH()b?SElz-ko=S`{re*-0OG303IO+vr*0b zoiIR5wBSLe1z%ce!Qe9$E$BYd)OTC&%a@-}x`b7GKfOm5O?Pa@Pj6hu9##9vca z4Qs+A75{8&`Ry>rkZ`cV1+%m=;DVg&HU|XVHt-IL&821s9S|TNW==Lg=~yQuP|;pp z>KF*%iG%Y1>HY`gemO30`9A(L zN;aQ8pVvx+q#-RMRS-ZMlp!v3w4@=L0mw;0Q8Gds08(F2x;VeSz7er^a{YA;^Eeha z#wbZp)|6;)V2BA07+-~*ZZpVWQVb!_rrA4r-Lx0fHb#EE)WwXS0^(SnDW7JP1{1&O~ZS}-!(<(lqqVwO5k?yo0oMC`Tt z4vj!%psG>WppVbZ**CW!hyGI?1Pj5v>yR*|nUTO?jJ6wwJQ%77)B;P!h7Y30EfwpM zY?NB4*XR@)v|MN~&_u^AyT_K4$BjMn>&rhIn}5gXpAs&bG(oJy2vVNzO%pTPNy;T> z-$}|DC#aKW3^obv##^$&?y8%NyYw! zfymnJB=YBYkloXjB}9_82!t!Y$d{LsUkfAt8h=FqRG_f7eLPuj*#gk8n+_Uw)P_3r zfFFO36O3r;(9U;^WMHRA0063i;q#aCU^$8aqQ@Eav^LJ@swk!lM`>ib&_JdO2MRSk zkwZkFK-e!=Zd?NX8w<-Fs|iA^hL&4my3kx2`Zi5fKgI+pn%P^nAmfk+FFE3d|Nb!J zwwunof5lCE{LTw25@bX%tQ4!Mt>pzV(Sk>r7HqK6g7HTvS`hkG*b(il^@kuK*I!xM zSls|d!B^)mw~~i#%3w1VN0gRpB{C5bLDk+4Ki9)Edj z!)XXvtD~+$T#k@M#6%0$FfI7hN(;OL6)hOwC7oN9=rOe zK;5XnxMnM9e@wLCai#_Tv(kc`y%jAuAyw!Lwq?meV#frLh(#w6bFA|1Lov|_0NMip zFw{(VMgf2|S~VD274CU<{T50WTEZMB%;57WHb;nIx()(~M9t0SXRdJ4JJhy+H#>&< zkBX%JeYHMnpb}|#q3v@(1rOIHUit-;V$D@d^h_;ZAq-i`e$H3LQlICuOZj{%}+4 z@|3jP9w7r71|iB>XzM>QR~v8klAK&x54&jM{eo4Y(z znn>|@l4Hqk=4GGi?z_dqL@fqd@FdfM53RId<^_rtRKDVJ^{Ie9u=`G0V;KCZ-S&AAXh-AX(Ib9q$-qVs8bZhK`fAvQ#jUEDEAyl<09W z#oF!k$cPq_J7(p?ZYC@db>-WFin4?|m%M!b%E@=mtAFs!RcoB0Qo5aUe+X~fjut2g zv}$kUxTIqQ3he^5L`ANy;o&G^1}$Mhxy^gW7N*31ckFj}Jojt< zb>DS+EjjHhu_7Y$DH-W9T;E`=d&une)>Z4`ad$?AAbZb$VpIqrfoP7J3ooGULrx*! zZcAN0g*iw2xO{rWHrr2mqr$u-yRNR9+)!Z3kW>`J*MMIHGlR{2c;a`D8^SV?CcAqt z2?@H#Yx7Bsk*!$MwiiU4wFRhPh%Sgg97Lnh{KVx>(ueA;+r^k@!CIyT?^$WV5qBzD zu>T^Lt9gskj=>y>k(i^8)+;AFQ7suBeMc3G5R5w_3~{*=VYCGj7-kY*MD7<`FtG2e z(-WVZvpna4zeatVf1Lk$p4$j8fI!sZ+_MD(+lJIa5GH%6MF*)u)(n61_&+u`uL_y8 z>W%cxvYtoAphTp~3V#LMPiNPcRtaOmA=;quBOcOkK_mXb+K~2i$%u&-Jj1l$|E#pY zU!`cln^i8C@-g$eQw4O2gd@K4dH$Nxq&a>|yozlYyoh6AvNqZfd<3KmZ3K!DPIgfi zc=zr~rm>k*Vqjww`^$rfiQLpq$x&Bq0gSO^010n8Kew3-AmR74Icn<|=&?s6^cbWK zK<5+HWQ)|LQ4vUrAXQEXL|*PhAZ>v_!ct;{FI%2BTO4xpA2;+_b=NVu7oM@~qk}gL z@5(hJaY$OaI38_rNIMH9Vxk4lGA&qdr3DLyD_W4>=yJsndZL5yO)O@ft;RQkjBF>- zGMh~fCVbdiDj0D$pHCF5S(4Y|Ny+kNc|BsRaI^`MyVVk5Y{Mu+@RM7PGI;2E&XOpj z=QQm&h)Keeby3V^e=Wt5Zx>&Z9*^-c7@IBWp1SBHQ5zAxBm9<&oWvT3+i4{w4m%3m&>x=c$%E#E-6vWMpDzf znPLmK81=*-=N#oLzD$GkJN{6L@-+!bzSN(H@-;rbHwv~SL77Ty_Sk8MtbS-{{Iu)( zZTRoO_f=l$q&eBX5}Re}iOpKtKM{>=EN6Rz#ad*-H!75wN?MvY&0H^{9rAe{o?vaf zNuJfRL(CRiPM!Gju%16POj+nmBH2GiezoaJ5nMJ9^1%N?r?iI9r9+a_vRjus`z z`tF)c>J$?#c%Es&J62k-aG9b7p;?d-8N>+#lg@6)t#?Fj7NIJvCoyDED6o*Co`ID! zf}SDAw&eLQ3Kp)TQL1QpJ1O!+ms7MI1u*wD)6Zk#4g9o6UaBo;1I*fOC#@t=B;rb9J@;ZP_PG1Pop{Za?9R+ea z*V?ie^YL?{K+_2fO;ZV)4vT=MT6{0UNn4ORx3$nTCR*?U(}K6HwBVQwMGL0h>~j56 zAg>!xG#cb3h`L=s**#29w%OCj7RA>5>(dAK91+U7`Q0-w?|*xy2s05WAx%#agv}Pj zwzGsZ21(}j31Yp@AQo-}5%3iGUW6QQ`*2-v4l=ey%3#Q0va(XMQUyoW(O7Y-7=6V= z3tnVe@RpSpobaWh1^JJIFYtIhS!wWyOLb?Yreq+QrEQ8KuUK+1W6+#dV9;obzWbia z6m6uo0O0a~U}!;oL;DC+6SgF4!B8DeLgsF2HDjNXoB(7^yLYl>-a;d_?NN}nRlrdTL5wus z`By8j$Uqw@G94M+4^lX!NDBgo6leRgYb)}zeUuBZJpu*2%?DR(qOIXN7U{3`4Qn|+ z_7o>Pa%6{ewqr1fy*U|%E3ve;A`w%~IUt*f8I&qcBPT2(FK+=BiHR1x%(P&gl@^@t zQ?%d*=wL$uL_G4h z`=7cW*YEcG1^s!8{u6M{wu(oxodq_~<0*j+r7@s@Lv~t6p2B}3MA^G}n>6^Ic)ae6 zthB5&sUZAY2yj}8Q3OX)+zO1Mueq3L!7EG)-mubwa}yLTIGp?ou#%&%(kq<0~rm*VhGW>-`k<2aH9VYx}w%x&@GER~-@!)&|=WTP>59q`JN7X(^t}wo)bu)7wawJ^Q55 z?J6%3yJHLGCA=!)hPEUO!4Dc87hj24&aQ8&sqr_20_92B)m6bzpkZFk+@gbv4)B!} z&n@<4&lT0CmDbO*soP8k;?F;uL%)PR<^u zfA<~4-=`L%+?V7@N=wRgC#7V%Q&Uni)4Ul;DH)#3EO<_MGT}p!>PgGWO81~bdS-g6 z*PH6eNb+WQ(^E3CQaxGYOif{z+_||26c*>s_0FaB+T%rKG4-Uj5a?;TKUC&N*roP% z7?{eNCpMYVC>=lz(}vi0fS-Q06NXyckzMZ?7-b*!Q4L;eR9@2W*8xbyL@d}mn%)aw#5K#dosT2G?Kzm3^2Lf7)gyb0ov$ikS(UY^~NJlyyKC*_J1@x zY0kRKU(xuqiompKQ7xndao*0fi4Ib>ZOP1kzO%rsuw?=_Co_MouOY7ULRcp_&cCr_ zE+$&=I@5wzt+e3k-4reG!gnj&$iI~!+mn)+3T{#AJO5DvKY{;`ZiT?FE!KRGxe9|G zz#%g7d^sM9*IURC(w!E6*=#jemiVj z{A&NRUU#i2Y+66tNeo7czF3rqaWUQ}l$M4UrjyqsiS96Tu0d#^Q`@NxRA-A7nK99V zH<%W@VxpbeGnAfOcORCSSDlA4w_`a1ZuV=7qKAeuG z&d$%}4FT7v2Y&nYk)>zk=3UzV**$jq`N5aDW`rMSiU-WQykrx(^zQ`lyxQQp>G?U3 ziXb9Eb>3pc468?ANa0Hck*yaxA8%H2hSo!VgH<){>t@_ImwfT~ODX3xAGU1CwLLe# zC&iar?8ccIiSIamrI6We-S8jBM3ZkG5q9!s;N-OwrKixrt-L*vaX2F_D<#EToHe(;&t=pl-s5?N-X7N)AVH*KF(+74 z*Vxcf1Q!!6SjV*BWh*VX^;AU*=KKzu(lUgZO{5@PWEmGI_tz7&GJnqr)>a0p8biW} zKR0LJ+=86(_)m2Z#}b`5J+?$HnW)Pp5g*QOSolmk(@841Fvj8B3fPhDlh(}_tNYyTcDU1-+f@%Ru^rmLWXz=zZF+DBQ+e(xeA4Rzv-;+>c zyhbSTvj~*+;iV_vtYwdkqBuZ@UeS~siL8Y;xS!MR$60{ku4)vE1 z>HDrOj;K{2zO8^-@h&H1tfRzHCRt##eQzrXY})mixg)Q*bn1NzzFq0ADLI<=#Xkut z#zYI=WLof&l@{FnFGUMn!yzM@$6#C+4K;&64cuvfQJ#zTMxYTPLIk#qlsu+J775tW z5eU?DvMU5iMefYBR2^UgA9p6avjv^23z&l^=@ekU+tXT`2QZL#-rw)&LK0fjB(r0ZF&gq)p%NrcT4aGHg4?IxIPUjd?J~<@k$y)~kTAI$!Z5{$z?%AdxAi*!M zSHZ6+0z&AIJqQ4t(!2^ewKY&JOYp_EP%R}DO>1RXH`jb;9kOetHiIOCZW2<-KZ-US z@7kHAffTMI)wRQx>LD$Y?+hdUJurRn#G8N0z2M~k9Wv;nC+9oC2zSP|t%r2=MsO2~ zZ$kg2zeD?Xb6sAT-RBFWsHBgp_qZ{`KEc2H?Q>suSDvfu`rtcE3!b;qf~O8qv|vyo z?t*kkbll!4=YJ>lB<@7bvty18Ls4QvM^0JjD80ic-Ci zMea1N)n*z1 zOxKQq$}K0`E3-cZE5ofO+MHB%e|ifj^H^PlH$vMvS~vI|7dWZ%j_degh*hQM@whXg zU3RlfmU|hMVyB^QriY}wTsJ*ZrMH_l5(Aki7er#PGLbcWgx0LuJ$qS8nwz9Zx~wH8 zzTjP^1?v&>^8iaMKwLj7{H9MhUl7+ATu-zh=&{m*R~~0tFf1`XFxcgiX6Q-L5?QubUL$Bod&p}% o>7I8eCp5?W~$}^#c<06SYq02|gJAbJ5)VKLf`q=l}o! literal 0 HcmV?d00001 diff --git a/testing/btest/scripts/base/protocols/ldap/add.zeek b/testing/btest/scripts/base/protocols/ldap/add.zeek new file mode 100644 index 0000000000..fbe2c9a4ad --- /dev/null +++ b/testing/btest/scripts/base/protocols/ldap/add.zeek @@ -0,0 +1,11 @@ +# Copyright (c) 2024 by the Zeek Project. See LICENSE for details. + +# @TEST-REQUIRES: have-spicy +# @TEST-EXEC: zeek -C -r ${TRACES}/ldap/ldap-add.pcap %INPUT +# @TEST-EXEC: cat conn.log | zeek-cut -Cn local_orig local_resp > conn.log2 && mv conn.log2 conn.log +# @TEST-EXEC: btest-diff conn.log +# @TEST-EXEC: btest-diff ldap.log +# @TEST-EXEC: ! test -f dpd.log +# @TEST-EXEC: ! test -f analyzer.log +# +# @TEST-DOC: The addRequest/addResponse operation is not implemented, yet we process it. diff --git a/testing/btest/scripts/base/protocols/ldap/sasl-signed-clear-2.zeek b/testing/btest/scripts/base/protocols/ldap/sasl-signed-clear-2.zeek new file mode 100644 index 0000000000..12f397a62b --- /dev/null +++ b/testing/btest/scripts/base/protocols/ldap/sasl-signed-clear-2.zeek @@ -0,0 +1,11 @@ +# Copyright (c) 2024 by the Zeek Project. See LICENSE for details. + +# @TEST-REQUIRES: have-spicy +# @TEST-EXEC: zeek -C -r ${TRACES}/ldap/missing_krbtgt_ldap_request.pcapng %INPUT +# @TEST-EXEC: cat conn.log | zeek-cut -Cn local_orig local_resp > conn.log2 && mv conn.log2 conn.log +# @TEST-EXEC: btest-diff conn.log +# @TEST-EXEC: btest-diff ldap.log +# @TEST-EXEC: btest-diff ldap_search.log +# @TEST-EXEC: ! test -f dpd.log +# +# @TEST-DOC: Test LDAP analyzer with GSS-API integrity traffic where we can still peak into LDAP wrapped into WRAP tokens. diff --git a/testing/btest/scripts/base/protocols/ldap/sasl-signed-clear.zeek b/testing/btest/scripts/base/protocols/ldap/sasl-signed-clear.zeek new file mode 100644 index 0000000000..4ae8d4b639 --- /dev/null +++ b/testing/btest/scripts/base/protocols/ldap/sasl-signed-clear.zeek @@ -0,0 +1,11 @@ +# Copyright (c) 2024 by the Zeek Project. See LICENSE for details. + +# @TEST-REQUIRES: have-spicy +# @TEST-EXEC: zeek -C -r ${TRACES}/ldap/missing_ldap_logs.pcapng %INPUT +# @TEST-EXEC: cat conn.log | zeek-cut -Cn local_orig local_resp > conn.log2 && mv conn.log2 conn.log +# @TEST-EXEC: btest-diff conn.log +# @TEST-EXEC: btest-diff ldap.log +# @TEST-EXEC: btest-diff ldap_search.log +# @TEST-EXEC: ! test -f dpd.log +# +# @TEST-DOC: Test LDAP analyzer with GSS-API integrity traffic where we can still peak into LDAP wrapped into WRAP tokens. From 6f65b88f1b3a94c2bb6c3e3c97f64cdb253bde7b Mon Sep 17 00:00:00 2001 From: Arne Welzel Date: Tue, 23 Jul 2024 12:38:54 +0200 Subject: [PATCH 34/91] Merge remote-tracking branch 'origin/topic/awelzel/ldap-extended-request-response-starttls' * origin/topic/awelzel/ldap-extended-request-response-starttls: ldap: Add heuristic for wrap tokens ldap: Ignore ec/rrc for sealed wrap tokens ldap: Add LDAP sample with SASL-SRP mechanism ldap: Reintroduce encryption after SASL heuristic ldap: Fix assuming GSS-SPNEGO for all bindResponses ldap: Implement extended request/response and StartTLS support (cherry picked from commit 6a6a5c3d0d60a1d4d32ba2173c035023c29fbf1d) --- scripts/base/protocols/ldap/consts.zeek | 7 + scripts/base/protocols/ldap/main.zeek | 3 + scripts/base/protocols/ldap/spicy-events.zeek | 41 +++ src/analyzer/protocol/ldap/CMakeLists.txt | 4 +- src/analyzer/protocol/ldap/ldap.evt | 15 ++ src/analyzer/protocol/ldap/ldap.spicy | 243 ++++++++++++++---- src/analyzer/protocol/ldap/ldap_zeek.spicy | 12 + .../conn.log | 11 + .../ldap.log | 13 + .../ldap_search.log | 11 + .../conn.log | 11 + .../ldap.log | 13 + .../ldap_search.log | 11 + .../conn.log | 11 + .../ldap.log | 12 + .../conn.log | 11 + .../ldap.log | 11 + .../scripts.base.protocols.ldap.starttls/out | 4 + .../ssl.log | 11 + .../conn.log | 11 + .../ldap.log | 13 + .../scripts.base.protocols.ldap.who-am-i/out | 3 + testing/btest/Traces/ldap/ldap-starttls.pcap | Bin 0 -> 6009 bytes testing/btest/Traces/ldap/ldap-who-am-i.pcap | Bin 0 -> 1248 bytes testing/btest/Traces/ldap/sasl-ntlm.pcap | Bin 0 -> 4052 bytes .../btest/Traces/ldap/sasl-scram-sha-512.pcap | Bin 0 -> 4297 bytes .../btest/Traces/ldap/sasl-srp-who-am-i.pcap | Bin 0 -> 2838 bytes .../base/protocols/ldap/sasl-ntlm.zeek | 12 + .../protocols/ldap/sasl-scram-sha-512.zeek | 12 + .../protocols/ldap/sasl-srp-who-am-i.zeek | 11 + .../scripts/base/protocols/ldap/starttls.zeek | 25 ++ .../scripts/base/protocols/ldap/who-am-i.zeek | 20 ++ 32 files changed, 506 insertions(+), 56 deletions(-) create mode 100644 src/analyzer/protocol/ldap/ldap_zeek.spicy create mode 100644 testing/btest/Baseline/scripts.base.protocols.ldap.sasl-ntlm/conn.log create mode 100644 testing/btest/Baseline/scripts.base.protocols.ldap.sasl-ntlm/ldap.log create mode 100644 testing/btest/Baseline/scripts.base.protocols.ldap.sasl-ntlm/ldap_search.log create mode 100644 testing/btest/Baseline/scripts.base.protocols.ldap.sasl-scram-sha-512/conn.log create mode 100644 testing/btest/Baseline/scripts.base.protocols.ldap.sasl-scram-sha-512/ldap.log create mode 100644 testing/btest/Baseline/scripts.base.protocols.ldap.sasl-scram-sha-512/ldap_search.log create mode 100644 testing/btest/Baseline/scripts.base.protocols.ldap.sasl-srp-who-am-i/conn.log create mode 100644 testing/btest/Baseline/scripts.base.protocols.ldap.sasl-srp-who-am-i/ldap.log create mode 100644 testing/btest/Baseline/scripts.base.protocols.ldap.starttls/conn.log create mode 100644 testing/btest/Baseline/scripts.base.protocols.ldap.starttls/ldap.log create mode 100644 testing/btest/Baseline/scripts.base.protocols.ldap.starttls/out create mode 100644 testing/btest/Baseline/scripts.base.protocols.ldap.starttls/ssl.log create mode 100644 testing/btest/Baseline/scripts.base.protocols.ldap.who-am-i/conn.log create mode 100644 testing/btest/Baseline/scripts.base.protocols.ldap.who-am-i/ldap.log create mode 100644 testing/btest/Baseline/scripts.base.protocols.ldap.who-am-i/out create mode 100644 testing/btest/Traces/ldap/ldap-starttls.pcap create mode 100644 testing/btest/Traces/ldap/ldap-who-am-i.pcap create mode 100644 testing/btest/Traces/ldap/sasl-ntlm.pcap create mode 100644 testing/btest/Traces/ldap/sasl-scram-sha-512.pcap create mode 100644 testing/btest/Traces/ldap/sasl-srp-who-am-i.pcap create mode 100644 testing/btest/scripts/base/protocols/ldap/sasl-ntlm.zeek create mode 100644 testing/btest/scripts/base/protocols/ldap/sasl-scram-sha-512.zeek create mode 100644 testing/btest/scripts/base/protocols/ldap/sasl-srp-who-am-i.zeek create mode 100644 testing/btest/scripts/base/protocols/ldap/starttls.zeek create mode 100644 testing/btest/scripts/base/protocols/ldap/who-am-i.zeek diff --git a/scripts/base/protocols/ldap/consts.zeek b/scripts/base/protocols/ldap/consts.zeek index bbd378c7e8..5b29fd22e4 100644 --- a/scripts/base/protocols/ldap/consts.zeek +++ b/scripts/base/protocols/ldap/consts.zeek @@ -120,4 +120,11 @@ export { "searching", [ LDAP::SearchDerefAlias_DEREF_FINDING_BASE ] = "finding", [ LDAP::SearchDerefAlias_DEREF_ALWAYS ] = "always", } &default="unknown"; + + const EXTENDED_REQUESTS = { + # StartTLS, https://datatracker.ietf.org/doc/html/rfc4511#section-4.14.1 + [ "1.3.6.1.4.1.1466.20037" ] = "StartTLS", + # whoami, https://datatracker.ietf.org/doc/html/rfc4532#section-2 + [ "1.3.6.1.4.1.4203.1.11.3" ] = "whoami", + } &default="unknown" &redef; } diff --git a/scripts/base/protocols/ldap/main.zeek b/scripts/base/protocols/ldap/main.zeek index 93c301a65a..da4a21871c 100644 --- a/scripts/base/protocols/ldap/main.zeek +++ b/scripts/base/protocols/ldap/main.zeek @@ -258,6 +258,9 @@ event LDAP::message(c: connection, } m$object = object; + + if ( opcode == LDAP::ProtocolOpcode_EXTENDED_REQUEST ) + m$object += fmt(" (%s)", EXTENDED_REQUESTS[object]); } if ( argument != "" ) { diff --git a/scripts/base/protocols/ldap/spicy-events.zeek b/scripts/base/protocols/ldap/spicy-events.zeek index fa670f3456..baa00ba548 100644 --- a/scripts/base/protocols/ldap/spicy-events.zeek +++ b/scripts/base/protocols/ldap/spicy-events.zeek @@ -98,3 +98,44 @@ global LDAP::search_result_entry: event ( message_id: int, object_name: string ); + +## Event generated for each ExtendedRequest in LDAP messages. +## +## c: The connection. +## +## message_id: The messageID element. +## +## request_name: The name of the extended request. +## +## request_value: The value of the extended request (empty if missing). +global LDAP::extended_request: event ( + c: connection, + message_id: int, + request_name: string, + request_value: string +); + +## Event generated for each ExtendedResponse in LDAP messages. +## +## c: The connection. +## +## message_id: The messageID element. +## +## result: The result code of the response. +## +## response_name: The name of the extended response (empty if missing). +## +## response_value: The value of the extended response (empty if missing). +global LDAP::extended_response: event ( + c: connection, + message_id: int, + result: LDAP::ResultCode, + response_name: string, + response_value: string +); + +## Event generated when a plaintext LDAP connection switched to TLS. +## +## c: The connection. +## +global LDAP::starttls: event(c: connection); diff --git a/src/analyzer/protocol/ldap/CMakeLists.txt b/src/analyzer/protocol/ldap/CMakeLists.txt index a687e880ff..3f69e6543d 100644 --- a/src/analyzer/protocol/ldap/CMakeLists.txt +++ b/src/analyzer/protocol/ldap/CMakeLists.txt @@ -1,5 +1,5 @@ spicy_add_analyzer( NAME LDAP PACKAGE_NAME spicy-ldap - SOURCES ldap.spicy ldap.evt asn1.spicy - MODULES LDAP ASN1) + SOURCES ldap.spicy ldap.evt asn1.spicy ldap_zeek.spicy + MODULES LDAP ASN1 LDAP_Zeek) diff --git a/src/analyzer/protocol/ldap/ldap.evt b/src/analyzer/protocol/ldap/ldap.evt index 96baef6f98..77f34fb62e 100644 --- a/src/analyzer/protocol/ldap/ldap.evt +++ b/src/analyzer/protocol/ldap/ldap.evt @@ -41,3 +41,18 @@ on LDAP::SearchRequest -> event LDAP::search_request($conn, on LDAP::SearchResultEntry -> event LDAP::search_result_entry($conn, message.messageID, self.objectName); + +on LDAP::ExtendedRequest -> event LDAP::extended_request($conn, + message.messageID, + self.requestName, + self.requestValue); + +on LDAP::ExtendedResponse -> event LDAP::extended_response($conn, + message.messageID, + message.result_.code, + self.responseName, + self.responseValue); + +# Once switched into MessageMode::TLS, we won't parse messages anymore, +# so this is raised just once. +on LDAP::Message if (ctx.messageMode == LDAP::MessageMode::TLS) -> event LDAP::starttls($conn); diff --git a/src/analyzer/protocol/ldap/ldap.spicy b/src/analyzer/protocol/ldap/ldap.spicy index 2d4f821d78..96f942d7a3 100644 --- a/src/analyzer/protocol/ldap/ldap.spicy +++ b/src/analyzer/protocol/ldap/ldap.spicy @@ -130,29 +130,104 @@ public type Result = unit { const GSSAPI_MECH_MS_KRB5 = "1.2.840.48018.1.2.2"; # Supported SASL stripping modes. -type SaslStripping = enum { - MS_KRB5 = 1, # Payload starts with a 4 byte length followed by a wrap token that may or may not be sealed. +type MessageMode = enum { + MS_KRB5 = 1, # Payload starts with a 4 byte length followed by a wrap token that may or may not be sealed. + TLS = 2, # Client/server used StartTLS, forward to SSL analyzer. + MAYBE_ENCRYPTED = 3, # Use a heuristic to determine encrypted traffic. + CLEARTEXT = 4, # Assume cleartext. + ENCRYPTED = 5, # Assume encrypted. }; type Ctx = struct { - saslStripping: SaslStripping; # Which mode of SASL stripping to use. + messageMode: MessageMode; # Message dispatching mode + saslMechanism: string; # The SASL mechanism selected by the client. + startTlsRequested: bool; # Did the client use the StartTLS extended request? }; #----------------------------------------------------------------------------- public type Messages = unit { %context = Ctx; - : SASLStrip(self.context())[]; + : MessageDispatch(self.context())[]; }; #----------------------------------------------------------------------------- -public type SASLStrip = unit(ctx: Ctx&) { - switch( ctx.saslStripping ) { - SaslStripping::Undef -> : Message(ctx); - SaslStripping::MS_KRB5 -> : SaslMsKrb5Stripper(ctx); +public type MessageDispatch = unit(ctx: Ctx&) { + switch( ctx.messageMode ) { + MessageMode::Undef -> : Message(ctx); + MessageMode::MS_KRB5 -> : SaslMsKrb5Stripper(ctx); + MessageMode::TLS -> : TlsForward; # never returns + MessageMode::MAYBE_ENCRYPTED -> : MaybeEncrypted(ctx); + MessageMode::CLEARTEXT -> : Message(ctx); + MessageMode::ENCRYPTED -> : EncryptedMessage; }; }; +#----------------------------------------------------------------------------- +type MaybeEncrypted = unit(ctx: Ctx&) { + # A plaintext LDAP message always starts with at least 3 bytes and the first + # byte is 0x30 for the sequence. A SASL encrypted message starts with a 4 byte + # length field. The heuristic here is that if the first byte is a 0x30, + # assume it's unencrypted LDAP. This should be pretty good, if it was an + # encrypted/SASL wrapped message, it would have a size between 0x30000000 and + # 0x30FFFFFF, meaning at least a size of ~768MB, which seems unlikely. + var start: iterator; + var saslLen: uint64; + var mech: bytes; + + on %init { + self.start = self.input(); + # Don't have starts_with() on string, work around that. + # https://github.com/zeek/spicy/issues/1807 + self.mech = ctx.saslMechanism.encode(spicy::Charset::UTF8); + } + + first: uint8 { + if ( $$ == 0x30 ) { + ctx.messageMode = MessageMode::CLEARTEXT; + } else { + ctx.messageMode = MessageMode::ENCRYPTED; + } + } + + # As a further heuristic, if encrypted mode was decided and the client + # requested GSSAPI or GSS-SPNEGO (or we just didn't see it) peak a bit + # into the SASL payload and check if it starts with a 0504 (WRAP_TOKEN). + # If so, switch into KRB mode assuming that's what is being used and + # have a chance seeing some more plaintext LDAP in non-sealed tokens. + rem: uint8[3] if ( ctx.messageMode == MessageMode::ENCRYPTED && (|self.mech| == 0 || self.mech.starts_with(b"GSS")) ) { + self.saslLen = (self.first << 24) + ($$[0] << 16) + ($$[1] << 8) + $$[2]; + } + + : uint16 if ( self.saslLen >= 2 ) { + if ( $$ == 0x0504 ) { + ctx.messageMode = MessageMode::MS_KRB5; + } + } + + # Rewind the input. + : void { + # Prevent MessageDispatch from recursing endlessly. + assert ctx.messageMode != MessageMode::MAYBE_ENCRYPTED; + self.set_input(self.start); + } + + # One recursion to parse with the new ctx.messageMode setting. + : MessageDispatch(ctx); +}; + +#----------------------------------------------------------------------------- +type EncryptedMessage = unit { + len: uint32; + : skip bytes &size=self.len; +}; + +#----------------------------------------------------------------------------- +type TlsForward = unit { + # Just consume everything. This is hooked in ldap_zeek.spicy + chunk: bytes &chunked &eod; +}; + type KrbWrapToken = unit { # https://datatracker.ietf.org/doc/html/rfc4121#section-4.2.6.2 @@ -174,7 +249,10 @@ type KrbWrapToken = unit { } else if ( self.rrc == 0 ) { self.trailer_ec = self.ec; } else { - throw "Unhandled rc %s and ec %s" % (self.ec, self.rrc); + if ( ! self.ctx_flags.sealed ) + # If it's sealed, we'll consume until &eod anyhow + # and ec/rrc shouldn't apply, otherwise, bail. + throw "Unhandled rc %s and ec %s" % (self.ec, self.rrc); } } @@ -223,6 +301,7 @@ public type Message = unit(ctx: Ctx&) { var arg: string = ""; var seqHeaderLen: uint64; var msgLen: uint64; + var opLen: uint64; seqHeader: ASN1::ASN1Header &requires=($$.tag.class == ASN1::ASN1Class::Universal && $$.tag.type_ == ASN1::ASN1Type::Sequence) { self.msgLen = $$.len.len; @@ -241,10 +320,11 @@ public type Message = unit(ctx: Ctx&) { protocolOp: ASN1::ASN1Header &requires=($$.tag.class == ASN1::ASN1Class::Application) { self.opcode = cast(cast($$.tag.type_)); + self.opLen = $$.len.len; } switch ( self.opcode ) { - ProtocolOpcode::BIND_REQUEST -> BIND_REQUEST: BindRequest(self); + ProtocolOpcode::BIND_REQUEST -> BIND_REQUEST: BindRequest(self, ctx); ProtocolOpcode::BIND_RESPONSE -> BIND_RESPONSE: BindResponse(self, ctx); ProtocolOpcode::UNBIND_REQUEST -> UNBIND_REQUEST: UnbindRequest(self); ProtocolOpcode::SEARCH_REQUEST -> SEARCH_REQUEST: SearchRequest(self); @@ -263,12 +343,12 @@ public type Message = unit(ctx: Ctx&) { # just commenting this out, it will stop processing LDAP Messages in this connection ProtocolOpcode::ADD_REQUEST -> ADD_REQUEST: NotImplemented(self); ProtocolOpcode::COMPARE_REQUEST -> COMPARE_REQUEST: NotImplemented(self); - ProtocolOpcode::EXTENDED_REQUEST -> EXTENDED_REQUEST: NotImplemented(self); - ProtocolOpcode::EXTENDED_RESPONSE -> EXTENDED_RESPONSE: NotImplemented(self); + ProtocolOpcode::EXTENDED_REQUEST -> EXTENDED_REQUEST: ExtendedRequest(self, ctx); + ProtocolOpcode::EXTENDED_RESPONSE -> EXTENDED_RESPONSE: ExtendedResponse(self, ctx); ProtocolOpcode::INTERMEDIATE_RESPONSE -> INTERMEDIATE_RESPONSE: NotImplemented(self); ProtocolOpcode::MOD_DN_REQUEST -> MOD_DN_REQUEST: NotImplemented(self); ProtocolOpcode::SEARCH_RESULT_REFERENCE -> SEARCH_RESULT_REFERENCE: NotImplemented(self); - } &size=self.protocolOp.len.len; + } &size=self.opLen; # Ensure some invariants hold after parsing the command. : void &requires=(self.offset() >= self.seqHeaderLen); @@ -296,7 +376,7 @@ type GSS_SPNEGO_negTokenInit = unit { }; # Peak into GSS-SPNEGO payload and ensure it is indeed GSS-SPNEGO. -type GSS_SPNEGO = unit { +type GSS_SPNEGO_Init = unit { # This is the optional octet string in SaslCredentials. credentialsHeader: ASN1::ASN1Header &requires=($$.tag.type_ == ASN1::ASN1Type::OctetString); @@ -322,12 +402,19 @@ type SaslCredentials = unit() { # Peak into GSS-SPNEGO payload if we have any. switch ( self.mechanism ) { - "GSS-SPNEGO" -> gss_spnego: GSS_SPNEGO; + "GSS-SPNEGO" -> gss_spnego: GSS_SPNEGO_Init; * -> : skip bytes &eod; }; }; -type NegTokenResp = unit { +type GSS_SPNEGO_Subsequent = unit { + token: ASN1::ASN1Header &requires=($$.tag.class == ASN1::ASN1Class::ContextSpecific); + switch ( self.token.tag.type_ ) { + ASN1::ASN1Type(1) -> negTokenResp: GSS_SPNEGO_negTokenResp; + }; +}; + +type GSS_SPNEGO_negTokenResp = unit { var accepted: bool; var supportedMech: ASN1::ASN1Message; @@ -355,34 +442,13 @@ type NegTokenResp = unit { } &parse-from=self.supportedMech.application_data; }; -type ServerSaslCreds = unit { - serverSaslCreds: ASN1::ASN1Header &requires=($$.tag.class == ASN1::ASN1Class::ContextSpecific && $$.tag.type_ == ASN1::ASN1Type(7)); - - # The PCAP missing_ldap_logs.pcapng has a1 81 b6 here for the GSS-SPNEGO response. - # - # This is context-specific ID 1, constructed, and a length of 182 as - # specified by in 4.2 of RFC4178. - # - # https://www.rfc-editor.org/rfc/rfc4178#section-4.2 - # - # TODO: This is only valid for a GSS-SPNEGO negTokenResp. - # If you want to support something else, remove the requires - # and add more to the switch below. - choice: ASN1::ASN1Header &requires=($$.tag.class == ASN1::ASN1Class::ContextSpecific); - - switch ( self.choice.tag.type_ ) { - ASN1::ASN1Type(1) -> negTokenResp: NegTokenResp; - # ... - } &size=self.choice.len.len; -}; - # TODO(fox-ds): A helper unit for requests for which no handling has been implemented. # Eventually all uses of this unit should be replaced with actual parsers so this unit can be removed. type NotImplemented = unit(inout message: Message) { : skip bytes &eod; }; -type BindRequest = unit(inout message: Message) { +type BindRequest = unit(inout message: Message, ctx: Ctx&) { version: ASN1::ASN1Message(True) &convert=$$.body.num_value; name: ASN1::ASN1Message(True) &convert=$$.body.str_value { message.obj = self.name; @@ -406,12 +472,32 @@ type BindRequest = unit(inout message: Message) { saslCreds: SaslCredentials() &parse-from=self.authData if ((self.authType == BindAuthType::BIND_AUTH_SASL) && (|self.authData| > 0)) { message.arg = self.saslCreds.mechanism; + ctx.saslMechanism = self.saslCreds.mechanism; } } &requires=(self?.authType && (self.authType != BindAuthType::Undef)); +type ServerSaslCreds = unit { + serverSaslCreds: ASN1::ASN1Header &requires=($$.tag.class == ASN1::ASN1Class::ContextSpecific && $$.tag.type_ == ASN1::ASN1Type(7)); + payload: bytes &size=self.serverSaslCreds.len.len; +}; + type BindResponse = unit(inout message: Message, ctx: Ctx&) { : Result { message.result_ = $$; + + # The SASL authentication was successful. We do not actually + # know if the following messages are encrypted or not. This may be + # mechanism and parameter specific. For example SCRAM-SHA512 or NTLM + # will continue to be cleartext, while SRP or GSS-API would be encrypted. + # + # Switch messageMode into trial mode which is explored via MessageDispatch + # and the MaybeEncrypted unit. + # + # Note, messageMode may be changed to something more specific like + # MS_KRB5 below. + if ( |ctx.saslMechanism| > 0 && $$.code == ResultCode::SUCCESS ) { + ctx.messageMode = MessageMode::MAYBE_ENCRYPTED; + } } # Try to parse serverSaslCreds if there's any input remaining. This @@ -421,14 +507,18 @@ type BindResponse = unit(inout message: Message, ctx: Ctx&) { # if the serverSaslCreds field exists or not. But, not sure we can # check if there's any bytes left at this point outside of passing # in the length and playing with offset(). - serverSaslCreds: ServerSaslCreds[] &eod { - if ( |self.serverSaslCreds| > 0 ) { - if ( self.serverSaslCreds[0]?.negTokenResp ) { - local token = self.serverSaslCreds[0].negTokenResp; - if ( token.accepted && token?.supportedMechOid ) { - if ( token.supportedMechOid == GSSAPI_MECH_MS_KRB5 ) { - ctx.saslStripping = SaslStripping::MS_KRB5; - } + serverSaslCreds: ServerSaslCreds[] &eod; + + # If the client requested GSS-SPNEGO, try to parse the server's response + # to switch message mode. + gss_spnego: GSS_SPNEGO_Subsequent &parse-from=self.serverSaslCreds[0].payload + if (ctx.saslMechanism == "GSS-SPNEGO" && |self.serverSaslCreds| > 0) { + + if ( $$?.negTokenResp ) { + local token = $$.negTokenResp; + if ( token.accepted && token?.supportedMechOid ) { + if ( token.supportedMechOid == GSSAPI_MECH_MS_KRB5 ) { + ctx.messageMode = MessageMode::MS_KRB5; } } } @@ -980,16 +1070,61 @@ type AbandonRequest = unit(inout message: Message) { #----------------------------------------------------------------------------- # Extended Operation # https://tools.ietf.org/html/rfc4511#section-4.12 +type ExtendedRequest = unit(inout message: Message, ctx: Ctx&) { + var requestValue: bytes; + header: ASN1::ASN1Header &requires=($$.tag.class == ASN1::ASN1Class::ContextSpecific); + requestName: bytes &size=self.header.len.len &convert=$$.decode(spicy::Charset::ASCII) { + message.obj = $$; + } -# TODO: implement ExtendedRequest -# type ExtendedRequest = unit(inout message: Message) { -# -# }; + # If there's more byte to parse, it's the requestValue. + : ASN1::ASN1Message(False) + &requires=($$.head.tag.class == ASN1::ASN1Class::ContextSpecific) + if ( message.opLen > self.offset() ) { -# TODO: implement ExtendedResponse -# type ExtendedResponse = unit(inout message: Message) { -# -# }; + self.requestValue = $$.application_data; + } + + on %done { + # Did the client request StartTLS? + # + # https://datatracker.ietf.org/doc/html/rfc4511#section-4.14.1 + if ( self.requestName == "1.3.6.1.4.1.1466.20037" ) + ctx.startTlsRequested = True; + } +}; + +#----------------------------------------------------------------------------- +type ExtendedResponseEntry = unit(inout r: ExtendedResponse) { + : ASN1::ASN1Message(False) &requires=($$.head.tag.class == ASN1::ASN1Class::ContextSpecific) { + if ( $$.head.tag.type_ == ASN1::ASN1Type(10) ) + r.responseName = $$.application_data; + else if ( $$.head.tag.type_ == ASN1::ASN1Type(11) ) + r.responseValue = $$.application_data; + else + throw "Unhandled extended response tag %s" % $$.head.tag; + } +}; + +#----------------------------------------------------------------------------- +type ExtendedResponse = unit(inout message: Message, ctx: Ctx&) { + var responseName: bytes; + var responseValue: bytes; + : Result { + message.result_ = $$; + } + + # Try to parse two ASN1 entries if there are bytes left in the unit. + # Both are optional and identified by context specific tagging. + : ExtendedResponseEntry(self) if ( message.opLen > self.offset() ); + : ExtendedResponseEntry(self) if ( message.opLen > self.offset() ); + + on %done { + # Client had requested StartTLS and it was successful? Switch to SSL. + if ( ctx.startTlsRequested && message.result_.code == ResultCode::SUCCESS ) + ctx.messageMode = MessageMode::TLS; + } +}; #----------------------------------------------------------------------------- # IntermediateResponse Message diff --git a/src/analyzer/protocol/ldap/ldap_zeek.spicy b/src/analyzer/protocol/ldap/ldap_zeek.spicy new file mode 100644 index 0000000000..3a6784589f --- /dev/null +++ b/src/analyzer/protocol/ldap/ldap_zeek.spicy @@ -0,0 +1,12 @@ +module LDAP_Zeek; + +import LDAP; +import zeek; + +on LDAP::TlsForward::%init { + zeek::protocol_begin("SSL"); +} + +on LDAP::TlsForward::chunk { + zeek::protocol_data_in(zeek::is_orig(), self.chunk); +} diff --git a/testing/btest/Baseline/scripts.base.protocols.ldap.sasl-ntlm/conn.log b/testing/btest/Baseline/scripts.base.protocols.ldap.sasl-ntlm/conn.log new file mode 100644 index 0000000000..27c56bc33b --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.ldap.sasl-ntlm/conn.log @@ -0,0 +1,11 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path conn +#open XXXX-XX-XX-XX-XX-XX +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p proto service duration orig_bytes resp_bytes conn_state missed_bytes history orig_pkts orig_ip_bytes resp_pkts resp_ip_bytes tunnel_parents +#types time string addr port addr port enum string interval count count string count string count count count count set[string] +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 60126 127.0.1.1 389 tcp ldap_tcp 2.290081 289 1509 SF 0 ShADadFf 12 921 15 2297 - +#close XXXX-XX-XX-XX-XX-XX diff --git a/testing/btest/Baseline/scripts.base.protocols.ldap.sasl-ntlm/ldap.log b/testing/btest/Baseline/scripts.base.protocols.ldap.sasl-ntlm/ldap.log new file mode 100644 index 0000000000..cd94c49d5b --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.ldap.sasl-ntlm/ldap.log @@ -0,0 +1,13 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path ldap +#open XXXX-XX-XX-XX-XX-XX +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p message_id version opcode result diagnostic_message object argument +#types time string addr port addr port int int string string string string string +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 60126 127.0.1.1 389 1 3 bind SASL SASL bind in progress SASL(0): successful result: - NTLM +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 60126 127.0.1.1 389 2 3 bind SASL success - - NTLM +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 60126 127.0.1.1 389 4 - unbind - - - - +#close XXXX-XX-XX-XX-XX-XX diff --git a/testing/btest/Baseline/scripts.base.protocols.ldap.sasl-ntlm/ldap_search.log b/testing/btest/Baseline/scripts.base.protocols.ldap.sasl-ntlm/ldap_search.log new file mode 100644 index 0000000000..3ff2f3b1a6 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.ldap.sasl-ntlm/ldap_search.log @@ -0,0 +1,11 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path ldap_search +#open XXXX-XX-XX-XX-XX-XX +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p message_id scope deref_aliases base_object result_count result diagnostic_message filter attributes +#types time string addr port addr port int string string string count string string string vector[string] +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 60126 127.0.1.1 389 3 tree never dc=example,dc=com 9 success - (objectclass=*) - +#close XXXX-XX-XX-XX-XX-XX diff --git a/testing/btest/Baseline/scripts.base.protocols.ldap.sasl-scram-sha-512/conn.log b/testing/btest/Baseline/scripts.base.protocols.ldap.sasl-scram-sha-512/conn.log new file mode 100644 index 0000000000..5fcce64ab8 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.ldap.sasl-scram-sha-512/conn.log @@ -0,0 +1,11 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path conn +#open XXXX-XX-XX-XX-XX-XX +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p proto service duration orig_bytes resp_bytes conn_state missed_bytes history orig_pkts orig_ip_bytes resp_pkts resp_ip_bytes tunnel_parents +#types time string addr port addr port enum string interval count count string count string count count count count set[string] +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 59552 127.0.1.1 389 tcp ldap_tcp 2.231680 353 1772 SF 0 ShADadFf 11 933 15 2560 - +#close XXXX-XX-XX-XX-XX-XX diff --git a/testing/btest/Baseline/scripts.base.protocols.ldap.sasl-scram-sha-512/ldap.log b/testing/btest/Baseline/scripts.base.protocols.ldap.sasl-scram-sha-512/ldap.log new file mode 100644 index 0000000000..7c3478b262 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.ldap.sasl-scram-sha-512/ldap.log @@ -0,0 +1,13 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path ldap +#open XXXX-XX-XX-XX-XX-XX +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p message_id version opcode result diagnostic_message object argument +#types time string addr port addr port int int string string string string string +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 59552 127.0.1.1 389 1 3 bind SASL SASL bind in progress SASL(0): successful result: user: sasladmin@slapd.ldap property: slapAuthzDN not found in sasldb - SCRAM-SHA-512 +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 59552 127.0.1.1 389 2 3 bind SASL success - - SCRAM-SHA-512 +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 59552 127.0.1.1 389 4 - unbind - - - - +#close XXXX-XX-XX-XX-XX-XX diff --git a/testing/btest/Baseline/scripts.base.protocols.ldap.sasl-scram-sha-512/ldap_search.log b/testing/btest/Baseline/scripts.base.protocols.ldap.sasl-scram-sha-512/ldap_search.log new file mode 100644 index 0000000000..edcf38ced5 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.ldap.sasl-scram-sha-512/ldap_search.log @@ -0,0 +1,11 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path ldap_search +#open XXXX-XX-XX-XX-XX-XX +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p message_id scope deref_aliases base_object result_count result diagnostic_message filter attributes +#types time string addr port addr port int string string string count string string string vector[string] +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 59552 127.0.1.1 389 3 tree never dc=example,dc=com 9 success - (objectclass=*) - +#close XXXX-XX-XX-XX-XX-XX diff --git a/testing/btest/Baseline/scripts.base.protocols.ldap.sasl-srp-who-am-i/conn.log b/testing/btest/Baseline/scripts.base.protocols.ldap.sasl-srp-who-am-i/conn.log new file mode 100644 index 0000000000..2638ca3cba --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.ldap.sasl-srp-who-am-i/conn.log @@ -0,0 +1,11 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path conn +#open XXXX-XX-XX-XX-XX-XX +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p proto service duration orig_bytes resp_bytes conn_state missed_bytes history orig_pkts orig_ip_bytes resp_pkts resp_ip_bytes tunnel_parents +#types time string addr port addr port enum string interval count count string count string count count count count set[string] +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 60648 127.0.1.1 389 tcp ldap_tcp 2.114467 548 1020 SF 0 ShADadFf 9 1024 6 1340 - +#close XXXX-XX-XX-XX-XX-XX diff --git a/testing/btest/Baseline/scripts.base.protocols.ldap.sasl-srp-who-am-i/ldap.log b/testing/btest/Baseline/scripts.base.protocols.ldap.sasl-srp-who-am-i/ldap.log new file mode 100644 index 0000000000..facaf46bc7 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.ldap.sasl-srp-who-am-i/ldap.log @@ -0,0 +1,12 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path ldap +#open XXXX-XX-XX-XX-XX-XX +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p message_id version opcode result diagnostic_message object argument +#types time string addr port addr port int int string string string string string +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 60648 127.0.1.1 389 1 3 bind SASL SASL bind in progress SASL(0): successful result: user: zeek@ubuntu-01.example.com property: slapAuthzDN not found in sasldb - SRP +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 60648 127.0.1.1 389 2 3 bind SASL success - - SRP +#close XXXX-XX-XX-XX-XX-XX diff --git a/testing/btest/Baseline/scripts.base.protocols.ldap.starttls/conn.log b/testing/btest/Baseline/scripts.base.protocols.ldap.starttls/conn.log new file mode 100644 index 0000000000..db789c02c1 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.ldap.starttls/conn.log @@ -0,0 +1,11 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path conn +#open XXXX-XX-XX-XX-XX-XX +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p proto service duration orig_bytes resp_bytes conn_state missed_bytes history orig_pkts orig_ip_bytes resp_pkts resp_ip_bytes tunnel_parents +#types time string addr port addr port enum string interval count count string count string count count count count set[string] +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 45936 127.0.1.1 389 tcp ldap_tcp,ssl 0.016922 683 3002 RSTO 0 ShADadFR 14 1407 14 3738 - +#close XXXX-XX-XX-XX-XX-XX diff --git a/testing/btest/Baseline/scripts.base.protocols.ldap.starttls/ldap.log b/testing/btest/Baseline/scripts.base.protocols.ldap.starttls/ldap.log new file mode 100644 index 0000000000..95a084dab8 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.ldap.starttls/ldap.log @@ -0,0 +1,11 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path ldap +#open XXXX-XX-XX-XX-XX-XX +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p message_id version opcode result diagnostic_message object argument +#types time string addr port addr port int int string string string string string +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 45936 127.0.1.1 389 1 - extended success - 1.3.6.1.4.1.1466.20037 (StartTLS) - +#close XXXX-XX-XX-XX-XX-XX diff --git a/testing/btest/Baseline/scripts.base.protocols.ldap.starttls/out b/testing/btest/Baseline/scripts.base.protocols.ldap.starttls/out new file mode 100644 index 0000000000..08e6ccc9f2 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.ldap.starttls/out @@ -0,0 +1,4 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +CHhAvVGS1DHFjwGM9, extended_request, 1.3.6.1.4.1.1466.20037 (StartTLS), +CHhAvVGS1DHFjwGM9, extended_response, LDAP::ResultCode_SUCCESS, , +CHhAvVGS1DHFjwGM9, LDAP::starttls diff --git a/testing/btest/Baseline/scripts.base.protocols.ldap.starttls/ssl.log b/testing/btest/Baseline/scripts.base.protocols.ldap.starttls/ssl.log new file mode 100644 index 0000000000..19fdd43528 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.ldap.starttls/ssl.log @@ -0,0 +1,11 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path ssl +#open XXXX-XX-XX-XX-XX-XX +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p version cipher curve server_name resumed last_alert next_protocol established ssl_history cert_chain_fps client_cert_chain_fps sni_matches_cert +#types time string addr port addr port string string string string bool string string bool string vector[string] vector[string] bool +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 45936 127.0.1.1 389 TLSv13 TLS_AES_256_GCM_SHA384 secp256r1 ubuntu-01.example.com F - - T CsiI - - - +#close XXXX-XX-XX-XX-XX-XX diff --git a/testing/btest/Baseline/scripts.base.protocols.ldap.who-am-i/conn.log b/testing/btest/Baseline/scripts.base.protocols.ldap.who-am-i/conn.log new file mode 100644 index 0000000000..9914fbe2dc --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.ldap.who-am-i/conn.log @@ -0,0 +1,11 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path conn +#open XXXX-XX-XX-XX-XX-XX +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p proto service duration orig_bytes resp_bytes conn_state missed_bytes history orig_pkts orig_ip_bytes resp_pkts resp_ip_bytes tunnel_parents +#types time string addr port addr port enum string interval count count string count string count count count count set[string] +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 48122 127.0.1.1 389 tcp ldap_tcp 0.001192 83 59 SF 0 ShADadFf 8 507 5 327 - +#close XXXX-XX-XX-XX-XX-XX diff --git a/testing/btest/Baseline/scripts.base.protocols.ldap.who-am-i/ldap.log b/testing/btest/Baseline/scripts.base.protocols.ldap.who-am-i/ldap.log new file mode 100644 index 0000000000..80da834eba --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.ldap.who-am-i/ldap.log @@ -0,0 +1,13 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path ldap +#open XXXX-XX-XX-XX-XX-XX +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p message_id version opcode result diagnostic_message object argument +#types time string addr port addr port int int string string string string string +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 48122 127.0.1.1 389 1 3 bind simple success - cn=admin,dc=example,dc=com REDACTED +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 48122 127.0.1.1 389 2 - extended success - 1.3.6.1.4.1.4203.1.11.3 (whoami) - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 48122 127.0.1.1 389 3 - unbind - - - - +#close XXXX-XX-XX-XX-XX-XX diff --git a/testing/btest/Baseline/scripts.base.protocols.ldap.who-am-i/out b/testing/btest/Baseline/scripts.base.protocols.ldap.who-am-i/out new file mode 100644 index 0000000000..c4dbc10489 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.ldap.who-am-i/out @@ -0,0 +1,3 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +CHhAvVGS1DHFjwGM9, extended_request, 1.3.6.1.4.1.4203.1.11.3 (whoami), +CHhAvVGS1DHFjwGM9, extended_response, LDAP::ResultCode_SUCCESS, , dn:cn=admin,dc=example,dc=com diff --git a/testing/btest/Traces/ldap/ldap-starttls.pcap b/testing/btest/Traces/ldap/ldap-starttls.pcap new file mode 100644 index 0000000000000000000000000000000000000000..0cb6035125efd4ca7094ea308e0aec2ef1f37e9f GIT binary patch literal 6009 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 DyIjjT literal 0 HcmV?d00001 diff --git a/testing/btest/Traces/ldap/ldap-who-am-i.pcap b/testing/btest/Traces/ldap/ldap-who-am-i.pcap new file mode 100644 index 0000000000000000000000000000000000000000..75dae01d4e5c84bb150be922d14eef212fba067d GIT binary patch literal 1248 zcmaKr&ui0g7{=dknyq8(U?<`nY)nBBf0V>^Q`;3r!Gn64;8kqaBsjF~ytpzZi?FKL zZHF-sFEWcDDhL)~wmS&w#i0j_?hhEd<=jKpLw(|TbR@e z&Qq^F-cxU-M8uD;0VZ$|YG?60iQ*&^ueBxiLH&JwpSVo9D?K=m7VH*yhGaf9KalUU zf%BZ#6Hi_%xPcwsz`gyvHqrGmIgY*om_)18&SJ;c?F&qtYD>foENr`p%Ah2qnIqO= zH9Q<14Xfb@^*Lo2FDgDG#WE^pQHt7Gtf&=JoRR9uXa`d-S(wqSxGSSg(TrMZ~YZL_5YFA9_4i&|@#3 IpCPx$KS)1C6#xJL literal 0 HcmV?d00001 diff --git a/testing/btest/Traces/ldap/sasl-ntlm.pcap b/testing/btest/Traces/ldap/sasl-ntlm.pcap new file mode 100644 index 0000000000000000000000000000000000000000..ef2fb91ab4e18be7df4fbe120116ef99178c1ce9 GIT binary patch literal 4052 zcmb7{e`phD7{}kczD;YJ^p{oZkJ_kotJB#_twXJ4ZJk&({ef+DbDMg(T+^$`UCbro zWKL6bGOC+Y9Tf$Cfj`Ek(+Q3t_=o;6VGIP(unifLfH>G6f-rTPd!F}_cz2Bf-}KFU zx#Yg@=lMR*``-2T^-CvsLP@$ke@+MoA1+lK?w_XeWF;J9H@8BvjF2UX!4}fukh*rj z1v?1GJ-o;5K0M5wz+WEcw{I;!PY6%*FH^p-=+1-p*W-CEFRuWV>vJj-g33)lpem|! zyC2?rTsyKD)K4C-_&EH}w=a~Pn}=qidRn;!l-pn??B>Rp8xxxt^BNoTNl|LL^*onH$*DR@JA1ty z)Q#^wJ>AUt0^XR#otg|sc<)*ql|diaa@Y%c>{@Au=&g#FbD&r}eb->KZ$LH|9@FidY=(nXe%R^lb?aMVM3nIp@9|K*M( zLM$`Aw#+0T*XLNSy_U?(x(trg{^%fo!MxbbjXCmrLPbU2nXHPC>uW30ivCsTvk*VW zbNt5mDI?qQBdK)9N7C`2`7_p5Q0~_Vev4$5=kP|`w091n5u?2qHfo?^{6C`(Z(DC)YvVyn63AYTCjc5`DSN0U{| zyH=ZbSHQcg=$-3W#=COx&MWi-iC@e@B6x+lG&TKFoZeGS^P*aq7W$N-6J`JmY9VDm?VC6UbpHvp$CWdU7%&2M^7A@qwB&`5z57 z^7vjvkAF(1YO&^SSxcE{^-~B4b=D{*8&Oo4*~MU=szikn%4;!CA$1sP!W>%cmvt$k zgfT$RG&*Ierbb0Yl_TzcE#i*pa3HJEh$8D4pbrB41nz0r%?(q-g_Bb-z`jkk0MDlb zl;_w29O4#YghQN%z8+Kj&0xB!%j(=*;SO($7jOM|Nn7`Dd!bCbQplp%VPBA3o`8F})6C)yermN`LN(Lv4r@W+kT(r1N^y%)@ z$yu~CDhK88fTqfwv5-%Wc*En0yz97NZMC-O6>81JYOR3gGcn}d0=y>y6uY@G-h;_$jCYxp_fUJ9_rIq$-u1}) z9$OsCBU&t+4S4Y@0B075p@ziUf%r6_VmCKNJesU##4R@BvuWbx4{gLgB>s?AgTo!7 zGyoNujd{r{Fqbiti)dk552<$n^%20uZf=ZvUvfI5UTLNN(wV0I6do^eD~B6{v4O5d z>eZ|+R`^3=I7?kL3bU+BvXW-oeljJ&bP)9mK)nl$*v*Zh-b~goRF@4^PNQD9Z$pib zAZvUtt(DZ~fD9XfjGM_z%R>^TTDhIHD6HwqR(1t0eOT(S^bIMY61NC{YJEdxdvKi! z)2*9mDRr@{-J&FEF*S-|9)d7)+^#ocm{Pax=6dyU?V+=9yZ(Fsej`k{opoSVQ1J{X zu7h0|ySbrpoHyx4#lFvM#yw3Nr{PpDa@-*dah2%Y5a*(`xD&td?qyp+{J!v-)w@Zw zAQduoG80=31IE}`YV5rhUtv#i&U!pkpGwkXS`^d* zirO-O3pO$nVTE+1QM zqi%eFT6-;{*ooC94W?L>F}D&HM<*(ZITaHz#^|*%-T=lK%+A6LV>bj}`9DG^6M6su literal 0 HcmV?d00001 diff --git a/testing/btest/Traces/ldap/sasl-scram-sha-512.pcap b/testing/btest/Traces/ldap/sasl-scram-sha-512.pcap new file mode 100644 index 0000000000000000000000000000000000000000..70fd3d6b0d3659dec9bf9e97aa1d87ecce5a5af5 GIT binary patch literal 4297 zcmb7{4@?{P702()kMPI*OQBu*C!4i2BOL_JV8BUZ2?ORo1TX}LZB@?a!#--?S$Ajt zc-{D;wMbdIbXis9KXk34sp_ODTDP{_5@=Fsnc8Sm6Q)L6D=nKAG)3K{NmG|i-FrXV z^zP!)<%uWY;J){H-}iox0#!%F0iSANLe9-S9Q0G4dH7!|Y2Q zZf2Udtk%xL4YLf(-dbj#E-nAyQT)wi+qb6o|BYd6B=@JpmS4EG{_YT7XLEA$Q28gD zDl-f!KmI1FqB{HZt!1_H_^HLuv_O}js`*!;~y}KKnb!4AhT`hYwUW@Xfm?SsD=Xj_l8sg*Cs%Lbf zSDk548V<;^-d;a?V5Ca#AN0%Ja;G{t=57-aw)9G>^z7x^Uq@K3&|>U0Fm?{g|M-K( z6l{_DpR;T0*KeTWE040w*I*(rje+H}efBp{vF7ht6}K@TGmmU2zJ`k20((Cgz%Q^R zg=`67$RWSi-@A)@Y_CI02!g0-5)?jg6kz9-x#j*L#U`i6qTp-5e~ ziGhBlGd|f9j7NL>v?DzecJmSq<0N^n9H zbRo)X8poiEr{-AZ6+pl=1|>Od{{?k%$?W3EQE+hS!LdcjXKFO65TS#ygki2wxNd5+p z{|=BbjX}vT*?&pNr!3?bGvr?_u#nFmLG<}&$iqs)GaxEy6U}~dVQ!bXiU(6w+-GFx zqa(7Ub0x&4B%JwVOG=HaBKDA|391yw0-cYLhgua`=OtNGVdJTERXRjjS0z!y0^foH zVa91%3uNQ=UtxhYSIh;T>dzGTW4IHC1WtXbH4Cg8D_mfmq%t9eJYc%4iE{O3Mn%GLi#N#Qvop$~`~|!qTKD_wz9kueb1O zkXL#1Oq0>GZVJbh6PqAAi;2C34{DC|#T}$n7o%c4qR3)@A{G=?XBjEk<>K6rIT{)o zcGvHztAlCVHqHy06qBOj@Mgd5;vlvY662+)^L|pEMr=-Zz6OpFcH=U1W0TGP9Cl;X zX*sg9YUSy}xY^&|k?IBLNRy^y?ZWP+z#_0uOQhL+Qvvw9Yp;jp#B~hF^xe{uh`$Bs859$iHU8J z3U3XHI^!%MMYVXPHf`yHq%f+4CD|Vlqfw`w6x0SKxi-ja5pFBV4U2-J85*$NY&D2s z!A7V53{G#dWxtP3uX1;9*`@QiWv|~!Ic?ms>!3IQO~W(>9nlv1Wjdmke}0zEXL|RX zWa(WIbWY4mzb4{r9A03VE)d2v2GxH&d5jY8%0j$?FHlP_n2EVu8%tW~o7p)K-o%O@ zP~jSj@H1-V(#qUcu;MRfVMGmlXER0n+tiBxn#Xu)1*}-4iZ?f`xQYg&;x{){Og>K; UcUu@2fpL|#>rWeu_?mL{e?Fa+O8@`> literal 0 HcmV?d00001 diff --git a/testing/btest/Traces/ldap/sasl-srp-who-am-i.pcap b/testing/btest/Traces/ldap/sasl-srp-who-am-i.pcap new file mode 100644 index 0000000000000000000000000000000000000000..9e70f2d1b063516f418723540e8cc557d484e226 GIT binary patch literal 2838 zcmb7`3pkW%8^@n_W*n9aIfP1@$tqKr8KuNhidD+tGt$Xv@Q#LId~+bP)EJ}m_1UCa zBjvnHv<@Y^Y#XtZw6T>^)aszv(2*-tzULWRtJ${e`tIwx=bCx1XMXqpxu5&}zwfoC zllcTd0`FpS5&#VTF#j@(-Q5g;JN%AvdZ+_e0KVv1v7mfPv}dtG^EXPG8zB9tWCob%{S1|x(u>Foq1Jp4 z0*HVpl+!~&^zX4$5TiayGzJsleea0=0fk?G@2(uY_bKoaA4 zlNr^lSOq&EqY^F1Fg9V*xPZo$mLvewCE#i{- zxIn}e+LJ{BoNrG?n_MLd5k(6{R&<6nzJnDN!^N#bc~RsTJ}(C63*+IxxvUsxk#M`% z#giP(6O!3HQFIuY6HOMd1l+KYJyOD3I055uP)|g5JKMM)$$rMZ6R5v;Gp&MOgU{MC ztoE9bamev>uy>(=+E$&HHI#I)R}>eX@7QUkSGJzW(E4@P+T*uKZ@l}}S8#@Y2(N4p zK5TTv(Eb#Aw#r23cxgY?`1m(8&4WK~9E(3Vm>Kv-iIz~K`{kriu%*Mfv&pG=u7#;f zq(Pj+#ms7Zvk8e|?9XKJ8g5w9vn#b~dyKxEz3rII!_-%CYkghKPJdq6nHX3sUMRXU zI8L;j=pLb++QAB5m`>^wKdji}DIi{EQjcCDnS9lx-nGb2{-UI#N&4?{+gAhK6E%lU zUm$kniXYhCF^lpE@)c#{_xZ1{fBjsiSa)8I`=kJ1gc*FB;MaMrjD~2vas2k({&N^G zW&gHqpGW6jhEI05&^Ilx(eRR?dgJ$V36dm|QSt8}$!Kt%9hq*R&%FPVu@A^r6sSj? zbdPs3HU8`wCt&*{S+~Ed-S`TjUZ&$!i{%O0HD&SFqg?{yei%5mH2`G9TnKk-eN{_K zdah49CS3T%3HyV1f%RmXEV-iHLuS%Hcqs91y+y(U`LDZQbPVkOd@rZHvwhvVg&DP@ zk9UR^-P?cfMw!mOb)NFz2c?f!?sCyft}I%>8&I_iiqtIGRPwxoo4cxKUqncXZIPz+ z?ICTa=!^?uDBOadL$u~JaH(Rkqzb?lINcsZi6q~x;+4(4^sqFb^#g#Vh z0QfyBjOEB&>ukla_hIfCtfBdl>|`dTq; z>@1^LJ3>TkHqIAt#JJ-!TiYee(7nuo_wqlxLywihmkufU67*3YL*x!^WAA;51s%d1 z5mVy{;1M)`l+yz_9d@(F8W97AKT3q|FbHjI$~*lzh)9=W`2>s*EX9sYxt$a{Fy(hr zEEO)5VZce#PTxDF^{h^FCO2wz!)5Wzvy<&^<sqsZ|*Q{OU(F>O?Qs2 z+%9ZG)#`%qbic*bNAn3!>||P96#Fxrnu~Xn8*i?wy;Ue*qO#kO8Wby&Tse0?EA?e2 zPlx{MjJ2&zhR4pQ=QFwKPWH(ywT30~Z|kZ5U;%3#LczGac#EIwiKrgDN-UbCTh#;B1*Te~5D z)QGAc_a`FN(CP%3hIKfR`!Pl5%KLOiIgHloNcPqRyk~Ip9B%{ i584`ui1SlEsnJHEQR!W^tq*Fnu2oFiol>Y&A4anR8 literal 0 HcmV?d00001 diff --git a/testing/btest/scripts/base/protocols/ldap/sasl-ntlm.zeek b/testing/btest/scripts/base/protocols/ldap/sasl-ntlm.zeek new file mode 100644 index 0000000000..0504ba7a0a --- /dev/null +++ b/testing/btest/scripts/base/protocols/ldap/sasl-ntlm.zeek @@ -0,0 +1,12 @@ +# Copyright (c) 2024 by the Zeek Project. See LICENSE for details. + +# @TEST-REQUIRES: have-spicy +# @TEST-EXEC: zeek -C -r ${TRACES}/ldap/sasl-ntlm.pcap %INPUT +# @TEST-EXEC: cat conn.log | zeek-cut -Cn local_orig local_resp > conn.log2 && mv conn.log2 conn.log +# @TEST-EXEC: btest-diff conn.log +# @TEST-EXEC: btest-diff ldap.log +# @TEST-EXEC: btest-diff ldap_search.log +# @TEST-EXEC: ! test -f dpd.log +# @TEST-EXEC: ! test -f analyzer.log +# +# @TEST-DOC: This broke after #3826 got merged diff --git a/testing/btest/scripts/base/protocols/ldap/sasl-scram-sha-512.zeek b/testing/btest/scripts/base/protocols/ldap/sasl-scram-sha-512.zeek new file mode 100644 index 0000000000..9db41f96bc --- /dev/null +++ b/testing/btest/scripts/base/protocols/ldap/sasl-scram-sha-512.zeek @@ -0,0 +1,12 @@ +# Copyright (c) 2024 by the Zeek Project. See LICENSE for details. + +# @TEST-REQUIRES: have-spicy +# @TEST-EXEC: zeek -C -r ${TRACES}/ldap/sasl-scram-sha-512.pcap %INPUT +# @TEST-EXEC: cat conn.log | zeek-cut -Cn local_orig local_resp > conn.log2 && mv conn.log2 conn.log +# @TEST-EXEC: btest-diff conn.log +# @TEST-EXEC: btest-diff ldap.log +# @TEST-EXEC: btest-diff ldap_search.log +# @TEST-EXEC: ! test -f dpd.log +# @TEST-EXEC: ! test -f analyzer.log +# +# @TEST-DOC: This broke after #3826 got merged diff --git a/testing/btest/scripts/base/protocols/ldap/sasl-srp-who-am-i.zeek b/testing/btest/scripts/base/protocols/ldap/sasl-srp-who-am-i.zeek new file mode 100644 index 0000000000..b467dbe484 --- /dev/null +++ b/testing/btest/scripts/base/protocols/ldap/sasl-srp-who-am-i.zeek @@ -0,0 +1,11 @@ +# Copyright (c) 2024 by the Zeek Project. See LICENSE for details. + +# @TEST-REQUIRES: have-spicy +# @TEST-EXEC: zeek -C -r ${TRACES}/ldap/sasl-srp-who-am-i.pcap %INPUT +# @TEST-EXEC: cat conn.log | zeek-cut -Cn local_orig local_resp > conn.log2 && mv conn.log2 conn.log +# @TEST-EXEC: btest-diff conn.log +# @TEST-EXEC: btest-diff ldap.log +# @TEST-EXEC: ! test -f dpd.log +# @TEST-EXEC: ! test -f analyzer.log +# +# @TEST-DOC: SASL authentication using SRP (Secure Remote Password) diff --git a/testing/btest/scripts/base/protocols/ldap/starttls.zeek b/testing/btest/scripts/base/protocols/ldap/starttls.zeek new file mode 100644 index 0000000000..df94315210 --- /dev/null +++ b/testing/btest/scripts/base/protocols/ldap/starttls.zeek @@ -0,0 +1,25 @@ +# Copyright (c) 2024 by the Zeek Project. See LICENSE for details. + +# @TEST-REQUIRES: have-spicy +# @TEST-EXEC: zeek -C -r ${TRACES}/ldap/ldap-starttls.pcap %INPUT >out +# @TEST-EXEC: cat conn.log | zeek-cut -Cn local_orig local_resp > conn.log2 && mv conn.log2 conn.log +# @TEST-EXEC: btest-diff out +# @TEST-EXEC: btest-diff conn.log +# @TEST-EXEC: btest-diff ldap.log +# @TEST-EXEC: btest-diff ssl.log +# @TEST-EXEC: ! test -f dpd.log +# @TEST-EXEC: ! test -f analyzer.log +# +# @TEST-DOC: LDAP supports StartTLS through extendedRequest 1.3.6.1.4.1.1466.20037 + +event LDAP::extended_request(c: connection, message_id: int, request_name: string, request_value: string) { + print c$uid, "extended_request", fmt("%s (%s)", request_name, LDAP::EXTENDED_REQUESTS[request_name]), request_value; +} + +event LDAP::extended_response(c: connection, message_id: int, result: LDAP::ResultCode, response_name: string, response_value: string) { + print c$uid, "extended_response", result, response_name, response_value; +} + +event LDAP::starttls(c: connection) { + print c$uid, "LDAP::starttls"; +} diff --git a/testing/btest/scripts/base/protocols/ldap/who-am-i.zeek b/testing/btest/scripts/base/protocols/ldap/who-am-i.zeek new file mode 100644 index 0000000000..6026add5cc --- /dev/null +++ b/testing/btest/scripts/base/protocols/ldap/who-am-i.zeek @@ -0,0 +1,20 @@ +# Copyright (c) 2024 by the Zeek Project. See LICENSE for details. + +# @TEST-REQUIRES: have-spicy +# @TEST-EXEC: zeek -C -r ${TRACES}/ldap/ldap-who-am-i.pcap %INPUT >out +# @TEST-EXEC: cat conn.log | zeek-cut -Cn local_orig local_resp > conn.log2 && mv conn.log2 conn.log +# @TEST-EXEC: btest-diff out +# @TEST-EXEC: btest-diff conn.log +# @TEST-EXEC: btest-diff ldap.log +# @TEST-EXEC: ! test -f dpd.log +# @TEST-EXEC: ! test -f analyzer.log +# +# @TEST-DOC: Testing OpenLDAP's ldapwhoami utility with simple authentication. + +event LDAP::extended_request(c: connection, message_id: int, request_name: string, request_value: string) { + print c$uid, "extended_request", fmt("%s (%s)", request_name, LDAP::EXTENDED_REQUESTS[request_name]), request_value; +} + +event LDAP::extended_response(c: connection, message_id: int, result: LDAP::ResultCode, response_name: string, response_value: string) { + print c$uid, "extended_response", result, response_name, response_value; +} From 382b4b5473a79546662cd868e6828ae7028f3f8b Mon Sep 17 00:00:00 2001 From: Arne Welzel Date: Wed, 7 Aug 2024 14:10:54 +0200 Subject: [PATCH 35/91] Merge remote-tracking branch 'origin/topic/awelzel/ldap-fix-uint8-shift' * origin/topic/awelzel/ldap-fix-uint8-shift: ldap: Promote uint8 to uint64 before shifting (cherry picked from commit 97fa7cdc0a49869ee6605fac9cfc15f11d8c855b) --- src/analyzer/protocol/ldap/ldap.spicy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/analyzer/protocol/ldap/ldap.spicy b/src/analyzer/protocol/ldap/ldap.spicy index 96f942d7a3..c8ec94273f 100644 --- a/src/analyzer/protocol/ldap/ldap.spicy +++ b/src/analyzer/protocol/ldap/ldap.spicy @@ -196,7 +196,7 @@ type MaybeEncrypted = unit(ctx: Ctx&) { # If so, switch into KRB mode assuming that's what is being used and # have a chance seeing some more plaintext LDAP in non-sealed tokens. rem: uint8[3] if ( ctx.messageMode == MessageMode::ENCRYPTED && (|self.mech| == 0 || self.mech.starts_with(b"GSS")) ) { - self.saslLen = (self.first << 24) + ($$[0] << 16) + ($$[1] << 8) + $$[2]; + self.saslLen = (uint64(self.first) << 24) + (uint64($$[0]) << 16) + (uint64($$[1]) << 8) + uint64($$[2]); } : uint16 if ( self.saslLen >= 2 ) { From 8f9c5f79c6b95fc667ce101368e0d8bee3f05360 Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Fri, 30 Aug 2024 12:34:09 -0700 Subject: [PATCH 36/91] Updating CHANGES and VERSION. --- CHANGES | 145 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ VERSION | 2 +- 2 files changed, 146 insertions(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index bcfa60229b..e81fcbf5e4 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,148 @@ +7.0.0-9 | 2024-08-30 11:47:39 -0700 + + * ldap: Promote uint8 to uint64 before shifting (Arne Welzel, Corelight) + + (cherry picked from commit 97fa7cdc0a49869ee6605fac9cfc15f11d8c855b) + + * ldap: Add heuristic for wrap tokens (Arne Welzel, Corelight) + + Instead of dissecting the GSSAPI handshake, add another heuristic + into MaybeEncrypted to check for the WRAP token identifier. + + After this change, the pcap on the following ticket is processed + nicely: https://gitlab.com/wireshark/migration-test/-/issues/9398 + + (cherry picked from commit 6a6a5c3d0d60a1d4d32ba2173c035023c29fbf1d) + + * ldap: Ignore ec/rrc for sealed wrap tokens (Arne Welzel, Corelight) + + It shouldn't matter for the encrypted payload that we'll + just consume and ignore. + + (cherry picked from commit 6a6a5c3d0d60a1d4d32ba2173c035023c29fbf1d) + + * ldap: Add LDAP sample with SASL-SRP mechanism (Arne Welzel, Corelight) + + This is what @dopheide-esnet actually saw. Produced with a custom + cyrus-sasl and openldap build :-( + + (cherry picked from commit 6a6a5c3d0d60a1d4d32ba2173c035023c29fbf1d) + + * ldap: Reintroduce encryption after SASL heuristic (Arne Welzel, Corelight) + + @dopheide-esnet provided sample captures where SASL SRP is used as + a SASL mechanism and the follow-up LDAP messages are encrypted. It's + not clear how to determine whether encryption will or will not happen, + so re-add a heuristic to determine this based on the first byte of + the first message *after* the successful bindResponse handshake. If + that byte is 0x30, assume cleartext. + + I haven't been able to produce such pcaps, unfortunately, but the + cleartext path is tested via the existing sasl-ntlm.pcap. + + (cherry picked from commit 6a6a5c3d0d60a1d4d32ba2173c035023c29fbf1d) + + * ldap: Fix assuming GSS-SPNEGO for all bindResponses (Arne Welzel, Corelight) + + In retrospect that's an obvious bug. + + (cherry picked from commit 6a6a5c3d0d60a1d4d32ba2173c035023c29fbf1d) + + * ldap: Implement extended request/response and StartTLS support (Arne Welzel, Corelight) + + PCAP was produced with a local OpenLDAP server configured to support StartTLS. + + This puts the Zeek calls into a separate ldap_zeek.spicy file/module + to separate it from LDAP. + + (cherry picked from commit 6a6a5c3d0d60a1d4d32ba2173c035023c29fbf1d) + + * ldap: Remove MessageWrapper with magic 0x30 searching (Arne Welzel, Corelight) + + This unit implements a heuristic to search for the 0x30 sequence + byte if Message couldn't readily be parsed. Remove it with the + idea of explicit and predictable support for SASL mechanisms. + + (cherry picked from commit 2ea3a651bd83b0dfa15924417e4667241531b57b) + + * ldap: Harden parsing a bit (Arne Welzel, Corelight) + + ASN1Message(True) may go off parsing arbitrary input data as + "something ASN.1" This could be GBs of octet strings or just very + long sequences. Avoid this by open-coding some top-level types expected. + + This also tries to avoid some of the &parse-from usages that result + in unnecessary copies of data. + + Adds a locally generated PCAP with addRequest/addResponse that we + don't currently handle. + + (cherry picked from commit 2ea3a651bd83b0dfa15924417e4667241531b57b) + + * ldap: Handle integrity-only KRB wrap tokens (Arne Welzel, Corelight) + + Mostly staring at the PCAPs and opened a few RFCs. For now, only if the + MS_KRB5 OID is used and accepted in a bind response, start stripping + KRB5 wrap tokens for both, client and server traffic. + + Would probably be nice to forward the GSS-API data to the analyzer... + + (cherry picked from commit 2ea3a651bd83b0dfa15924417e4667241531b57b) + + * http: fix password capture when enabled (Pierre Lalet) + + The current implementation would only log, if the password contains a + colon, the part before the first colon (e.g., the password + `password:password` would be logged as `password`). + + (cherry picked from commit c27e18631c5d9c6f04c230bd421c9750a1f02342) + + * Analyzer: Do not add child analyzers when finished (Arne Welzel, Corelight) + + Depending on an analyzer's implementation, its Done() method may + attempt to access analyzer or connection state when executing. + When this happens in the destructor of the parent analyzer during + the process of destructing a connection, this state may have been + deleted, resulting in use-after-free crashes or worse memory + corruption. + + The following cases have been observed in the wild for when this happens. + + * PIA matching during Done() for undelivered TCP data enables a Spicy + based analyzer which in turn attempts to raise an analyzer violation + during Done()->EndOfData(). + + * Spicy analyzers attaching new analyzers during their Done() processing + which in turn attempt to use TCP() (to call FindChild()) during Done() + while the analyzer tree / connection is being destructed. + + The second scenario was previously found to happen in the HTTP analyzer + and fixed with 6ef9423f3cff13e6c73f97eb6a3a27d6f64cc320. + + Plug these scenarios by short-circuiting AddChildAnalyzer() if the analyzer + or connection have finished or are being finished. + + (cherry picked from commit 45b33bf5c17d5e8cf6c777a9bd57e4a803dfad19) + + * TCP_Reassembler: Fix IsOrig() position in Match() call (Arne Welzel, Corelight) + + Found during a debug session with @rsmmr. Undelivered TCP data + would only be matched for the responder and eol set to IsOrig(). + + (cherry picked from commit 4a4cbf25765f387f0aa20277afd133918292b9c4) + + * Process metric callbacks from the main-loop thread (Tim Wojtulewicz, Corelight) + + This avoids the callbacks from being processed on the worker thread + spawned by Civetweb. It fixes data race issues with lookups involving + global variables, amongst other threading issues. + + (cherry picked from commit 3c3853dc7da9aad94a9b2d5a143cc7bd9476ea7a) + + * CI: Use 16GB of memory for FreeBSD builds (Tim Wojtulewicz, Corelight) + + (cherry picked from commit 9d9cc51e9dd93668cd332aa1aef283c9dc23a677) + 7.0.0 | 2024-07-31 09:37:03 -0700 * Release 7.0.0. diff --git a/VERSION b/VERSION index 66ce77b7ea..b1cd350f84 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -7.0.0 +7.0.0-9 From 15be682f63e3622b245ff5744eb1ec212355bfc8 Mon Sep 17 00:00:00 2001 From: Robin Sommer Date: Fri, 23 Aug 2024 08:10:02 +0200 Subject: [PATCH 37/91] Merge remote-tracking branch 'origin/topic/robin/gh-3881-spicy-ports' * origin/topic/robin/gh-3881-spicy-ports: Spicy: Register well-known ports through an event handler. Revert "Remove deprecated port/ports fields for spicy analyzers" (cherry picked from commit a2079bcda6e40180b888240a281c12cc0ca735be) --- CHANGES | 21 ++++++++++++ VERSION | 2 +- doc | 2 +- .../base/frameworks/spicy/init-framework.zeek | 8 ++++- src/spicy/manager.cc | 25 ++++++++++++--- src/spicy/manager.h | 4 +-- src/spicy/port-range.h | 5 +++ .../core.check-unused-event-handlers/.stderr | 1 + .../Baseline/spicy.port-deprecated/out.stderr | 2 -- testing/btest/Baseline/spicy.port-fail/output | 2 +- testing/btest/Baseline/spicy.port/output | 19 +++++++++++ testing/btest/spicy/port-deprecated.evt | 21 ------------ testing/btest/spicy/port-fail.evt | 2 -- testing/btest/spicy/port-range-one-port.zeek | 2 +- testing/btest/spicy/port.zeek | 32 +++++++++++++++++++ 15 files changed, 112 insertions(+), 36 deletions(-) delete mode 100644 testing/btest/Baseline/spicy.port-deprecated/out.stderr create mode 100644 testing/btest/Baseline/spicy.port/output delete mode 100644 testing/btest/spicy/port-deprecated.evt create mode 100644 testing/btest/spicy/port.zeek diff --git a/CHANGES b/CHANGES index e81fcbf5e4..d765816ae0 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,24 @@ +7.0.0-11 | 2024-08-30 12:38:59 -0700 + + * Spicy: Register well-known ports through an event handler. (Robin Sommer, Corelight) + + This avoids the earlier problem of not tracking ports correctly in + scriptland, while still supporting `port` in EVT files and `%port` in + Spicy files. + + As it turns out we are already following the same approach for file + analyzers' MIME types, so I'm applying the same pattern: it's one + event per port, without further customization points. That leaves the + patch pretty small after all while fixing the original issue. + + (cherry picked from commit a2079bcda6e40180b888240a281c12cc0ca735be) + + * Revert "Remove deprecated port/ports fields for spicy analyzers" (Robin Sommer, Corelight) + + This reverts commit 15d404dd191a723960e4efd956eec22739d3f1c2. + + (cherry picked from commit a2079bcda6e40180b888240a281c12cc0ca735be) + 7.0.0-9 | 2024-08-30 11:47:39 -0700 * ldap: Promote uint8 to uint64 before shifting (Arne Welzel, Corelight) diff --git a/VERSION b/VERSION index b1cd350f84..2283f0636c 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -7.0.0-9 +7.0.0-11 diff --git a/doc b/doc index 4e2413e2fb..b845bee39f 160000 --- a/doc +++ b/doc @@ -1 +1 @@ -Subproject commit 4e2413e2fb2f98298430b3e2cb384fc5f18cbde4 +Subproject commit b845bee39fa241892458d274184e2e9f22f4d096 diff --git a/scripts/base/frameworks/spicy/init-framework.zeek b/scripts/base/frameworks/spicy/init-framework.zeek index ae3a3b8e65..de6b528ee4 100644 --- a/scripts/base/frameworks/spicy/init-framework.zeek +++ b/scripts/base/frameworks/spicy/init-framework.zeek @@ -47,12 +47,18 @@ export { # Marked with &is_used to suppress complaints when there aren't any # Spicy file analyzers loaded, and hence this event can't be generated. -# The attribute is only supported for Zeek 5.0 and higher. event spicy_analyzer_for_mime_type(a: Files::Tag, mt: string) &is_used { Files::register_for_mime_type(a, mt); } +# Marked with &is_used to suppress complaints when there aren't any +# Spicy protocol analyzers loaded, and hence this event can't be generated. +event spicy_analyzer_for_port(a: Analyzer::Tag, p: port) &is_used + { + Analyzer::register_for_port(a, p); + } + function enable_protocol_analyzer(tag: Analyzer::Tag) : bool { return Spicy::__toggle_analyzer(tag, T); diff --git a/src/spicy/manager.cc b/src/spicy/manager.cc index 1a9420e22a..423febf1c9 100644 --- a/src/spicy/manager.cc +++ b/src/spicy/manager.cc @@ -6,6 +6,7 @@ #include #include +#include #include #include @@ -32,6 +33,7 @@ #include "zeek/spicy/file-analyzer.h" #include "zeek/spicy/packet-analyzer.h" #include "zeek/spicy/protocol-analyzer.h" +#include "zeek/spicy/runtime-support.h" #include "zeek/zeek-config-paths.h" using namespace zeek; @@ -74,9 +76,13 @@ void Manager::registerProtocolAnalyzer(const std::string& name, hilti::rt::Proto info.name_zeek = hilti::rt::replace(name, "::", "_"); info.name_zeekygen = hilti::rt::fmt("", name); info.protocol = proto; - info.ports = ports; info.linker_scope = linker_scope; + // Store ports in a deterministic order. We can't (easily) sort the + // `hilti::rt::Vector` unfortunately. + std::copy(ports.begin(), ports.end(), std::back_inserter(info.ports)); + std::sort(info.ports.begin(), info.ports.end()); + // We may have that analyzer already iff it was previously pre-registered // without a linker scope. We'll then only set the scope now. if ( auto t = _analyzer_name_to_tag_type.find(info.name_zeek); t != _analyzer_name_to_tag_type.end() ) { @@ -701,14 +707,25 @@ void Manager::InitPostScript() { if ( ! tag ) reporter->InternalError("cannot get analyzer tag for '%s'", p.name_analyzer.c_str()); + auto register_analyzer_for_port = [&](auto tag, const hilti::rt::Port& port_) { + SPICY_DEBUG(hilti::rt::fmt(" Scheduling analyzer for port %s", port_)); + + // Well-known ports are registered in scriptland, so we'll raise an + // event that will do it for us through a predefined handler. + zeek::Args vals = Args(); + vals.emplace_back(tag.AsVal()); + vals.emplace_back(zeek::spicy::rt::to_val(port_, base_type(TYPE_PORT))); + EventHandlerPtr handler = event_registry->Register("spicy_analyzer_for_port"); + event_mgr.Enqueue(handler, vals); + }; + for ( const auto& ports : p.ports ) { const auto proto = ports.begin.protocol(); // Port ranges are closed intervals. for ( auto port = ports.begin.port(); port <= ports.end.port(); ++port ) { const auto port_ = hilti::rt::Port(port, proto); - SPICY_DEBUG(hilti::rt::fmt(" Scheduling analyzer for port %s", port_)); - analyzer_mgr->RegisterAnalyzerForPort(tag, transport_protocol(port_), port); + register_analyzer_for_port(tag, port_); // Don't double register in case of single-port ranges. if ( ports.begin.port() == ports.end.port() ) @@ -727,7 +744,7 @@ void Manager::InitPostScript() { continue; SPICY_DEBUG(hilti::rt::fmt(" Scheduling analyzer for port %s", port.port)); - analyzer_mgr->RegisterAnalyzerForPort(tag, transport_protocol(port.port), port.port.port()); + register_analyzer_for_port(tag, port.port); } } } diff --git a/src/spicy/manager.h b/src/spicy/manager.h index 118e03b6c3..55f47c51fd 100644 --- a/src/spicy/manager.h +++ b/src/spicy/manager.h @@ -85,7 +85,7 @@ public: * * @param name name of the analyzer as defined in its EVT file * @param proto analyzer's transport-layer protocol - * @param prts well-known ports for the analyzer; it'll be activated automatically for these + * @param ports well-known ports for the analyzer; it'll be activated automatically for these * @param parser_orig name of the Spicy parser for the originator side; must match the name that * Spicy registers the unit's parser with * @param parser_resp name of the Spicy parser for the originator side; must match the name that @@ -343,7 +343,7 @@ private: std::string name_parser_resp; std::string name_replaces; hilti::rt::Protocol protocol = hilti::rt::Protocol::Undef; - hilti::rt::Vector<::zeek::spicy::rt::PortRange> ports; + std::vector<::zeek::spicy::rt::PortRange> ports; // we keep this sorted std::string linker_scope; // Computed and available once the analyzer has been registered. diff --git a/src/spicy/port-range.h b/src/spicy/port-range.h index bbe0d58c12..7e71d433f8 100644 --- a/src/spicy/port-range.h +++ b/src/spicy/port-range.h @@ -19,6 +19,11 @@ struct PortRange { hilti::rt::Port begin; /**< first port in the range */ hilti::rt::Port end; /**< last port in the range */ + + bool operator<(const PortRange& other) const { + // Just get us a deterministic order. + return std::tie(begin, end) < std::tie(other.begin, other.end); + } }; inline bool operator==(const PortRange& a, const PortRange& b) { diff --git a/testing/btest/Baseline/core.check-unused-event-handlers/.stderr b/testing/btest/Baseline/core.check-unused-event-handlers/.stderr index 69f805dbf7..9fc3532832 100644 --- a/testing/btest/Baseline/core.check-unused-event-handlers/.stderr +++ b/testing/btest/Baseline/core.check-unused-event-handlers/.stderr @@ -22,5 +22,6 @@ warning in , line 1: event handler never invoked: SupervisorControl::res warning in , line 1: event handler never invoked: SupervisorControl::status_request warning in , line 1: event handler never invoked: SupervisorControl::stop_request warning in , line 1: event handler never invoked: spicy_analyzer_for_mime_type +warning in , line 1: event handler never invoked: spicy_analyzer_for_port warning in , line 1: event handler never invoked: terminate_event warning in , line 1: event handler never invoked: this_is_never_used diff --git a/testing/btest/Baseline/spicy.port-deprecated/out.stderr b/testing/btest/Baseline/spicy.port-deprecated/out.stderr deleted file mode 100644 index a033682601..0000000000 --- a/testing/btest/Baseline/spicy.port-deprecated/out.stderr +++ /dev/null @@ -1,2 +0,0 @@ -### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. -[warning] <...>/udp-test.evt:4: Remove in v7.1: Analyzer spicy::TEST is using the deprecated 'port' or 'ports' keyword to register well-known ports. Use Analyzer::register_for_ports() in the accompanying Zeek script instead. diff --git a/testing/btest/Baseline/spicy.port-fail/output b/testing/btest/Baseline/spicy.port-fail/output index f572d2e79a..24eb09807d 100644 --- a/testing/btest/Baseline/spicy.port-fail/output +++ b/testing/btest/Baseline/spicy.port-fail/output @@ -1,3 +1,3 @@ ### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. -[error] <...>/port-fail.evt:9: port outside of valid range +[error] <...>/port-fail.evt:7: port outside of valid range [error] error loading EVT file "<...>/port-fail.evt" diff --git a/testing/btest/Baseline/spicy.port/output b/testing/btest/Baseline/spicy.port/output new file mode 100644 index 0000000000..938a6c7b35 --- /dev/null +++ b/testing/btest/Baseline/spicy.port/output @@ -0,0 +1,19 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +Analyzer::ANALYZER_SPICY_TEST, 11337/udp +Analyzer::ANALYZER_SPICY_TEST, 11338/udp +Analyzer::ANALYZER_SPICY_TEST, 11339/udp +Analyzer::ANALYZER_SPICY_TEST, 11340/udp +Analyzer::ANALYZER_SPICY_TEST, 31337/udp +Analyzer::ANALYZER_SPICY_TEST, 31338/udp +Analyzer::ANALYZER_SPICY_TEST, 31339/udp +Analyzer::ANALYZER_SPICY_TEST, 31340/udp +{ +31339/udp, +31337/udp, +31338/udp, +11339/udp, +11338/udp, +11340/udp, +31340/udp, +11337/udp +} diff --git a/testing/btest/spicy/port-deprecated.evt b/testing/btest/spicy/port-deprecated.evt deleted file mode 100644 index 220a9d1faf..0000000000 --- a/testing/btest/spicy/port-deprecated.evt +++ /dev/null @@ -1,21 +0,0 @@ -# @TEST-REQUIRES: have-spicy -# -# @TEST-EXEC: spicyz -d -o test.hlto ./udp-test.evt 2>out.stderr -# @TEST-EXEC: TEST_DIFF_CANONIFIER=$SCRIPTS/diff-remove-abspath btest-diff out.stderr -# -# @TEST-DOC: Remove with v7.1: Specifying ports is deprecated. - -module Test; - -import zeek; - -public type Message = unit { - data: bytes &eod {} -}; - -# @TEST-START-FILE udp-test.evt -protocol analyzer spicy::TEST over UDP: - parse with Test::Message, - port 11337/udp-11340/udp, - ports {31337/udp-31340/udp}; -# @TEST-END-FILE diff --git a/testing/btest/spicy/port-fail.evt b/testing/btest/spicy/port-fail.evt index e51ca0fb79..f00efc6210 100644 --- a/testing/btest/spicy/port-fail.evt +++ b/testing/btest/spicy/port-fail.evt @@ -2,8 +2,6 @@ # # @TEST-EXEC-FAIL: spicyz %INPUT -d -o x.hlto >output 2>&1 # @TEST-EXEC: TEST_DIFF_CANONIFIER=diff-canonifier-spicy btest-diff output -# -# @TEST-DOC: Remove with v7.1 protocol analyzer spicy::SSH over TCP: port 123456/udp; diff --git a/testing/btest/spicy/port-range-one-port.zeek b/testing/btest/spicy/port-range-one-port.zeek index 95c32f2b27..bdc5219791 100644 --- a/testing/btest/spicy/port-range-one-port.zeek +++ b/testing/btest/spicy/port-range-one-port.zeek @@ -5,7 +5,7 @@ # @TEST-EXEC: grep -e 'Scheduling analyzer' -e 'error during parsing' < out > out.filtered # @TEST-EXEC: btest-diff out.filtered -# @TEST-DOC: Remove with v7.1. Expect a single 'Scheduling analyzer ...' message in the debug output and no parsing errors. There was a bug that 'port 31336/udp' would be wrongly interpreted as a 31336/udp-31337/udp port range. Regression test for #3278. +# @TEST-DOC: Expect a single 'Scheduling analyzer ...' message in the debug output and no parsing errors. There was a bug that 'port 31336/udp' would be wrongly interpreted as a 31336/udp-31337/udp port range. Regression test for #3278. # @TEST-START-FILE udp-test.spicy module UDPTest; diff --git a/testing/btest/spicy/port.zeek b/testing/btest/spicy/port.zeek new file mode 100644 index 0000000000..81d3586c68 --- /dev/null +++ b/testing/btest/spicy/port.zeek @@ -0,0 +1,32 @@ +# @TEST-REQUIRES: have-spicy +# +# @TEST-EXEC: spicyz -d -o test.hlto test.spicy test.evt +# @TEST-EXEC: zeek test.hlto %INPUT >output +# @TEST-EXEC: btest-diff output +# +# @TEST-DOC: Check that we raise port events for Spicy analyzers, and that the ports get correctly registered. + +event spicy_analyzer_for_port(a: Analyzer::Tag, p: port){ + print a, p; +} + +event zeek_done() { + print Analyzer::ports[Analyzer::ANALYZER_SPICY_TEST]; +} + +# @TEST-START-FILE test.spicy +module Test; + +import zeek; + +public type Message = unit { + data: bytes &eod {} +}; +# @TEST-END-FILE + +# @TEST-START-FILE test.evt +protocol analyzer spicy::Test over UDP: + parse with Test::Message, + port 11337/udp-11340/udp, + ports {31337/udp-31340/udp}; +# @TEST-END-FILE From 74b832fa39e296402fe8fddc72c3d4609a8f8f2a Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Fri, 30 Aug 2024 14:39:46 -0700 Subject: [PATCH 38/91] Update docs submodule [nomail] [skip ci] --- doc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc b/doc index b845bee39f..8039548924 160000 --- a/doc +++ b/doc @@ -1 +1 @@ -Subproject commit b845bee39fa241892458d274184e2e9f22f4d096 +Subproject commit 8039548924d13b991a7329691fef4c64b03d13fc From 595cdf8b557013a3e04627c9bcbd7544b02e9199 Mon Sep 17 00:00:00 2001 From: Benjamin Bannier Date: Mon, 2 Sep 2024 12:44:54 +0200 Subject: [PATCH 39/91] Bump auxil/spicy to latest release --- auxil/spicy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/auxil/spicy b/auxil/spicy index 7ddf6ce441..a1b7c78287 160000 --- a/auxil/spicy +++ b/auxil/spicy @@ -1 +1 @@ -Subproject commit 7ddf6ce441d63aa5894dd11d9a5047ddc761de9a +Subproject commit a1b7c78287ecb29cf17a3ef8a94125d87eadb152 From 89b9f9a456fbaeac84f2c1e65c142fef4182d0d1 Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Tue, 3 Sep 2024 13:03:51 -0700 Subject: [PATCH 40/91] Update zeek-aux submodule to pick up zeek-archiver permissions fix --- auxil/zeek-aux | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/auxil/zeek-aux b/auxil/zeek-aux index 8a66cd60fb..e850412ab5 160000 --- a/auxil/zeek-aux +++ b/auxil/zeek-aux @@ -1 +1 @@ -Subproject commit 8a66cd60fb29a1237b5070854cb194f43a3f7a30 +Subproject commit e850412ab5dea10ee2ebb98e42527d80fcf9a7ed From 3bf8bfaac6784105d0c3cbbc18cf1d27952da81f Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Tue, 3 Sep 2024 13:04:23 -0700 Subject: [PATCH 41/91] Update CHANGES, VERSION, and NEWS for 7.0.1 release --- CHANGES | 6 ++++++ NEWS | 20 ++++++++++++++++++++ VERSION | 2 +- 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index 8a1d0481dc..a124a7824b 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,9 @@ +7.0.1 | 2024-09-03 13:04:23 -0700 + + * Update CHANGES, VERSION, and NEWS for 7.0.1 release (Tim Wojtulewicz, Corelight) + + * Update zeek-aux submodule to pick up zeek-archiver permissions fix (Tim Wojtulewicz, Corelight) + 7.0.0-14 | 2024-09-03 09:02:19 -0700 * Bump auxil/spicy to latest release (Benjamin Bannier, Corelight) diff --git a/NEWS b/NEWS index 57a02b61a0..dd0c324b26 100644 --- a/NEWS +++ b/NEWS @@ -3,6 +3,26 @@ This document summarizes the most important changes in the current Zeek release. For an exhaustive list of changes, see the ``CHANGES`` file (note that submodules, such as Broker, come with their own ``CHANGES``.) +Zeek 7.0.1 +========== + +This release fixes the following bugs: + +- HTTP passwords with colon characters in them are now correctly logged. + +- The LDAP analyzer now supports handling of non-sealed GSS-API WRAP tokens. + +- Heuristics for parsing SASL encrypted and signed LDAP traffic have been made + more strict and predictable. Please provide input if this results in less + visibility in your environment. + +- StartTLS support was added to the LDAP analyzer. The SSL analyzer is enabled + for connections where client and server negotiate to TLS through the extended + request/response mechanism. + +- Specify less-strict permissions for directories and files created by + zeek-archiver to play more nicely with user's umask setting. + Zeek 7.0.0 ========== diff --git a/VERSION b/VERSION index fb81d6448a..9fe9ff9d99 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -7.0.0-14 +7.0.1 From 2cc6c735d35f6edad81663dc57305cec3c4a8311 Mon Sep 17 00:00:00 2001 From: Benjamin Bannier Date: Thu, 19 Sep 2024 13:40:34 +0200 Subject: [PATCH 42/91] Bump auxil/spicy to latest release --- auxil/spicy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/auxil/spicy b/auxil/spicy index a1b7c78287..d923cc0bb5 160000 --- a/auxil/spicy +++ b/auxil/spicy @@ -1 +1 @@ -Subproject commit a1b7c78287ecb29cf17a3ef8a94125d87eadb152 +Subproject commit d923cc0bb5da8481a13fa6741c007f43c8fd08d5 From 95e7c5a63eff56c824fee20032ab987cd8e9c4ba Mon Sep 17 00:00:00 2001 From: Arne Welzel Date: Fri, 26 Jul 2024 15:14:36 +0200 Subject: [PATCH 43/91] Merge remote-tracking branch 'origin/topic/awelzel/3853-ldap-spnego-ntlmssp' * origin/topic/awelzel/3853-ldap-spnego-ntlmssp: ldap: Recognize SASL+SPNEGO+NTLMSSP (cherry picked from commit 152bbbd680e6c329255dc28d57cd506e7d2c09ff) --- src/analyzer/protocol/ldap/ldap.spicy | 34 ++++++++++-------- .../conn.log | 12 +++++++ .../ldap.log | 14 ++++++++ testing/btest/Traces/README | 3 ++ .../ctu-sme-11-win7ad-1-ldap-tcp-50041.pcap | Bin 0 -> 2084 bytes .../base/protocols/ldap/spnego-ntlmssp.zeek | 15 ++++++++ 6 files changed, 64 insertions(+), 14 deletions(-) create mode 100644 testing/btest/Baseline/scripts.base.protocols.ldap.spnego-ntlmssp/conn.log create mode 100644 testing/btest/Baseline/scripts.base.protocols.ldap.spnego-ntlmssp/ldap.log create mode 100644 testing/btest/Traces/ldap/ctu-sme-11-win7ad-1-ldap-tcp-50041.pcap create mode 100644 testing/btest/scripts/base/protocols/ldap/spnego-ntlmssp.zeek diff --git a/src/analyzer/protocol/ldap/ldap.spicy b/src/analyzer/protocol/ldap/ldap.spicy index c8ec94273f..0816e6afe9 100644 --- a/src/analyzer/protocol/ldap/ldap.spicy +++ b/src/analyzer/protocol/ldap/ldap.spicy @@ -375,26 +375,29 @@ type GSS_SPNEGO_negTokenInit = unit { : skip bytes &eod; }; -# Peak into GSS-SPNEGO payload and ensure it is indeed GSS-SPNEGO. +# Peak into GSS-SPNEGO payload and ensure it is indeed GSS-SPNEGO, +# or GSS-SPNEGO with a NTMLSSP payload that starts with NTLMSSP. type GSS_SPNEGO_Init = unit { # This is the optional octet string in SaslCredentials. credentialsHeader: ASN1::ASN1Header &requires=($$.tag.type_ == ASN1::ASN1Type::OctetString); # Now we either have the initial message as specified in RFC2743 or - # a continuation from RFC4178 + # a continuation from RFC4178, or a "NTMLSSP" signature. # - # 60 -> APPLICATION [0] https://datatracker.ietf.org/doc/html/rfc2743#page-81) + # 60 -> APPLICATION [0] https://datatracker.ietf.org/doc/html/rfc2743#page-81 # a1 -> CHOICE [1] https://www.rfc-editor.org/rfc/rfc4178#section-4.2 + # "NTMLSSP" https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-nlmp/907f519d-6217-45b1-b421-dca10fc8af0d # - gssapiHeader: ASN1::ASN1Header &requires=( - $$.tag.class == ASN1::ASN1Class::Application && $$.tag.type_ == ASN1::ASN1Type(0) - || $$.tag.class == ASN1::ASN1Class::ContextSpecific && $$.tag.type_ == ASN1::ASN1Type(1) - ); + switch { + -> spnegoInitByte: uint8(0x60); + -> spnegoChoiceByte: uint8(0xa1); + -> ntlmSignature: skip b"NTLMSSP"; # Unsupported, should forward to child analyzer! + }; - switch ( self.gssapiHeader.tag.type_ ) { - ASN1::ASN1Type(0) -> initial: GSS_SPNEGO_negTokenInit; - * -> : skip bytes &eod; - } &size=self.gssapiHeader.len.len; + spnegoLen: skip ASN1::LengthType if (self?.spnegoInitByte || self?.spnegoChoiceByte); + + # Peak into the SPNEGO_negTokenInit + spnegoInitial: skip GSS_SPNEGO_negTokenInit if (self?.spnegoInitByte); }; type SaslCredentials = unit() { @@ -408,10 +411,13 @@ type SaslCredentials = unit() { }; type GSS_SPNEGO_Subsequent = unit { - token: ASN1::ASN1Header &requires=($$.tag.class == ASN1::ASN1Class::ContextSpecific); - switch ( self.token.tag.type_ ) { - ASN1::ASN1Type(1) -> negTokenResp: GSS_SPNEGO_negTokenResp; + switch { + -> spnegoChoiceByte: uint8(0xa1); + -> ntmlSignature: skip b"NTLMSSP"; # Unsupported, should forward to NTLM! }; + + spnegoChoiceLen: skip ASN1::LengthType if (self?.spnegoChoiceByte); + negTokenResp: GSS_SPNEGO_negTokenResp if (self?.spnegoChoiceByte); }; type GSS_SPNEGO_negTokenResp = unit { diff --git a/testing/btest/Baseline/scripts.base.protocols.ldap.spnego-ntlmssp/conn.log b/testing/btest/Baseline/scripts.base.protocols.ldap.spnego-ntlmssp/conn.log new file mode 100644 index 0000000000..84a495d3fb --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.ldap.spnego-ntlmssp/conn.log @@ -0,0 +1,12 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path conn +#open XXXX-XX-XX-XX-XX-XX +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p proto service duration orig_bytes resp_bytes conn_state missed_bytes history orig_pkts orig_ip_bytes resp_pkts resp_ip_bytes tunnel_parents +#types time string addr port addr port enum string interval count count string count string count count count count set[string] +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 192.168.1.105 50041 192.168.1.108 389 tcp ldap_tcp 0.004745 93 283 RSTR 0 ShADdFar 5 305 4 455 - +XXXXXXXXXX.XXXXXX ClEkJM2Vm5giqnMf4h 192.168.1.107 50041 192.168.1.108 389 tcp ldap_tcp 0.005883 93 283 RSTR 0 ShADdFar 5 305 4 455 - +#close XXXX-XX-XX-XX-XX-XX diff --git a/testing/btest/Baseline/scripts.base.protocols.ldap.spnego-ntlmssp/ldap.log b/testing/btest/Baseline/scripts.base.protocols.ldap.spnego-ntlmssp/ldap.log new file mode 100644 index 0000000000..07355e0e78 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.ldap.spnego-ntlmssp/ldap.log @@ -0,0 +1,14 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path ldap +#open XXXX-XX-XX-XX-XX-XX +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p message_id version opcode result diagnostic_message object argument +#types time string addr port addr port int int string string string string string +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 192.168.1.105 50041 192.168.1.108 389 160 3 bind SASL SASL bind in progress - - GSS-SPNEGO +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 192.168.1.105 50041 192.168.1.108 389 161 - unbind - - - - +XXXXXXXXXX.XXXXXX ClEkJM2Vm5giqnMf4h 192.168.1.107 50041 192.168.1.108 389 427 3 bind SASL SASL bind in progress - - GSS-SPNEGO +XXXXXXXXXX.XXXXXX ClEkJM2Vm5giqnMf4h 192.168.1.107 50041 192.168.1.108 389 428 - unbind - - - - +#close XXXX-XX-XX-XX-XX-XX diff --git a/testing/btest/Traces/README b/testing/btest/Traces/README index bc5a304436..43942584f2 100644 --- a/testing/btest/Traces/README +++ b/testing/btest/Traces/README @@ -18,3 +18,6 @@ Trace Index/Sources: - one `\x30` byte in the ciphertext changed to `\x00` - ldap/issue-32.pcapng: Provided by GH user martinvanhensbergen, +- ldap/ctu-sme-11-win7ad-1-ldap-tcp-50041.pcap: Harvested from CTU-SME-11 + (Experiment-VM-Microsoft-Windows7AD-1) dataset, filtering on tcp port 389 and port 50041. + https://zenodo.org/records/7958259 (DOI 10.5281/zenodo.7958258). diff --git a/testing/btest/Traces/ldap/ctu-sme-11-win7ad-1-ldap-tcp-50041.pcap b/testing/btest/Traces/ldap/ctu-sme-11-win7ad-1-ldap-tcp-50041.pcap new file mode 100644 index 0000000000000000000000000000000000000000..dd2b34ce4add5cef82f592fb7a64421f6153fcf4 GIT binary patch literal 2084 zcmds%Uq}>D6voe;9rurtyDOOzY#36mq9U=16hW@3P@8V84+*wv24-tS=F39rwrC;= zAwBqq3N@2*?ZFTUdZ`ww$AU6ae9-Elf7l1)xifcWc7F5Cch3D@ zgzpYYAjA451H+SG+?U!GI|C=qX&52xnIQ-F=lhn8Pz2zxHSdFfzGC}>TdW>OL)g#S z)1OaYB2qv~0d^Tcl4B;APG@9HmWcQyT_AFn!X=`shlm*lq7jv~hyC8FMGI290tqQF zzA2LUIfFqSzL7?RM!T(rYs}PW>_V#5ZDC-UQ@*s)!Jq>PG$JT|TPsnHPDiCAGq`pU zAg2uqP))M}iRomxLDM`rw#4Jf^0-TjO3Gw=X}Rl=$K&QE_XLge_zz*zvvC_< zFq2*5xeN|tHE5{Tt9G$MS1-x3f794yMZ0F*DC=vzB8w%GtQyq9;$m663^H^C8K^=e zd|Lwk^6{7$?3_Q{oZOc7F@CSAY7!>l0G{Y|fgN}-d!QVSKmqQ{z=cOANceQ*RR+mX zu4ci0C`1KY@m>=&LJjWEAg2b7LpIJDp$>H55biecyULTb4Y0KT&CwY|qo zSYu5Jc>70`6p-hLa`rw_d_wZsD_mw2u%mSrA_QZM$urViJGYRK5 z?8kSU7#4}6CQif@7+zBP@s&ss3J-Sg3Q>|mV&P{NQin!ksjG(<70Q(+L5r61i&I9U LQZNN>eggOn=p^s( literal 0 HcmV?d00001 diff --git a/testing/btest/scripts/base/protocols/ldap/spnego-ntlmssp.zeek b/testing/btest/scripts/base/protocols/ldap/spnego-ntlmssp.zeek new file mode 100644 index 0000000000..e936332b47 --- /dev/null +++ b/testing/btest/scripts/base/protocols/ldap/spnego-ntlmssp.zeek @@ -0,0 +1,15 @@ +# Copyright (c) 2024 by the Zeek Project. See LICENSE for details. +# +# The ctu-sme-11-win7ad-1-ldap-tcp-50041.pcap file was harvested +# from the CTU-SME-11 (Experiment-VM-Microsoft-Windows7AD-1) dataset +# at https://zenodo.org/records/7958259 (DOI 10.5281/zenodo.7958258). + +# @TEST-REQUIRES: have-spicy +# @TEST-EXEC: zeek -C -r ${TRACES}/ldap/ctu-sme-11-win7ad-1-ldap-tcp-50041.pcap +# @TEST-EXEC: cat conn.log | zeek-cut -Cn local_orig local_resp > conn.log2 && mv conn.log2 conn.log +# @TEST-EXEC: btest-diff conn.log +# @TEST-EXEC: btest-diff ldap.log +# @TEST-EXEC: ! test -f dpd.log +# @TEST-EXEC: ! test -f analyzer.log +# +# @TEST-DOC: SASL bindRequest with SPNEGO NTLMSSP. From 5a0e2bf77157c752fc1427aa33370ee77311e7af Mon Sep 17 00:00:00 2001 From: Arne Welzel Date: Fri, 6 Sep 2024 19:17:29 +0200 Subject: [PATCH 44/91] Merge remote-tracking branch 'origin/topic/awelzel/3919-ldap-logs-missing' * origin/topic/awelzel/3919-ldap-logs-missing: btest/ldap: Add regression test for #3919 (cherry picked from commit a339cfa4c007762c6fbb16a35576220851fe4a82) --- .../ldap.log | 35 ++++++++++++++++++ testing/btest/Traces/README | 2 + .../Traces/ldap/ldap_invalid_credentials.pcap | Bin 0 -> 15618 bytes .../protocols/ldap/invalid_credentials.zeek | 5 +++ 4 files changed, 42 insertions(+) create mode 100644 testing/btest/Baseline/scripts.base.protocols.ldap.invalid_credentials/ldap.log create mode 100644 testing/btest/Traces/ldap/ldap_invalid_credentials.pcap create mode 100644 testing/btest/scripts/base/protocols/ldap/invalid_credentials.zeek diff --git a/testing/btest/Baseline/scripts.base.protocols.ldap.invalid_credentials/ldap.log b/testing/btest/Baseline/scripts.base.protocols.ldap.invalid_credentials/ldap.log new file mode 100644 index 0000000000..4ca02e8489 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.ldap.invalid_credentials/ldap.log @@ -0,0 +1,35 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path ldap +#open XXXX-XX-XX-XX-XX-XX +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p message_id version opcode result diagnostic_message object argument +#types time string addr port addr port int int string string string string string +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 192.168.66.141 53653 192.168.66.138 389 65 3 bind SASL SASL bind in progress - - GSS-SPNEGO +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 192.168.66.141 53653 192.168.66.138 389 66 3 bind SASL invalid credentials 8009030C: LdapErr: DSID-0C090569, comment: AcceptSecurityContext error, data 52e, v4563? - GSS-SPNEGO +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 192.168.66.141 53653 192.168.66.138 389 83 3 bind SASL SASL bind in progress - - GSS-SPNEGO +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 192.168.66.141 53653 192.168.66.138 389 84 3 bind SASL invalid credentials 8009030C: LdapErr: DSID-0C090569, comment: AcceptSecurityContext error, data 52e, v4563? - GSS-SPNEGO +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 192.168.66.141 53653 192.168.66.138 389 101 3 bind SASL SASL bind in progress - - GSS-SPNEGO +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 192.168.66.141 53653 192.168.66.138 389 102 3 bind SASL invalid credentials 8009030C: LdapErr: DSID-0C090569, comment: AcceptSecurityContext error, data 52e, v4563? - GSS-SPNEGO +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 192.168.66.141 53653 192.168.66.138 389 119 3 bind SASL SASL bind in progress - - GSS-SPNEGO +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 192.168.66.141 53653 192.168.66.138 389 120 3 bind SASL invalid credentials 8009030C: LdapErr: DSID-0C090569, comment: AcceptSecurityContext error, data 52e, v4563? - GSS-SPNEGO +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 192.168.66.141 53653 192.168.66.138 389 137 3 bind SASL SASL bind in progress - - GSS-SPNEGO +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 192.168.66.141 53653 192.168.66.138 389 138 3 bind SASL invalid credentials 8009030C: LdapErr: DSID-0C090569, comment: AcceptSecurityContext error, data 52e, v4563? - GSS-SPNEGO +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 192.168.66.141 53653 192.168.66.138 389 155 3 bind SASL SASL bind in progress - - GSS-SPNEGO +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 192.168.66.141 53653 192.168.66.138 389 156 3 bind SASL invalid credentials 8009030C: LdapErr: DSID-0C090569, comment: AcceptSecurityContext error, data 52e, v4563? - GSS-SPNEGO +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 192.168.66.141 53653 192.168.66.138 389 173 3 bind SASL SASL bind in progress - - GSS-SPNEGO +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 192.168.66.141 53653 192.168.66.138 389 174 3 bind SASL invalid credentials 8009030C: LdapErr: DSID-0C090569, comment: AcceptSecurityContext error, data 52e, v4563? - GSS-SPNEGO +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 192.168.66.141 53653 192.168.66.138 389 191 3 bind SASL SASL bind in progress - - GSS-SPNEGO +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 192.168.66.141 53653 192.168.66.138 389 192 3 bind SASL invalid credentials 8009030C: LdapErr: DSID-0C090569, comment: AcceptSecurityContext error, data 52e, v4563? - GSS-SPNEGO +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 192.168.66.141 53653 192.168.66.138 389 209 3 bind SASL SASL bind in progress - - GSS-SPNEGO +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 192.168.66.141 53653 192.168.66.138 389 210 3 bind SASL invalid credentials 8009030C: LdapErr: DSID-0C090569, comment: AcceptSecurityContext error, data 52e, v4563? - GSS-SPNEGO +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 192.168.66.141 53653 192.168.66.138 389 227 3 bind SASL SASL bind in progress - - GSS-SPNEGO +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 192.168.66.141 53653 192.168.66.138 389 228 3 bind SASL invalid credentials 8009030C: LdapErr: DSID-0C090569, comment: AcceptSecurityContext error, data 52e, v4563? - GSS-SPNEGO +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 192.168.66.141 53653 192.168.66.138 389 245 3 bind SASL SASL bind in progress - - GSS-SPNEGO +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 192.168.66.141 53653 192.168.66.138 389 246 3 bind SASL invalid credentials 8009030C: LdapErr: DSID-0C090569, comment: AcceptSecurityContext error, data 52e, v4563? - GSS-SPNEGO +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 192.168.66.141 53653 192.168.66.138 389 263 3 bind SASL SASL bind in progress - - GSS-SPNEGO +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 192.168.66.141 53653 192.168.66.138 389 264 3 bind SASL invalid credentials 8009030C: LdapErr: DSID-0C090569, comment: AcceptSecurityContext error, data 52e, v4563? - GSS-SPNEGO +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 192.168.66.141 53653 192.168.66.138 389 349 - unbind - - - - +#close XXXX-XX-XX-XX-XX-XX diff --git a/testing/btest/Traces/README b/testing/btest/Traces/README index 43942584f2..2dec7f683f 100644 --- a/testing/btest/Traces/README +++ b/testing/btest/Traces/README @@ -21,3 +21,5 @@ Trace Index/Sources: - ldap/ctu-sme-11-win7ad-1-ldap-tcp-50041.pcap: Harvested from CTU-SME-11 (Experiment-VM-Microsoft-Windows7AD-1) dataset, filtering on tcp port 389 and port 50041. https://zenodo.org/records/7958259 (DOI 10.5281/zenodo.7958258). +- ldap/ldap_invalid_credentials.pcap + Provided by Martin van Hensbergen in issue #3919. diff --git a/testing/btest/Traces/ldap/ldap_invalid_credentials.pcap b/testing/btest/Traces/ldap/ldap_invalid_credentials.pcap new file mode 100644 index 0000000000000000000000000000000000000000..b273b140bd30aa6744355817214ef8a06fed2b0c GIT binary patch literal 15618 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 KpU(^TBmV_9cnq)r literal 0 HcmV?d00001 diff --git a/testing/btest/scripts/base/protocols/ldap/invalid_credentials.zeek b/testing/btest/scripts/base/protocols/ldap/invalid_credentials.zeek new file mode 100644 index 0000000000..041d03464d --- /dev/null +++ b/testing/btest/scripts/base/protocols/ldap/invalid_credentials.zeek @@ -0,0 +1,5 @@ +# @TEST-DOC: Regression test case for #3919 for invalid credentials. +# +# @TEST-REQUIRES: have-spicy +# @TEST-EXEC: zeek -C -r ${TRACES}/ldap/ldap_invalid_credentials.pcap %INPUT +# @TEST-EXEC: btest-diff ldap.log From fb51e3a88f69633882282693378ecbf56cafb8b6 Mon Sep 17 00:00:00 2001 From: Arne Welzel Date: Tue, 17 Sep 2024 18:50:40 +0200 Subject: [PATCH 45/91] Merge remote-tracking branch 'origin/topic/awelzel/prom-callbacks-2' * origin/topic/awelzel/prom-callbacks-2: Update broker submodule telemetry: Move callbacks to Zeek auxil/prometheus-cpp: Pin to 1.2.4 (cherry picked from commit f24bc1ee882b3b266ca9dc325a1b5584addb155e) --- auxil/broker | 2 +- auxil/prometheus-cpp | 2 +- src/Timer.cc | 3 --- src/telemetry/Counter.cc | 31 +++++++++++++------------- src/telemetry/Counter.h | 28 +++++++++++++++++++----- src/telemetry/Gauge.cc | 29 +++++++++++-------------- src/telemetry/Gauge.h | 25 ++++++++++++++++----- src/telemetry/Histogram.h | 2 ++ src/telemetry/Manager.cc | 42 ++++++++++-------------------------- src/telemetry/Manager.h | 12 +++++++---- src/telemetry/MetricFamily.h | 2 ++ src/telemetry/Utils.h | 1 - 12 files changed, 96 insertions(+), 83 deletions(-) diff --git a/auxil/broker b/auxil/broker index 5b3ed87a93..a80bf420aa 160000 --- a/auxil/broker +++ b/auxil/broker @@ -1 +1 @@ -Subproject commit 5b3ed87a93b2ded1f3c95ff1a3b99e2c6ab84ef4 +Subproject commit a80bf420aa6f55b4eb959ae89c184522a096a119 diff --git a/auxil/prometheus-cpp b/auxil/prometheus-cpp index 4649065e2a..ad99e21f47 160000 --- a/auxil/prometheus-cpp +++ b/auxil/prometheus-cpp @@ -1 +1 @@ -Subproject commit 4649065e2a1dd21c81e41cd6007dce5486b77fc0 +Subproject commit ad99e21f4706193670c42b36c9824dc997f4c475 diff --git a/src/Timer.cc b/src/Timer.cc index ef2763071a..65bcae4c2b 100644 --- a/src/Timer.cc +++ b/src/Timer.cc @@ -2,14 +2,11 @@ #include "zeek/Timer.h" -#include "zeek/zeek-config.h" - #include "zeek/Desc.h" #include "zeek/NetVar.h" #include "zeek/RunState.h" #include "zeek/broker/Manager.h" #include "zeek/iosource/Manager.h" -#include "zeek/iosource/PktSrc.h" #include "zeek/util.h" namespace zeek::detail { diff --git a/src/telemetry/Counter.cc b/src/telemetry/Counter.cc index 8b34624254..889a17f1a7 100644 --- a/src/telemetry/Counter.cc +++ b/src/telemetry/Counter.cc @@ -2,27 +2,17 @@ using namespace zeek::telemetry; -Counter::Counter(FamilyType* family, const prometheus::Labels& labels, prometheus::CollectCallbackPtr callback) noexcept - : handle(family->Add(labels)), labels(labels) { - if ( callback ) { - handle.AddCollectCallback(std::move(callback)); - has_callback = true; - } -} +Counter::Counter(FamilyType* family, const prometheus::Labels& labels, detail::CollectCallbackPtr callback) noexcept + : family(family), handle(family->Add(labels)), labels(labels), callback(std::move(callback)) {} double Counter::Value() const noexcept { - if ( has_callback ) { - // Use Collect() here instead of Value() to correctly handle metrics with - // callbacks. - auto metric = handle.Collect(); - return metric.counter.value; - } + if ( callback ) + return callback(); return handle.Value(); } -std::shared_ptr CounterFamily::GetOrAdd(Span labels, - prometheus::CollectCallbackPtr callback) { +std::shared_ptr CounterFamily::GetOrAdd(Span labels, detail::CollectCallbackPtr callback) { prometheus::Labels p_labels = detail::BuildPrometheusLabels(labels); auto check = [&](const std::shared_ptr& counter) { return counter->CompareLabels(p_labels); }; @@ -36,6 +26,15 @@ std::shared_ptr CounterFamily::GetOrAdd(Span labels, } std::shared_ptr CounterFamily::GetOrAdd(std::initializer_list labels, - prometheus::CollectCallbackPtr callback) { + detail::CollectCallbackPtr callback) { return GetOrAdd(Span{labels.begin(), labels.size()}, std::move(callback)); } + +void CounterFamily::RunCallbacks() { + for ( auto& c : counters ) { + if ( c->HasCallback() ) { + double val = c->RunCallback(); + c->Set(val); + } + } +} diff --git a/src/telemetry/Counter.h b/src/telemetry/Counter.h index f6c49315b7..c9595c7709 100644 --- a/src/telemetry/Counter.h +++ b/src/telemetry/Counter.h @@ -4,7 +4,6 @@ #include #include -#include #include #include @@ -15,6 +14,12 @@ namespace zeek::telemetry { +namespace detail { +using CollectCallbackPtr = std::function; +} + +class CounterFamily; + /** * A handle to a metric that can only go up. */ @@ -26,7 +31,7 @@ public: using FamilyType = prometheus::Family; explicit Counter(FamilyType* family, const prometheus::Labels& labels, - prometheus::CollectCallbackPtr callback = nullptr) noexcept; + detail::CollectCallbackPtr callback = nullptr) noexcept; /** * Increments the value by 1. @@ -55,10 +60,21 @@ public: bool CompareLabels(const prometheus::Labels& lbls) const { return labels == lbls; } + bool HasCallback() const noexcept { return callback != nullptr; } + double RunCallback() const { return callback(); } + private: + friend class CounterFamily; + void Set(double val) { + // Counter has no Set(), but we can fake it. + handle.Reset(); + handle.Increment(val); + } + + FamilyType* family = nullptr; Handle& handle; prometheus::Labels labels; - bool has_callback = false; + detail::CollectCallbackPtr callback; }; using CounterPtr = std::shared_ptr; @@ -74,15 +90,17 @@ public: * Returns the metrics handle for given labels, creating a new instance * lazily if necessary. */ - CounterPtr GetOrAdd(Span labels, prometheus::CollectCallbackPtr callback = nullptr); + CounterPtr GetOrAdd(Span labels, detail::CollectCallbackPtr callback = nullptr); /** * @copydoc GetOrAdd */ - CounterPtr GetOrAdd(std::initializer_list labels, prometheus::CollectCallbackPtr callback = nullptr); + CounterPtr GetOrAdd(std::initializer_list labels, detail::CollectCallbackPtr callback = nullptr); zeek_int_t MetricType() const noexcept override { return BifEnum::Telemetry::MetricType::COUNTER; } + void RunCallbacks() override; + private: prometheus::Family* family; std::vector counters; diff --git a/src/telemetry/Gauge.cc b/src/telemetry/Gauge.cc index 273c9a57bf..79550c8128 100644 --- a/src/telemetry/Gauge.cc +++ b/src/telemetry/Gauge.cc @@ -3,26 +3,16 @@ using namespace zeek::telemetry; double Gauge::Value() const noexcept { - if ( has_callback ) { - // Use Collect() here instead of Value() to correctly handle metrics - // with callbacks. - auto metric = handle.Collect(); - return metric.gauge.value; - } + if ( callback ) + return callback(); return handle.Value(); } +Gauge::Gauge(FamilyType* family, const prometheus::Labels& labels, detail::CollectCallbackPtr callback) noexcept + : family(family), handle(family->Add(labels)), labels(labels), callback(std::move(callback)) {} -Gauge::Gauge(FamilyType* family, const prometheus::Labels& labels, prometheus::CollectCallbackPtr callback) noexcept - : handle(family->Add(labels)), labels(labels) { - if ( callback ) { - handle.AddCollectCallback(std::move(callback)); - has_callback = true; - } -} - -std::shared_ptr GaugeFamily::GetOrAdd(Span labels, prometheus::CollectCallbackPtr callback) { +std::shared_ptr GaugeFamily::GetOrAdd(Span labels, detail::CollectCallbackPtr callback) { prometheus::Labels p_labels = detail::BuildPrometheusLabels(labels); auto check = [&](const std::shared_ptr& gauge) { return gauge->CompareLabels(p_labels); }; @@ -36,6 +26,13 @@ std::shared_ptr GaugeFamily::GetOrAdd(Span labels, prome } std::shared_ptr GaugeFamily::GetOrAdd(std::initializer_list labels, - prometheus::CollectCallbackPtr callback) { + detail::CollectCallbackPtr callback) { return GetOrAdd(Span{labels.begin(), labels.size()}, std::move(callback)); } + +void GaugeFamily::RunCallbacks() { + for ( const auto& g : gauges ) { + if ( g->HasCallback() ) + g->Set(g->RunCallback()); + } +} diff --git a/src/telemetry/Gauge.h b/src/telemetry/Gauge.h index 900cb7b784..22b0e4a0aa 100644 --- a/src/telemetry/Gauge.h +++ b/src/telemetry/Gauge.h @@ -4,7 +4,7 @@ #include #include -#include +#include #include #include @@ -15,6 +15,10 @@ namespace zeek::telemetry { +namespace detail { +using CollectCallbackPtr = std::function; +} + /** * A handle to a metric that can count up and down. */ @@ -26,7 +30,7 @@ public: using FamilyType = prometheus::Family; explicit Gauge(FamilyType* family, const prometheus::Labels& labels, - prometheus::CollectCallbackPtr callback = nullptr) noexcept; + detail::CollectCallbackPtr callback = nullptr) noexcept; /** * Increments the value by 1. @@ -57,6 +61,11 @@ public: */ void Dec(double amount) noexcept { handle.Decrement(amount); } + /** + * Set the value by @p val. + */ + void Set(double val) noexcept { handle.Set(val); } + /** * Decrements the value by 1. * @return The new value. @@ -73,10 +82,14 @@ public: bool CompareLabels(const prometheus::Labels& lbls) const { return labels == lbls; } + bool HasCallback() const noexcept { return callback != nullptr; } + double RunCallback() const { return callback(); } + private: + FamilyType* family = nullptr; Handle& handle; prometheus::Labels labels; - bool has_callback = false; + detail::CollectCallbackPtr callback; }; using GaugePtr = std::shared_ptr; @@ -89,18 +102,20 @@ public: * Returns the metrics handle for given labels, creating a new instance * lazily if necessary. */ - GaugePtr GetOrAdd(Span labels, prometheus::CollectCallbackPtr callback = nullptr); + GaugePtr GetOrAdd(Span labels, detail::CollectCallbackPtr callback = nullptr); /** * @copydoc GetOrAdd */ - GaugePtr GetOrAdd(std::initializer_list labels, prometheus::CollectCallbackPtr callback = nullptr); + GaugePtr GetOrAdd(std::initializer_list labels, detail::CollectCallbackPtr callback = nullptr); zeek_int_t MetricType() const noexcept override { return BifEnum::Telemetry::MetricType::GAUGE; } GaugeFamily(prometheus::Family* family, Span labels) : MetricFamily(labels), family(family) {} + void RunCallbacks() override; + private: prometheus::Family* family; std::vector gauges; diff --git a/src/telemetry/Histogram.h b/src/telemetry/Histogram.h index ec8858e463..b2131b40c8 100644 --- a/src/telemetry/Histogram.h +++ b/src/telemetry/Histogram.h @@ -66,6 +66,8 @@ public: zeek_int_t MetricType() const noexcept override { return BifEnum::Telemetry::MetricType::HISTOGRAM; } + void RunCallbacks() override {} + private: prometheus::Family* family; prometheus::Histogram::BucketBoundaries boundaries; diff --git a/src/telemetry/Manager.cc b/src/telemetry/Manager.cc index 6ae4e06ec6..c8650476d6 100644 --- a/src/telemetry/Manager.cc +++ b/src/telemetry/Manager.cc @@ -122,36 +122,16 @@ void Manager::InitPostScript() { return &this->current_process_stats; }; rss_gauge = GaugeInstance("process", "resident_memory", {}, "Resident memory size", "bytes", - []() -> prometheus::ClientMetric { - auto* s = get_stats(); - prometheus::ClientMetric metric; - metric.gauge.value = static_cast(s->rss); - return metric; - }); + []() { return static_cast(get_stats()->rss); }); vms_gauge = GaugeInstance("process", "virtual_memory", {}, "Virtual memory size", "bytes", - []() -> prometheus::ClientMetric { - auto* s = get_stats(); - prometheus::ClientMetric metric; - metric.gauge.value = static_cast(s->vms); - return metric; - }); + []() { return static_cast(get_stats()->vms); }); cpu_gauge = GaugeInstance("process", "cpu", {}, "Total user and system CPU time spent", "seconds", - []() -> prometheus::ClientMetric { - auto* s = get_stats(); - prometheus::ClientMetric metric; - metric.gauge.value = s->cpu; - return metric; - }); + []() { return get_stats()->cpu; }); fds_gauge = GaugeInstance("process", "open_fds", {}, "Number of open file descriptors", "", - []() -> prometheus::ClientMetric { - auto* s = get_stats(); - prometheus::ClientMetric metric; - metric.gauge.value = static_cast(s->fds); - return metric; - }); + []() { return static_cast(get_stats()->fds); }); #endif iosource_mgr->RegisterFd(collector_flare.FD(), this); @@ -491,7 +471,7 @@ CounterFamilyPtr Manager::CounterFamily(std::string_view prefix, std::string_vie CounterPtr Manager::CounterInstance(std::string_view prefix, std::string_view name, Span labels, std::string_view helptext, std::string_view unit, - prometheus::CollectCallbackPtr callback) { + detail::CollectCallbackPtr callback) { return WithLabelNames(labels, [&, this](auto labelNames) { auto family = CounterFamily(prefix, name, labelNames, helptext, unit); return family->GetOrAdd(labels, callback); @@ -500,7 +480,7 @@ CounterPtr Manager::CounterInstance(std::string_view prefix, std::string_view na CounterPtr Manager::CounterInstance(std::string_view prefix, std::string_view name, std::initializer_list labels, std::string_view helptext, - std::string_view unit, prometheus::CollectCallbackPtr callback) { + std::string_view unit, detail::CollectCallbackPtr callback) { auto lbl_span = Span{labels.begin(), labels.size()}; return CounterInstance(prefix, name, lbl_span, helptext, unit, std::move(callback)); } @@ -529,8 +509,7 @@ GaugeFamilyPtr Manager::GaugeFamily(std::string_view prefix, std::string_view na } GaugePtr Manager::GaugeInstance(std::string_view prefix, std::string_view name, Span labels, - std::string_view helptext, std::string_view unit, - prometheus::CollectCallbackPtr callback) { + std::string_view helptext, std::string_view unit, detail::CollectCallbackPtr callback) { return WithLabelNames(labels, [&, this](auto labelNames) { auto family = GaugeFamily(prefix, name, labelNames, helptext, unit); return family->GetOrAdd(labels, callback); @@ -538,8 +517,7 @@ GaugePtr Manager::GaugeInstance(std::string_view prefix, std::string_view name, } GaugePtr Manager::GaugeInstance(std::string_view prefix, std::string_view name, std::initializer_list labels, - std::string_view helptext, std::string_view unit, - prometheus::CollectCallbackPtr callback) { + std::string_view helptext, std::string_view unit, detail::CollectCallbackPtr callback) { auto lbl_span = Span{labels.begin(), labels.size()}; return GaugeInstance(prefix, name, lbl_span, helptext, unit, std::move(callback)); } @@ -588,7 +566,9 @@ void Manager::ProcessFd(int fd, int flags) { collector_flare.Extinguish(); - prometheus_registry->UpdateViaCallbacks(); + for ( const auto& [name, f] : families ) + f->RunCallbacks(); + collector_response_idx = collector_request_idx; lk.unlock(); diff --git a/src/telemetry/Manager.h b/src/telemetry/Manager.h index d967fe43c0..476589642e 100644 --- a/src/telemetry/Manager.h +++ b/src/telemetry/Manager.h @@ -31,6 +31,10 @@ class Registry; namespace zeek::telemetry { +namespace detail { +using CollectCallbackPtr = std::function; +} + class ZeekCollectable; /** @@ -98,12 +102,12 @@ public: */ CounterPtr CounterInstance(std::string_view prefix, std::string_view name, Span labels, std::string_view helptext, std::string_view unit = "", - prometheus::CollectCallbackPtr callback = nullptr); + detail::CollectCallbackPtr callback = nullptr); /// @copydoc counterInstance CounterPtr CounterInstance(std::string_view prefix, std::string_view name, std::initializer_list labels, std::string_view helptext, std::string_view unit = "", - prometheus::CollectCallbackPtr callback = nullptr); + detail::CollectCallbackPtr callback = nullptr); /** * @return A gauge metric family. Creates the family lazily if necessary. @@ -134,12 +138,12 @@ public: */ GaugePtr GaugeInstance(std::string_view prefix, std::string_view name, Span labels, std::string_view helptext, std::string_view unit = "", - prometheus::CollectCallbackPtr callback = nullptr); + detail::CollectCallbackPtr callback = nullptr); /// @copydoc GaugeInstance GaugePtr GaugeInstance(std::string_view prefix, std::string_view name, std::initializer_list labels, std::string_view helptext, std::string_view unit = "", - prometheus::CollectCallbackPtr callback = nullptr); + detail::CollectCallbackPtr callback = nullptr); // Forces the compiler to use the type `Span` instead of trying to // match parameters to a `span`. diff --git a/src/telemetry/MetricFamily.h b/src/telemetry/MetricFamily.h index 942932566e..e10ac608e0 100644 --- a/src/telemetry/MetricFamily.h +++ b/src/telemetry/MetricFamily.h @@ -22,6 +22,8 @@ public: std::vector LabelNames() const { return label_names; } + virtual void RunCallbacks() = 0; + protected: MetricFamily(Span labels) { for ( const auto& lbl : labels ) diff --git a/src/telemetry/Utils.h b/src/telemetry/Utils.h index 8eb0f98d99..77489fc260 100644 --- a/src/telemetry/Utils.h +++ b/src/telemetry/Utils.h @@ -5,7 +5,6 @@ #include #include "zeek/Span.h" -#include "zeek/Val.h" namespace zeek::telemetry { From 40db8463dfcfa790d112752961217c21d74e5edb Mon Sep 17 00:00:00 2001 From: Johanna Amann Date: Thu, 12 Sep 2024 08:52:02 +0200 Subject: [PATCH 46/91] Merge remote-tracking branch 'origin/topic/timw/remove-negative-timestamp-test' * origin/topic/timw/remove-negative-timestamp-test: Remove core.negative-time btest (cherry picked from commit 899f7297d7b8c83ef2640e7cf40d3f230e42cc6b) --- CHANGES | 44 ++++++++++++++++++ VERSION | 2 +- .../Baseline/core.negative-time/weird.log | 11 ----- testing/btest/Traces/negative-time.pcap | Bin 260 -> 0 bytes testing/btest/core/negative-time.test | 2 - 5 files changed, 45 insertions(+), 14 deletions(-) delete mode 100644 testing/btest/Baseline/core.negative-time/weird.log delete mode 100644 testing/btest/Traces/negative-time.pcap delete mode 100644 testing/btest/core/negative-time.test diff --git a/CHANGES b/CHANGES index a124a7824b..0e32b999ec 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,47 @@ +7.0.1-6 | 2024-09-23 10:01:55 -0700 + + * Remove core.negative-time btest (Tim Wojtulewicz, Corelight) + + This test is failing with libpcap libpcap 1.10.5; for more information + see https://github.com/zeek/zeek/issues/3921 + + (cherry picked from commit 899f7297d7b8c83ef2640e7cf40d3f230e42cc6b) + + * Update broker submodule (Arne Welzel, Corelight) + + ...to pin prometheus to 1.2.4 + + (cherry picked from commit f24bc1ee882b3b266ca9dc325a1b5584addb155e) + + * telemetry: Move callbacks to Zeek (Arne Welzel, Corelight) + + Now that we run callbacks on the main loop, we can move callback support + for Counter and Gauge instances directly into Zeek and don't need to patch + prometheus-cpp anymore. + + (cherry picked from commit f24bc1ee882b3b266ca9dc325a1b5584addb155e) + + * auxil/prometheus-cpp: Pin to 1.2.4 (Arne Welzel, Corelight) + + (cherry picked from commit f24bc1ee882b3b266ca9dc325a1b5584addb155e) + + * btest/ldap: Add regression test for #3919 (Arne Welzel, Corelight) + + This works as expected in master, it's just that we forgot to backport + PR #3845 to 7.0.1. Add the PCAP from Martin anyhow. + + (cherry picked from commit a339cfa4c007762c6fbb16a35576220851fe4a82) + + * GH-3853: ldap: Recognize SASL+SPNEGO+NTLMSSP (Arne Welzel, Corelight) + + The ctu-sme-11-win7ad-1-ldap-tcp-50041.pcap file was harvested + from the CTU-SME-11 (Experiment-VM-Microsoft-Windows7AD-1) dataset + at https://zenodo.org/records/7958259 (DOI 10.5281/zenodo.7958258). + + (cherry picked from commit 152bbbd680e6c329255dc28d57cd506e7d2c09ff) + + * Bump auxil/spicy to latest release (Benjamin Bannier, Corelight) + 7.0.1 | 2024-09-03 13:04:23 -0700 * Update CHANGES, VERSION, and NEWS for 7.0.1 release (Tim Wojtulewicz, Corelight) diff --git a/VERSION b/VERSION index 9fe9ff9d99..73e224f839 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -7.0.1 +7.0.1-6 diff --git a/testing/btest/Baseline/core.negative-time/weird.log b/testing/btest/Baseline/core.negative-time/weird.log deleted file mode 100644 index 49c7011a3b..0000000000 --- a/testing/btest/Baseline/core.negative-time/weird.log +++ /dev/null @@ -1,11 +0,0 @@ -### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. -#separator \x09 -#set_separator , -#empty_field (empty) -#unset_field - -#path weird -#open XXXX-XX-XX-XX-XX-XX -#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p name addl notice peer source -#types time string addr port addr port string string bool string string -XXXXXXXXXX.XXXXXX - - - - - negative_packet_timestamp - F zeek - -#close XXXX-XX-XX-XX-XX-XX diff --git a/testing/btest/Traces/negative-time.pcap b/testing/btest/Traces/negative-time.pcap deleted file mode 100644 index a216f1eb6ebf278c46a8a1ee6aa8d0af47d09b3b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 260 zcmca|c+)~A1{MYw`2U}Qff2}Q=>HVLXU)bC0Az#kiR+R@vhp!MEv5$Na4@(sFgUdw zVqkC(EMPdWf@wMsGoF~mV9KEPpni}MK)`4Lf$W)ix``<%MJ$O$1&Is{JPeFL z^H;BRVPmKPssdq%$q-w>=H~%T2b#ZS8pv#r9So*G8=}4yFWS}E05l(L18(yV@PKS# mU Date: Mon, 23 Sep 2024 10:59:51 -0700 Subject: [PATCH 47/91] Merge remote-tracking branch 'origin/topic/awelzel/3936-pop3-and-redis' * origin/topic/awelzel/3936-pop3-and-redis: pop3: Remove unused headers pop3: Prevent unbounded state growth btest/pop3: Add somewhat more elaborate testing (cherry picked from commit 702fb031a4ea2b00364d6a7321384a45551ce3a2) --- scripts/base/init-bare.zeek | 16 ++++++ src/analyzer/protocol/pop3/CMakeLists.txt | 1 + src/analyzer/protocol/pop3/POP3.cc | 37 ++++++++++++-- src/analyzer/protocol/pop3/POP3.h | 3 +- src/analyzer/protocol/pop3/consts.bif | 2 + .../core.max-analyzer-violations/weird.log | 2 +- .../canonified_loaded_scripts.log | 1 + .../canonified_loaded_scripts.log | 1 + testing/btest/Baseline/plugins.hooks/output | 6 +++ .../conn.log | 21 ++++++++ .../scripts.base.protocols.pop3.basic/out | 48 ++++++++++++++++++ .../analyzer.log | 16 ++++++ .../conn.log | 11 ++++ .../scripts.base.protocols.pop3.redis/out | 4 ++ .../weird.log | 12 +++++ testing/btest/Traces/README | 3 ++ testing/btest/Traces/pop3/pop3.pcap | Bin 0 -> 29993 bytes testing/btest/Traces/pop3/redis-50-pings.pcap | Bin 0 -> 10770 bytes .../scripts/base/protocols/pop3/basic.zeek | 20 ++++++++ .../scripts/base/protocols/pop3/redis.zeek | 20 ++++++++ 20 files changed, 217 insertions(+), 7 deletions(-) create mode 100644 src/analyzer/protocol/pop3/consts.bif create mode 100644 testing/btest/Baseline/scripts.base.protocols.pop3.basic/conn.log create mode 100644 testing/btest/Baseline/scripts.base.protocols.pop3.basic/out create mode 100644 testing/btest/Baseline/scripts.base.protocols.pop3.redis/analyzer.log create mode 100644 testing/btest/Baseline/scripts.base.protocols.pop3.redis/conn.log create mode 100644 testing/btest/Baseline/scripts.base.protocols.pop3.redis/out create mode 100644 testing/btest/Baseline/scripts.base.protocols.pop3.redis/weird.log create mode 100644 testing/btest/Traces/pop3/pop3.pcap create mode 100644 testing/btest/Traces/pop3/redis-50-pings.pcap create mode 100644 testing/btest/scripts/base/protocols/pop3/basic.zeek create mode 100644 testing/btest/scripts/base/protocols/pop3/redis.zeek diff --git a/scripts/base/init-bare.zeek b/scripts/base/init-bare.zeek index 85a1dc0f20..25746c1bea 100644 --- a/scripts/base/init-bare.zeek +++ b/scripts/base/init-bare.zeek @@ -2903,6 +2903,22 @@ export { } # end export +module POP3; + +export { + ## How many commands a POP3 client may have pending + ## before Zeek forcefully removes the oldest. + ## + ## Setting this value to 0 removes the limit. + const max_pending_commands = 10 &redef; + + ## How many invalid commands a POP3 client may use + ## before Zeek starts raising analyzer violations. + ## + ## Setting this value to 0 removes the limit. + const max_unknown_client_commands = 10 &redef; + +} # end export module Threading; diff --git a/src/analyzer/protocol/pop3/CMakeLists.txt b/src/analyzer/protocol/pop3/CMakeLists.txt index f5283b17e4..11e0e43439 100644 --- a/src/analyzer/protocol/pop3/CMakeLists.txt +++ b/src/analyzer/protocol/pop3/CMakeLists.txt @@ -5,4 +5,5 @@ zeek_add_plugin( POP3.cc Plugin.cc BIFS + consts.bif events.bif) diff --git a/src/analyzer/protocol/pop3/POP3.cc b/src/analyzer/protocol/pop3/POP3.cc index ed3a8f2aa1..a65c8410ba 100644 --- a/src/analyzer/protocol/pop3/POP3.cc +++ b/src/analyzer/protocol/pop3/POP3.cc @@ -3,8 +3,6 @@ #include "zeek/analyzer/protocol/pop3/POP3.h" -#include "zeek/zeek-config.h" - #include #include #include @@ -12,6 +10,7 @@ #include "zeek/Base64.h" #include "zeek/Reporter.h" #include "zeek/analyzer/Manager.h" +#include "zeek/analyzer/protocol/pop3/consts.bif.h" #include "zeek/analyzer/protocol/pop3/events.bif.h" namespace zeek::analyzer::pop3 { @@ -41,6 +40,7 @@ POP3_Analyzer::POP3_Analyzer(Connection* conn) : analyzer::tcp::TCP_ApplicationA authLines = 0; mail = nullptr; + unknown_client_cmds = 0; cl_orig = new analyzer::tcp::ContentLine_Analyzer(conn, true); AddSupportAnalyzer(cl_orig); @@ -205,6 +205,21 @@ void POP3_Analyzer::ProcessRequest(int length, const char* line) { // keep a list of pending commands. cmds.emplace_back(line); + // Prevent unbounded state growth of cmds if there are no matching + // server replies by just processing commands even if we didn't see + // the server response. + // + // This may be caused by packet drops, one-sided traffic, analyzing + // the wrong protocol (Redis), etc. + if ( zeek::BifConst::POP3::max_pending_commands > 0 ) { + if ( cmds.size() > zeek::BifConst::POP3::max_pending_commands ) { + Weird("pop3_client_too_many_pending_commands"); + + ProcessClientCmd(); + cmds.pop_front(); + } + } + if ( cmds.size() == 1 ) // Not waiting for another server response, // so we can process it immediately. @@ -236,10 +251,19 @@ void POP3_Analyzer::ProcessClientCmd() { if ( cmd_code == -1 ) { if ( ! waitingForAuthentication ) { - Weird("pop3_client_command_unknown"); + Weird("pop3_client_command_unknown", (tokens.size() > 0 ? tokens[0].c_str() : "???")); if ( subState == detail::POP3_WOK ) subState = detail::POP3_OK; + + ++unknown_client_cmds; + + if ( zeek::BifConst::POP3::max_unknown_client_commands > 0 ) { + if ( unknown_client_cmds > zeek::BifConst::POP3::max_unknown_client_commands ) { + AnalyzerViolation("too many unknown client commands"); + } + } } + return; } @@ -299,6 +323,7 @@ void POP3_Analyzer::ProcessClientCmd() { if ( masterState == detail::POP3_AUTHORIZATION ) { POP3Event(pop3_request, true, cmd, message); if ( ! *message ) { + // This is the client requesting a list of AUTH mechanisms available. requestForMultiLine = true; state = detail::AUTH; subState = detail::POP3_WOK; @@ -555,9 +580,13 @@ void POP3_Analyzer::ProcessReply(int length, const char* line) { AnalyzerViolation(util::fmt("unknown server command (%s)", (tokens.size() > 0 ? tokens[0].c_str() : "???")), line, length); - Weird("pop3_server_command_unknown"); + Weird("pop3_server_command_unknown", (tokens.size() > 0 ? tokens[0].c_str() : "???")); if ( subState == detail::POP3_WOK ) subState = detail::POP3_OK; + + // If we're not in state AUTH and receive "some" response, + // assume it was for the last command from the client. + FinishClientCmd(); } return; } diff --git a/src/analyzer/protocol/pop3/POP3.h b/src/analyzer/protocol/pop3/POP3.h index 629387d402..697bc73183 100644 --- a/src/analyzer/protocol/pop3/POP3.h +++ b/src/analyzer/protocol/pop3/POP3.h @@ -4,11 +4,9 @@ #pragma once -#include #include #include -#include "zeek/analyzer/protocol/login/NVT.h" #include "zeek/analyzer/protocol/mime/MIME.h" #include "zeek/analyzer/protocol/tcp/ContentLine.h" #include "zeek/analyzer/protocol/tcp/TCP.h" @@ -106,6 +104,7 @@ protected: analyzer::mime::MIME_Mail* mail; std::list cmds; + zeek_uint_t unknown_client_cmds; private: bool tls; diff --git a/src/analyzer/protocol/pop3/consts.bif b/src/analyzer/protocol/pop3/consts.bif new file mode 100644 index 0000000000..29fcd14e3d --- /dev/null +++ b/src/analyzer/protocol/pop3/consts.bif @@ -0,0 +1,2 @@ +const POP3::max_pending_commands: count; +const POP3::max_unknown_client_commands: count; diff --git a/testing/btest/Baseline/core.max-analyzer-violations/weird.log b/testing/btest/Baseline/core.max-analyzer-violations/weird.log index 99b5e14621..8d0cb822e6 100644 --- a/testing/btest/Baseline/core.max-analyzer-violations/weird.log +++ b/testing/btest/Baseline/core.max-analyzer-violations/weird.log @@ -7,7 +7,7 @@ #open XXXX-XX-XX-XX-XX-XX #fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p name addl notice peer source #types time string addr port addr port string string bool string string -XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 58246 127.0.0.1 110 pop3_server_command_unknown - F zeek POP3 +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 58246 127.0.0.1 110 pop3_server_command_unknown + F zeek POP3 XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 58246 127.0.0.1 110 line_terminated_with_single_CR - F zeek CONTENTLINE XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 58246 127.0.0.1 110 too_many_analyzer_violations - F zeek POP3 #close XXXX-XX-XX-XX-XX-XX diff --git a/testing/btest/Baseline/coverage.bare-load-baseline/canonified_loaded_scripts.log b/testing/btest/Baseline/coverage.bare-load-baseline/canonified_loaded_scripts.log index 5466f0ea13..4601778fcb 100644 --- a/testing/btest/Baseline/coverage.bare-load-baseline/canonified_loaded_scripts.log +++ b/testing/btest/Baseline/coverage.bare-load-baseline/canonified_loaded_scripts.log @@ -192,6 +192,7 @@ scripts/base/init-frameworks-and-bifs.zeek build/scripts/base/bif/plugins/Zeek_NTLM.events.bif.zeek build/scripts/base/bif/plugins/Zeek_NTP.types.bif.zeek build/scripts/base/bif/plugins/Zeek_NTP.events.bif.zeek + build/scripts/base/bif/plugins/Zeek_POP3.consts.bif.zeek build/scripts/base/bif/plugins/Zeek_POP3.events.bif.zeek build/scripts/base/bif/plugins/Zeek_RADIUS.events.bif.zeek build/scripts/base/bif/plugins/Zeek_RDP.events.bif.zeek diff --git a/testing/btest/Baseline/coverage.default-load-baseline/canonified_loaded_scripts.log b/testing/btest/Baseline/coverage.default-load-baseline/canonified_loaded_scripts.log index 07dc32da6d..a499ccfd25 100644 --- a/testing/btest/Baseline/coverage.default-load-baseline/canonified_loaded_scripts.log +++ b/testing/btest/Baseline/coverage.default-load-baseline/canonified_loaded_scripts.log @@ -192,6 +192,7 @@ scripts/base/init-frameworks-and-bifs.zeek build/scripts/base/bif/plugins/Zeek_NTLM.events.bif.zeek build/scripts/base/bif/plugins/Zeek_NTP.types.bif.zeek build/scripts/base/bif/plugins/Zeek_NTP.events.bif.zeek + build/scripts/base/bif/plugins/Zeek_POP3.consts.bif.zeek build/scripts/base/bif/plugins/Zeek_POP3.events.bif.zeek build/scripts/base/bif/plugins/Zeek_RADIUS.events.bif.zeek build/scripts/base/bif/plugins/Zeek_RDP.events.bif.zeek diff --git a/testing/btest/Baseline/plugins.hooks/output b/testing/btest/Baseline/plugins.hooks/output index 2514d98015..bbdfa3720d 100644 --- a/testing/btest/Baseline/plugins.hooks/output +++ b/testing/btest/Baseline/plugins.hooks/output @@ -385,6 +385,7 @@ 0.000000 MetaHookPost LoadFile(0, ./Zeek_NetBIOS.functions.bif.zeek, <...>/Zeek_NetBIOS.functions.bif.zeek) -> -1 0.000000 MetaHookPost LoadFile(0, ./Zeek_NoneWriter.none.bif.zeek, <...>/Zeek_NoneWriter.none.bif.zeek) -> -1 0.000000 MetaHookPost LoadFile(0, ./Zeek_PE.events.bif.zeek, <...>/Zeek_PE.events.bif.zeek) -> -1 +0.000000 MetaHookPost LoadFile(0, ./Zeek_POP3.consts.bif.zeek, <...>/Zeek_POP3.consts.bif.zeek) -> -1 0.000000 MetaHookPost LoadFile(0, ./Zeek_POP3.events.bif.zeek, <...>/Zeek_POP3.events.bif.zeek) -> -1 0.000000 MetaHookPost LoadFile(0, ./Zeek_RADIUS.events.bif.zeek, <...>/Zeek_RADIUS.events.bif.zeek) -> -1 0.000000 MetaHookPost LoadFile(0, ./Zeek_RDP.events.bif.zeek, <...>/Zeek_RDP.events.bif.zeek) -> -1 @@ -680,6 +681,7 @@ 0.000000 MetaHookPost LoadFileExtended(0, ./Zeek_NetBIOS.functions.bif.zeek, <...>/Zeek_NetBIOS.functions.bif.zeek) -> (-1, ) 0.000000 MetaHookPost LoadFileExtended(0, ./Zeek_NoneWriter.none.bif.zeek, <...>/Zeek_NoneWriter.none.bif.zeek) -> (-1, ) 0.000000 MetaHookPost LoadFileExtended(0, ./Zeek_PE.events.bif.zeek, <...>/Zeek_PE.events.bif.zeek) -> (-1, ) +0.000000 MetaHookPost LoadFileExtended(0, ./Zeek_POP3.consts.bif.zeek, <...>/Zeek_POP3.consts.bif.zeek) -> (-1, ) 0.000000 MetaHookPost LoadFileExtended(0, ./Zeek_POP3.events.bif.zeek, <...>/Zeek_POP3.events.bif.zeek) -> (-1, ) 0.000000 MetaHookPost LoadFileExtended(0, ./Zeek_RADIUS.events.bif.zeek, <...>/Zeek_RADIUS.events.bif.zeek) -> (-1, ) 0.000000 MetaHookPost LoadFileExtended(0, ./Zeek_RDP.events.bif.zeek, <...>/Zeek_RDP.events.bif.zeek) -> (-1, ) @@ -1307,6 +1309,7 @@ 0.000000 MetaHookPre LoadFile(0, ./Zeek_NetBIOS.functions.bif.zeek, <...>/Zeek_NetBIOS.functions.bif.zeek) 0.000000 MetaHookPre LoadFile(0, ./Zeek_NoneWriter.none.bif.zeek, <...>/Zeek_NoneWriter.none.bif.zeek) 0.000000 MetaHookPre LoadFile(0, ./Zeek_PE.events.bif.zeek, <...>/Zeek_PE.events.bif.zeek) +0.000000 MetaHookPre LoadFile(0, ./Zeek_POP3.consts.bif.zeek, <...>/Zeek_POP3.consts.bif.zeek) 0.000000 MetaHookPre LoadFile(0, ./Zeek_POP3.events.bif.zeek, <...>/Zeek_POP3.events.bif.zeek) 0.000000 MetaHookPre LoadFile(0, ./Zeek_RADIUS.events.bif.zeek, <...>/Zeek_RADIUS.events.bif.zeek) 0.000000 MetaHookPre LoadFile(0, ./Zeek_RDP.events.bif.zeek, <...>/Zeek_RDP.events.bif.zeek) @@ -1602,6 +1605,7 @@ 0.000000 MetaHookPre LoadFileExtended(0, ./Zeek_NetBIOS.functions.bif.zeek, <...>/Zeek_NetBIOS.functions.bif.zeek) 0.000000 MetaHookPre LoadFileExtended(0, ./Zeek_NoneWriter.none.bif.zeek, <...>/Zeek_NoneWriter.none.bif.zeek) 0.000000 MetaHookPre LoadFileExtended(0, ./Zeek_PE.events.bif.zeek, <...>/Zeek_PE.events.bif.zeek) +0.000000 MetaHookPre LoadFileExtended(0, ./Zeek_POP3.consts.bif.zeek, <...>/Zeek_POP3.consts.bif.zeek) 0.000000 MetaHookPre LoadFileExtended(0, ./Zeek_POP3.events.bif.zeek, <...>/Zeek_POP3.events.bif.zeek) 0.000000 MetaHookPre LoadFileExtended(0, ./Zeek_RADIUS.events.bif.zeek, <...>/Zeek_RADIUS.events.bif.zeek) 0.000000 MetaHookPre LoadFileExtended(0, ./Zeek_RDP.events.bif.zeek, <...>/Zeek_RDP.events.bif.zeek) @@ -2228,6 +2232,7 @@ 0.000000 | HookLoadFile ./Zeek_NetBIOS.functions.bif.zeek <...>/Zeek_NetBIOS.functions.bif.zeek 0.000000 | HookLoadFile ./Zeek_NoneWriter.none.bif.zeek <...>/Zeek_NoneWriter.none.bif.zeek 0.000000 | HookLoadFile ./Zeek_PE.events.bif.zeek <...>/Zeek_PE.events.bif.zeek +0.000000 | HookLoadFile ./Zeek_POP3.consts.bif.zeek <...>/Zeek_POP3.consts.bif.zeek 0.000000 | HookLoadFile ./Zeek_POP3.events.bif.zeek <...>/Zeek_POP3.events.bif.zeek 0.000000 | HookLoadFile ./Zeek_RADIUS.events.bif.zeek <...>/Zeek_RADIUS.events.bif.zeek 0.000000 | HookLoadFile ./Zeek_RDP.events.bif.zeek <...>/Zeek_RDP.events.bif.zeek @@ -2523,6 +2528,7 @@ 0.000000 | HookLoadFileExtended ./Zeek_NetBIOS.functions.bif.zeek <...>/Zeek_NetBIOS.functions.bif.zeek 0.000000 | HookLoadFileExtended ./Zeek_NoneWriter.none.bif.zeek <...>/Zeek_NoneWriter.none.bif.zeek 0.000000 | HookLoadFileExtended ./Zeek_PE.events.bif.zeek <...>/Zeek_PE.events.bif.zeek +0.000000 | HookLoadFileExtended ./Zeek_POP3.consts.bif.zeek <...>/Zeek_POP3.consts.bif.zeek 0.000000 | HookLoadFileExtended ./Zeek_POP3.events.bif.zeek <...>/Zeek_POP3.events.bif.zeek 0.000000 | HookLoadFileExtended ./Zeek_RADIUS.events.bif.zeek <...>/Zeek_RADIUS.events.bif.zeek 0.000000 | HookLoadFileExtended ./Zeek_RDP.events.bif.zeek <...>/Zeek_RDP.events.bif.zeek diff --git a/testing/btest/Baseline/scripts.base.protocols.pop3.basic/conn.log b/testing/btest/Baseline/scripts.base.protocols.pop3.basic/conn.log new file mode 100644 index 0000000000..d123788c75 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.pop3.basic/conn.log @@ -0,0 +1,21 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path conn +#open XXXX-XX-XX-XX-XX-XX +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p proto service duration orig_bytes resp_bytes conn_state local_orig local_resp missed_bytes history orig_pkts orig_ip_bytes resp_pkts resp_ip_bytes tunnel_parents +#types time string addr port addr port enum string interval count count string bool bool count string count count count count set[string] +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 192.168.0.4 26242 212.227.15.188 110 tcp - 0.050692 0 0 REJ T F 0 Sr 1 52 1 40 - +XXXXXXXXXX.XXXXXX ClEkJM2Vm5giqnMf4h 192.168.0.4 26242 212.227.15.188 110 tcp - 0.060847 0 0 REJ T F 0 Sr 1 52 1 40 - +XXXXXXXXXX.XXXXXX C4J4Th3PJpwUYZZ6gc 192.168.0.4 26245 212.227.15.171 110 tcp - 0.050705 0 0 REJ T F 0 Sr 1 52 1 40 - +XXXXXXXXXX.XXXXXX CtPZjS20MLrsMUOJi2 192.168.0.4 26245 212.227.15.171 110 tcp - 0.050062 0 0 REJ T F 0 Sr 1 52 1 40 - +XXXXXXXXXX.XXXXXX CUM0KZ3MLUfNB0cl11 192.168.0.4 26242 212.227.15.188 110 tcp - 0.050967 0 0 REJ T F 0 Sr 1 48 1 40 - +XXXXXXXXXX.XXXXXX CmES5u32sYpV7JYN 192.168.0.4 26245 212.227.15.171 110 tcp - 0.047718 0 0 REJ T F 0 Sr 1 48 1 40 - +XXXXXXXXXX.XXXXXX CP5puj4I8PtEU4qzYg 192.168.0.4 26272 212.227.15.166 110 tcp pop3 0.163506 12 175 SF T F 0 ShAdDafF 6 264 6 427 - +XXXXXXXXXX.XXXXXX C37jN32gN3y3AZzyf6 192.168.0.4 26284 212.227.15.166 110 tcp pop3 3.469839 86 205 SF T F 0 ShAdDafF 9 470 9 577 - +XXXXXXXXXX.XXXXXX C3eiCBGOLw3VtHfOj 192.168.0.4 26304 212.227.15.166 110 tcp pop3 0.206558 12 175 SF T F 0 ShAdDafF 6 264 6 427 - +XXXXXXXXXX.XXXXXX CwjjYJ2WqgTbAqiHl6 192.168.0.4 26308 212.227.15.166 110 tcp pop3 0.537230 96 297 SF T F 0 ShAdDafF 9 468 10 709 - +XXXXXXXXXX.XXXXXX C0LAHyvtKSQHyJxIl 192.168.0.4 26383 212.227.15.166 110 tcp pop3 1.213485 138 19651 SF T F 0 ShAdDafF 22 1030 30 20863 - +#close XXXX-XX-XX-XX-XX-XX diff --git a/testing/btest/Baseline/scripts.base.protocols.pop3.basic/out b/testing/btest/Baseline/scripts.base.protocols.pop3.basic/out new file mode 100644 index 0000000000..199ebac41b --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.pop3.basic/out @@ -0,0 +1,48 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +CP5puj4I8PtEU4qzYg, pop3_reply, F, OK, POP server ready H mimap4 0MHoUr-1VDxRD3Ui5-003eq2 +CP5puj4I8PtEU4qzYg, pop3_request, T, CAPA, +CP5puj4I8PtEU4qzYg, pop3_reply, F, OK, Capability list follows +CP5puj4I8PtEU4qzYg, pop3_request, T, QUIT, +CP5puj4I8PtEU4qzYg, pop3_reply, F, OK, POP server signing off +C37jN32gN3y3AZzyf6, pop3_reply, F, OK, POP server ready H mimap8 0MHXFQ-1VDgSF1308-003NYq +C37jN32gN3y3AZzyf6, pop3_request, T, AUTH, +C37jN32gN3y3AZzyf6, pop3_reply, F, ERR, 1 argument required +C37jN32gN3y3AZzyf6, pop3_request, T, CAPA, +C37jN32gN3y3AZzyf6, pop3_reply, F, OK, Capability list follows +C37jN32gN3y3AZzyf6, pop3_request, T, AUTH, PLAIN +C37jN32gN3y3AZzyf6, pop3_reply, F, ERR, authentication failed +C3eiCBGOLw3VtHfOj, pop3_reply, F, OK, POP server ready H mimap9 0MK0or-1VBlin3ixZ-001RVN +C3eiCBGOLw3VtHfOj, pop3_request, T, CAPA, +C3eiCBGOLw3VtHfOj, pop3_reply, F, OK, Capability list follows +C3eiCBGOLw3VtHfOj, pop3_request, T, QUIT, +C3eiCBGOLw3VtHfOj, pop3_reply, F, OK, POP server signing off +CwjjYJ2WqgTbAqiHl6, pop3_reply, F, OK, POP server ready H mimap13 0MW5rZ-1VayeZ2jFp-00XVZd +CwjjYJ2WqgTbAqiHl6, pop3_request, T, AUTH, +CwjjYJ2WqgTbAqiHl6, pop3_reply, F, ERR, 1 argument required +CwjjYJ2WqgTbAqiHl6, pop3_request, T, CAPA, +CwjjYJ2WqgTbAqiHl6, pop3_reply, F, OK, Capability list follows +CwjjYJ2WqgTbAqiHl6, pop3_request, T, AUTH, PLAIN +CwjjYJ2WqgTbAqiHl6, pop3_reply, F, OK, mailbox "digitalinvestigator@networksims.com" has 3 messages (19191 octets) H mimap13 +CwjjYJ2WqgTbAqiHl6, pop3_request, T, QUIT, +CwjjYJ2WqgTbAqiHl6, pop3_reply, F, OK, POP server signing off +C0LAHyvtKSQHyJxIl, pop3_reply, F, OK, POP server ready H mimap15 0LfD5x-1VsVU4327M-00pHSn +C0LAHyvtKSQHyJxIl, pop3_request, T, AUTH, +C0LAHyvtKSQHyJxIl, pop3_reply, F, ERR, 1 argument required +C0LAHyvtKSQHyJxIl, pop3_request, T, CAPA, +C0LAHyvtKSQHyJxIl, pop3_reply, F, OK, Capability list follows +C0LAHyvtKSQHyJxIl, pop3_request, T, AUTH, PLAIN +C0LAHyvtKSQHyJxIl, pop3_reply, F, OK, mailbox "digitalinvestigator@networksims.com" has 3 messages (19191 octets) H mimap15 +C0LAHyvtKSQHyJxIl, pop3_request, T, STAT, +C0LAHyvtKSQHyJxIl, pop3_reply, F, OK, 3 19191 +C0LAHyvtKSQHyJxIl, pop3_request, T, LIST, +C0LAHyvtKSQHyJxIl, pop3_reply, F, OK, +C0LAHyvtKSQHyJxIl, pop3_request, T, UIDL, +C0LAHyvtKSQHyJxIl, pop3_reply, F, OK, +C0LAHyvtKSQHyJxIl, pop3_request, T, RETR, 1 +C0LAHyvtKSQHyJxIl, pop3_reply, F, OK, +C0LAHyvtKSQHyJxIl, pop3_request, T, RETR, 2 +C0LAHyvtKSQHyJxIl, pop3_reply, F, OK, +C0LAHyvtKSQHyJxIl, pop3_request, T, RETR, 3 +C0LAHyvtKSQHyJxIl, pop3_reply, F, OK, +C0LAHyvtKSQHyJxIl, pop3_request, T, QUIT, +C0LAHyvtKSQHyJxIl, pop3_reply, F, OK, POP server signing off diff --git a/testing/btest/Baseline/scripts.base.protocols.pop3.redis/analyzer.log b/testing/btest/Baseline/scripts.base.protocols.pop3.redis/analyzer.log new file mode 100644 index 0000000000..3c1d391690 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.pop3.redis/analyzer.log @@ -0,0 +1,16 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path analyzer +#open XXXX-XX-XX-XX-XX-XX +#fields ts cause analyzer_kind analyzer_name uid fuid id.orig_h id.orig_p id.resp_h id.resp_p failure_reason failure_data +#types time string string string string string addr port addr port string string +XXXXXXXXXX.XXXXXX violation protocol POP3 CHhAvVGS1DHFjwGM9 - 127.0.0.1 59954 127.0.0.1 6379 too many unknown client commands - +XXXXXXXXXX.XXXXXX violation protocol POP3 CHhAvVGS1DHFjwGM9 - 127.0.0.1 59954 127.0.0.1 6379 too many unknown client commands - +XXXXXXXXXX.XXXXXX violation protocol POP3 CHhAvVGS1DHFjwGM9 - 127.0.0.1 59954 127.0.0.1 6379 too many unknown client commands - +XXXXXXXXXX.XXXXXX violation protocol POP3 CHhAvVGS1DHFjwGM9 - 127.0.0.1 59954 127.0.0.1 6379 too many unknown client commands - +XXXXXXXXXX.XXXXXX violation protocol POP3 CHhAvVGS1DHFjwGM9 - 127.0.0.1 59954 127.0.0.1 6379 too many unknown client commands - +XXXXXXXXXX.XXXXXX violation protocol POP3 CHhAvVGS1DHFjwGM9 - 127.0.0.1 59954 127.0.0.1 6379 too many unknown client commands - +#close XXXX-XX-XX-XX-XX-XX diff --git a/testing/btest/Baseline/scripts.base.protocols.pop3.redis/conn.log b/testing/btest/Baseline/scripts.base.protocols.pop3.redis/conn.log new file mode 100644 index 0000000000..deeefbdba5 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.pop3.redis/conn.log @@ -0,0 +1,11 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path conn +#open XXXX-XX-XX-XX-XX-XX +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p proto service duration orig_bytes resp_bytes conn_state local_orig local_resp missed_bytes history orig_pkts orig_ip_bytes resp_pkts resp_ip_bytes tunnel_parents +#types time string addr port addr port enum string interval count count string bool bool count string count count count count set[string] +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 59954 127.0.0.1 6379 tcp - 0.002030 848 370 SF T T 0 ShADadfF 58 3872 58 3394 - +#close XXXX-XX-XX-XX-XX-XX diff --git a/testing/btest/Baseline/scripts.base.protocols.pop3.redis/out b/testing/btest/Baseline/scripts.base.protocols.pop3.redis/out new file mode 100644 index 0000000000..de83d41ef3 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.pop3.redis/out @@ -0,0 +1,4 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +CHhAvVGS1DHFjwGM9, pop3_reply, F, OK, +CHhAvVGS1DHFjwGM9, pop3_request, T, AUTH, +CHhAvVGS1DHFjwGM9, pop3_reply, F, OK, diff --git a/testing/btest/Baseline/scripts.base.protocols.pop3.redis/weird.log b/testing/btest/Baseline/scripts.base.protocols.pop3.redis/weird.log new file mode 100644 index 0000000000..36a176032c --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.pop3.redis/weird.log @@ -0,0 +1,12 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path weird +#open XXXX-XX-XX-XX-XX-XX +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p name addl notice peer source +#types time string addr port addr port string string bool string string +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 59954 127.0.0.1 6379 pop3_client_command_unknown *2 F zeek POP3 +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 59954 127.0.0.1 6379 pop3_client_too_many_pending_commands - F zeek POP3 +#close XXXX-XX-XX-XX-XX-XX diff --git a/testing/btest/Traces/README b/testing/btest/Traces/README index 2dec7f683f..b097576d0d 100644 --- a/testing/btest/Traces/README +++ b/testing/btest/Traces/README @@ -23,3 +23,6 @@ Trace Index/Sources: https://zenodo.org/records/7958259 (DOI 10.5281/zenodo.7958258). - ldap/ldap_invalid_credentials.pcap Provided by Martin van Hensbergen in issue #3919. +- pop3/POP3.pcap: Picked up from POP tutorial on tranalyzer.com + https://tranalyzer.com/tutorial/pop + https://tranalyzer.com/download/data/pop3.pcap diff --git a/testing/btest/Traces/pop3/pop3.pcap b/testing/btest/Traces/pop3/pop3.pcap new file mode 100644 index 0000000000000000000000000000000000000000..856c498950b1c7d2bc0e4cdfc25d173aa0e9a64b GIT binary patch literal 29993 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 +# @TEST-EXEC: btest-diff conn.log +# @TEST-EXEC: btest-diff out +# @TEST-EXEC: test ! -f weird.log +# @TEST-EXEC: test ! -f analyzer.log + +@load base/frameworks/notice/weird +@load base/protocols/conn +@load base/protocols/pop3 + +event pop3_request(c: connection, is_orig: bool, cmd: string, arg: string) + { + print c$uid, "pop3_request", is_orig, cmd, arg; + } + +event pop3_reply(c: connection, is_orig: bool, cmd: string, arg: string) + { + print c$uid, "pop3_reply", is_orig, cmd, arg; + } diff --git a/testing/btest/scripts/base/protocols/pop3/redis.zeek b/testing/btest/scripts/base/protocols/pop3/redis.zeek new file mode 100644 index 0000000000..d19845aae2 --- /dev/null +++ b/testing/btest/scripts/base/protocols/pop3/redis.zeek @@ -0,0 +1,20 @@ +# @TEST-DOC: The POP3 signature triggered on Redis traffic. Ensure the analyzer is eventually removed to avoid. +# @TEST-EXEC: zeek -C -b -r $TRACES/pop3/redis-50-pings.pcap %INPUT >out +# @TEST-EXEC: btest-diff conn.log +# @TEST-EXEC: btest-diff out +# @TEST-EXEC: btest-diff weird.log +# @TEST-EXEC: btest-diff analyzer.log + +@load base/frameworks/notice/weird +@load base/protocols/conn +@load base/protocols/pop3 + +event pop3_request(c: connection, is_orig: bool, cmd: string, arg: string) + { + print c$uid, "pop3_request", is_orig, cmd, arg; + } + +event pop3_reply(c: connection, is_orig: bool, cmd: string, arg: string) + { + print c$uid, "pop3_reply", is_orig, cmd, arg; + } From 815001f2aad3f7ad0392f6523eecc6b35afe548b Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Mon, 23 Sep 2024 11:58:24 -0700 Subject: [PATCH 48/91] Update docs submodule [nomail] [skip ci] --- doc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc b/doc index 8039548924..fe0488a117 160000 --- a/doc +++ b/doc @@ -1 +1 @@ -Subproject commit 8039548924d13b991a7329691fef4c64b03d13fc +Subproject commit fe0488a117bdbbda85a0ab09343e06460a8a4921 From 270429bfeacbcc21eabe1a73f26707e68d418abf Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Mon, 23 Sep 2024 12:01:55 -0700 Subject: [PATCH 49/91] Update CHANGES, VERSION, and NEWS for 7.0.2 release --- CHANGES | 27 +++++++++++++++++++++++++++ NEWS | 17 +++++++++++++++++ VERSION | 2 +- 3 files changed, 45 insertions(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index 0e32b999ec..08701d4c64 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,30 @@ +7.0.2 | 2024-09-23 12:01:55 -0700 + + * pop3: Remove unused headers (Arne Welzel, Corelight) + + (cherry picked from commit 702fb031a4ea2b00364d6a7321384a45551ce3a2) + + * pop3: Prevent unbounded state growth (Arne Welzel, Corelight) + + The cmds list may grow unbounded due to the POP3 analyzer being in + multiLine mode after seeing `AUTH` in a Redis connection, but never + a `.` terminator. This can easily be provoked by the Redis ping + command. + + This adds two heuristics: 1) Forcefully process the oldest commands in + the cmds list and cap it at max_pending_commands. 2) Start raising + analyzer violations if the client has been using more than + max_unknown_client_commands commands (default 10). + + (cherry picked from commit 702fb031a4ea2b00364d6a7321384a45551ce3a2) + + * btest/pop3: Add somewhat more elaborate testing (Arne Welzel, Corelight) + + PCAP taken from here: https://tranalyzer.com/tutorial/pop and reference + added to Traces/README. + + (cherry picked from commit 702fb031a4ea2b00364d6a7321384a45551ce3a2) + 7.0.1-6 | 2024-09-23 10:01:55 -0700 * Remove core.negative-time btest (Tim Wojtulewicz, Corelight) diff --git a/NEWS b/NEWS index dd0c324b26..18a0fe49a3 100644 --- a/NEWS +++ b/NEWS @@ -3,6 +3,23 @@ This document summarizes the most important changes in the current Zeek release. For an exhaustive list of changes, see the ``CHANGES`` file (note that submodules, such as Broker, come with their own ``CHANGES``.) +Zeek 7.0.2 +========== + +This release fixes the following security issues: + +- The POP3 parser has been hardened to avoid unbounded state growth in the + face of one-sided traffic capture or when enabled for non-POP3 traffic. + Concretely, the Redis protocol's AUTH mechanism enables the POP3 analyzer + for such connections through DPD. + +This release fixes the following bugs: + +- Support for SASL+SPNEGO+NTLMSSP was added to the LDAP analyzer. + +- Telemetry callbacks are now handled via Zeek instead of depending on the + prometehus-cpp library to handle them. + Zeek 7.0.1 ========== diff --git a/VERSION b/VERSION index 73e224f839..a8907c025d 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -7.0.1-6 +7.0.2 From 0e4f2a2babfc9b9dada0d97255a20097f177dfe2 Mon Sep 17 00:00:00 2001 From: Benjamin Bannier Date: Wed, 2 Oct 2024 12:39:26 +0200 Subject: [PATCH 50/91] Bump auxil/spicy to latest release --- auxil/spicy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/auxil/spicy b/auxil/spicy index d923cc0bb5..31880e215f 160000 --- a/auxil/spicy +++ b/auxil/spicy @@ -1 +1 @@ -Subproject commit d923cc0bb5da8481a13fa6741c007f43c8fd08d5 +Subproject commit 31880e215ff6f85ad95507d7a760e81ae2e0999d From 121170a5de0d0adbd0a89e91cb1563e61408602b Mon Sep 17 00:00:00 2001 From: Benjamin Bannier Date: Fri, 27 Sep 2024 11:09:47 +0200 Subject: [PATCH 51/91] Merge remote-tracking branch 'origin/topic/bbannier/ci-opensuse-leap-ps-dep' (cherry picked from commit a27066e3fc58d70401359887fcf34bd0bb83d433) --- ci/opensuse-leap-15.5/Dockerfile | 1 + ci/opensuse-leap-15.6/Dockerfile | 1 + 2 files changed, 2 insertions(+) diff --git a/ci/opensuse-leap-15.5/Dockerfile b/ci/opensuse-leap-15.5/Dockerfile index be927da6c0..b59f445a2a 100644 --- a/ci/opensuse-leap-15.5/Dockerfile +++ b/ci/opensuse-leap-15.5/Dockerfile @@ -21,6 +21,7 @@ RUN zypper addrepo https://download.opensuse.org/repositories/openSUSE:Leap:15.5 libpcap-devel \ make \ openssh \ + procps \ python311 \ python311-devel \ python311-pip \ diff --git a/ci/opensuse-leap-15.6/Dockerfile b/ci/opensuse-leap-15.6/Dockerfile index a2b94c91c8..359c282f01 100644 --- a/ci/opensuse-leap-15.6/Dockerfile +++ b/ci/opensuse-leap-15.6/Dockerfile @@ -21,6 +21,7 @@ RUN zypper addrepo https://download.opensuse.org/repositories/openSUSE:Leap:15.6 libpcap-devel \ make \ openssh \ + procps \ python312 \ python312-devel \ python312-pip \ From c988bd2e4d9a70087e54bb61d47286091a04a9a7 Mon Sep 17 00:00:00 2001 From: Christian Kreibich Date: Fri, 4 Oct 2024 10:28:13 -0700 Subject: [PATCH 52/91] Update docs submodule [nomail] [skip ci] --- CHANGES | 4 ++++ VERSION | 2 +- doc | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/CHANGES b/CHANGES index fb656b574c..aaeab45fb9 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,7 @@ +7.0.2-4 | 2024-10-04 10:28:13 -0700 + + * Update docs submodule [nomail] [skip ci] (Christian Kreibich, Corelight) + 7.0.2-3 | 2024-10-04 09:54:48 -0700 * Bump auxil/spicy to latest release (Benjamin Bannier, Corelight) diff --git a/VERSION b/VERSION index 09e1ff4b36..0f7e9dcaac 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -7.0.2-3 +7.0.2-4 diff --git a/doc b/doc index fe0488a117..c18d39be79 160000 --- a/doc +++ b/doc @@ -1 +1 @@ -Subproject commit fe0488a117bdbbda85a0ab09343e06460a8a4921 +Subproject commit c18d39be7969bc3662896e558af9a6730bbd76a8 From ea44c302721bc8d5a45c904bb5e9a4c393e3af7e Mon Sep 17 00:00:00 2001 From: Christian Kreibich Date: Fri, 4 Oct 2024 10:31:38 -0700 Subject: [PATCH 53/91] Merge remote-tracking branch 'security/topic/awelzel/215-pop3-mail-null-deref' * security/topic/awelzel/215-pop3-mail-null-deref: POP3: Rework unbounded pending command fix (cherry picked from commit 7fea32c6edc5d4d14646366f87c9208c8c9cf555) --- CHANGES | 9 +++++++++ VERSION | 2 +- src/analyzer/protocol/pop3/POP3.cc | 12 +++--------- .../analyzer.log | 11 +++++++++++ .../conn.log | 11 +++++++++++ .../weird.log | 11 +++++++++++ .../analyzer.log | 10 +++++----- .../scripts.base.protocols.pop3.redis/out | 2 +- .../scripts.base.protocols.pop3.redis/weird.log | 1 + .../btest/Traces/pop3/bad-list-retr-crafted.pcap | Bin 0 -> 3253 bytes .../protocols/pop3/bad-list-retr-crafted.zeek | 14 ++++++++++++++ .../btest/scripts/base/protocols/pop3/redis.zeek | 2 ++ 12 files changed, 69 insertions(+), 16 deletions(-) create mode 100644 testing/btest/Baseline/scripts.base.protocols.pop3.bad-list-retr-crafted/analyzer.log create mode 100644 testing/btest/Baseline/scripts.base.protocols.pop3.bad-list-retr-crafted/conn.log create mode 100644 testing/btest/Baseline/scripts.base.protocols.pop3.bad-list-retr-crafted/weird.log create mode 100644 testing/btest/Traces/pop3/bad-list-retr-crafted.pcap create mode 100644 testing/btest/scripts/base/protocols/pop3/bad-list-retr-crafted.zeek diff --git a/CHANGES b/CHANGES index aaeab45fb9..eba74fc287 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,12 @@ +7.0.2-5 | 2024-10-04 10:46:01 -0700 + + * Merge remote-tracking branch 'security/topic/awelzel/215-pop3-mail-null-deref' (Christian Kreibich, Corelight) + + * security/topic/awelzel/215-pop3-mail-null-deref: + POP3: Rework unbounded pending command fix + + (cherry picked from commit 7fea32c6edc5d4d14646366f87c9208c8c9cf555) + 7.0.2-4 | 2024-10-04 10:28:13 -0700 * Update docs submodule [nomail] [skip ci] (Christian Kreibich, Corelight) diff --git a/VERSION b/VERSION index 0f7e9dcaac..189fa8c988 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -7.0.2-4 +7.0.2-5 diff --git a/src/analyzer/protocol/pop3/POP3.cc b/src/analyzer/protocol/pop3/POP3.cc index a65c8410ba..fc11b4ca41 100644 --- a/src/analyzer/protocol/pop3/POP3.cc +++ b/src/analyzer/protocol/pop3/POP3.cc @@ -206,16 +206,14 @@ void POP3_Analyzer::ProcessRequest(int length, const char* line) { cmds.emplace_back(line); // Prevent unbounded state growth of cmds if there are no matching - // server replies by just processing commands even if we didn't see - // the server response. + // server replies by simply dropping the oldest command. // - // This may be caused by packet drops, one-sided traffic, analyzing - // the wrong protocol (Redis), etc. + // This may be caused by packet drops of the server side, one-sided + // traffic, or analyzing the wrong protocol (Redis), etc. if ( zeek::BifConst::POP3::max_pending_commands > 0 ) { if ( cmds.size() > zeek::BifConst::POP3::max_pending_commands ) { Weird("pop3_client_too_many_pending_commands"); - ProcessClientCmd(); cmds.pop_front(); } } @@ -583,10 +581,6 @@ void POP3_Analyzer::ProcessReply(int length, const char* line) { Weird("pop3_server_command_unknown", (tokens.size() > 0 ? tokens[0].c_str() : "???")); if ( subState == detail::POP3_WOK ) subState = detail::POP3_OK; - - // If we're not in state AUTH and receive "some" response, - // assume it was for the last command from the client. - FinishClientCmd(); } return; } diff --git a/testing/btest/Baseline/scripts.base.protocols.pop3.bad-list-retr-crafted/analyzer.log b/testing/btest/Baseline/scripts.base.protocols.pop3.bad-list-retr-crafted/analyzer.log new file mode 100644 index 0000000000..23f62ab8e7 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.pop3.bad-list-retr-crafted/analyzer.log @@ -0,0 +1,11 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path analyzer +#open XXXX-XX-XX-XX-XX-XX +#fields ts cause analyzer_kind analyzer_name uid fuid id.orig_h id.orig_p id.resp_h id.resp_p failure_reason failure_data +#types time string string string string string addr port addr port string string +XXXXXXXXXX.XXXXXX violation protocol POP3 CHhAvVGS1DHFjwGM9 - 127.0.0.1 58854 127.0.0.1 110 unknown server command (GARBAGE) GARBAGE (and LIST response missing .) +#close XXXX-XX-XX-XX-XX-XX diff --git a/testing/btest/Baseline/scripts.base.protocols.pop3.bad-list-retr-crafted/conn.log b/testing/btest/Baseline/scripts.base.protocols.pop3.bad-list-retr-crafted/conn.log new file mode 100644 index 0000000000..1ead1294bf --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.pop3.bad-list-retr-crafted/conn.log @@ -0,0 +1,11 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path conn +#open XXXX-XX-XX-XX-XX-XX +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p proto service duration orig_bytes resp_bytes conn_state local_orig local_resp missed_bytes history orig_pkts orig_ip_bytes resp_pkts resp_ip_bytes tunnel_parents +#types time string addr port addr port enum string interval count count string bool bool count string count count count count set[string] +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 58854 127.0.0.1 110 tcp - 0.151387 20 253 RSTO T T 0 ShAdDaFR 20 1056 16 1093 - +#close XXXX-XX-XX-XX-XX-XX diff --git a/testing/btest/Baseline/scripts.base.protocols.pop3.bad-list-retr-crafted/weird.log b/testing/btest/Baseline/scripts.base.protocols.pop3.bad-list-retr-crafted/weird.log new file mode 100644 index 0000000000..b661991b9e --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.pop3.bad-list-retr-crafted/weird.log @@ -0,0 +1,11 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path weird +#open XXXX-XX-XX-XX-XX-XX +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p name addl notice peer source +#types time string addr port addr port string string bool string string +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 58854 127.0.0.1 110 pop3_server_command_unknown GARBAGE F zeek POP3 +#close XXXX-XX-XX-XX-XX-XX diff --git a/testing/btest/Baseline/scripts.base.protocols.pop3.redis/analyzer.log b/testing/btest/Baseline/scripts.base.protocols.pop3.redis/analyzer.log index 3c1d391690..3f9f9ae848 100644 --- a/testing/btest/Baseline/scripts.base.protocols.pop3.redis/analyzer.log +++ b/testing/btest/Baseline/scripts.base.protocols.pop3.redis/analyzer.log @@ -8,9 +8,9 @@ #fields ts cause analyzer_kind analyzer_name uid fuid id.orig_h id.orig_p id.resp_h id.resp_p failure_reason failure_data #types time string string string string string addr port addr port string string XXXXXXXXXX.XXXXXX violation protocol POP3 CHhAvVGS1DHFjwGM9 - 127.0.0.1 59954 127.0.0.1 6379 too many unknown client commands - -XXXXXXXXXX.XXXXXX violation protocol POP3 CHhAvVGS1DHFjwGM9 - 127.0.0.1 59954 127.0.0.1 6379 too many unknown client commands - -XXXXXXXXXX.XXXXXX violation protocol POP3 CHhAvVGS1DHFjwGM9 - 127.0.0.1 59954 127.0.0.1 6379 too many unknown client commands - -XXXXXXXXXX.XXXXXX violation protocol POP3 CHhAvVGS1DHFjwGM9 - 127.0.0.1 59954 127.0.0.1 6379 too many unknown client commands - -XXXXXXXXXX.XXXXXX violation protocol POP3 CHhAvVGS1DHFjwGM9 - 127.0.0.1 59954 127.0.0.1 6379 too many unknown client commands - -XXXXXXXXXX.XXXXXX violation protocol POP3 CHhAvVGS1DHFjwGM9 - 127.0.0.1 59954 127.0.0.1 6379 too many unknown client commands - +XXXXXXXXXX.XXXXXX violation protocol POP3 CHhAvVGS1DHFjwGM9 - 127.0.0.1 59954 127.0.0.1 6379 unknown server command (+PONG) +PONG +XXXXXXXXXX.XXXXXX violation protocol POP3 CHhAvVGS1DHFjwGM9 - 127.0.0.1 59954 127.0.0.1 6379 unknown server command (+PONG) +PONG +XXXXXXXXXX.XXXXXX violation protocol POP3 CHhAvVGS1DHFjwGM9 - 127.0.0.1 59954 127.0.0.1 6379 unknown server command (+PONG) +PONG +XXXXXXXXXX.XXXXXX violation protocol POP3 CHhAvVGS1DHFjwGM9 - 127.0.0.1 59954 127.0.0.1 6379 unknown server command (+PONG) +PONG +XXXXXXXXXX.XXXXXX violation protocol POP3 CHhAvVGS1DHFjwGM9 - 127.0.0.1 59954 127.0.0.1 6379 unknown server command (+PONG) +PONG #close XXXX-XX-XX-XX-XX-XX diff --git a/testing/btest/Baseline/scripts.base.protocols.pop3.redis/out b/testing/btest/Baseline/scripts.base.protocols.pop3.redis/out index de83d41ef3..fe3bec3f1d 100644 --- a/testing/btest/Baseline/scripts.base.protocols.pop3.redis/out +++ b/testing/btest/Baseline/scripts.base.protocols.pop3.redis/out @@ -1,4 +1,4 @@ ### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. CHhAvVGS1DHFjwGM9, pop3_reply, F, OK, -CHhAvVGS1DHFjwGM9, pop3_request, T, AUTH, +CHhAvVGS1DHFjwGM9, pop3_reply, F, OK, CHhAvVGS1DHFjwGM9, pop3_reply, F, OK, diff --git a/testing/btest/Baseline/scripts.base.protocols.pop3.redis/weird.log b/testing/btest/Baseline/scripts.base.protocols.pop3.redis/weird.log index 36a176032c..7ac280b3c0 100644 --- a/testing/btest/Baseline/scripts.base.protocols.pop3.redis/weird.log +++ b/testing/btest/Baseline/scripts.base.protocols.pop3.redis/weird.log @@ -9,4 +9,5 @@ #types time string addr port addr port string string bool string string XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 59954 127.0.0.1 6379 pop3_client_command_unknown *2 F zeek POP3 XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 59954 127.0.0.1 6379 pop3_client_too_many_pending_commands - F zeek POP3 +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 59954 127.0.0.1 6379 pop3_server_command_unknown +PONG F zeek POP3 #close XXXX-XX-XX-XX-XX-XX diff --git a/testing/btest/Traces/pop3/bad-list-retr-crafted.pcap b/testing/btest/Traces/pop3/bad-list-retr-crafted.pcap new file mode 100644 index 0000000000000000000000000000000000000000..7543e833e159d7ae7f1bb4f7052517bdec857371 GIT binary patch literal 3253 zcmaKu?{8C87{|}bQgMjC5)xl5@tB2JMks4>IO{YUQbsMyezb^UT-R=QTV?Gfy%!ZD zFfS@9;U6&0zzdf7!Z$)9Vl*l*B_heuVe{IeV*r@GtQ~yKFPCm%l3Ib z&-b34cH-2hM|`ZB$tsl?tAcO7UAZvO9jsx`!fR}`ma-^g&Hf85ti|7WaUc8vc5$BN zzpj6}2Y>UhuQWM!fH7ZnX|me4wC42og;xA|)siK5A-Tts%oviJPf9Y&7w1RU=8ge9 zb@;*3cauJyjC4sJ0`dl!gsm1iKjxn%=b|JF=M>P7kKFHL|9%CIRjw~m(e(=;rT~Sl z77@FgH;{NTAc?~DIJ%BJ((TU!Yf8$c@2*H z#(RN_w7?ZPPFdhAEpS91hs2NmtYMqM99u0~AmX1P;&eqKEYSJ+BGJZ3w!{)i*YsoH z-Z^S#4+XPPaz!v_AsB;98#S(trV~KSf+DtBWcs4Bmx#3$iC~JyRz!`ac3W%rhSs(y z52W+`9JP7Duy&ex%iy`JWo7e&Jh;kT<(%g#{!0|mtQ;&tH{jGP&?@)pgK?Er^}4s}9I4Jou%cQ=s&hIRRd0Q^%AnubAUd2=$UILa2ifa(GQWT(6PG z@W6@V#s|#dVe?hX9n%71?)*>hFVX_#mq~7PZN7;j$>?J+k|+?jf-$yQB;MxiC-K!~ z;!RR~)0aB2J=Pvw^PEwzvSvQQLqYK*H+yT(llBEUL_A5^m(C8mk-y;WewEy(nTq8hvRtk+(K6$m@VjLBh$ITjL(=kmQYR*d44yIj zcXM-q+whtK4!Z7!xBIW;J}DBntPV(*4x5 zP86Cuyfv?rX8C1}m&Q10{-Hxr^Z7mZczqQ6jfiKYrn2}rUebwMi^M6o{>Qqu#>7Xl zUBLCYm2VJtqKs>i=>rhx37w0k9{@29Nn)!-NA@Y_eF`)vi6YQ(2-HT?W4GT^(R2#m nPBOa<_vwEE==H$FR*TR9#t_~7y+n%;Z2Zm6YQ|2(2Y~+o^L#$H literal 0 HcmV?d00001 diff --git a/testing/btest/scripts/base/protocols/pop3/bad-list-retr-crafted.zeek b/testing/btest/scripts/base/protocols/pop3/bad-list-retr-crafted.zeek new file mode 100644 index 0000000000..2aedeac81e --- /dev/null +++ b/testing/btest/scripts/base/protocols/pop3/bad-list-retr-crafted.zeek @@ -0,0 +1,14 @@ +# @TEST-DOC: Crafted pcap causing crashes due to mail not initialized. +# @TEST-EXEC: zeek -b -r $TRACES/pop3/bad-list-retr-crafted.pcap %INPUT +# @TEST-EXEC: btest-diff conn.log +# @TEST-EXEC: btest-diff weird.log +# @TEST-EXEC: btest-diff analyzer.log + +@load base/frameworks/notice/weird +@load base/protocols/conn +@load base/protocols/pop3 + +event zeek_init() + { + Analyzer::register_for_port(Analyzer::ANALYZER_POP3, 110/tcp); + } diff --git a/testing/btest/scripts/base/protocols/pop3/redis.zeek b/testing/btest/scripts/base/protocols/pop3/redis.zeek index d19845aae2..137baf459c 100644 --- a/testing/btest/scripts/base/protocols/pop3/redis.zeek +++ b/testing/btest/scripts/base/protocols/pop3/redis.zeek @@ -9,6 +9,8 @@ @load base/protocols/conn @load base/protocols/pop3 +redef POP3::max_unknown_client_commands = 3; + event pop3_request(c: connection, is_orig: bool, cmd: string, arg: string) { print c$uid, "pop3_request", is_orig, cmd, arg; From 7a73f817929b72b8c7acf697bf52b7267606a207 Mon Sep 17 00:00:00 2001 From: Christian Kreibich Date: Fri, 4 Oct 2024 15:42:14 -0700 Subject: [PATCH 54/91] Update CHANGES, VERSION, and NEWS for 7.0.3 release --- CHANGES | 4 ++++ NEWS | 15 +++++++++++++++ VERSION | 2 +- 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index eba74fc287..88ce88fbd7 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,7 @@ +7.0.3 | 2024-10-04 15:42:14 -0700 + + * Update CHANGES, VERSION, and NEWS for 7.0.3 release (Christian Kreibich, Corelight) + 7.0.2-5 | 2024-10-04 10:46:01 -0700 * Merge remote-tracking branch 'security/topic/awelzel/215-pop3-mail-null-deref' (Christian Kreibich, Corelight) diff --git a/NEWS b/NEWS index 18a0fe49a3..e96b28f4d3 100644 --- a/NEWS +++ b/NEWS @@ -3,6 +3,21 @@ This document summarizes the most important changes in the current Zeek release. For an exhaustive list of changes, see the ``CHANGES`` file (note that submodules, such as Broker, come with their own ``CHANGES``.) +Zeek 7.0.3 +========== + +This release fixes the following security issue: + +- Adding to the POP3 hardening in 7.0.2, the parser now simply discards too many + pending commands, rather than any attempting to process them. Further, invalid + server responses do not result in command completion anymore. Processing + out-of-order commands or finishing commands based on invalid server responses + could result in inconsistent analyzer state, potentially triggering null + pointer references for crafted traffic. + +This release ships with Spicy 1.11.3, a bugfix release. Please refer to its +release notes for details. + Zeek 7.0.2 ========== diff --git a/VERSION b/VERSION index 189fa8c988..a50da181e9 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -7.0.2-5 +7.0.3 From 9eb3ada8c80a7da31bc63efed484038cd93e2106 Mon Sep 17 00:00:00 2001 From: Christian Kreibich Date: Fri, 18 Oct 2024 09:55:20 -0700 Subject: [PATCH 55/91] Merge remote-tracking branch 'origin/topic/bbannier/fix-docs-ci-again' * origin/topic/bbannier/fix-docs-ci-again: Fix installation of Python packages in generate docs CI job again (cherry picked from commit c28442a9a178b735e3fe1b5f5938f922a5aa7a66) --- .github/workflows/generate-docs.yml | 2 +- CHANGES | 9 +++++++++ VERSION | 2 +- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/.github/workflows/generate-docs.yml b/.github/workflows/generate-docs.yml index be60b0cc9f..49b04394f7 100644 --- a/.github/workflows/generate-docs.yml +++ b/.github/workflows/generate-docs.yml @@ -17,7 +17,7 @@ jobs: permissions: contents: write # for Git to git push if: github.repository == 'zeek/zeek' - runs-on: ubuntu-latest + runs-on: ubuntu-22.04 steps: # We only perform a push if the action was triggered via a schedule diff --git a/CHANGES b/CHANGES index 88ce88fbd7..e182d8d713 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,12 @@ +7.0.3-1 | 2024-10-18 17:15:02 -0700 + + * Merge remote-tracking branch 'origin/topic/bbannier/fix-docs-ci-again' (Christian Kreibich, Corelight) + + * origin/topic/bbannier/fix-docs-ci-again: + Fix installation of Python packages in generate docs CI job again + + (cherry picked from commit c28442a9a178b735e3fe1b5f5938f922a5aa7a66) + 7.0.3 | 2024-10-04 15:42:14 -0700 * Update CHANGES, VERSION, and NEWS for 7.0.3 release (Christian Kreibich, Corelight) diff --git a/VERSION b/VERSION index a50da181e9..f6e4a54c10 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -7.0.3 +7.0.3-1 From fabb4023c91e837130d5afbc425f867a9bf2299c Mon Sep 17 00:00:00 2001 From: Vern Paxson Date: Thu, 7 Nov 2024 17:13:22 -0800 Subject: [PATCH 56/91] fixed access to uninitialized memory in ZAM's "cat" built-in --- src/script_opt/ZAM/BuiltInSupport.cc | 2 +- src/script_opt/ZAM/BuiltInSupport.h | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/script_opt/ZAM/BuiltInSupport.cc b/src/script_opt/ZAM/BuiltInSupport.cc index 4bc833814d..a41311c7ae 100644 --- a/src/script_opt/ZAM/BuiltInSupport.cc +++ b/src/script_opt/ZAM/BuiltInSupport.cc @@ -73,7 +73,7 @@ void FixedCatArg::RenderInto(ZVal* zframe, int slot, char*& res) { n = modp_dtoa2(d, res, 6); res += n; - if ( util::approx_equal(d, nearbyint(d), 1e-9) && std::isfinite(d) && ! strchr(tmp, 'e') ) { + if ( util::approx_equal(d, nearbyint(d), 1e-9) && std::isfinite(d) ) { // disambiguate from integer *(res++) = '.'; *(res++) = '0'; diff --git a/src/script_opt/ZAM/BuiltInSupport.h b/src/script_opt/ZAM/BuiltInSupport.h index 7169ea94d1..daa8c9c087 100644 --- a/src/script_opt/ZAM/BuiltInSupport.h +++ b/src/script_opt/ZAM/BuiltInSupport.h @@ -42,7 +42,6 @@ public: protected: TypePtr t; - char tmp[256]; }; class StringCatArg : public CatArg { From dfbeb3e71fefe35259ab1e3d0d20572c6f91cf08 Mon Sep 17 00:00:00 2001 From: Vern Paxson Date: Mon, 11 Nov 2024 11:38:04 -0800 Subject: [PATCH 57/91] porting of GH-4013 --- src/script_opt/ZAM/OPs/ZAM.op | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/script_opt/ZAM/OPs/ZAM.op b/src/script_opt/ZAM/OPs/ZAM.op index 6b18b4156e..155a9c0d42 100644 --- a/src/script_opt/ZAM/OPs/ZAM.op +++ b/src/script_opt/ZAM/OPs/ZAM.op @@ -2133,7 +2133,10 @@ type VVVV eval NextVectorIterCore(z.v3, v4) frame[z.v1].uint_val = si.iter; if ( z.is_managed ) + { + ZVal::DeleteManagedType(frame[z.v2]); frame[z.v2] = BuildVal(vv[si.iter]->ToVal(z.t), z.t); + } else frame[z.v2] = *vv[si.iter]; si.IterFinished(); @@ -2145,7 +2148,10 @@ internal-op Next-Vector-Blank-Iter-Val-Var type VVV eval NextVectorIterCore(z.v2, v3) if ( z.is_managed ) + { + ZVal::DeleteManagedType(frame[z.v1]); frame[z.v1] = BuildVal(vv[si.iter]->ToVal(z.t), z.t); + } else frame[z.v1] = *vv[si.iter]; si.IterFinished(); From c86f9267fff7aa60636dd5fabc6862d1eb09ac6b Mon Sep 17 00:00:00 2001 From: Vern Paxson Date: Mon, 11 Nov 2024 11:54:15 -0800 Subject: [PATCH 58/91] porting of GH-4016 --- src/script_opt/ZAM/OPs/ZAM.op | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/script_opt/ZAM/OPs/ZAM.op b/src/script_opt/ZAM/OPs/ZAM.op index 155a9c0d42..36f8beddd9 100644 --- a/src/script_opt/ZAM/OPs/ZAM.op +++ b/src/script_opt/ZAM/OPs/ZAM.op @@ -1561,7 +1561,9 @@ eval if ( frame[z.v2].vector_val->Size() > 0 ) unary-expr-op To-Any-Coerce op-type X set-type $1 -eval AssignV1(ZVal(frame[z.v2].ToVal(z.t), ZAM::any_base_type)) +eval auto orig_lhs = frame[z.v1]; /* hold in case z.v1 = z.v2 */ + AssignV1(ZVal(frame[z.v2].ToVal(z.t), ZAM::any_base_type)) + ZVal::DeleteManagedType(orig_lhs); unary-expr-op From-Any-Coerce op-type X From f693f221922ce029c4bcb77df7e8d30112b2fe54 Mon Sep 17 00:00:00 2001 From: Vern Paxson Date: Tue, 12 Nov 2024 15:41:20 -0800 Subject: [PATCH 59/91] porting of GH-4022 --- src/Val.cc | 5 +++-- src/script_opt/Expr.cc | 3 +++ src/script_opt/ZAM/OPs/ZAM.op | 27 ++++++++++++++++++++++----- src/script_opt/ZAM/ZBody.cc | 19 ++++++++++++------- 4 files changed, 40 insertions(+), 14 deletions(-) diff --git a/src/Val.cc b/src/Val.cc index bf86360b70..e82f0e9c1b 100644 --- a/src/Val.cc +++ b/src/Val.cc @@ -3241,10 +3241,11 @@ bool VectorVal::Assign(unsigned int index, ValPtr element) { if ( yield_types ) { const auto& t = element->GetType(); - (*yield_types)[index] = t; + auto& yt_i = (*yield_types)[index]; auto& elem = vector_val[index]; if ( elem ) - ZVal::DeleteIfManaged(*elem, t); + ZVal::DeleteIfManaged(*elem, yt_i); + yt_i = t; elem = ZVal(std::move(element), t); } else { diff --git a/src/script_opt/Expr.cc b/src/script_opt/Expr.cc index 1ad24c5277..8516224106 100644 --- a/src/script_opt/Expr.cc +++ b/src/script_opt/Expr.cc @@ -1629,6 +1629,9 @@ ExprPtr AssignExpr::Reduce(Reducer* c, StmtPtr& red_stmt) { StmtPtr lhs_stmt; StmtPtr rhs_stmt; + if ( GetType()->Tag() == TYPE_ANY && op2->GetType()->Tag() != TYPE_ANY ) + op2 = with_location_of(make_intrusive(op2), op2); + auto lhs_e = field_e->Op()->Reduce(c, lhs_stmt); auto rhs_e = op2->ReduceToFieldAssignment(c, rhs_stmt); diff --git a/src/script_opt/ZAM/OPs/ZAM.op b/src/script_opt/ZAM/OPs/ZAM.op index 36f8beddd9..bd78716459 100644 --- a/src/script_opt/ZAM/OPs/ZAM.op +++ b/src/script_opt/ZAM/OPs/ZAM.op @@ -934,13 +934,13 @@ eval auto& vsel = frame[z.v2].vector_val->RawVec(); auto& v1 = frame[z.v3].vector_val->RawVec(); auto& v2 = frame[z.v4].vector_val->RawVec(); auto n = v1.size(); - auto res = new vector>(n); + vector> res(n); for ( auto i = 0U; i < n; ++i ) if ( vsel[i] ) - (*res)[i] = vsel[i]->int_val ? v1[i] : v2[i]; + res[i] = vsel[i]->int_val ? v1[i] : v2[i]; auto& full_res = frame[z.v1].vector_val; Unref(full_res); - full_res = new VectorVal(cast_intrusive(z.t), res); + full_res = new VectorVal(cast_intrusive(z.t), &res); # Our instruction format doesn't accommodate two constants, so for # the singular case of a V ? C1 : C2 conditional, we split it into @@ -1254,9 +1254,14 @@ macro AssignFromRec() for ( size_t i = 0U; i < n; ++i ) { auto rhs_i = rhs->RawField(rhs_map[i]); + auto& init_i = init_vals[lhs_map[i]]; if ( is_managed[i] ) + { zeek::Ref(rhs_i.ManagedVal()); - init_vals[lhs_map[i]] = rhs_i; + if ( init_i ) + ZVal::DeleteManagedType(*init_i); + } + init_i = rhs_i; } op Construct-Known-Record-From @@ -1606,7 +1611,19 @@ op Any-Vector-Elem-Assign op1-read set-type $1 type VVV -eval EvalVectorElemAssign(, vv->Assign(ind, frame[z.v3].ToVal(z.t))) +eval auto ind = frame[z.v2].AsCount(); + auto vv = frame[z.v1].AsVector(); + auto yt = vv->RawYieldTypes(); + if ( ind < vv->Size() && yt && (*yt)[ind] && ZVal::IsManagedType((*yt)[ind]) ) + { + auto orig_elem = vv->RawVec()[ind]; + if ( ! vv->Assign(ind, frame[z.v3].ToVal(z.t)) ) + ZAM_run_time_error(z.loc, "value used but not set"); + if ( orig_elem ) + ZVal::DeleteManagedType(*orig_elem); + } + else if ( ! vv->Assign(ind, frame[z.v3].ToVal(z.t)) ) + ZAM_run_time_error(z.loc, "value used but not set"); op Vector-Elem-Assign-Any op1-read diff --git a/src/script_opt/ZAM/ZBody.cc b/src/script_opt/ZAM/ZBody.cc index 0eb283284a..77bb11b93b 100644 --- a/src/script_opt/ZAM/ZBody.cc +++ b/src/script_opt/ZAM/ZBody.cc @@ -214,8 +214,9 @@ static void vec_exec(ZOp op, TypePtr t, VectorVal*& v1, const VectorVal* v2, con std::string err = "overflow promoting from "; \ err += ov_err; \ err += " arithmetic value"; \ + /* The run-time error will throw an exception, so recover intermediary memory. */ \ + delete res_zv; \ ZAM_run_time_error(z.loc, err.c_str()); \ - res[i] = std::nullopt; \ } \ else \ res[i] = ZVal(cast(vi)); \ @@ -604,8 +605,7 @@ static void vec_exec(ZOp op, TypePtr t, VectorVal*& v1, const VectorVal* v2, con auto& vec2 = v2->RawVec(); auto n = vec2.size(); - auto vec1_ptr = new vector>(n); - auto& vec1 = *vec1_ptr; + vector> vec1(n); for ( auto i = 0U; i < n; ++i ) { if ( vec2[i] ) @@ -620,7 +620,7 @@ static void vec_exec(ZOp op, TypePtr t, VectorVal*& v1, const VectorVal* v2, con auto vt = cast_intrusive(std::move(t)); auto old_v1 = v1; - v1 = new VectorVal(std::move(vt), vec1_ptr); + v1 = new VectorVal(std::move(vt), &vec1); Unref(old_v1); } @@ -631,8 +631,13 @@ static void vec_exec(ZOp op, TypePtr t, VectorVal*& v1, const VectorVal* v2, con auto& vec2 = v2->RawVec(); auto& vec3 = v3->RawVec(); auto n = vec2.size(); - auto vec1_ptr = new vector>(n); - auto& vec1 = *vec1_ptr; + + if ( vec3.size() != n ) { + ZAM_run_time_error(util::fmt("vector operands are of different sizes (%d vs. %d)", int(n), int(vec3.size()))); + return; + } + + vector> vec1(n); for ( auto i = 0U; i < vec2.size(); ++i ) { if ( vec2[i] && vec3[i] ) @@ -647,7 +652,7 @@ static void vec_exec(ZOp op, TypePtr t, VectorVal*& v1, const VectorVal* v2, con auto vt = cast_intrusive(std::move(t)); auto old_v1 = v1; - v1 = new VectorVal(std::move(vt), vec1_ptr); + v1 = new VectorVal(std::move(vt), &vec1); Unref(old_v1); } From 10d5ca59489e81f472b17ec8d81852a32f97e99b Mon Sep 17 00:00:00 2001 From: Vern Paxson Date: Mon, 5 Aug 2024 09:21:13 +0100 Subject: [PATCH 60/91] fixes for script optimization of coerce-to-any expressions --- src/Expr.h | 3 +++ src/Stmt.cc | 3 ++- src/script_opt/Expr.cc | 17 +++++++++++++++++ src/script_opt/ZAM/OPs/ZAM.op | 2 +- 4 files changed, 23 insertions(+), 2 deletions(-) diff --git a/src/Expr.h b/src/Expr.h index 73929a2114..ffead932af 100644 --- a/src/Expr.h +++ b/src/Expr.h @@ -1642,6 +1642,9 @@ class CoerceToAnyExpr : public UnaryExpr { public: CoerceToAnyExpr(ExprPtr op); + bool IsReduced(Reducer* c) const override; + ExprPtr Reduce(Reducer* c, StmtPtr& red_stmt) override; + protected: ValPtr Fold(Val* v) const override; diff --git a/src/Stmt.cc b/src/Stmt.cc index a1edb51ee0..01e892ead0 100644 --- a/src/Stmt.cc +++ b/src/Stmt.cc @@ -1849,7 +1849,8 @@ void WhenInfo::Build(StmtPtr ws) { auto else_branch = timeout_s ? timeout_s : empty; auto do_bodies = make_intrusive(two_test, s, else_branch); - auto dummy_return = make_intrusive(true_const); + auto any_true_const = make_intrusive(true_const); + auto dummy_return = make_intrusive(any_true_const); auto shebang = make_intrusive(do_test, do_bodies, dummy_return); diff --git a/src/script_opt/Expr.cc b/src/script_opt/Expr.cc index 8516224106..7591affd7b 100644 --- a/src/script_opt/Expr.cc +++ b/src/script_opt/Expr.cc @@ -3094,6 +3094,23 @@ CoerceToAnyExpr::CoerceToAnyExpr(ExprPtr arg_op) : UnaryExpr(EXPR_TO_ANY_COERCE, type = base_type(TYPE_ANY); } +bool CoerceToAnyExpr::IsReduced(Reducer* c) const { return HasReducedOps(c); } + +ExprPtr CoerceToAnyExpr::Reduce(Reducer* c, StmtPtr& red_stmt) { + if ( c->Optimizing() ) + op = c->UpdateExpr(op); + + red_stmt = nullptr; + + if ( ! op->IsSingleton(c) ) + op = op->ReduceToSingleton(c, red_stmt); + + if ( c->Optimizing() ) + return ThisPtr(); + else + return AssignToTemporary(c, red_stmt); +} + ValPtr CoerceToAnyExpr::Fold(Val* v) const { return {NewRef{}, v}; } ExprPtr CoerceToAnyExpr::Duplicate() { return SetSucc(new CoerceToAnyExpr(op->Duplicate())); } diff --git a/src/script_opt/ZAM/OPs/ZAM.op b/src/script_opt/ZAM/OPs/ZAM.op index bd78716459..f773e60a2f 100644 --- a/src/script_opt/ZAM/OPs/ZAM.op +++ b/src/script_opt/ZAM/OPs/ZAM.op @@ -1567,7 +1567,7 @@ unary-expr-op To-Any-Coerce op-type X set-type $1 eval auto orig_lhs = frame[z.v1]; /* hold in case z.v1 = z.v2 */ - AssignV1(ZVal(frame[z.v2].ToVal(z.t), ZAM::any_base_type)) + frame[z.v1] = ZVal($1.ToVal(z.t), ZAM::any_base_type); ZVal::DeleteManagedType(orig_lhs); unary-expr-op From-Any-Coerce From bcfd47c28db9a7781fdf66cf79b916e2ec66f78a Mon Sep 17 00:00:00 2001 From: Vern Paxson Date: Wed, 11 Sep 2024 16:31:23 +0200 Subject: [PATCH 61/91] fix for setting object locations to avoid use-after-free situation --- src/Obj.cc | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/Obj.cc b/src/Obj.cc index a3b36dee76..5e346fead9 100644 --- a/src/Obj.cc +++ b/src/Obj.cc @@ -130,11 +130,14 @@ bool Obj::SetLocationInfo(const detail::Location* start, const detail::Location* // We already have a better location, so don't use this one. return true; - delete location; - - location = + auto new_location = new detail::Location(start->filename, start->first_line, end->last_line, start->first_column, end->last_column); + // Don't delete this until we've constructed the new location, in case + // "start" or "end" are our own location. + delete location; + location = new_location; + return true; } From 3281aa6284cd5c5b5f87e43e0702df9839fc624a Mon Sep 17 00:00:00 2001 From: Vern Paxson Date: Wed, 13 Nov 2024 16:54:47 -0800 Subject: [PATCH 62/91] import of GH-4022 BTest additions ZAM baseline update --- .../btest/Baseline.zam/bifs.from_json-2/.stderr | 2 +- .../core.max-analyzer-violations/weird.log | 2 +- .../core.option-runtime-errors-2/.stderr | 2 +- .../core.option-runtime-errors-3/.stderr | 2 +- .../core.option-runtime-errors/.stderr | 2 +- .../btest/Baseline/opt.regress-any-leak/output | 3 +++ testing/btest/Baseline/opt.regress-any/output | 3 +++ .../Baseline/opt.regress-vector-mismatch/output | 1 + testing/btest/opt/regress-any-leak.zeek | 16 ++++++++++++++++ testing/btest/opt/regress-any.zeek | 16 ++++++++++++++++ testing/btest/opt/regress-vector-mismatch.zeek | 17 +++++++++++++++++ 11 files changed, 61 insertions(+), 5 deletions(-) create mode 100644 testing/btest/Baseline/opt.regress-any-leak/output create mode 100644 testing/btest/Baseline/opt.regress-any/output create mode 100644 testing/btest/Baseline/opt.regress-vector-mismatch/output create mode 100644 testing/btest/opt/regress-any-leak.zeek create mode 100644 testing/btest/opt/regress-any.zeek create mode 100644 testing/btest/opt/regress-vector-mismatch.zeek diff --git a/testing/btest/Baseline.zam/bifs.from_json-2/.stderr b/testing/btest/Baseline.zam/bifs.from_json-2/.stderr index 372f599e7f..1a3fceee72 100644 --- a/testing/btest/Baseline.zam/bifs.from_json-2/.stderr +++ b/testing/btest/Baseline.zam/bifs.from_json-2/.stderr @@ -1,2 +1,2 @@ ### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. -error in <...>/from_json.zeek, line 4: from_json() requires a type argument (from_json([], 10, from_json_default_key_mapper)) +error in <...>/from_json.zeek, line 4: from_json() requires a type argument (from_json([], ::#0, from_json_default_key_mapper)) diff --git a/testing/btest/Baseline.zam/core.max-analyzer-violations/weird.log b/testing/btest/Baseline.zam/core.max-analyzer-violations/weird.log index 99b5e14621..8d0cb822e6 100644 --- a/testing/btest/Baseline.zam/core.max-analyzer-violations/weird.log +++ b/testing/btest/Baseline.zam/core.max-analyzer-violations/weird.log @@ -7,7 +7,7 @@ #open XXXX-XX-XX-XX-XX-XX #fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p name addl notice peer source #types time string addr port addr port string string bool string string -XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 58246 127.0.0.1 110 pop3_server_command_unknown - F zeek POP3 +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 58246 127.0.0.1 110 pop3_server_command_unknown + F zeek POP3 XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 58246 127.0.0.1 110 line_terminated_with_single_CR - F zeek CONTENTLINE XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 58246 127.0.0.1 110 too_many_analyzer_violations - F zeek POP3 #close XXXX-XX-XX-XX-XX-XX diff --git a/testing/btest/Baseline.zam/core.option-runtime-errors-2/.stderr b/testing/btest/Baseline.zam/core.option-runtime-errors-2/.stderr index 719b74fadc..15561eb6c9 100644 --- a/testing/btest/Baseline.zam/core.option-runtime-errors-2/.stderr +++ b/testing/btest/Baseline.zam/core.option-runtime-errors-2/.stderr @@ -1,2 +1,2 @@ ### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. -error in <...>/option-runtime-errors.zeek, line 3: Incompatible type for set of ID 'A': got 'string', need 'count' (Option::set(A, hi, )) +error in <...>/option-runtime-errors.zeek, line 3: Incompatible type for set of ID 'A': got 'string', need 'count' (Option::set(A, ::#0, )) diff --git a/testing/btest/Baseline.zam/core.option-runtime-errors-3/.stderr b/testing/btest/Baseline.zam/core.option-runtime-errors-3/.stderr index f121199a5d..682f1fbe27 100644 --- a/testing/btest/Baseline.zam/core.option-runtime-errors-3/.stderr +++ b/testing/btest/Baseline.zam/core.option-runtime-errors-3/.stderr @@ -1,2 +1,2 @@ ### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. -error in <...>/option-runtime-errors.zeek, line 3: ID 'A' is not an option (Option::set(A, 6, )) +error in <...>/option-runtime-errors.zeek, line 3: ID 'A' is not an option (Option::set(A, ::#0, )) diff --git a/testing/btest/Baseline.zam/core.option-runtime-errors/.stderr b/testing/btest/Baseline.zam/core.option-runtime-errors/.stderr index 7537f10f90..5e6d272614 100644 --- a/testing/btest/Baseline.zam/core.option-runtime-errors/.stderr +++ b/testing/btest/Baseline.zam/core.option-runtime-errors/.stderr @@ -1,2 +1,2 @@ ### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. -error in <...>/option-runtime-errors.zeek, line 9: Could not find ID named 'B' (Option::set(B, 6, )) +error in <...>/option-runtime-errors.zeek, line 9: Could not find ID named 'B' (Option::set(B, ::#0, )) diff --git a/testing/btest/Baseline/opt.regress-any-leak/output b/testing/btest/Baseline/opt.regress-any-leak/output new file mode 100644 index 0000000000..d5c6e60615 --- /dev/null +++ b/testing/btest/Baseline/opt.regress-any-leak/output @@ -0,0 +1,3 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +[[a=abc-1]] +[1] diff --git a/testing/btest/Baseline/opt.regress-any/output b/testing/btest/Baseline/opt.regress-any/output new file mode 100644 index 0000000000..9627885028 --- /dev/null +++ b/testing/btest/Baseline/opt.regress-any/output @@ -0,0 +1,3 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +[a=123, b=[abc]] +[a=123, b=1] diff --git a/testing/btest/Baseline/opt.regress-vector-mismatch/output b/testing/btest/Baseline/opt.regress-vector-mismatch/output new file mode 100644 index 0000000000..49d861c74c --- /dev/null +++ b/testing/btest/Baseline/opt.regress-vector-mismatch/output @@ -0,0 +1 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. diff --git a/testing/btest/opt/regress-any-leak.zeek b/testing/btest/opt/regress-any-leak.zeek new file mode 100644 index 0000000000..118356aa07 --- /dev/null +++ b/testing/btest/opt/regress-any-leak.zeek @@ -0,0 +1,16 @@ +# @TEST-DOC: Regression test for leak when mixing "any" types (affected both ZAM and non-ZAM) +# @TEST-EXEC: zeek -b -O ZAM %INPUT >output +# @TEST-EXEC: btest-diff output + +type X: record { + a: string; +}; + +event zeek_init() + { + local vec: vector of any; + vec += X($a="abc-1"); + print vec; + vec[0] = 1; + print vec; + } diff --git a/testing/btest/opt/regress-any.zeek b/testing/btest/opt/regress-any.zeek new file mode 100644 index 0000000000..98c4116392 --- /dev/null +++ b/testing/btest/opt/regress-any.zeek @@ -0,0 +1,16 @@ +# @TEST-DOC: Regression test for reassigning an "any" field +# @TEST-EXEC: zeek -b -O ZAM %INPUT >output +# @TEST-EXEC: btest-diff output + +type X: record { + a: string; + b: any; +}; + +event zeek_init() + { + local x = X($a="123", $b=vector("abc")); + print x; + x$b = 1; + print x; + } diff --git a/testing/btest/opt/regress-vector-mismatch.zeek b/testing/btest/opt/regress-vector-mismatch.zeek new file mode 100644 index 0000000000..e07411750d --- /dev/null +++ b/testing/btest/opt/regress-vector-mismatch.zeek @@ -0,0 +1,17 @@ +# @TEST-DOC: Regression test for coercing vectors-of-any +# @TEST-EXEC: zeek -b -O ZAM %INPUT >output +# @TEST-EXEC: btest-diff output + +module X; + +export { + option o: vector of string = vector(); +} + +event zeek_init() + { + local x: any = vector(); + Config::set_value("X::o", vector("a") + (x as vector of string)); + print X::o; + print x; + } From 300b7a11acab8104ef2bbc5310e79445239fd234 Mon Sep 17 00:00:00 2001 From: Christian Kreibich Date: Wed, 9 Oct 2024 14:26:35 -0700 Subject: [PATCH 63/91] Merge branch 'topic/awelzel/3957-raw-reader-spinning' * topic/awelzel/3957-raw-reader-spinning: input/Raw: Rework GetLine() (cherry picked from commit 2a23e9fc1962419e41133689c2a682455d24e35e) --- CHANGES | 10 +++ VERSION | 2 +- src/input/readers/raw/Raw.cc | 66 ++++++++++++------- src/input/readers/raw/Raw.h | 3 +- .../zeek..stdout | 4 ++ .../zeek..stdout | 4 ++ .../zeek..stdout | 4 ++ .../zeek..stdout | 4 ++ .../input/raw/executestream-leftover.zeek | 52 +++++++++++++++ .../raw/executestream-no-last-separator.zeek | 53 +++++++++++++++ .../input/raw/executestream-slow-long.zeek | 62 +++++++++++++++++ .../input/raw/executestream-slow.zeek | 55 ++++++++++++++++ 12 files changed, 292 insertions(+), 27 deletions(-) create mode 100644 testing/btest/Baseline/scripts.base.frameworks.input.raw.executestream-leftover/zeek..stdout create mode 100644 testing/btest/Baseline/scripts.base.frameworks.input.raw.executestream-no-last-separator/zeek..stdout create mode 100644 testing/btest/Baseline/scripts.base.frameworks.input.raw.executestream-slow-long/zeek..stdout create mode 100644 testing/btest/Baseline/scripts.base.frameworks.input.raw.executestream-slow/zeek..stdout create mode 100644 testing/btest/scripts/base/frameworks/input/raw/executestream-leftover.zeek create mode 100644 testing/btest/scripts/base/frameworks/input/raw/executestream-no-last-separator.zeek create mode 100644 testing/btest/scripts/base/frameworks/input/raw/executestream-slow-long.zeek create mode 100644 testing/btest/scripts/base/frameworks/input/raw/executestream-slow.zeek diff --git a/CHANGES b/CHANGES index eccc09d9b1..0bbcd905b5 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,13 @@ +7.0.3-10 | 2024-11-14 11:30:00 -0700 + + * GH-3957: input/Raw: Rework GetLine() (Arne Welzel, Corelight) + + (cherry picked from commit 2a23e9fc1962419e41133689c2a682455d24e35e) + + * GH-215: POP3: Rework unbounded pending command fix (Arne Welzel, Corelight) + + (cherry picked from commit 2a23e9fc1962419e41133689c2a682455d24e35e) + 7.0.3-9 | 2024-11-14 10:21:55 -0700 * import of GH-4022 BTest additions (Vern Paxson, Corelight) diff --git a/VERSION b/VERSION index 76dea29291..8bea599430 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -7.0.3-9 +7.0.3-10 diff --git a/src/input/readers/raw/Raw.cc b/src/input/readers/raw/Raw.cc index 5161843af0..af8c434bbf 100644 --- a/src/input/readers/raw/Raw.cc +++ b/src/input/readers/raw/Raw.cc @@ -46,6 +46,7 @@ Raw::Raw(ReaderFrontend* frontend) : ReaderBackend(frontend), file(nullptr, fclo sep_length = BifConst::InputRaw::record_separator->Len(); bufpos = 0; + bufsize = 0; stdin_fileno = fileno(stdin); stdout_fileno = fileno(stdout); @@ -420,59 +421,74 @@ bool Raw::DoInit(const ReaderInfo& info, int num_fields, const Field* const* fie int64_t Raw::GetLine(FILE* arg_file) { errno = 0; - int pos = 0; // strstr_n only works on ints - so no use to use something different here - int offset = 0; - if ( ! buf ) + if ( ! buf ) { buf = std::unique_ptr(new char[block_size]); - - int repeats = 1; + bufpos = 0; + bufsize = block_size; + } for ( ;; ) { - size_t readbytes = fread(buf.get() + bufpos + offset, 1, block_size - bufpos, arg_file); - pos += bufpos + readbytes; - // printf("Pos: %d\n", pos); - bufpos = offset = 0; // read full block size in next read... + size_t readbytes = fread(buf.get() + bufpos, 1, bufsize - bufpos, arg_file); - if ( pos == 0 && errno != 0 ) + bufpos = bufpos + readbytes; + + // Nothing in the buffer and errno set, yield. + if ( bufpos == 0 && errno != 0 ) break; // researching everything each time is a bit... cpu-intensive. But otherwise we have // to deal with situations where the separator is multi-character and split over multiple // reads... - int found = util::strstr_n(pos, (unsigned char*)buf.get(), separator.size(), (unsigned char*)separator.c_str()); + // + // memmem() would be more appropriate, but not available on Windows. + int found = util::strstr_n(bufpos, reinterpret_cast(buf.get()), separator.size(), + reinterpret_cast(separator.c_str())); if ( found == -1 ) { - // we did not find it and have to search again in the next try. resize buffer.... + // we did not find it and have to search again in the next try. // but first check if we encountered the file end - because if we did this was it. if ( feof(arg_file) != 0 ) { - if ( pos == 0 ) + if ( bufpos == 0 ) return -1; // signal EOF - and that we had no more data. else { outbuf = std::move(buf); // buf is null after this - return pos; + return bufpos; // flush out remaining buffered data as line } } - repeats++; - // bah, we cannot use realloc because we would have to change the delete in the manager - // to a free. - std::unique_ptr newbuf = std::unique_ptr(new char[block_size * repeats]); - memcpy(newbuf.get(), buf.get(), block_size * (repeats - 1)); - buf = std::move(newbuf); - offset = block_size * (repeats - 1); + // No separator found and buffer full, realloc and retry reading more right away. + if ( bufpos == bufsize ) { + std::unique_ptr newbuf = std::unique_ptr(new char[bufsize + block_size]); + memcpy(newbuf.get(), buf.get(), bufsize); + buf = std::move(newbuf); + bufsize = bufsize + block_size; + } + else { + // Short or empty read, some data in the buffer, but no separator found + // and also not EOF: This is likely reading from a pipe where the separator + // wasn't yet produced. Yield to retry on the next heartbeat. + return -2; + } } else { + size_t sep_idx = static_cast(found); + assert(sep_idx <= bufsize - sep_length); + size_t remaining = bufpos - sep_idx - sep_length; + outbuf = std::move(buf); - if ( found < pos ) { + if ( remaining > 0 ) { // we have leftovers. copy them into the buffer for the next line + assert(remaining <= block_size); buf = std::unique_ptr(new char[block_size]); - memcpy(buf.get(), outbuf.get() + found + sep_length, pos - found - sep_length); - bufpos = pos - found - sep_length; + bufpos = remaining; + bufsize = block_size; + + memcpy(buf.get(), outbuf.get() + sep_idx + sep_length, remaining); } - return found; + return sep_idx; } } diff --git a/src/input/readers/raw/Raw.h b/src/input/readers/raw/Raw.h index e7f788afda..1fc1b52097 100644 --- a/src/input/readers/raw/Raw.h +++ b/src/input/readers/raw/Raw.h @@ -58,7 +58,8 @@ private: std::string separator; unsigned int sep_length; // length of the separator - int bufpos; + size_t bufpos; // Where in buf to read more data. + size_t bufsize; // Currently allocated size of buf. std::unique_ptr buf; std::unique_ptr outbuf; diff --git a/testing/btest/Baseline/scripts.base.frameworks.input.raw.executestream-leftover/zeek..stdout b/testing/btest/Baseline/scripts.base.frameworks.input.raw.executestream-leftover/zeek..stdout new file mode 100644 index 0000000000..9097f9f60b --- /dev/null +++ b/testing/btest/Baseline/scripts.base.frameworks.input.raw.executestream-leftover/zeek..stdout @@ -0,0 +1,4 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +Input::EVENT_NEW, aaa +Input::EVENT_NEW, bbb +Input::EVENT_NEW, final diff --git a/testing/btest/Baseline/scripts.base.frameworks.input.raw.executestream-no-last-separator/zeek..stdout b/testing/btest/Baseline/scripts.base.frameworks.input.raw.executestream-no-last-separator/zeek..stdout new file mode 100644 index 0000000000..9097f9f60b --- /dev/null +++ b/testing/btest/Baseline/scripts.base.frameworks.input.raw.executestream-no-last-separator/zeek..stdout @@ -0,0 +1,4 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +Input::EVENT_NEW, aaa +Input::EVENT_NEW, bbb +Input::EVENT_NEW, final diff --git a/testing/btest/Baseline/scripts.base.frameworks.input.raw.executestream-slow-long/zeek..stdout b/testing/btest/Baseline/scripts.base.frameworks.input.raw.executestream-slow-long/zeek..stdout new file mode 100644 index 0000000000..94bf7b6faf --- /dev/null +++ b/testing/btest/Baseline/scripts.base.frameworks.input.raw.executestream-slow-long/zeek..stdout @@ -0,0 +1,4 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +Input::EVENT_NEW, 24612, binary start\x00\x00\x00\x00, \x00\x00\x00\x00\x00binary done +Input::EVENT_NEW, 3, ccc, ccc +Input::EVENT_NEW, 5, final, final diff --git a/testing/btest/Baseline/scripts.base.frameworks.input.raw.executestream-slow/zeek..stdout b/testing/btest/Baseline/scripts.base.frameworks.input.raw.executestream-slow/zeek..stdout new file mode 100644 index 0000000000..c561637236 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.frameworks.input.raw.executestream-slow/zeek..stdout @@ -0,0 +1,4 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +Input::EVENT_NEW, aaa-bbb-ccc +Input::EVENT_NEW, aaa-bbb-ccc +Input::EVENT_NEW, final diff --git a/testing/btest/scripts/base/frameworks/input/raw/executestream-leftover.zeek b/testing/btest/scripts/base/frameworks/input/raw/executestream-leftover.zeek new file mode 100644 index 0000000000..f40a7d52a3 --- /dev/null +++ b/testing/btest/scripts/base/frameworks/input/raw/executestream-leftover.zeek @@ -0,0 +1,52 @@ +# @TEST-DOC: Launching a program that produces output slowly and strangely separated. +# @TEST-EXEC: chmod +x run.sh +# @TEST-EXEC: btest-bg-run zeek zeek -b %INPUT +# @TEST-EXEC: btest-bg-wait 10 +# @TEST-EXEC: btest-diff zeek/.stdout + +redef exit_only_after_terminate = T; + +redef Threading::heartbeat_interval = 0.01sec; + +@TEST-START-FILE run.sh +#!/usr/bin/env bash +echo -e -n "aaa\nb" +sleep 0.1 +echo -e -n "bb\nfi" +sleep 0.1 +echo "nal" + +sleep infinity +@TEST-END-FILE + +module A; + +type Val: record { + s: string; +}; + +global lines = 0; + +event one_line(description: Input::EventDescription, tpe: Input::Event, s: string) + { + print tpe, s; + ++lines; + + if ( lines == 3 ) + { + Input::remove("input"); + terminate(); + } + } + +event zeek_init() + { + Input::add_event([ + $name="run", + $source="../run.sh |", + $reader=Input::READER_RAW, + $mode=Input::STREAM, + $fields=Val, + $ev=one_line, $want_record=F, + ]); + } diff --git a/testing/btest/scripts/base/frameworks/input/raw/executestream-no-last-separator.zeek b/testing/btest/scripts/base/frameworks/input/raw/executestream-no-last-separator.zeek new file mode 100644 index 0000000000..eeb77ac884 --- /dev/null +++ b/testing/btest/scripts/base/frameworks/input/raw/executestream-no-last-separator.zeek @@ -0,0 +1,53 @@ +# @TEST-DOC: Launching a program that doesn't end it's final line with a \n +# @TEST-EXEC: chmod +x run.sh +# @TEST-EXEC: btest-bg-run zeek zeek -b %INPUT +# @TEST-EXEC: btest-bg-wait 10 +# @TEST-EXEC: btest-diff zeek/.stdout + +redef exit_only_after_terminate = T; + +redef Threading::heartbeat_interval = 0.01sec; + +@TEST-START-FILE run.sh +#!/usr/bin/env bash +sleep 0.1 +echo "aaa" +sleep 0.1 +echo "bbb" +sleep 0.1 +echo -n "final" + +sleep 0.1 +exit 0 +@TEST-END-FILE + +module A; + +type Val: record { + s: string; +}; + +global lines = 0; + +event one_line(description: Input::EventDescription, tpe: Input::Event, s: string) + { + print tpe, s; + ++lines; + if ( lines == 3 ) + { + Input::remove("input"); + terminate(); + } + } + +event zeek_init() + { + Input::add_event([ + $name="run", + $source="../run.sh |", + $reader=Input::READER_RAW, + $mode=Input::STREAM, + $fields=Val, + $ev=one_line, $want_record=F, + ]); + } diff --git a/testing/btest/scripts/base/frameworks/input/raw/executestream-slow-long.zeek b/testing/btest/scripts/base/frameworks/input/raw/executestream-slow-long.zeek new file mode 100644 index 0000000000..da6e489b4e --- /dev/null +++ b/testing/btest/scripts/base/frameworks/input/raw/executestream-slow-long.zeek @@ -0,0 +1,62 @@ +# @TEST-DOC: Launching a program that produces output slowly and exercises buffering. +# @TEST-EXEC: chmod +x run.sh +# @TEST-EXEC: btest-bg-run zeek zeek -b %INPUT +# @TEST-EXEC: btest-bg-wait 10 +# @TEST-EXEC: btest-diff zeek/.stdout + +redef exit_only_after_terminate = T; + +redef Threading::heartbeat_interval = 0.01sec; + +@TEST-START-FILE run.sh +#!/usr/bin/env bash +sleep 0.1 +echo -n "binary start" +sleep 0.1 +dd if=/dev/zero bs=1 count=8192 +sleep 0.1 +echo -n "binary middle" +sleep 0.1 +dd if=/dev/zero bs=1 count=8192 +sleep 0.1 +dd if=/dev/zero bs=1 count=8192 +sleep 0.1 +echo "binary done" +sleep 0.1 +echo "ccc" +sleep 0.1 +echo "final" + +sleep infinity +@TEST-END-FILE + +module A; + +type Val: record { + s: string; +}; + +global lines = 0; + +event one_line(description: Input::EventDescription, tpe: Input::Event, s: string) + { + print tpe,|s|, s[:16], s[-16:]; + ++lines; + if ( lines == 3 ) + { + Input::remove("input"); + terminate(); + } + } + +event zeek_init() + { + Input::add_event([ + $name="run", + $source="../run.sh |", + $reader=Input::READER_RAW, + $mode=Input::STREAM, + $fields=Val, + $ev=one_line, $want_record=F, + ]); + } diff --git a/testing/btest/scripts/base/frameworks/input/raw/executestream-slow.zeek b/testing/btest/scripts/base/frameworks/input/raw/executestream-slow.zeek new file mode 100644 index 0000000000..d221805b33 --- /dev/null +++ b/testing/btest/scripts/base/frameworks/input/raw/executestream-slow.zeek @@ -0,0 +1,55 @@ +# @TEST-DOC: Launching a program that produces output slowly puts the raw reader into an endless loop. +# @TEST-EXEC: chmod +x run.sh +# @TEST-EXEC: btest-bg-run zeek zeek -b %INPUT +# @TEST-EXEC: btest-bg-wait 10 +# @TEST-EXEC: btest-diff zeek/.stdout + +redef exit_only_after_terminate = T; + +redef Threading::heartbeat_interval = 0.01sec; + +@TEST-START-FILE run.sh +#!/usr/bin/env bash +sleep 0.1 +echo -n "aaa-" +sleep 0.1 +echo -n "bbb-" +sleep 0.1 +echo "ccc" +sleep 0.1 +echo "aaa-bbb-ccc" +echo "final" + +sleep infinity +@TEST-END-FILE + +module A; + +type Val: record { + s: string; +}; + +global lines = 0; + +event one_line(description: Input::EventDescription, tpe: Input::Event, s: string) + { + print tpe, s; + ++lines; + if ( lines == 3 ) + { + Input::remove("input"); + terminate(); + } + } + +event zeek_init() + { + Input::add_event([ + $name="run", + $source="../run.sh |", + $reader=Input::READER_RAW, + $mode=Input::STREAM, + $fields=Val, + $ev=one_line, $want_record=F, + ]); + } From 3ebe867193df00acfc5ea9157a37708929261a70 Mon Sep 17 00:00:00 2001 From: Arne Welzel Date: Mon, 21 Oct 2024 15:51:05 +0200 Subject: [PATCH 64/91] Merge branch 'modbus-fixes' of https://github.com/zambo99/zeek * 'modbus-fixes' of https://github.com/zambo99/zeek: Prevent non-Modbus on port 502 to be reported as Modbus (cherry picked from commit 4763282f36d13808b58948cc378a7df00201c9f5) --- CHANGES | 13 +++++++++++ VERSION | 2 +- .../protocol/modbus/modbus-protocol.pac | 4 ++-- .../modbus.log | 10 ++++---- .../analyzer.log | 20 ++++++++++++++++ .../conn.log | 18 ++++++++++++++ .../modbus.log | 22 ++++++++++++++++++ .../modbus/modbus-and-non-modbus-p502.pcap | Bin 0 -> 7414 bytes .../modbus_and_non_modbus_on_port_502.test | 7 ++++++ 9 files changed, 88 insertions(+), 8 deletions(-) create mode 100644 testing/btest/Baseline/scripts.base.protocols.modbus.modbus_and_non_modbus_on_port_502/analyzer.log create mode 100644 testing/btest/Baseline/scripts.base.protocols.modbus.modbus_and_non_modbus_on_port_502/conn.log create mode 100644 testing/btest/Baseline/scripts.base.protocols.modbus.modbus_and_non_modbus_on_port_502/modbus.log create mode 100644 testing/btest/Traces/modbus/modbus-and-non-modbus-p502.pcap create mode 100644 testing/btest/scripts/base/protocols/modbus/modbus_and_non_modbus_on_port_502.test diff --git a/CHANGES b/CHANGES index 0bbcd905b5..5c5e754ad1 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,16 @@ +7.0.3-11 | 2024-11-14 11:31:35 -0700 + + * GH-3962: Prevent non-Modbus on port 502 to be reported as Modbus (Emmanuele Zambon) + + This commit prevents most non-Modbus TCP traffic on port 502 to be + reported as Modbus in conn.log as well as in modbus.log. + To do so, we have introduced two &enforce checks in the Modbus + protocol definition that checks that some specific fields of the + (supposedly) Modbus header are compatible with values specified in + the specs. + + (cherry picked from commit 4763282f36d13808b58948cc378a7df00201c9f5) + 7.0.3-10 | 2024-11-14 11:30:00 -0700 * GH-3957: input/Raw: Rework GetLine() (Arne Welzel, Corelight) diff --git a/VERSION b/VERSION index 8bea599430..0550c7cb26 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -7.0.3-10 +7.0.3-11 diff --git a/src/analyzer/protocol/modbus/modbus-protocol.pac b/src/analyzer/protocol/modbus/modbus-protocol.pac index ebd1805815..5b566e6729 100644 --- a/src/analyzer/protocol/modbus/modbus-protocol.pac +++ b/src/analyzer/protocol/modbus/modbus-protocol.pac @@ -90,8 +90,8 @@ type ModbusTCP_PDU(is_orig: bool) = record { type ModbusTCP_TransportHeader = record { tid: uint16; # Transaction identifier - pid: uint16; # Protocol identifier - len: uint16; # Length of everything after this field + pid: uint16 &enforce(pid == 0); # Protocol identifier + len: uint16 &enforce(len >= 2); # Length of everything after this field uid: uint8; # Unit identifier (previously 'slave address') fc: uint8; # MODBUS function code (see function_codes enum) } &byteorder=bigendian, &let { diff --git a/testing/btest/Baseline/scripts.base.protocols.modbus.exception_handling/modbus.log b/testing/btest/Baseline/scripts.base.protocols.modbus.exception_handling/modbus.log index 9298bf4eeb..07518ad4fc 100644 --- a/testing/btest/Baseline/scripts.base.protocols.modbus.exception_handling/modbus.log +++ b/testing/btest/Baseline/scripts.base.protocols.modbus.exception_handling/modbus.log @@ -11,15 +11,15 @@ XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 192.168.66.235 2582 166.161.16.230 502 0 1 u XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 192.168.66.235 2582 166.161.16.230 502 0 1 unknown-29 REQ - XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 192.168.66.235 2582 166.161.16.230 502 0 1 unknown-160 RESP - XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 192.168.66.235 2582 166.161.16.230 502 0 1 unknown-33 REQ - -XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 192.168.66.235 2582 166.161.16.230 502 0 0 WRITE_SINGLE_REGISTER REQ - -XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 192.168.66.235 2582 166.161.16.230 502 0 1 unknown-162 RESP - XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 192.168.66.235 2582 166.161.16.230 502 21504 1 unknown-35 REQ - XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 192.168.66.235 2582 166.161.16.230 502 0 1 unknown-36 REQ - XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 192.168.66.235 2582 166.161.16.230 502 0 1 unknown-37 REQ - XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 192.168.66.235 2582 166.161.16.230 502 0 0 unknown-38 REQ - XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 192.168.66.235 2582 166.161.16.230 502 0 1 unknown-175 RESP - XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 192.168.66.235 2582 166.161.16.230 502 0 1 unknown-179 RESP - -XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 192.168.66.235 2582 166.161.16.230 502 12032 0 unknown-0 REQ - -XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 192.168.66.235 2582 166.161.16.230 502 0 0 unknown-0 REQ - -XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 192.168.66.235 2582 166.161.16.230 502 0 1 unknown-165 RESP - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 192.168.66.235 2582 166.161.16.230 502 0 1 unknown-54 REQ - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 192.168.66.235 2582 166.161.16.230 502 37 1 unknown-71 REQ - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 192.168.66.235 2582 166.161.16.230 502 0 1 unknown-63 REQ - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 192.168.66.235 2582 166.161.16.230 502 0 1 unknown-65 REQ - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 192.168.66.235 2582 166.161.16.230 502 0 1 unknown-71 REQ - #close XXXX-XX-XX-XX-XX-XX diff --git a/testing/btest/Baseline/scripts.base.protocols.modbus.modbus_and_non_modbus_on_port_502/analyzer.log b/testing/btest/Baseline/scripts.base.protocols.modbus.modbus_and_non_modbus_on_port_502/analyzer.log new file mode 100644 index 0000000000..ab8cb41827 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.modbus.modbus_and_non_modbus_on_port_502/analyzer.log @@ -0,0 +1,20 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path analyzer +#open XXXX-XX-XX-XX-XX-XX +#fields ts cause analyzer_kind analyzer_name uid fuid id.orig_h id.orig_p id.resp_h id.resp_p failure_reason failure_data +#types time string string string string string addr port addr port string string +XXXXXXXXXX.XXXXXX violation protocol MODBUS ClEkJM2Vm5giqnMf4h - 87.236.176.106 38129 192.168.10.111 502 Binpac exception: binpac exception: &enforce violation : ModbusTCP_TransportHeader:pid - +XXXXXXXXXX.XXXXXX violation protocol MODBUS ClEkJM2Vm5giqnMf4h - 87.236.176.106 38129 192.168.10.111 502 Binpac exception: binpac exception: &enforce violation : ModbusTCP_TransportHeader:pid - +XXXXXXXXXX.XXXXXX violation protocol MODBUS C4J4Th3PJpwUYZZ6gc - 87.236.176.96 60175 192.168.10.111 502 Binpac exception: binpac exception: &enforce violation : ModbusTCP_TransportHeader:pid - +XXXXXXXXXX.XXXXXX violation protocol MODBUS C4J4Th3PJpwUYZZ6gc - 87.236.176.96 60175 192.168.10.111 502 Binpac exception: binpac exception: &enforce violation : ModbusTCP_TransportHeader:pid - +XXXXXXXXXX.XXXXXX violation protocol MODBUS CtPZjS20MLrsMUOJi2 - 66.175.213.4 58380 192.168.10.111 502 Binpac exception: binpac exception: &enforce violation : ModbusTCP_TransportHeader:pid - +XXXXXXXXXX.XXXXXX violation protocol MODBUS CtPZjS20MLrsMUOJi2 - 66.175.213.4 58380 192.168.10.111 502 Binpac exception: binpac exception: &enforce violation : ModbusTCP_TransportHeader:pid - +XXXXXXXXXX.XXXXXX violation protocol MODBUS CP5puj4I8PtEU4qzYg - 159.203.208.13 33752 192.168.10.113 502 Binpac exception: binpac exception: &enforce violation : ModbusTCP_TransportHeader:pid - +XXXXXXXXXX.XXXXXX violation protocol MODBUS CP5puj4I8PtEU4qzYg - 159.203.208.13 33752 192.168.10.113 502 Binpac exception: binpac exception: &enforce violation : ModbusTCP_TransportHeader:pid - +XXXXXXXXXX.XXXXXX violation protocol MODBUS C37jN32gN3y3AZzyf6 - 62.122.184.123 7488 192.168.10.111 502 Binpac exception: binpac exception: &enforce violation : ModbusTCP_TransportHeader:pid - +XXXXXXXXXX.XXXXXX violation protocol MODBUS C37jN32gN3y3AZzyf6 - 62.122.184.123 7488 192.168.10.111 502 Binpac exception: binpac exception: &enforce violation : ModbusTCP_TransportHeader:pid - +#close XXXX-XX-XX-XX-XX-XX diff --git a/testing/btest/Baseline/scripts.base.protocols.modbus.modbus_and_non_modbus_on_port_502/conn.log b/testing/btest/Baseline/scripts.base.protocols.modbus.modbus_and_non_modbus_on_port_502/conn.log new file mode 100644 index 0000000000..945c873d56 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.modbus.modbus_and_non_modbus_on_port_502/conn.log @@ -0,0 +1,18 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path conn +#open XXXX-XX-XX-XX-XX-XX +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p proto service duration orig_bytes resp_bytes conn_state local_orig local_resp missed_bytes history orig_pkts orig_ip_bytes resp_pkts resp_ip_bytes tunnel_parents +#types time string addr port addr port enum string interval count count string bool bool count string count count count count set[string] +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 10.0.0.9 3082 10.0.0.3 502 tcp modbus 177.095534 72 69 SF T T 0 ShADdFaf 16 720 9 437 - +XXXXXXXXXX.XXXXXX ClEkJM2Vm5giqnMf4h 87.236.176.106 38129 192.168.10.111 502 tcp dce_rpc 5.102604 72 9 SF F T 0 ShADadFf 6 392 4 225 - +XXXXXXXXXX.XXXXXX C4J4Th3PJpwUYZZ6gc 87.236.176.96 60175 192.168.10.111 502 tcp - 5.052092 44 9 SF F T 0 ShADadFf 6 364 4 225 - +XXXXXXXXXX.XXXXXX CtPZjS20MLrsMUOJi2 66.175.213.4 58380 192.168.10.111 502 tcp ssl 59.999857 138 9 SF F T 0 ShADadFf 9 610 7 377 - +XXXXXXXXXX.XXXXXX CUM0KZ3MLUfNB0cl11 198.74.56.135 60293 192.168.10.111 502 tcp - 0.117322 0 0 RSTO F T 0 ShR 2 80 1 44 - +XXXXXXXXXX.XXXXXX CmES5u32sYpV7JYN 198.74.56.135 60293 192.168.10.111 502 tcp - 0.000054 109 0 RSTRH F T 0 Dr 1 149 1 40 - +XXXXXXXXXX.XXXXXX CP5puj4I8PtEU4qzYg 159.203.208.13 33752 192.168.10.113 502 tcp - 0.470159 24 9 SF F T 0 ShADadFf 6 344 4 225 - +XXXXXXXXXX.XXXXXX C37jN32gN3y3AZzyf6 62.122.184.123 7488 192.168.10.111 502 tcp - 30.159557 43 9 SF F T 0 ShADadFf 6 295 4 181 - +#close XXXX-XX-XX-XX-XX-XX diff --git a/testing/btest/Baseline/scripts.base.protocols.modbus.modbus_and_non_modbus_on_port_502/modbus.log b/testing/btest/Baseline/scripts.base.protocols.modbus.modbus_and_non_modbus_on_port_502/modbus.log new file mode 100644 index 0000000000..0bf4ca545b --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.modbus.modbus_and_non_modbus_on_port_502/modbus.log @@ -0,0 +1,22 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path modbus +#open XXXX-XX-XX-XX-XX-XX +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p tid unit func pdu_type exception +#types time string addr port addr port count count string string string +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 10.0.0.9 3082 10.0.0.3 502 1 10 READ_COILS REQ - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 10.0.0.9 3082 10.0.0.3 502 1 10 READ_COILS RESP - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 10.0.0.9 3082 10.0.0.3 502 1 10 READ_COILS REQ - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 10.0.0.9 3082 10.0.0.3 502 1 10 READ_COILS RESP - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 10.0.0.9 3082 10.0.0.3 502 1 10 READ_HOLDING_REGISTERS REQ - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 10.0.0.9 3082 10.0.0.3 502 1 10 READ_HOLDING_REGISTERS RESP - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 10.0.0.9 3082 10.0.0.3 502 1 10 WRITE_SINGLE_COIL REQ - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 10.0.0.9 3082 10.0.0.3 502 1 10 WRITE_SINGLE_COIL RESP - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 10.0.0.9 3082 10.0.0.3 502 1 10 WRITE_SINGLE_COIL REQ - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 10.0.0.9 3082 10.0.0.3 502 1 10 WRITE_SINGLE_COIL RESP - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 10.0.0.9 3082 10.0.0.3 502 1 10 WRITE_SINGLE_REGISTER REQ - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 10.0.0.9 3082 10.0.0.3 502 1 10 WRITE_SINGLE_REGISTER RESP - +#close XXXX-XX-XX-XX-XX-XX diff --git a/testing/btest/Traces/modbus/modbus-and-non-modbus-p502.pcap b/testing/btest/Traces/modbus/modbus-and-non-modbus-p502.pcap new file mode 100644 index 0000000000000000000000000000000000000000..a3b1ea28f848db3fbb49fdeae33b59d7bba2acbd GIT binary patch literal 7414 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 Date: Tue, 22 Oct 2024 11:24:50 +0200 Subject: [PATCH 65/91] Merge remote-tracking branch 'origin/topic/awelzel/3978-zeekjs-0.12.1-bump' * origin/topic/awelzel/3978-zeekjs-0.12.1-bump: Bump zeekjs to 0.12.1 (cherry picked from commit d74b073852b748aca7793f557f0a5378cb30ca19) --- CHANGES | 9 +++++++++ VERSION | 2 +- auxil/zeekjs | 2 +- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/CHANGES b/CHANGES index 5c5e754ad1..59d61d1bcd 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,12 @@ +7.0.3-12 | 2024-11-14 11:33:09 -0700 + + * GH-3978: Bump zeekjs to 0.12.1 (Arne Welzel, Corelight) + 7ec0953 ci: Bump actions/upload-artifact + 8e5914d ci/docker: Bump distros, update some OBS repos + 129b737 Fix crash during shutdown + + (cherry picked from commit d74b073852b748aca7793f557f0a5378cb30ca19) + 7.0.3-11 | 2024-11-14 11:31:35 -0700 * GH-3962: Prevent non-Modbus on port 502 to be reported as Modbus (Emmanuele Zambon) diff --git a/VERSION b/VERSION index 0550c7cb26..bee16bfcd8 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -7.0.3-11 +7.0.3-12 diff --git a/auxil/zeekjs b/auxil/zeekjs index 230f53c159..acae06c60c 160000 --- a/auxil/zeekjs +++ b/auxil/zeekjs @@ -1 +1 @@ -Subproject commit 230f53c1596ee88289e96397f0810ca60ed897e3 +Subproject commit acae06c60c4631892c5b497557c5e12283e4218f From e3845060dca77795a8dd29c69fc6d6a723a96ae2 Mon Sep 17 00:00:00 2001 From: Evan Typanski Date: Tue, 29 Oct 2024 09:48:04 -0400 Subject: [PATCH 66/91] Fix Clang 19 deprecation failure Fixes #3994 Clang 19 with libc++ started failing to compile because the default implementation of `std::char_traits` was removed, making uses of `std::char_traits` invalid. This was more of used for convenience before, but it should be roughly the same behavior with `char`. See relevant LLVM commits: https://github.com/llvm/llvm-project/commit/aeecef08c385b1e4955155dd649a2d3724463849 https://github.com/llvm/llvm-project/commit/08a0faf4cd32bce6c51027ea9b5ec351747995b4 (cherry picked from commit 985f4f7c725ae1a9f85dbc112e5bc340a34a034b) --- src/DFA.cc | 6 +++--- src/DFA.h | 4 ++-- src/analyzer/protocol/ssl/SSL.cc | 31 ++++++++++++++++++------------- 3 files changed, 23 insertions(+), 18 deletions(-) diff --git a/src/DFA.cc b/src/DFA.cc index b9d62f8db4..c2ac56b616 100644 --- a/src/DFA.cc +++ b/src/DFA.cc @@ -265,9 +265,9 @@ DFA_State_Cache::~DFA_State_Cache() { DFA_State* DFA_State_Cache::Lookup(const NFA_state_list& nfas, DigestStr* digest) { // We assume that state ID's don't exceed 10 digits, plus // we allow one more character for the delimiter. - auto id_tag_buf = std::make_unique(nfas.length() * 11 + 1); + auto id_tag_buf = std::make_unique(nfas.length() * 11 + 1); auto id_tag = id_tag_buf.get(); - u_char* p = id_tag; + char* p = id_tag; for ( int i = 0; i < nfas.length(); ++i ) { NFA_State* n = nfas[i]; @@ -287,7 +287,7 @@ DFA_State* DFA_State_Cache::Lookup(const NFA_state_list& nfas, DigestStr* digest // HashKey because the data is copied into the key. hash128_t hash; KeyedHash::Hash128(id_tag, p - id_tag, &hash); - *digest = DigestStr(reinterpret_cast(hash), 16); + *digest = DigestStr(reinterpret_cast(hash), 16); auto entry = states.find(*digest); if ( entry == states.end() ) { diff --git a/src/DFA.h b/src/DFA.h index 1bf2979ec3..e44fa05b22 100644 --- a/src/DFA.h +++ b/src/DFA.h @@ -2,7 +2,7 @@ #pragma once -#include // for u_char +#include #include #include #include @@ -67,7 +67,7 @@ protected: DFA_State* mark; }; -using DigestStr = std::basic_string; +using DigestStr = std::string; struct DFA_State_Cache_Stats { // Sum of all NFA states diff --git a/src/analyzer/protocol/ssl/SSL.cc b/src/analyzer/protocol/ssl/SSL.cc index 55f3469870..8a4718dab7 100644 --- a/src/analyzer/protocol/ssl/SSL.cc +++ b/src/analyzer/protocol/ssl/SSL.cc @@ -3,6 +3,7 @@ #include #include #include +#include #include "zeek/Reporter.h" #include "zeek/analyzer/Manager.h" @@ -22,6 +23,8 @@ namespace zeek::analyzer::ssl { +using byte_buffer = std::vector; + template static inline T MSB(const T a) { return ((a >> 8) & 0xff); @@ -32,12 +35,13 @@ static inline T LSB(const T a) { return (a & 0xff); } -static std::basic_string fmt_seq(uint32_t num) { - std::basic_string out(4, '\0'); +static byte_buffer fmt_seq(uint32_t num) { + byte_buffer out(4, '\0'); out.reserve(13); uint32_t netnum = htonl(num); - out.append(reinterpret_cast(&netnum), 4); - out.append(5, '\0'); + uint8_t* p = reinterpret_cast(&netnum); + out.insert(out.end(), p, p + 4); + out.insert(out.end(), 5, '\0'); return out; } @@ -271,7 +275,7 @@ bool SSL_Analyzer::TryDecryptApplicationData(int len, const u_char* data, bool i const u_char* s_iv = keys.data() + 68; // FIXME: should we change types here? - u_char* encrypted = (u_char*)data; + const u_char* encrypted = data; size_t encrypted_len = len; if ( is_orig ) @@ -280,14 +284,15 @@ bool SSL_Analyzer::TryDecryptApplicationData(int len, const u_char* data, bool i s_seq++; // AEAD nonce, length 12 - std::basic_string s_aead_nonce; + byte_buffer s_aead_nonce; + s_aead_nonce.reserve(12); if ( is_orig ) - s_aead_nonce.assign(c_iv, 4); + s_aead_nonce.insert(s_aead_nonce.end(), c_iv, c_iv + 4); else - s_aead_nonce.assign(s_iv, 4); + s_aead_nonce.insert(s_aead_nonce.end(), s_iv, s_iv + 4); // this should be the explicit counter - s_aead_nonce.append(encrypted, 8); + s_aead_nonce.insert(s_aead_nonce.end(), encrypted, encrypted + 8); assert(s_aead_nonce.size() == 12); EVP_CIPHER_CTX* ctx = EVP_CIPHER_CTX_new(); @@ -310,28 +315,28 @@ bool SSL_Analyzer::TryDecryptApplicationData(int len, const u_char* data, bool i else EVP_DecryptInit(ctx, EVP_aes_256_gcm(), s_wk, s_aead_nonce.data()); - EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, 16, encrypted + encrypted_len); + EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, 16, const_cast(encrypted + encrypted_len)); // AEAD tag - std::basic_string s_aead_tag; + byte_buffer s_aead_tag; if ( is_orig ) s_aead_tag = fmt_seq(c_seq); else s_aead_tag = fmt_seq(s_seq); + assert(s_aead_tag.size() == 13); s_aead_tag[8] = content_type; s_aead_tag[9] = MSB(raw_tls_version); s_aead_tag[10] = LSB(raw_tls_version); s_aead_tag[11] = MSB(encrypted_len); s_aead_tag[12] = LSB(encrypted_len); - assert(s_aead_tag.size() == 13); auto decrypted = std::vector(encrypted_len + 16); // see OpenSSL manpage - 16 is the block size for the supported cipher int decrypted_len = 0; EVP_DecryptUpdate(ctx, NULL, &decrypted_len, s_aead_tag.data(), s_aead_tag.size()); - EVP_DecryptUpdate(ctx, decrypted.data(), &decrypted_len, (const u_char*)encrypted, encrypted_len); + EVP_DecryptUpdate(ctx, decrypted.data(), &decrypted_len, encrypted, encrypted_len); assert(static_cast(decrypted_len) <= decrypted.size()); decrypted.resize(decrypted_len); From 107c0da15dede9b1c09290fe4098222eef9076ea Mon Sep 17 00:00:00 2001 From: Evan Typanski Date: Tue, 29 Oct 2024 11:37:20 -0400 Subject: [PATCH 67/91] Fix up minor warnings in touched files (cherry picked from commit 36af0591a6f2c7270c68deaee4c4d733fa4086b1) --- CHANGES | 16 ++++++++++++++++ VERSION | 2 +- src/DFA.cc | 2 -- src/DFA.h | 2 +- src/analyzer/protocol/ssl/SSL.cc | 3 +-- 5 files changed, 19 insertions(+), 6 deletions(-) diff --git a/CHANGES b/CHANGES index 59d61d1bcd..e24426a505 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,19 @@ +7.0.3-14 | 2024-11-14 11:52:34 -0700 + + * Fix up minor warnings in touched files (Evan Typanski, Corelight) + + (cherry picked from commit 36af0591a6f2c7270c68deaee4c4d733fa4086b1) + + * Fix Clang 19 deprecation failure (Evan Typanski, Corelight) + + Clang 19 with libc++ started failing to compile because the default + implementation of `std::char_traits` was removed, making uses of + `std::char_traits` invalid. This was more of used for + convenience before, but it should be roughly the same behavior with + `char`. + + (cherry picked from commit 985f4f7c725ae1a9f85dbc112e5bc340a34a034b) + 7.0.3-12 | 2024-11-14 11:33:09 -0700 * GH-3978: Bump zeekjs to 0.12.1 (Arne Welzel, Corelight) diff --git a/VERSION b/VERSION index bee16bfcd8..49c645ee23 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -7.0.3-12 +7.0.3-14 diff --git a/src/DFA.cc b/src/DFA.cc index c2ac56b616..9de8c025c9 100644 --- a/src/DFA.cc +++ b/src/DFA.cc @@ -2,8 +2,6 @@ #include "zeek/DFA.h" -#include "zeek/zeek-config.h" - #include "zeek/Desc.h" #include "zeek/EquivClass.h" #include "zeek/Hash.h" diff --git a/src/DFA.h b/src/DFA.h index e44fa05b22..7944a6053f 100644 --- a/src/DFA.h +++ b/src/DFA.h @@ -18,7 +18,7 @@ class DFA_Machine; // Transitions to the uncomputed state indicate that we haven't yet // computed the state to go to. -#define DFA_UNCOMPUTED_STATE -2 +#define DFA_UNCOMPUTED_STATE (-2) #define DFA_UNCOMPUTED_STATE_PTR ((DFA_State*)DFA_UNCOMPUTED_STATE) class DFA_State : public Obj { diff --git a/src/analyzer/protocol/ssl/SSL.cc b/src/analyzer/protocol/ssl/SSL.cc index 8a4718dab7..b6a3043a21 100644 --- a/src/analyzer/protocol/ssl/SSL.cc +++ b/src/analyzer/protocol/ssl/SSL.cc @@ -6,7 +6,6 @@ #include #include "zeek/Reporter.h" -#include "zeek/analyzer/Manager.h" #include "zeek/analyzer/protocol/ssl/events.bif.h" #include "zeek/analyzer/protocol/ssl/ssl_pac.h" #include "zeek/analyzer/protocol/ssl/tls-handshake_pac.h" @@ -276,7 +275,7 @@ bool SSL_Analyzer::TryDecryptApplicationData(int len, const u_char* data, bool i // FIXME: should we change types here? const u_char* encrypted = data; - size_t encrypted_len = len; + int encrypted_len = len; if ( is_orig ) c_seq++; From 1c3be97fe9c991d5adffa0af70837f19310eec4c Mon Sep 17 00:00:00 2001 From: Benjamin Bannier Date: Tue, 5 Nov 2024 17:38:41 +0100 Subject: [PATCH 68/91] Merge remote-tracking branch 'origin/topic/bbannier/spicy-cookie-nullptr-deref' (cherry picked from commit 2e8d6e86e75bc7b0c7be67ab9c38738a1318f6ff) --- CHANGES | 22 +++ VERSION | 2 +- src/spicy/runtime-support.cc | 304 ++++++++++++++++++----------------- 3 files changed, 179 insertions(+), 149 deletions(-) diff --git a/CHANGES b/CHANGES index e24426a505..3db7e4d363 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,25 @@ +7.0.3-15 | 2024-11-14 11:56:06 -0700 + + * Fix potential nullptr deref in Spicy plugin runtime (Benjamin Bannier, Corelight) + + If we added a file but the other side of the connection had already run + into a protocol violation and shut down we could previously have + dereferenced a null cookie. This patch fixes the code so it now throws + in such scenarios. + + (cherry picked from commit 2e8d6e86e75bc7b0c7be67ab9c38738a1318f6ff) + + * Assume no Spicy cookie in most places (Benjamin Bannier, Corelight) + + We would previously assert that it was available which could have lead + to aborts since when the analyzer for either side of a connection shuts + down the connection cookie could get cleared and become nil. This patch + reworks the code slightly so we now never assume it is available. We do + this by either throwing or by making the whole operation requesting the + cookie a noop. + + (cherry picked from commit 2e8d6e86e75bc7b0c7be67ab9c38738a1318f6ff) + 7.0.3-14 | 2024-11-14 11:52:34 -0700 * Fix up minor warnings in touched files (Evan Typanski, Corelight) diff --git a/VERSION b/VERSION index 49c645ee23..27940d65f6 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -7.0.3-14 +7.0.3-15 diff --git a/src/spicy/runtime-support.cc b/src/spicy/runtime-support.cc index f5afd37461..c5d36e0b30 100644 --- a/src/spicy/runtime-support.cc +++ b/src/spicy/runtime-support.cc @@ -223,47 +223,47 @@ TypePtr rt::event_arg_type(const EventHandlerPtr& handler, const hilti::rt::inte ValPtr& rt::current_conn() { auto _ = hilti::rt::profiler::start("zeek/rt/current_conn"); - auto cookie = static_cast(hilti::rt::context::cookie()); - assert(cookie); - if ( cookie->cache.conn ) - return cookie->cache.conn; + if ( auto cookie = static_cast(hilti::rt::context::cookie()) ) { + if ( cookie->cache.conn ) + return cookie->cache.conn; - if ( auto x = cookie->protocol ) { - cookie->cache.conn = x->analyzer->Conn()->GetVal(); - return cookie->cache.conn; + if ( auto x = cookie->protocol ) { + cookie->cache.conn = x->analyzer->Conn()->GetVal(); + return cookie->cache.conn; + } } - else - throw ValueUnavailable("$conn not available"); + + throw ValueUnavailable("$conn not available"); } ValPtr& rt::current_is_orig() { auto _ = hilti::rt::profiler::start("zeek/rt/current_is_orig"); - auto cookie = static_cast(hilti::rt::context::cookie()); - assert(cookie); - if ( cookie->cache.is_orig ) - return cookie->cache.is_orig; + if ( auto cookie = static_cast(hilti::rt::context::cookie()) ) { + if ( cookie->cache.is_orig ) + return cookie->cache.is_orig; - if ( auto x = cookie->protocol ) { - cookie->cache.is_orig = val_mgr->Bool(x->is_orig); - return cookie->cache.is_orig; + if ( auto x = cookie->protocol ) { + cookie->cache.is_orig = val_mgr->Bool(x->is_orig); + return cookie->cache.is_orig; + } } - else - throw ValueUnavailable("$is_orig not available"); + + throw ValueUnavailable("$is_orig not available"); } void rt::debug(const std::string& msg) { auto _ = hilti::rt::profiler::start("zeek/rt/debug"); auto cookie = static_cast(hilti::rt::context::cookie()); - assert(cookie); + if ( ! cookie ) + return SPICY_DEBUG(msg); + rt::debug(*cookie, msg); } void rt::debug(const Cookie& cookie, const std::string& msg) { auto _ = hilti::rt::profiler::start("zeek/rt/debug"); - std::string name; - std::string id; if ( const auto p = cookie.protocol ) { auto name = p->analyzer->GetAnalyzerName(); @@ -285,12 +285,14 @@ void rt::debug(const Cookie& cookie, const std::string& msg) { inline rt::cookie::FileStateStack* _file_state_stack(rt::Cookie* cookie) { auto _ = hilti::rt::profiler::start("zeek/rt/file_state_stack"); - if ( auto c = cookie->protocol ) - return c->is_orig ? &c->fstate_orig : &c->fstate_resp; - else if ( auto f = cookie->file ) - return &f->fstate; - else - throw rt::ValueUnavailable("no current connection or file available"); + if ( cookie ) { + if ( auto c = cookie->protocol ) + return c->is_orig ? &c->fstate_orig : &c->fstate_resp; + else if ( auto f = cookie->file ) + return &f->fstate; + } + + throw rt::ValueUnavailable("no current connection or file available"); } inline const rt::cookie::FileState* _file_state(rt::Cookie* cookie, std::optional fid) { @@ -313,14 +315,14 @@ inline const rt::cookie::FileState* _file_state(rt::Cookie* cookie, std::optiona ValPtr rt::current_file() { auto _ = hilti::rt::profiler::start("zeek/rt/current_file"); - auto cookie = static_cast(hilti::rt::context::cookie()); - assert(cookie); - if ( auto x = cookie->file ) - return x->analyzer->GetFile()->ToVal(); - else if ( auto* fstate = _file_state(cookie, {}) ) { - if ( auto* f = file_mgr->LookupFile(fstate->fid) ) - return f->ToVal(); + if ( auto cookie = static_cast(hilti::rt::context::cookie()) ) { + if ( auto x = cookie->file ) + return x->analyzer->GetFile()->ToVal(); + else if ( auto* fstate = _file_state(cookie, {}) ) { + if ( auto* f = file_mgr->LookupFile(fstate->fid) ) + return f->ToVal(); + } } throw ValueUnavailable("$file not available"); @@ -328,43 +330,43 @@ ValPtr rt::current_file() { ValPtr rt::current_packet() { auto _ = hilti::rt::profiler::start("zeek/rt/current_packet"); - auto cookie = static_cast(hilti::rt::context::cookie()); - assert(cookie); - if ( auto c = cookie->packet ) { - if ( ! c->packet_val ) - // We cache the built value in case we need it multiple times. - c->packet_val = c->packet->ToRawPktHdrVal(); + if ( auto cookie = static_cast(hilti::rt::context::cookie()) ) { + if ( auto c = cookie->packet ) { + if ( ! c->packet_val ) + // We cache the built value in case we need it multiple times. + c->packet_val = c->packet->ToRawPktHdrVal(); - return c->packet_val; + return c->packet_val; + } } - else - throw ValueUnavailable("$packet not available"); + + throw ValueUnavailable("$packet not available"); } hilti::rt::Bool rt::is_orig() { auto _ = hilti::rt::profiler::start("zeek/rt/is_orig"); - auto cookie = static_cast(hilti::rt::context::cookie()); - assert(cookie); - if ( auto x = cookie->protocol ) - return x->is_orig; - else - throw ValueUnavailable("is_orig() not available in current context"); + if ( auto cookie = static_cast(hilti::rt::context::cookie()) ) { + if ( auto x = cookie->protocol ) + return x->is_orig; + } + + throw ValueUnavailable("is_orig() not available in current context"); } std::string rt::uid() { auto _ = hilti::rt::profiler::start("zeek/rt/uid"); - auto cookie = static_cast(hilti::rt::context::cookie()); - assert(cookie); - if ( auto c = cookie->protocol ) { - // Retrieve the ConnVal() so that we ensure the UID has been set. - c->analyzer->ConnVal(); - return c->analyzer->Conn()->GetUID().Base62("C"); + if ( auto cookie = static_cast(hilti::rt::context::cookie()) ) { + if ( auto c = cookie->protocol ) { + // Retrieve the ConnVal() so that we ensure the UID has been set. + c->analyzer->ConnVal(); + return c->analyzer->Conn()->GetUID().Base62("C"); + } } - else - throw ValueUnavailable("uid() not available in current context"); + + throw ValueUnavailable("uid() not available in current context"); } std::tuple rt::conn_id() { @@ -395,58 +397,59 @@ std::tuple(hilti::rt::context::cookie()); - assert(cookie); - - if ( auto c = cookie->protocol ) { - const auto* conn = c->analyzer->Conn(); - return std::make_tuple(convert_address(conn->OrigAddr()), convert_port(conn->OrigPort(), conn->ConnTransport()), - convert_address(conn->RespAddr()), - convert_port(conn->RespPort(), conn->ConnTransport())); + if ( auto cookie = static_cast(hilti::rt::context::cookie()) ) { + if ( auto c = cookie->protocol ) { + const auto* conn = c->analyzer->Conn(); + return std::make_tuple(convert_address(conn->OrigAddr()), + convert_port(conn->OrigPort(), conn->ConnTransport()), + convert_address(conn->RespAddr()), + convert_port(conn->RespPort(), conn->ConnTransport())); + } } - else - throw ValueUnavailable("conn_id() not available in current context"); + + throw ValueUnavailable("conn_id() not available in current context"); } void rt::flip_roles() { auto _ = hilti::rt::profiler::start("zeek/rt/flip_roles"); - auto cookie = static_cast(hilti::rt::context::cookie()); - assert(cookie); - rt::debug(*cookie, "flipping roles"); + if ( auto cookie = static_cast(hilti::rt::context::cookie()) ) { + rt::debug(*cookie, "flipping roles"); - if ( auto x = cookie->protocol ) - x->analyzer->Conn()->FlipRoles(); - else - throw ValueUnavailable("flip_roles() not available in current context"); + if ( auto x = cookie->protocol ) + return x->analyzer->Conn()->FlipRoles(); + } + + throw ValueUnavailable("flip_roles() not available in current context"); } hilti::rt::integer::safe rt::number_packets() { auto _ = hilti::rt::profiler::start("zeek/rt/number_packets"); - auto cookie = static_cast(hilti::rt::context::cookie()); - assert(cookie); - if ( auto x = cookie->protocol ) { - return x->num_packets; + if ( auto cookie = static_cast(hilti::rt::context::cookie()) ) { + if ( auto x = cookie->protocol ) { + return x->num_packets; + } } - else - throw ValueUnavailable("number_packets() not available in current context"); + + throw ValueUnavailable("number_packets() not available in current context"); } void rt::confirm_protocol() { auto _ = hilti::rt::profiler::start("zeek/rt/confirm_protocol"); - auto cookie = static_cast(hilti::rt::context::cookie()); - assert(cookie); - if ( cookie->cache.confirmed ) - return; + if ( auto cookie = static_cast(hilti::rt::context::cookie()) ) { + if ( cookie->cache.confirmed ) + return; - if ( auto x = cookie->protocol ) { - auto tag = spicy_mgr->tagForProtocolAnalyzer(x->analyzer->GetAnalyzerTag()); - SPICY_DEBUG(hilti::rt::fmt("confirming protocol %s", tag.AsString())); - cookie->cache.confirmed = true; - return x->analyzer->AnalyzerConfirmation(tag); + if ( auto x = cookie->protocol ) { + auto tag = spicy_mgr->tagForProtocolAnalyzer(x->analyzer->GetAnalyzerTag()); + SPICY_DEBUG(hilti::rt::fmt("confirming protocol %s", tag.AsString())); + cookie->cache.confirmed = true; + return x->analyzer->AnalyzerConfirmation(tag); + } } + throw ValueUnavailable("no current connection available"); } @@ -471,18 +474,17 @@ void rt::reject_protocol(const std::string& reason) { void rt::weird(const std::string& id, const std::string& addl) { auto _ = hilti::rt::profiler::start("zeek/rt/weird"); - auto cookie = static_cast(hilti::rt::context::cookie()); - assert(cookie); - if ( const auto x = cookie->protocol ) - x->analyzer->Weird(id.c_str(), addl.data()); - else if ( const auto x = cookie->file ) - zeek::reporter->Weird(x->analyzer->GetFile(), id.c_str(), addl.data()); - else if ( const auto x = cookie->packet ) { - x->analyzer->Weird(id.c_str(), x->packet, addl.c_str()); + if ( auto cookie = static_cast(hilti::rt::context::cookie()) ) { + if ( const auto x = cookie->protocol ) + return x->analyzer->Weird(id.c_str(), addl.data()); + else if ( const auto x = cookie->file ) + return zeek::reporter->Weird(x->analyzer->GetFile(), id.c_str(), addl.data()); + else if ( const auto x = cookie->packet ) + return x->analyzer->Weird(id.c_str(), x->packet, addl.c_str()); } - else - throw ValueUnavailable("none of $conn, $file, or $packet available for weird reporting"); + + throw ValueUnavailable("none of $conn, $file, or $packet available for weird reporting"); } void rt::protocol_begin(const std::optional& analyzer, const ::hilti::rt::Protocol& proto) { @@ -499,11 +501,11 @@ void rt::protocol_begin(const std::optional& analyzer, const ::hilt // doesn't need to track what the other side already did. auto cookie = static_cast(hilti::rt::context::cookie()); - assert(cookie); + + if ( ! cookie || ! cookie->protocol ) + throw ValueUnavailable("no current connection available"); auto c = cookie->protocol; - if ( ! c ) - throw ValueUnavailable("no current connection available"); switch ( proto.value() ) { case ::hilti::rt::Protocol::TCP: { @@ -547,12 +549,12 @@ void rt::protocol_begin(const ::hilti::rt::Protocol& proto) { return protocol_be rt::ProtocolHandle rt::protocol_handle_get_or_create(const std::string& analyzer, const ::hilti::rt::Protocol& proto) { auto _ = hilti::rt::profiler::start("zeek/rt/protocol_handle_get_or_create"); + auto cookie = static_cast(hilti::rt::context::cookie()); - assert(cookie); + if ( ! cookie || ! cookie->protocol ) + throw ValueUnavailable("no current connection available"); auto c = cookie->protocol; - if ( ! c ) - throw ValueUnavailable("no current connection available"); switch ( proto.value() ) { case ::hilti::rt::Protocol::TCP: { @@ -623,11 +625,11 @@ static void protocol_data_in(const hilti::rt::Bool& is_orig, const hilti::rt::By const std::optional& h) { auto _ = hilti::rt::profiler::start("zeek/rt/protocol_data_in"); auto cookie = static_cast(hilti::rt::context::cookie()); - assert(cookie); + + if ( ! cookie || ! cookie->protocol ) + throw ValueUnavailable("no current connection available"); auto c = cookie->protocol; - if ( ! c ) - throw ValueUnavailable("no current connection available"); // We need to copy the data here to be on the safe side: the streaming // input methods expect the data to stay around until they return. At first @@ -719,11 +721,11 @@ void rt::protocol_gap(const hilti::rt::Bool& is_orig, const hilti::rt::integer:: const hilti::rt::integer::safe& len, const std::optional& h) { auto _ = hilti::rt::profiler::start("zeek/rt/protocol_gap"); auto cookie = static_cast(hilti::rt::context::cookie()); - assert(cookie); + + if ( ! cookie || ! cookie->protocol ) + throw ValueUnavailable("no current connection available"); auto c = cookie->protocol; - if ( ! c ) - throw ValueUnavailable("no current connection available"); switch ( h->protocol().value() ) { case ::hilti::rt::Protocol::TCP: { @@ -761,25 +763,25 @@ void rt::protocol_gap(const hilti::rt::Bool& is_orig, const hilti::rt::integer:: void rt::protocol_end() { auto _ = hilti::rt::profiler::start("zeek/rt/protocol_end"); - auto cookie = static_cast(hilti::rt::context::cookie()); - assert(cookie); - auto c = cookie->protocol; - if ( ! c ) - throw ValueUnavailable("no current connection available"); + if ( auto cookie = static_cast(hilti::rt::context::cookie()) ) { + auto c = cookie->protocol; + if ( ! c ) + throw ValueUnavailable("no current connection available"); - for ( const auto& i : c->analyzer->GetChildren() ) - c->analyzer->RemoveChildAnalyzer(i); + for ( const auto& i : c->analyzer->GetChildren() ) + c->analyzer->RemoveChildAnalyzer(i); + } } void rt::protocol_handle_close(const ProtocolHandle& handle) { auto _ = hilti::rt::profiler::start("zeek/rt/protocol_handle_close"); auto cookie = static_cast(hilti::rt::context::cookie()); - assert(cookie); + + if ( ! cookie || ! cookie->protocol ) + throw ValueUnavailable("no current connection available"); auto c = cookie->protocol; - if ( ! c ) - throw ValueUnavailable("no current connection available"); switch ( handle.protocol().value() ) { case ::hilti::rt::Protocol::TCP: { @@ -827,7 +829,8 @@ rt::cookie::FileState* rt::cookie::FileStateStack::push(std::optional(hilti::rt::context::cookie()); - assert(cookie); + if ( ! cookie ) + throw ValueUnavailable("no current connection available"); if ( auto c = cookie->protocol ) { auto tag = spicy_mgr->tagForProtocolAnalyzer(c->analyzer->GetAnalyzerTag()); @@ -899,38 +902,38 @@ static void _data_in(const char* data, uint64_t len, std::optional off void rt::terminate_session() { auto _ = hilti::rt::profiler::start("zeek/rt/terminate_session"); - auto cookie = static_cast(hilti::rt::context::cookie()); - assert(cookie); - if ( auto c = cookie->protocol ) { - assert(session_mgr); - session_mgr->Remove(c->analyzer->Conn()); + if ( auto cookie = static_cast(hilti::rt::context::cookie()) ) { + if ( auto c = cookie->protocol ) { + assert(session_mgr); + return session_mgr->Remove(c->analyzer->Conn()); + } } - else - throw spicy::rt::ValueUnavailable("terminate_session() not available in the current context"); + + throw spicy::rt::ValueUnavailable("terminate_session() not available in the current context"); } void rt::skip_input() { auto _ = hilti::rt::profiler::start("zeek/rt/skip_input"); - auto cookie = static_cast(hilti::rt::context::cookie()); - assert(cookie); - if ( auto p = cookie->protocol ) - p->analyzer->SetSkip(true); - else if ( auto f = cookie->file ) - f->analyzer->SetSkip(true); - else - throw spicy::rt::ValueUnavailable("skip() not available in the current context"); + if ( auto cookie = static_cast(hilti::rt::context::cookie()) ) { + if ( auto p = cookie->protocol ) + return p->analyzer->SetSkip(true); + else if ( auto f = cookie->file ) + return f->analyzer->SetSkip(true); + } + + throw spicy::rt::ValueUnavailable("skip() not available in the current context"); } std::string rt::fuid() { auto _ = hilti::rt::profiler::start("zeek/rt/fuid"); - auto cookie = static_cast(hilti::rt::context::cookie()); - assert(cookie); - if ( auto f = cookie->file ) { - if ( auto file = f->analyzer->GetFile() ) - return file->GetID(); + if ( auto cookie = static_cast(hilti::rt::context::cookie()) ) { + if ( auto f = cookie->file ) { + if ( auto file = f->analyzer->GetFile() ) + return file->GetID(); + } } throw ValueUnavailable("fuid() not available in current context"); @@ -1003,6 +1006,9 @@ void rt::file_gap(const hilti::rt::integer::safe& offset, const hilti: const std::optional& fid) { auto _ = hilti::rt::profiler::start("zeek/rt/file_gap"); auto cookie = static_cast(hilti::rt::context::cookie()); + if ( ! cookie ) + throw spicy::rt::ValueUnavailable("file_gap() not available in the current context"); + auto* fstate = _file_state(cookie, fid); if ( auto c = cookie->protocol ) { @@ -1024,13 +1030,15 @@ void rt::file_end(const std::optional& fid) { void rt::forward_packet(const hilti::rt::integer::safe& identifier) { auto _ = hilti::rt::profiler::start("zeek/rt/forward_packet"); - auto cookie = static_cast(hilti::rt::context::cookie()); - assert(cookie); - if ( auto c = cookie->packet ) - c->next_analyzer = identifier; - else - throw ValueUnavailable("no current packet analyzer available"); + if ( auto cookie = static_cast(hilti::rt::context::cookie()) ) { + if ( auto c = cookie->packet ) { + c->next_analyzer = identifier; + return; + } + } + + throw ValueUnavailable("no current packet analyzer available"); } hilti::rt::Time rt::network_time() { From 826d5e6fb7cf8abf30dca1402c232334c83ccc5d Mon Sep 17 00:00:00 2001 From: Benjamin Bannier Date: Mon, 11 Nov 2024 21:05:41 +0100 Subject: [PATCH 69/91] Merge remote-tracking branch 'origin/topic/etyp/cookie-nullptr-spicy-dpd' (cherry picked from commit 1d38c310719088ca0e9610ec8458fe4cf8e4a318) --- CHANGES | 6 ++++++ VERSION | 2 +- src/spicy/manager.cc | 28 ++++++++++++++-------------- 3 files changed, 21 insertions(+), 15 deletions(-) diff --git a/CHANGES b/CHANGES index 3db7e4d363..f9f926d77b 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,9 @@ +7.0.3-16 | 2024-11-14 11:57:54 -0700 + + * GH-4006: Fix nullptr deref in Spicy accept/decline input (Evan Typanski, Corelight) + + (cherry picked from commit 1d38c310719088ca0e9610ec8458fe4cf8e4a318) + 7.0.3-15 | 2024-11-14 11:56:06 -0700 * Fix potential nullptr deref in Spicy plugin runtime (Benjamin Bannier, Corelight) diff --git a/VERSION b/VERSION index 27940d65f6..bf6d3118a1 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -7.0.3-15 +7.0.3-16 diff --git a/src/spicy/manager.cc b/src/spicy/manager.cc index 423febf1c9..414ba705ee 100644 --- a/src/spicy/manager.cc +++ b/src/spicy/manager.cc @@ -593,25 +593,25 @@ static ::TransportProto transport_protocol(const hilti::rt::Port port) { } static void hook_accept_input() { - auto cookie = static_cast(hilti::rt::context::cookie()); - assert(cookie); - - if ( auto x = cookie->protocol ) { - auto tag = spicy_mgr->tagForProtocolAnalyzer(x->analyzer->GetAnalyzerTag()); - SPICY_DEBUG(hilti::rt::fmt("confirming protocol %s", tag.AsString())); - return x->analyzer->AnalyzerConfirmation(tag); + if ( auto cookie = static_cast(hilti::rt::context::cookie()) ) { + if ( auto x = cookie->protocol ) { + auto tag = spicy_mgr->tagForProtocolAnalyzer(x->analyzer->GetAnalyzerTag()); + SPICY_DEBUG(hilti::rt::fmt("confirming protocol %s", tag.AsString())); + return x->analyzer->AnalyzerConfirmation(tag); + } } } static void hook_decline_input(const std::string& reason) { - auto cookie = static_cast(hilti::rt::context::cookie()); - assert(cookie); - - if ( auto x = cookie->protocol ) { - auto tag = spicy_mgr->tagForProtocolAnalyzer(x->analyzer->GetAnalyzerTag()); - SPICY_DEBUG(hilti::rt::fmt("rejecting protocol %s: %s", tag.AsString(), reason)); - return x->analyzer->AnalyzerViolation(reason.c_str(), nullptr, 0, tag); + if ( auto cookie = static_cast(hilti::rt::context::cookie()) ) { + if ( auto x = cookie->protocol ) { + auto tag = spicy_mgr->tagForProtocolAnalyzer(x->analyzer->GetAnalyzerTag()); + SPICY_DEBUG(hilti::rt::fmt("rejecting protocol %s: %s", tag.AsString(), reason)); + return x->analyzer->AnalyzerViolation(reason.c_str(), nullptr, 0, tag); + } } + else + SPICY_DEBUG(hilti::rt::fmt("attempting to reject protocol without cookie: %s", reason)); } void Manager::InitPostScript() { From f6976706687dff9409323d3090cc312b4ce2f096 Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Thu, 14 Nov 2024 12:03:43 -0700 Subject: [PATCH 70/91] Update zeekjs submodule to latest tagged version This picks up the changes to support Node.js v22.11.0. --- auxil/zeekjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/auxil/zeekjs b/auxil/zeekjs index acae06c60c..805a4663f9 160000 --- a/auxil/zeekjs +++ b/auxil/zeekjs @@ -1 +1 @@ -Subproject commit acae06c60c4631892c5b497557c5e12283e4218f +Subproject commit 805a4663f9326726d179f6af15a592ab4d9c2952 From 056b70bd2d3aae8529f3bae5fa5a35bd5bc8b197 Mon Sep 17 00:00:00 2001 From: Arne Welzel Date: Mon, 11 Nov 2024 09:34:10 +0100 Subject: [PATCH 71/91] Merge remote-tracking branch 'origin/topic/awelzel/community-id-new-connection' * origin/topic/awelzel/community-id-new-connection: policy/community-id: Populate conn$community_id in new_connection() (cherry picked from commit d3579c1f34fa679ac05df6f1f2cfbe11fc77b328) --- CHANGES | 15 +++++++++++++++ NEWS | 10 ++++++++++ VERSION | 2 +- .../policy/frameworks/notice/community-id.zeek | 10 ++++++++-- .../protocols/conn/community-id-logging.zeek | 5 ++++- .../notice.log.cut | 1 + .../conn.log.cut | 2 ++ .../out | 2 ++ .../policy/frameworks/notice/community-id.zeek | 9 +++++++++ .../conn/community-id-logging-flipped.zeek | 13 +++++++++++++ 10 files changed, 65 insertions(+), 4 deletions(-) create mode 100644 testing/btest/Baseline/scripts.policy.protocols.conn.community-id-logging-flipped/conn.log.cut create mode 100644 testing/btest/Baseline/scripts.policy.protocols.conn.community-id-logging-flipped/out create mode 100644 testing/btest/scripts/policy/protocols/conn/community-id-logging-flipped.zeek diff --git a/CHANGES b/CHANGES index f9f926d77b..ea8cb26bb4 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,18 @@ +7.0.3-18 | 2024-11-14 12:13:59 -0700 + + * policy/community-id: Populate conn$community_id in new_connection() (Arne Welzel, Corelight) + + This wasn't possible before #3028 was fixed, but now it's safe to set + the value in new_connection() and allow other users access to the + field much earlier. We do not have to deal with connection_flipped() + because the community-id hash is symmetric. + + (cherry picked from commit d3579c1f34fa679ac05df6f1f2cfbe11fc77b328) + + * Update zeekjs submodule to latest tagged version (Tim Wojtulewicz, Corelight) + + This picks up the changes to support Node.js v22.11.0. + 7.0.3-16 | 2024-11-14 11:57:54 -0700 * GH-4006: Fix nullptr deref in Spicy accept/decline input (Evan Typanski, Corelight) diff --git a/NEWS b/NEWS index e96b28f4d3..ea07332454 100644 --- a/NEWS +++ b/NEWS @@ -3,6 +3,16 @@ This document summarizes the most important changes in the current Zeek release. For an exhaustive list of changes, see the ``CHANGES`` file (note that submodules, such as Broker, come with their own ``CHANGES``.) +Zeek 7.0.4 +========== + +This release fixes the following bugs: + +- The community-id-logging.zeek policy script was used to set + ``c$conn$community_id`` during ``new_connection()`` rather than + ``connection_state_remove()``, allowing other scripts to reuse its value + early. + Zeek 7.0.3 ========== diff --git a/VERSION b/VERSION index bf6d3118a1..7f58b2fa2b 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -7.0.3-16 +7.0.3-18 diff --git a/scripts/policy/frameworks/notice/community-id.zeek b/scripts/policy/frameworks/notice/community-id.zeek index a1b9a65659..8dc71b1561 100644 --- a/scripts/policy/frameworks/notice/community-id.zeek +++ b/scripts/policy/frameworks/notice/community-id.zeek @@ -20,6 +20,12 @@ export { hook Notice::notice(n: Notice::Info) { - if ( CommunityID::Notice::enabled && n?$conn ) - n$community_id = community_id_v1(n$conn$id, CommunityID::seed, CommunityID::do_base64); + if ( CommunityID::Notice::enabled && n?$conn && n$conn?$conn ) + { + local info = n$conn$conn; + # This is set during new_connection(), so it should + # always be there, but better safe than sorry. + if ( info?$community_id ) + n$community_id = info$community_id; + } } diff --git a/scripts/policy/protocols/conn/community-id-logging.zeek b/scripts/policy/protocols/conn/community-id-logging.zeek index a08430727b..be8a7f8b7f 100644 --- a/scripts/policy/protocols/conn/community-id-logging.zeek +++ b/scripts/policy/protocols/conn/community-id-logging.zeek @@ -17,7 +17,10 @@ export { }; } -event connection_state_remove(c: connection) +module Conn; + +event new_connection(c: connection) &priority=5 { + Conn::set_conn(c, F); # likely first to access :-/ c$conn$community_id = community_id_v1(c$id, CommunityID::seed, CommunityID::do_base64); } diff --git a/testing/btest/Baseline/scripts.policy.frameworks.notice.community-id/notice.log.cut b/testing/btest/Baseline/scripts.policy.frameworks.notice.community-id/notice.log.cut index 7227d38c91..3fc24c4d1e 100644 --- a/testing/btest/Baseline/scripts.policy.frameworks.notice.community-id/notice.log.cut +++ b/testing/btest/Baseline/scripts.policy.frameworks.notice.community-id/notice.log.cut @@ -1,3 +1,4 @@ ### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. - - - - - - COMMUNITY_ID_INIT Zeek initializing +141.142.228.5 59856 192.150.187.43 80 tcp 1:yvyB8h+3dnggTZW0UEITWCst97w= COMMUNITY_ID_NEW_CONNECTION New connection 141.142.228.5 59856 192.150.187.43 80 tcp 1:yvyB8h+3dnggTZW0UEITWCst97w= COMMUNITY_ID_CONN_ESTABLISHED Connection establishment diff --git a/testing/btest/Baseline/scripts.policy.protocols.conn.community-id-logging-flipped/conn.log.cut b/testing/btest/Baseline/scripts.policy.protocols.conn.community-id-logging-flipped/conn.log.cut new file mode 100644 index 0000000000..b02a020eb9 --- /dev/null +++ b/testing/btest/Baseline/scripts.policy.protocols.conn.community-id-logging-flipped/conn.log.cut @@ -0,0 +1,2 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +141.142.228.5 59856 192.150.187.43 80 tcp - 1:yvyB8h+3dnggTZW0UEITWCst97w= diff --git a/testing/btest/Baseline/scripts.policy.protocols.conn.community-id-logging-flipped/out b/testing/btest/Baseline/scripts.policy.protocols.conn.community-id-logging-flipped/out new file mode 100644 index 0000000000..d70fe804fb --- /dev/null +++ b/testing/btest/Baseline/scripts.policy.protocols.conn.community-id-logging-flipped/out @@ -0,0 +1,2 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +new_connection, CHhAvVGS1DHFjwGM9, 1:yvyB8h+3dnggTZW0UEITWCst97w= diff --git a/testing/btest/scripts/policy/frameworks/notice/community-id.zeek b/testing/btest/scripts/policy/frameworks/notice/community-id.zeek index 8383017c63..07fd57a77d 100644 --- a/testing/btest/scripts/policy/frameworks/notice/community-id.zeek +++ b/testing/btest/scripts/policy/frameworks/notice/community-id.zeek @@ -13,6 +13,7 @@ redef enum Notice::Type += { COMMUNITY_ID_INIT, COMMUNITY_ID_CONN_ESTABLISHED, + COMMUNITY_ID_NEW_CONNECTION, }; event zeek_init() @@ -22,6 +23,14 @@ event zeek_init() $msg="Zeek initializing"]); } +event new_connection(c: connection) + { + # A notice with connection context + NOTICE([$note=COMMUNITY_ID_NEW_CONNECTION, + $msg="New connection", + $conn=c]); + } + event connection_established(c: connection) { # A notice with connection context diff --git a/testing/btest/scripts/policy/protocols/conn/community-id-logging-flipped.zeek b/testing/btest/scripts/policy/protocols/conn/community-id-logging-flipped.zeek new file mode 100644 index 0000000000..a7c425dca3 --- /dev/null +++ b/testing/btest/scripts/policy/protocols/conn/community-id-logging-flipped.zeek @@ -0,0 +1,13 @@ +# @TEST-DOC: Ensure community_id is logged even if the connection is flipped. + +# @TEST-EXEC: zeek -b -r $TRACES/tcp/handshake-reorder.trace %INPUT >out +# @TEST-EXEC: zeek-cut id.orig_h id.orig_p id.resp_h id.resp_p proto service community_id < conn.log > conn.log.cut +# @TEST-EXEC: btest-diff out +# @TEST-EXEC: btest-diff conn.log.cut + +@load protocols/conn/community-id-logging + +event new_connection(c: connection) + { + print "new_connection", c$uid, c$conn$community_id; + } From 7ed52733d298087943efdff28cb07ca995d79529 Mon Sep 17 00:00:00 2001 From: Arne Welzel Date: Fri, 8 Nov 2024 15:22:26 +0100 Subject: [PATCH 72/91] Merge remote-tracking branch 'origin/topic/awelzel/asan-zam-ci' * origin/topic/awelzel/asan-zam-ci: ci: Add asan and ubsan sanitizer tasks for ZAM (cherry picked from commit 8945b2b186e633f1f7c3a07f9e343da278c037ec) --- .cirrus.yml | 38 ++++++++++++++++++++++++++++++++++++++ CHANGES | 6 ++++++ VERSION | 2 +- 3 files changed, 45 insertions(+), 1 deletion(-) diff --git a/.cirrus.yml b/.cirrus.yml index 88ffb16c76..450518570a 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -66,6 +66,12 @@ skip_task_on_pr: &SKIP_TASK_ON_PR skip: > ($CIRRUS_PR != '' && $CIRRUS_PR_LABELS !=~ '.*fullci.*') +zam_skip_task_on_pr: &ZAM_SKIP_TASK_ON_PR + # Skip this task on PRs if it does not have the fullci or zamci label, + # it continues to run for direct pushes to master/release. + skip: > + ($CIRRUS_PR != '' && $CIRRUS_PR_LABELS !=~ '.*fullci.*' && $CIRRUS_PR_LABELS !=~ '.*zamci.*') + benchmark_only_if_template: &BENCHMARK_ONLY_IF_TEMPLATE # only_if condition for cron-triggered benchmarking tests. # These currently do not run for release/.* @@ -388,6 +394,21 @@ asan_sanitizer_task: # Use absolute paths for coverage files. CCACHE_BASEDIR: +# ASAN task executing btests with zam alternative. +asan_sanitizer_zam_task: + container: + dockerfile: ci/ubuntu-24.04/Dockerfile + << : *RESOURCES_TEMPLATE + + << : *CI_TEMPLATE + test_script: + # Run just the btests with zam as alternative. + - cd testing/btest && ../../auxil/btest/btest -a zam -A -d -b -j ${ZEEK_CI_BTEST_JOBS} + env: + ZEEK_CI_CONFIGURE_FLAGS: *ASAN_SANITIZER_CONFIG + ASAN_OPTIONS: detect_leaks=1:detect_odr_violation=0 + << : *ZAM_SKIP_TASK_ON_PR + ubsan_sanitizer_task: container: # Just uses a recent/common distro to run undefined behavior checks. @@ -405,6 +426,23 @@ ubsan_sanitizer_task: ZEEK_TAILORED_UB_CHECKS: 1 UBSAN_OPTIONS: print_stacktrace=1 +ubsan_sanitizer_zam_task: + container: + dockerfile: ci/ubuntu-24.04/Dockerfile + << : *RESOURCES_TEMPLATE + + << : *CI_TEMPLATE + test_script: + # Run just the btests with zam as alternative. + - cd testing/btest && ../../auxil/btest/btest -a zam -A -d -b -j ${ZEEK_CI_BTEST_JOBS} + env: + CC: clang-18 + CXX: clang++-18 + ZEEK_CI_CONFIGURE_FLAGS: *UBSAN_SANITIZER_CONFIG + ZEEK_TAILORED_UB_CHECKS: 1 + UBSAN_OPTIONS: print_stacktrace=1 + << : *ZAM_SKIP_TASK_ON_PR + tsan_sanitizer_task: container: # Just uses a recent/common distro to run memory error/leak checks. diff --git a/CHANGES b/CHANGES index ea8cb26bb4..1457c7dcef 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,9 @@ +7.0.3-19 | 2024-11-14 12:15:54 -0700 + + * ci: Add asan and ubsan sanitizer tasks for ZAM (Arne Welzel, Corelight) + + (cherry picked from commit 8945b2b186e633f1f7c3a07f9e343da278c037ec) + 7.0.3-18 | 2024-11-14 12:13:59 -0700 * policy/community-id: Populate conn$community_id in new_connection() (Arne Welzel, Corelight) diff --git a/VERSION b/VERSION index 7f58b2fa2b..8a8de13c36 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -7.0.3-18 +7.0.3-19 From d5c3cdf33a81e0c72b55cf00a4de810c38e5fb54 Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Thu, 14 Nov 2024 12:26:29 -0700 Subject: [PATCH 73/91] Update doc submodule [nomail] [skip ci] --- VERSION | 2 +- doc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/VERSION b/VERSION index 8a8de13c36..23d2cc5479 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -7.0.3-19 +7.0.3-20 diff --git a/doc b/doc index c18d39be79..c732062500 160000 --- a/doc +++ b/doc @@ -1 +1 @@ -Subproject commit c18d39be7969bc3662896e558af9a6730bbd76a8 +Subproject commit c732062500934855d8a9033f612074391707067c From 5ce0f2edb64c9dd625de4f31663373573b7debbd Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Thu, 14 Nov 2024 13:14:58 -0700 Subject: [PATCH 74/91] Fix ubsan warning with ZAM and mmdb btest --- testing/btest/core/mmdb/explicit-open.zeek | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/testing/btest/core/mmdb/explicit-open.zeek b/testing/btest/core/mmdb/explicit-open.zeek index 8300ef1604..9aa38c8362 100644 --- a/testing/btest/core/mmdb/explicit-open.zeek +++ b/testing/btest/core/mmdb/explicit-open.zeek @@ -45,6 +45,8 @@ event new_packet(c: connection, p: pkt_hdr) event zeek_init() { - assert mmdb_open_asn_db(asn_fn); - assert mmdb_open_location_db(city_fn); + if ( ! mmdb_open_asn_db(asn_fn) ) + Reporter::fatal("failed to open asn_db " + asn_fn); + if ( ! mmdb_open_location_db(city_fn) ) + Reporter::fatal("failed to open location db " + city_fn); } From b1fec3284e274c7e739f04e03ecb9fa38722c5bc Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Thu, 14 Nov 2024 15:47:18 -0700 Subject: [PATCH 75/91] Disable core.expr-execption btest under ZAM to fix CI builds --- .../Baseline/core.expr-exception/reporter.log | 18 +++++++++--------- testing/btest/core/expr-exception.zeek | 5 +++++ 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/testing/btest/Baseline/core.expr-exception/reporter.log b/testing/btest/Baseline/core.expr-exception/reporter.log index d16031f8ba..514aeb44af 100644 --- a/testing/btest/Baseline/core.expr-exception/reporter.log +++ b/testing/btest/Baseline/core.expr-exception/reporter.log @@ -7,13 +7,13 @@ #open XXXX-XX-XX-XX-XX-XX #fields ts level message location #types time enum string string -XXXXXXXXXX.XXXXXX Reporter::ERROR field value missing (c$ftp) <...>/expr-exception.zeek, line 10 -XXXXXXXXXX.XXXXXX Reporter::ERROR field value missing (c$ftp) <...>/expr-exception.zeek, line 10 -XXXXXXXXXX.XXXXXX Reporter::ERROR field value missing (c$ftp) <...>/expr-exception.zeek, line 10 -XXXXXXXXXX.XXXXXX Reporter::ERROR field value missing (c$ftp) <...>/expr-exception.zeek, line 10 -XXXXXXXXXX.XXXXXX Reporter::ERROR field value missing (c$ftp) <...>/expr-exception.zeek, line 10 -XXXXXXXXXX.XXXXXX Reporter::ERROR field value missing (c$ftp) <...>/expr-exception.zeek, line 10 -XXXXXXXXXX.XXXXXX Reporter::ERROR field value missing (c$ftp) <...>/expr-exception.zeek, line 10 -XXXXXXXXXX.XXXXXX Reporter::ERROR field value missing (c$ftp) <...>/expr-exception.zeek, line 10 -XXXXXXXXXX.XXXXXX Reporter::ERROR field value missing (c$ftp) <...>/expr-exception.zeek, line 10 +XXXXXXXXXX.XXXXXX Reporter::ERROR field value missing (c$ftp) <...>/expr-exception.zeek, line 15 +XXXXXXXXXX.XXXXXX Reporter::ERROR field value missing (c$ftp) <...>/expr-exception.zeek, line 15 +XXXXXXXXXX.XXXXXX Reporter::ERROR field value missing (c$ftp) <...>/expr-exception.zeek, line 15 +XXXXXXXXXX.XXXXXX Reporter::ERROR field value missing (c$ftp) <...>/expr-exception.zeek, line 15 +XXXXXXXXXX.XXXXXX Reporter::ERROR field value missing (c$ftp) <...>/expr-exception.zeek, line 15 +XXXXXXXXXX.XXXXXX Reporter::ERROR field value missing (c$ftp) <...>/expr-exception.zeek, line 15 +XXXXXXXXXX.XXXXXX Reporter::ERROR field value missing (c$ftp) <...>/expr-exception.zeek, line 15 +XXXXXXXXXX.XXXXXX Reporter::ERROR field value missing (c$ftp) <...>/expr-exception.zeek, line 15 +XXXXXXXXXX.XXXXXX Reporter::ERROR field value missing (c$ftp) <...>/expr-exception.zeek, line 15 #close XXXX-XX-XX-XX-XX-XX diff --git a/testing/btest/core/expr-exception.zeek b/testing/btest/core/expr-exception.zeek index 0f22d1c496..ef5d35d083 100644 --- a/testing/btest/core/expr-exception.zeek +++ b/testing/btest/core/expr-exception.zeek @@ -1,6 +1,11 @@ # Expressions in an event handler that raise interpreter exceptions # shouldn't abort Zeek entirely, but just return from the function body. # +# Skip this test when using ZAM. It generates a memory leak on CI under ASAN, +# which causes a build failure. We're only doing this check on the release +# branch and this check should be removed once it's fixed in master. +# @TEST-REQUIRES: test "${ZEEK_ZAM}" != "1" + # @TEST-EXEC: zeek -b -r $TRACES/wikipedia.trace base/protocols/ftp base/protocols/http base/frameworks/reporter %INPUT >output # @TEST-EXEC: TEST_DIFF_CANONIFIER="$SCRIPTS/diff-remove-abspath | $SCRIPTS/diff-remove-timestamps" btest-diff reporter.log # @TEST-EXEC: btest-diff output From 887d92e26c6a2c8b4aa7c70454cbcc75bb23326f Mon Sep 17 00:00:00 2001 From: Arne Welzel Date: Thu, 8 Aug 2024 18:53:23 +0200 Subject: [PATCH 76/91] Merge remote-tracking branch 'upstream/topic/awelzel/3774-skip-script-args-test-under-tsan' * upstream/topic/awelzel/3774-skip-script-args-test-under-tsan: btest: Skip core.script-args under TSAN (cherry picked from commit 159f40a4bff10e7000cb5f5c8a08c6d2b236baef) --- CHANGES | 10 ++++++++++ VERSION | 2 +- testing/btest/core/script-args.zeek | 4 ++++ testing/scripts/have-tsan | 7 +++++++ 4 files changed, 22 insertions(+), 1 deletion(-) create mode 100755 testing/scripts/have-tsan diff --git a/CHANGES b/CHANGES index 1457c7dcef..68eecb9cd6 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,13 @@ +7.0.3-23 | 2024-11-14 19:06:56 -0700 + + * btest: Skip core.script-args under TSAN (Arne Welzel, Corelight) + + (cherry picked from commit 159f40a4bff10e7000cb5f5c8a08c6d2b236baef) + + * Disable core.expr-execption btest under ZAM to fix CI builds (Tim Wojtulewicz, Corelight) + + * Fix ubsan warning with ZAM and mmdb btest (Tim Wojtulewicz) + 7.0.3-19 | 2024-11-14 12:15:54 -0700 * ci: Add asan and ubsan sanitizer tasks for ZAM (Arne Welzel, Corelight) diff --git a/VERSION b/VERSION index 23d2cc5479..28a55d2d02 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -7.0.3-20 +7.0.3-23 diff --git a/testing/btest/core/script-args.zeek b/testing/btest/core/script-args.zeek index b229c87ada..7484bb9441 100644 --- a/testing/btest/core/script-args.zeek +++ b/testing/btest/core/script-args.zeek @@ -2,6 +2,10 @@ # the script differently, leading to complaints that there are no scripts. # @TEST-REQUIRES: test "${ZEEK_USE_CPP}" != "1" +# TSAN may re-execute the executable when the memory layout doesn't fullfill +# requirements, causing argument confusion when that happens (see #3774). +# @TEST-REQUIRES: ! have-tsan + # @TEST-EXEC: printf '#!' > test.zeek # @TEST-EXEC: printf "$BUILD/src/zeek -b --\n" >> test.zeek # @TEST-EXEC: cat %INPUT >> test.zeek diff --git a/testing/scripts/have-tsan b/testing/scripts/have-tsan new file mode 100755 index 0000000000..8030c8d248 --- /dev/null +++ b/testing/scripts/have-tsan @@ -0,0 +1,7 @@ +#!/bin/sh + +if grep -q "ZEEK_SANITIZERS:STRING=.*thread.*" "${BUILD}"/CMakeCache.txt; then + exit 0 +fi + +exit 1 From 43ab74b70fb9b09c6eae819c1847f2f97aeb3142 Mon Sep 17 00:00:00 2001 From: Arne Welzel Date: Tue, 29 Oct 2024 14:05:54 +0100 Subject: [PATCH 77/91] Merge branch 'sqli-spaces-encode-to-plus' of https://github.com/cooper-grill/zeek * 'sqli-spaces-encode-to-plus' of https://github.com/cooper-grill/zeek: account for spaces encoding to plus signs in sqli regex detection (cherry picked from commit 5200b84fb3ce6c19e9d114b3d8fb0d964639446d) --- CHANGES | 6 ++++++ VERSION | 2 +- scripts/policy/protocols/http/detect-sqli.zeek | 10 +++++----- .../http.log.cut | 5 +++++ .../output | 4 ++++ testing/btest/Traces/README | 3 +++ .../btest/Traces/http/cooper-grill-dvwa.pcapng | Bin 0 -> 23312 bytes .../http/test-sql-injection-regex.zeek | 2 ++ 8 files changed, 26 insertions(+), 6 deletions(-) create mode 100644 testing/btest/Baseline/scripts.policy.protocols.http.sql-injection-plus-dvwa/http.log.cut create mode 100644 testing/btest/Baseline/scripts.policy.protocols.http.sql-injection-plus-dvwa/output create mode 100644 testing/btest/Traces/http/cooper-grill-dvwa.pcapng diff --git a/CHANGES b/CHANGES index 68eecb9cd6..9ffff87ba2 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,9 @@ +7.0.3-24 | 2024-11-19 09:32:54 -0700 + + * account for spaces encoding to plus signs in sqli regex detection (Cooper Grill) + + (cherry picked from commit 5200b84fb3ce6c19e9d114b3d8fb0d964639446d) + 7.0.3-23 | 2024-11-14 19:06:56 -0700 * btest: Skip core.script-args under TSAN (Arne Welzel, Corelight) diff --git a/VERSION b/VERSION index 28a55d2d02..447b000b06 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -7.0.3-23 +7.0.3-24 diff --git a/scripts/policy/protocols/http/detect-sqli.zeek b/scripts/policy/protocols/http/detect-sqli.zeek index 1a62c552fb..ed1a687f29 100644 --- a/scripts/policy/protocols/http/detect-sqli.zeek +++ b/scripts/policy/protocols/http/detect-sqli.zeek @@ -46,11 +46,11 @@ export { ## Regular expression is used to match URI based SQL injections. const match_sql_injection_uri = - /[\?&][^[:blank:]\x00-\x1f\|]+?=[\-[:alnum:]%]+([[:blank:]\x00-\x1f]|\/\*.*?\*\/)*['"]?([[:blank:]\x00-\x1f]|\/\*.*?\*\/|\)?;)+.*?([hH][aA][vV][iI][nN][gG]|[uU][nN][iI][oO][nN]|[eE][xX][eE][cC]|[sS][eE][lL][eE][cC][tT]|[dD][eE][lL][eE][tT][eE]|[dD][rR][oO][pP]|[dD][eE][cC][lL][aA][rR][eE]|[cC][rR][eE][aA][tT][eE]|[iI][nN][sS][eE][rR][tT])([[:blank:]\x00-\x1f]|\/\*.*?\*\/)+/ - | /[\?&][^[:blank:]\x00-\x1f\|]+?=[\-0-9%]+([[:blank:]\x00-\x1f]|\/\*.*?\*\/)*['"]?([[:blank:]\x00-\x1f]|\/\*.*?\*\/|\)?;)+([xX]?[oO][rR]|[nN]?[aA][nN][dD])([[:blank:]\x00-\x1f]|\/\*.*?\*\/)+['"]?(([^a-zA-Z&]+)?=|[eE][xX][iI][sS][tT][sS])/ - | /[\?&][^[:blank:]\x00-\x1f]+?=[\-0-9%]*([[:blank:]\x00-\x1f]|\/\*.*?\*\/)*['"]([[:blank:]\x00-\x1f]|\/\*.*?\*\/)*(-|=|\+|\|\|)([[:blank:]\x00-\x1f]|\/\*.*?\*\/)*([0-9]|\(?[cC][oO][nN][vV][eE][rR][tT]|[cC][aA][sS][tT])/ - | /[\?&][^[:blank:]\x00-\x1f\|]+?=([[:blank:]\x00-\x1f]|\/\*.*?\*\/)*['"]([[:blank:]\x00-\x1f]|\/\*.*?\*\/|;)*([xX]?[oO][rR]|[nN]?[aA][nN][dD]|[hH][aA][vV][iI][nN][gG]|[uU][nN][iI][oO][nN]|[eE][xX][eE][cC]|[sS][eE][lL][eE][cC][tT]|[dD][eE][lL][eE][tT][eE]|[dD][rR][oO][pP]|[dD][eE][cC][lL][aA][rR][eE]|[cC][rR][eE][aA][tT][eE]|[rR][eE][gG][eE][xX][pP]|[iI][nN][sS][eE][rR][tT])([[:blank:]\x00-\x1f]|\/\*.*?\*\/|[\[(])+[a-zA-Z&]{2,}/ - | /[\?&][^[:blank:]\x00-\x1f]+?=[^\.]*?([cC][hH][aA][rR]|[aA][sS][cC][iI][iI]|[sS][uU][bB][sS][tT][rR][iI][nN][gG]|[tT][rR][uU][nN][cC][aA][tT][eE]|[vV][eE][rR][sS][iI][oO][nN]|[lL][eE][nN][gG][tT][hH])\(/ + /[\?&][^[:blank:]\x00-\x1f\|\+]+?=[\-[:alnum:]%]+([[:blank:]\x00-\x1f\+]|\/\*.*?\*\/)*['"]?([[:blank:]\x00-\x1f\+]|\/\*.*?\*\/|\)?;)+.*?([hH][aA][vV][iI][nN][gG]|[uU][nN][iI][oO][nN]|[eE][xX][eE][cC]|[sS][eE][lL][eE][cC][tT]|[dD][eE][lL][eE][tT][eE]|[dD][rR][oO][pP]|[dD][eE][cC][lL][aA][rR][eE]|[cC][rR][eE][aA][tT][eE]|[iI][nN][sS][eE][rR][tT])([[:blank:]\x00-\x1f\+]|\/\*.*?\*\/)+/ + | /[\?&][^[:blank:]\x00-\x1f\|\+]+?=[\-0-9%]+([[:blank:]\x00-\x1f\+]|\/\*.*?\*\/)*['"]?([[:blank:]\x00-\x1f\+]|\/\*.*?\*\/|\)?;)+([xX]?[oO][rR]|[nN]?[aA][nN][dD])([[:blank:]\x00-\x1f\+]|\/\*.*?\*\/)+['"]?(([^a-zA-Z&]+)?=|[eE][xX][iI][sS][tT][sS])/ + | /[\?&][^[:blank:]\x00-\x1f\+]+?=[\-0-9%]*([[:blank:]\x00-\x1f\+]|\/\*.*?\*\/)*['"]([[:blank:]\x00-\x1f]|\/\*.*?\*\/)*(-|=|\+|\|\|)([[:blank:]\x00-\x1f\+]|\/\*.*?\*\/)*([0-9]|\(?[cC][oO][nN][vV][eE][rR][tT]|[cC][aA][sS][tT])/ + | /[\?&][^[:blank:]\x00-\x1f\|\+]+?=([[:blank:]\x00-\x1f\+]|\/\*.*?\*\/)*['"]([[:blank:]\x00-\x1f\+]|\/\*.*?\*\/|;)*([xX]?[oO][rR]|[nN]?[aA][nN][dD]|[hH][aA][vV][iI][nN][gG]|[uU][nN][iI][oO][nN]|[eE][xX][eE][cC]|[sS][eE][lL][eE][cC][tT]|[dD][eE][lL][eE][tT][eE]|[dD][rR][oO][pP]|[dD][eE][cC][lL][aA][rR][eE]|[cC][rR][eE][aA][tT][eE]|[rR][eE][gG][eE][xX][pP]|[iI][nN][sS][eE][rR][tT])([[:blank:]\x00-\x1f\+]|\/\*.*?\*\/|[\[(])+[a-zA-Z&]{2,}/ + | /[\?&][^[:blank:]\x00-\x1f\+]+?=[^\.]*?([cC][hH][aA][rR]|[aA][sS][cC][iI][iI]|[sS][uU][bB][sS][tT][rR][iI][nN][gG]|[tT][rR][uU][nN][cC][aA][tT][eE]|[vV][eE][rR][sS][iI][oO][nN]|[lL][eE][nN][gG][tT][hH])\(/ | /\/\*![[:digit:]]{5}.*?\*\// &redef; ## A hook that can be used to prevent specific requests from being counted diff --git a/testing/btest/Baseline/scripts.policy.protocols.http.sql-injection-plus-dvwa/http.log.cut b/testing/btest/Baseline/scripts.policy.protocols.http.sql-injection-plus-dvwa/http.log.cut new file mode 100644 index 0000000000..345a4837e7 --- /dev/null +++ b/testing/btest/Baseline/scripts.policy.protocols.http.sql-injection-plus-dvwa/http.log.cut @@ -0,0 +1,5 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +uid method host uri tags +ClEkJM2Vm5giqnMf4h GET 192.168.111.154 /dvwa/vulnerabilities/sqli/?id=1'+OR+'1'='1&Submit=Submit HTTP::URI_SQLI +C4J4Th3PJpwUYZZ6gc GET 192.168.111.154 /dvwa/vulnerabilities/sqli/?id=1'+UNION+SELECT+NULL,+version()+#&Submit=Submit HTTP::URI_SQLI +CtPZjS20MLrsMUOJi2 GET 192.168.111.154 /dvwa/vulnerabilities/sqli/?id=2'+OR+'2'='2&Submit=Submit HTTP::URI_SQLI diff --git a/testing/btest/Baseline/scripts.policy.protocols.http.sql-injection-plus-dvwa/output b/testing/btest/Baseline/scripts.policy.protocols.http.sql-injection-plus-dvwa/output new file mode 100644 index 0000000000..06c5829847 --- /dev/null +++ b/testing/btest/Baseline/scripts.policy.protocols.http.sql-injection-plus-dvwa/output @@ -0,0 +1,4 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +ClEkJM2Vm5giqnMf4h, [orig_h=192.168.111.148, orig_p=53796/tcp, resp_h=192.168.111.154, resp_p=80/tcp], {\x0a\x09HTTP::URI_SQLI\x0a} +C4J4Th3PJpwUYZZ6gc, [orig_h=192.168.111.148, orig_p=57524/tcp, resp_h=192.168.111.154, resp_p=80/tcp], {\x0a\x09HTTP::URI_SQLI\x0a} +CtPZjS20MLrsMUOJi2, [orig_h=192.168.111.148, orig_p=40112/tcp, resp_h=192.168.111.154, resp_p=80/tcp], {\x0a\x09HTTP::URI_SQLI\x0a} diff --git a/testing/btest/Traces/README b/testing/btest/Traces/README index b097576d0d..0e7f31431c 100644 --- a/testing/btest/Traces/README +++ b/testing/btest/Traces/README @@ -26,3 +26,6 @@ Trace Index/Sources: - pop3/POP3.pcap: Picked up from POP tutorial on tranalyzer.com https://tranalyzer.com/tutorial/pop https://tranalyzer.com/download/data/pop3.pcap +- http/cooper-grill-dvwa.pcapng + Provided by cooper-grill on #3995 + https://github.com/zeek/zeek/pull/3995 diff --git a/testing/btest/Traces/http/cooper-grill-dvwa.pcapng b/testing/btest/Traces/http/cooper-grill-dvwa.pcapng new file mode 100644 index 0000000000000000000000000000000000000000..b68eb250efbd0a3414159f13e150bd718432b31b GIT binary patch literal 23312 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 and 1=1"]; add positive_matches["/index.php?ID=60 and exists (select * from [news])"]; + add positive_matches["?id=1'+OR+'1'='1"]; + add positive_matches["?id=1'+UNION+SELECT+NULL,+version()+#"]; # These are not detected currently. #add positive_matches["/index.asp?ARF_ID=(1/(1-(asc(mid(now(),18,1))\(2^7) mod 2)))"]; From 91067b32cceec249050a719047e02322193a753f Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Tue, 19 Nov 2024 09:43:20 -0700 Subject: [PATCH 78/91] Update docs submodule [nomail] [skip ci] --- doc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc b/doc index c732062500..cafe6ac085 160000 --- a/doc +++ b/doc @@ -1 +1 @@ -Subproject commit c732062500934855d8a9033f612074391707067c +Subproject commit cafe6ac085091ad36bca74c8fc18ff6c1f4cf9fd From 56b596a3e36173d266e732ef8351094290216513 Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Tue, 19 Nov 2024 10:52:56 -0700 Subject: [PATCH 79/91] Merge remote-tracking branch 'origin/topic/timw/speed-up-zam-ci-testing' * origin/topic/timw/speed-up-zam-ci-testing: CI: Use test.sh script for running ZAM tests, but disable parts of it (cherry picked from commit d9a74680e08553b34cb164847f61b0ea00ad1f5f) --- .cirrus.yml | 12 ++++++------ CHANGES | 9 +++++++++ VERSION | 2 +- ci/test.sh | 14 ++++++++++++-- 4 files changed, 28 insertions(+), 9 deletions(-) diff --git a/.cirrus.yml b/.cirrus.yml index 450518570a..40af078b21 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -401,12 +401,12 @@ asan_sanitizer_zam_task: << : *RESOURCES_TEMPLATE << : *CI_TEMPLATE - test_script: - # Run just the btests with zam as alternative. - - cd testing/btest && ../../auxil/btest/btest -a zam -A -d -b -j ${ZEEK_CI_BTEST_JOBS} env: ZEEK_CI_CONFIGURE_FLAGS: *ASAN_SANITIZER_CONFIG ASAN_OPTIONS: detect_leaks=1:detect_odr_violation=0 + ZEEK_CI_SKIP_UNIT_TESTS: 1 + ZEEK_CI_SKIP_EXTERNAL_BTESTS: 1 + ZEEK_CI_BTEST_EXTRA_ARGS: -a zam << : *ZAM_SKIP_TASK_ON_PR ubsan_sanitizer_task: @@ -432,15 +432,15 @@ ubsan_sanitizer_zam_task: << : *RESOURCES_TEMPLATE << : *CI_TEMPLATE - test_script: - # Run just the btests with zam as alternative. - - cd testing/btest && ../../auxil/btest/btest -a zam -A -d -b -j ${ZEEK_CI_BTEST_JOBS} env: CC: clang-18 CXX: clang++-18 ZEEK_CI_CONFIGURE_FLAGS: *UBSAN_SANITIZER_CONFIG ZEEK_TAILORED_UB_CHECKS: 1 UBSAN_OPTIONS: print_stacktrace=1 + ZEEK_CI_SKIP_UNIT_TESTS: 1 + ZEEK_CI_SKIP_EXTERNAL_BTESTS: 1 + ZEEK_CI_BTEST_EXTRA_ARGS: -a zam << : *ZAM_SKIP_TASK_ON_PR tsan_sanitizer_task: diff --git a/CHANGES b/CHANGES index 9ffff87ba2..7e03228332 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,12 @@ +7.0.3-26 | 2024-11-19 10:56:06 -0700 + + * Merge remote-tracking branch 'origin/topic/timw/speed-up-zam-ci-testing' (Tim Wojtulewicz, Corelight) + + * origin/topic/timw/speed-up-zam-ci-testing: + CI: Use test.sh script for running ZAM tests, but disable parts of it + + (cherry picked from commit d9a74680e08553b34cb164847f61b0ea00ad1f5f) + 7.0.3-24 | 2024-11-19 09:32:54 -0700 * account for spaces encoding to plus signs in sqli regex detection (Cooper Grill) diff --git a/VERSION b/VERSION index 447b000b06..e7bc80348c 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -7.0.3-24 +7.0.3-26 diff --git a/ci/test.sh b/ci/test.sh index c5304b4512..1d5da9e2a7 100755 --- a/ci/test.sh +++ b/ci/test.sh @@ -40,6 +40,11 @@ function banner { } function run_unit_tests { + if [[ ${ZEEK_CI_SKIP_UNIT_TESTS} -eq 1 ]]; then + printf "Skipping unit tests as requested by task configureation\n\n" + return 0 + fi + banner "Running unit tests" pushd build @@ -60,7 +65,7 @@ function run_btests { pushd testing/btest ZEEK_PROFILER_FILE=$(pwd)/.tmp/script-coverage/XXXXXX \ - ${BTEST} -z ${ZEEK_CI_BTEST_RETRIES} -d -A -x btest-results.xml -j ${ZEEK_CI_BTEST_JOBS} || result=1 + ${BTEST} -z ${ZEEK_CI_BTEST_RETRIES} -d -A -x btest-results.xml -j ${ZEEK_CI_BTEST_JOBS} ${ZEEK_CI_BTEST_EXTRA_ARGS} || result=1 make coverage prep_artifacts popd @@ -68,11 +73,16 @@ function run_btests { } function run_external_btests { + if [[ ${ZEEK_CI_SKIP_EXTERNAL_BTESTS} -eq 1 ]]; then + printf "Skipping external tests as requested by task configuration\n\n" + return 0 + fi + local zeek_testing_pid="" local zeek_testing_pid_private="" pushd testing/external/zeek-testing ZEEK_PROFILER_FILE=$(pwd)/.tmp/script-coverage/XXXXXX \ - ${BTEST} -d -A -x btest-results.xml -j ${ZEEK_CI_BTEST_JOBS} >btest.out 2>&1 & + ${BTEST} -d -A -x btest-results.xml -j ${ZEEK_CI_BTEST_JOBS} ${ZEEK_CI_BTEST_EXTRA_ARGS} >btest.out 2>&1 & zeek_testing_pid=$! popd From fa5a7c4a5be82608fc41aafd20a01456641cfcca Mon Sep 17 00:00:00 2001 From: Arne Welzel Date: Tue, 19 Nov 2024 19:16:51 +0100 Subject: [PATCH 80/91] Merge remote-tracking branch 'origin/topic/awelzel/bump-zeekjs-0-13-2' * origin/topic/awelzel/bump-zeekjs-0-13-2: Bump zeekjs to 0.13.2 (cherry picked from commit 6e916efe8d9470cdca7b4f4933c44b8c1cab66b0) --- CHANGES | 6 ++++++ VERSION | 2 +- auxil/zeekjs | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/CHANGES b/CHANGES index 7e03228332..e4cb5ab849 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,9 @@ +7.0.3-27 | 2024-11-19 11:19:00 -0700 + + * Bump zeekjs to 0.13.2 (Arne Welzel, Corelight) + + (cherry picked from commit 6e916efe8d9470cdca7b4f4933c44b8c1cab66b0) + 7.0.3-26 | 2024-11-19 10:56:06 -0700 * Merge remote-tracking branch 'origin/topic/timw/speed-up-zam-ci-testing' (Tim Wojtulewicz, Corelight) diff --git a/VERSION b/VERSION index e7bc80348c..c91c73a9ec 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -7.0.3-26 +7.0.3-27 diff --git a/auxil/zeekjs b/auxil/zeekjs index 805a4663f9..d5bae4c4d2 160000 --- a/auxil/zeekjs +++ b/auxil/zeekjs @@ -1 +1 @@ -Subproject commit 805a4663f9326726d179f6af15a592ab4d9c2952 +Subproject commit d5bae4c4d29e3c5e87d54f94d7a9b3f86ae856a8 From f300ddb9fe018fe26209310e13ea2f7e4eb95702 Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Tue, 19 Nov 2024 12:31:05 -0700 Subject: [PATCH 81/91] Update CHANGES, VERSION, and NEWS for 7.0.4 release --- CHANGES | 4 ++++ NEWS | 12 ++++++++++++ VERSION | 2 +- 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index e4cb5ab849..11d5f09f13 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,7 @@ +7.0.4 | 2024-11-19 12:31:05 -0700 + + * Update CHANGES, VERSION, and NEWS for 7.0.4 release (Tim Wojtulewicz, Corelight) + 7.0.3-27 | 2024-11-19 11:19:00 -0700 * Bump zeekjs to 0.13.2 (Arne Welzel, Corelight) diff --git a/NEWS b/NEWS index ea07332454..d9174642a0 100644 --- a/NEWS +++ b/NEWS @@ -13,6 +13,18 @@ This release fixes the following bugs: ``connection_state_remove()``, allowing other scripts to reuse its value early. +- The input framework will no longer get stuck and use 100% of the CPU when + encountering lines not immediately terminated by a new line. + +- The Modbus analyzer added some additional protocol checks and should no longer + over-match on traffic that's not specifically on port 502. + +- ZeekJS was updated to version v0.13.2, which brings support for newer versions + of Node.js and a fix for a segfault when running under Alpine. + +- A minor bug was fixed in the detect-sqli policy script to handle spaces being + encoded as plus signs. + Zeek 7.0.3 ========== diff --git a/VERSION b/VERSION index c91c73a9ec..4489f5a6df 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -7.0.3-27 +7.0.4 From 35cd891d6eff431bcb51a2486abb4cfc2ba63408 Mon Sep 17 00:00:00 2001 From: Benjamin Bannier Date: Wed, 20 Nov 2024 09:34:10 +0100 Subject: [PATCH 82/91] Merge remote-tracking branch 'origin/topic/bbannier/doc-have-spicy' (cherry picked from commit 4a96d34af6fe68bad6afe12dffff6bd795e6b4b1) --- src/zeek.bif | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/zeek.bif b/src/zeek.bif index eccc7f0292..a63252b4ff 100644 --- a/src/zeek.bif +++ b/src/zeek.bif @@ -5304,7 +5304,7 @@ function has_module_events%(group: string%) : bool %} ## Returns true if Zeek was built with support for using Spicy analyzers (which -# is the default). +## is the default). function have_spicy%(%) : bool %{ #ifdef HAVE_SPICY From cf97ed6ac1990022f11d8ad743f3c8b11d607c49 Mon Sep 17 00:00:00 2001 From: Arne Welzel Date: Thu, 21 Nov 2024 10:22:21 +0100 Subject: [PATCH 83/91] Merge remote-tracking branch 'origin/topic/awelzel/bump-zeekjs-0-14-0' * origin/topic/awelzel/bump-zeekjs-0-14-0: Bump zeekjs to v0.14.0 (cherry picked from commit aac640ebffdd58b1e25e42eee538b7c8669b1dd4) --- CHANGES | 20 ++++++++++++++++++++ VERSION | 2 +- auxil/zeekjs | 2 +- 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/CHANGES b/CHANGES index 11d5f09f13..986b2be8c9 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,23 @@ +7.0.4-2 | 2024-12-12 12:44:36 -0700 + + * Bump zeekjs to v0.14.0 (Arne Welzel, Corelight) + 79b0c21 version: 0.14.0 + b75b384 docker: Use Fedora 41 packages + d65cbc8 Minor header cleanup + 4fd7e8b scripts: Remove __preload__.zeek and types.zeek + 93a8113 CreateEnvironment: Unset kOwnsProcessState and kOwnsInspector + 3b1f5d3 Instance::Init(): Replace parameters with Options struct + + (cherry picked from commit aac640ebffdd58b1e25e42eee538b7c8669b1dd4) + + * Fix documentation for `have_spicy` [skip CI] (Benjamin Bannier, Corelight) + + The continued line was incorrectly marked up (as a plain comment instead + of a Zeekygen comment) which caused only half of the docstring to be + rendered by Zeekygen. + + (cherry picked from commit 4a96d34af6fe68bad6afe12dffff6bd795e6b4b1) + 7.0.4 | 2024-11-19 12:31:05 -0700 * Update CHANGES, VERSION, and NEWS for 7.0.4 release (Tim Wojtulewicz, Corelight) diff --git a/VERSION b/VERSION index 4489f5a6df..5174b1adf7 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -7.0.4 +7.0.4-2 diff --git a/auxil/zeekjs b/auxil/zeekjs index d5bae4c4d2..79b0c2126f 160000 --- a/auxil/zeekjs +++ b/auxil/zeekjs @@ -1 +1 @@ -Subproject commit d5bae4c4d29e3c5e87d54f94d7a9b3f86ae856a8 +Subproject commit 79b0c2126fa0178dbc2e37536588fcd1db9f4443 From 68bfe8d1c0cbf0041bc9e68413c982456701627a Mon Sep 17 00:00:00 2001 From: Arne Welzel Date: Tue, 26 Nov 2024 17:17:00 +0100 Subject: [PATCH 84/91] Merge remote-tracking branch 'origin/topic/vern/zam-exception-leaks' * origin/topic/vern/zam-exception-leaks: More robust memory management for ZAM execution - fixes #4052 (cherry picked from commit c3b30b187e44de593d0ec685dc313e6aa10ff5e5) --- CHANGES | 6 ++ VERSION | 2 +- src/script_opt/ZAM/ZBody.cc | 79 +++++++++++-------- .../Baseline/core.expr-exception/reporter.log | 18 ++--- testing/btest/core/expr-exception.zeek | 5 -- 5 files changed, 62 insertions(+), 48 deletions(-) diff --git a/CHANGES b/CHANGES index 986b2be8c9..b3a3da9b5b 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,9 @@ +7.0.4-3 | 2024-12-12 13:04:44 -0700 + + * GH-4052: More robust memory management for ZAM execution - fixes #4052 (Vern Paxson, Corelight) + + (cherry picked from commit c3b30b187e44de593d0ec685dc313e6aa10ff5e5) + 7.0.4-2 | 2024-12-12 12:44:36 -0700 * Bump zeekjs to v0.14.0 (Arne Welzel, Corelight) diff --git a/VERSION b/VERSION index 5174b1adf7..ab87b76ddd 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -7.0.4-2 +7.0.4-3 diff --git a/src/script_opt/ZAM/ZBody.cc b/src/script_opt/ZAM/ZBody.cc index 77bb11b93b..16226c2112 100644 --- a/src/script_opt/ZAM/ZBody.cc +++ b/src/script_opt/ZAM/ZBody.cc @@ -327,6 +327,47 @@ std::shared_ptr ZBody::BuildProfVec() const { return pv; } +// Helper class for managing ZBody state to ensure that memory is recovered +// if a ZBody is exited via an exception. +class ZBodyStateManager { +public: + // If fixed_frame is nil then creates a dynamic frame. + ZBodyStateManager(ZVal* _fixed_frame, int frame_size, const std::vector& _managed_slots) + : fixed_frame(_fixed_frame), managed_slots(_managed_slots) { + if ( fixed_frame ) + frame = fixed_frame; + else { + frame = new ZVal[frame_size]; + for ( auto s : managed_slots ) + frame[s].ClearManagedVal(); + } + } + + ~ZBodyStateManager() { + if ( fixed_frame ) { + // Recover memory and reset for use in next call. + for ( auto s : managed_slots ) { + ZVal::DeleteManagedType(frame[s]); + frame[s].ClearManagedVal(); + } + } + + else { + // Recover memory, no need to reset. + for ( auto s : managed_slots ) + ZVal::DeleteManagedType(frame[s]); + delete[] frame; + } + } + + auto Frame() { return frame; } + +private: + ZVal* fixed_frame; + ZVal* frame; + const std::vector& managed_slots; +}; + ValPtr ZBody::Exec(Frame* f, StmtFlowType& flow) { unsigned int pc = 0; @@ -359,17 +400,16 @@ ValPtr ZBody::Exec(Frame* f, StmtFlowType& flow) { } #endif - ZVal* frame; + ZBodyStateManager state_mgr(fixed_frame, frame_size, managed_slots); std::unique_ptr local_table_iters; std::vector step_iters(num_step_iters); + ZVal* frame; + if ( fixed_frame ) frame = fixed_frame; else { - frame = new ZVal[frame_size]; - // Clear slots for which we do explicit memory management. - for ( auto s : managed_slots ) - frame[s].ClearManagedVal(); + frame = state_mgr.Frame(); if ( ! table_iters.empty() ) { local_table_iters = std::make_unique(table_iters.size()); @@ -424,33 +464,6 @@ ValPtr ZBody::Exec(Frame* f, StmtFlowType& flow) { ++pc; } - auto result = ret_type ? ret_u->ToVal(ret_type) : nullptr; - - if ( fixed_frame ) { - // Make sure we don't have any dangling iterators. - for ( auto& ti : table_iters ) - ti.Clear(); - - // Free slots for which we do explicit memory management, - // preparing them for reuse. - for ( auto& ms : managed_slots ) { - auto& v = frame[ms]; - ZVal::DeleteManagedType(v); - v.ClearManagedVal(); - } - } - else { - // Free those slots for which we do explicit memory management. - // No need to then clear them, as we're about to throw away - // the entire frame. - for ( auto& ms : managed_slots ) { - auto& v = frame[ms]; - ZVal::DeleteManagedType(v); - } - - delete[] frame; - } - #ifdef ENABLE_ZAM_PROFILE if ( profiling_active ) { tot_CPU_time += util::curr_CPU_time() - start_CPU_time; @@ -461,7 +474,7 @@ ValPtr ZBody::Exec(Frame* f, StmtFlowType& flow) { } #endif - return result; + return ret_type ? ret_u->ToVal(ret_type) : nullptr; } void ZBody::ReportExecutionProfile(ProfMap& pm) { diff --git a/testing/btest/Baseline/core.expr-exception/reporter.log b/testing/btest/Baseline/core.expr-exception/reporter.log index 514aeb44af..d16031f8ba 100644 --- a/testing/btest/Baseline/core.expr-exception/reporter.log +++ b/testing/btest/Baseline/core.expr-exception/reporter.log @@ -7,13 +7,13 @@ #open XXXX-XX-XX-XX-XX-XX #fields ts level message location #types time enum string string -XXXXXXXXXX.XXXXXX Reporter::ERROR field value missing (c$ftp) <...>/expr-exception.zeek, line 15 -XXXXXXXXXX.XXXXXX Reporter::ERROR field value missing (c$ftp) <...>/expr-exception.zeek, line 15 -XXXXXXXXXX.XXXXXX Reporter::ERROR field value missing (c$ftp) <...>/expr-exception.zeek, line 15 -XXXXXXXXXX.XXXXXX Reporter::ERROR field value missing (c$ftp) <...>/expr-exception.zeek, line 15 -XXXXXXXXXX.XXXXXX Reporter::ERROR field value missing (c$ftp) <...>/expr-exception.zeek, line 15 -XXXXXXXXXX.XXXXXX Reporter::ERROR field value missing (c$ftp) <...>/expr-exception.zeek, line 15 -XXXXXXXXXX.XXXXXX Reporter::ERROR field value missing (c$ftp) <...>/expr-exception.zeek, line 15 -XXXXXXXXXX.XXXXXX Reporter::ERROR field value missing (c$ftp) <...>/expr-exception.zeek, line 15 -XXXXXXXXXX.XXXXXX Reporter::ERROR field value missing (c$ftp) <...>/expr-exception.zeek, line 15 +XXXXXXXXXX.XXXXXX Reporter::ERROR field value missing (c$ftp) <...>/expr-exception.zeek, line 10 +XXXXXXXXXX.XXXXXX Reporter::ERROR field value missing (c$ftp) <...>/expr-exception.zeek, line 10 +XXXXXXXXXX.XXXXXX Reporter::ERROR field value missing (c$ftp) <...>/expr-exception.zeek, line 10 +XXXXXXXXXX.XXXXXX Reporter::ERROR field value missing (c$ftp) <...>/expr-exception.zeek, line 10 +XXXXXXXXXX.XXXXXX Reporter::ERROR field value missing (c$ftp) <...>/expr-exception.zeek, line 10 +XXXXXXXXXX.XXXXXX Reporter::ERROR field value missing (c$ftp) <...>/expr-exception.zeek, line 10 +XXXXXXXXXX.XXXXXX Reporter::ERROR field value missing (c$ftp) <...>/expr-exception.zeek, line 10 +XXXXXXXXXX.XXXXXX Reporter::ERROR field value missing (c$ftp) <...>/expr-exception.zeek, line 10 +XXXXXXXXXX.XXXXXX Reporter::ERROR field value missing (c$ftp) <...>/expr-exception.zeek, line 10 #close XXXX-XX-XX-XX-XX-XX diff --git a/testing/btest/core/expr-exception.zeek b/testing/btest/core/expr-exception.zeek index ef5d35d083..0f22d1c496 100644 --- a/testing/btest/core/expr-exception.zeek +++ b/testing/btest/core/expr-exception.zeek @@ -1,11 +1,6 @@ # Expressions in an event handler that raise interpreter exceptions # shouldn't abort Zeek entirely, but just return from the function body. # -# Skip this test when using ZAM. It generates a memory leak on CI under ASAN, -# which causes a build failure. We're only doing this check on the release -# branch and this check should be removed once it's fixed in master. -# @TEST-REQUIRES: test "${ZEEK_ZAM}" != "1" - # @TEST-EXEC: zeek -b -r $TRACES/wikipedia.trace base/protocols/ftp base/protocols/http base/frameworks/reporter %INPUT >output # @TEST-EXEC: TEST_DIFF_CANONIFIER="$SCRIPTS/diff-remove-abspath | $SCRIPTS/diff-remove-timestamps" btest-diff reporter.log # @TEST-EXEC: btest-diff output From f54416eae4319554a2c77b2f0a109df90ed2befb Mon Sep 17 00:00:00 2001 From: Arne Welzel Date: Thu, 12 Dec 2024 14:45:28 +0100 Subject: [PATCH 85/91] Merge remote-tracking branch 'origin/topic/christian/fix-zam-analyzer-name' * origin/topic/christian/fix-zam-analyzer-name: Fix ZAM's implementation of Analyzer::name() BiF (cherry picked from commit e100a8e698d1dba0fc339eae800d13b298e55d46) --- CHANGES | 6 ++++++ VERSION | 2 +- src/script_opt/ZAM/OPs/ZAM.op | 6 +++--- testing/btest/Baseline.zam/spicy.replaces/conn.log | 2 +- 4 files changed, 11 insertions(+), 5 deletions(-) diff --git a/CHANGES b/CHANGES index b3a3da9b5b..25d3f5949a 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,9 @@ +7.0.4-4 | 2024-12-12 13:12:30 -0700 + + * Fix ZAM's implementation of Analyzer::name() BiF (Christian Kreibich, Corelight) + + (cherry picked from commit e100a8e698d1dba0fc339eae800d13b298e55d46) + 7.0.4-3 | 2024-12-12 13:04:44 -0700 * GH-4052: More robust memory management for ZAM execution - fixes #4052 (Vern Paxson, Corelight) diff --git a/VERSION b/VERSION index ab87b76ddd..01e87766ae 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -7.0.4-3 +7.0.4-4 diff --git a/src/script_opt/ZAM/OPs/ZAM.op b/src/script_opt/ZAM/OPs/ZAM.op index f773e60a2f..36e960abec 100644 --- a/src/script_opt/ZAM/OPs/ZAM.op +++ b/src/script_opt/ZAM/OPs/ZAM.op @@ -3093,11 +3093,11 @@ macro AnalyzerName(tag) auto atype = tag.ToVal(z.t); auto val = atype->AsEnumVal(); Unref(frame[z.v1].string_val); - plugin::Component* component = zeek::analyzer_mgr->Lookup(val); + plugin::Component* component = zeek::analyzer_mgr->Lookup(val, false); if ( ! component ) - component = zeek::packet_mgr->Lookup(val); + component = zeek::packet_mgr->Lookup(val, false); if ( ! component ) - component = zeek::file_mgr->Lookup(val); + component = zeek::file_mgr->Lookup(val, false); if ( component ) frame[z.v1].string_val = new StringVal(component->CanonicalName()); else diff --git a/testing/btest/Baseline.zam/spicy.replaces/conn.log b/testing/btest/Baseline.zam/spicy.replaces/conn.log index 9a44cfd8c3..0202574b88 100644 --- a/testing/btest/Baseline.zam/spicy.replaces/conn.log +++ b/testing/btest/Baseline.zam/spicy.replaces/conn.log @@ -7,5 +7,5 @@ #open XXXX-XX-XX-XX-XX-XX #fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p proto service duration orig_bytes resp_bytes conn_state local_orig local_resp missed_bytes history orig_pkts orig_ip_bytes resp_pkts resp_ip_bytes tunnel_parents #types time string addr port addr port enum string interval count count string bool bool count string count count count count set[string] -XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 172.16.238.1 49656 172.16.238.131 80 tcp spicy_ssh 9.953807 2405 2887 SF T T 0 ShAdDaFf 40 4497 30 4455 - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 172.16.238.1 49656 172.16.238.131 80 tcp ssh 9.953807 2405 2887 SF T T 0 ShAdDaFf 40 4497 30 4455 - #close XXXX-XX-XX-XX-XX-XX From e7f694bcbb18fc0f65ecfc6e08d9f0b9a2f72016 Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Fri, 13 Dec 2024 08:04:17 -0700 Subject: [PATCH 86/91] Merge remote-tracking branch 'origin/topic/vern/ZAM-tbl-iteration-memory-mgt-fix' * origin/topic/vern/ZAM-tbl-iteration-memory-mgt-fix: fix for memory management associated with ZAM table iteration (cherry picked from commit 805e9db58840671c866c85461ad88198eeeec967) --- CHANGES | 6 ++++++ VERSION | 2 +- src/script_opt/ZAM/ZBody.cc | 15 ++++++++++++--- 3 files changed, 19 insertions(+), 4 deletions(-) diff --git a/CHANGES b/CHANGES index 25d3f5949a..21fa61a67f 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,9 @@ +7.0.4-5 | 2024-12-13 12:25:43 -0700 + + * fix for memory management associated with ZAM table iteration (Vern Paxson, Corelight) + + (cherry picked from commit 805e9db58840671c866c85461ad88198eeeec967) + 7.0.4-4 | 2024-12-12 13:12:30 -0700 * Fix ZAM's implementation of Analyzer::name() BiF (Christian Kreibich, Corelight) diff --git a/VERSION b/VERSION index 01e87766ae..cba4cff318 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -7.0.4-4 +7.0.4-5 diff --git a/src/script_opt/ZAM/ZBody.cc b/src/script_opt/ZAM/ZBody.cc index 16226c2112..72e5236419 100644 --- a/src/script_opt/ZAM/ZBody.cc +++ b/src/script_opt/ZAM/ZBody.cc @@ -332,8 +332,9 @@ std::shared_ptr ZBody::BuildProfVec() const { class ZBodyStateManager { public: // If fixed_frame is nil then creates a dynamic frame. - ZBodyStateManager(ZVal* _fixed_frame, int frame_size, const std::vector& _managed_slots) - : fixed_frame(_fixed_frame), managed_slots(_managed_slots) { + ZBodyStateManager(ZVal* _fixed_frame, int frame_size, const std::vector& _managed_slots, + TableIterVec* _tiv_ptr) + : fixed_frame(_fixed_frame), managed_slots(_managed_slots), tiv_ptr(_tiv_ptr) { if ( fixed_frame ) frame = fixed_frame; else { @@ -343,7 +344,13 @@ public: } } + void SetTableIters(TableIterVec* _tiv_ptr) { tiv_ptr = _tiv_ptr; } + ~ZBodyStateManager() { + if ( tiv_ptr ) + for ( auto& ti : *tiv_ptr ) + ti.Clear(); + if ( fixed_frame ) { // Recover memory and reset for use in next call. for ( auto s : managed_slots ) { @@ -366,6 +373,7 @@ private: ZVal* fixed_frame; ZVal* frame; const std::vector& managed_slots; + TableIterVec* tiv_ptr; }; ValPtr ZBody::Exec(Frame* f, StmtFlowType& flow) { @@ -400,7 +408,7 @@ ValPtr ZBody::Exec(Frame* f, StmtFlowType& flow) { } #endif - ZBodyStateManager state_mgr(fixed_frame, frame_size, managed_slots); + ZBodyStateManager state_mgr(fixed_frame, frame_size, managed_slots, &table_iters); std::unique_ptr local_table_iters; std::vector step_iters(num_step_iters); @@ -415,6 +423,7 @@ ValPtr ZBody::Exec(Frame* f, StmtFlowType& flow) { local_table_iters = std::make_unique(table_iters.size()); *local_table_iters = table_iters; tiv_ptr = &(*local_table_iters); + state_mgr.SetTableIters(nullptr); // unique_ptr will clean it up directly } } From 7c463b5f92427780458e1962f0cc98d3812de7ab Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Fri, 13 Dec 2024 13:08:51 -0700 Subject: [PATCH 87/91] Update docs submodule [nomail] [skip ci] --- doc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc b/doc index cafe6ac085..6fc35ef451 160000 --- a/doc +++ b/doc @@ -1 +1 @@ -Subproject commit cafe6ac085091ad36bca74c8fc18ff6c1f4cf9fd +Subproject commit 6fc35ef451358576c8a730ed78e54d5509897ee8 From 5fbb6b4599ef09da3f940838eb0682cfdd9a7e77 Mon Sep 17 00:00:00 2001 From: Arne Welzel Date: Wed, 11 Dec 2024 12:50:37 +0100 Subject: [PATCH 88/91] QUIC/decrypt_crypto: Fix decrypting into too small stack buffer A QUIC initial packet larger than 1500 bytes could lead to crashes due to the usage of a fixed size stack buffer for decryption. Allocate the necessary memory dynamically on the heap instead. --- src/analyzer/protocol/quic/decrypt_crypto.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/analyzer/protocol/quic/decrypt_crypto.cc b/src/analyzer/protocol/quic/decrypt_crypto.cc index d38bc4154f..693f77fdcc 100644 --- a/src/analyzer/protocol/quic/decrypt_crypto.cc +++ b/src/analyzer/protocol/quic/decrypt_crypto.cc @@ -60,7 +60,6 @@ const size_t AEAD_IV_LEN = 12; const size_t AEAD_HP_LEN = 16; const size_t AEAD_SAMPLE_LENGTH = 16; const size_t AEAD_TAG_LENGTH = 16; -const size_t MAXIMUM_PACKET_LENGTH = 1500; const size_t MAXIMUM_PACKET_NUMBER_LENGTH = 4; EVP_CIPHER_CTX* get_aes_128_ecb() { @@ -173,7 +172,8 @@ hilti::rt::Bytes decrypt(const std::vector& client_key, const hilti::rt const void* tag_to_check = all_data.data() + decryptInfo.unprotected_header.size() + encrypted_payload_size; int tag_to_check_length = AEAD_TAG_LENGTH; - std::array decrypt_buffer; + // Allocate memory for decryption. + std::vector decrypt_buffer(encrypted_payload_size); // Setup context auto* ctx = get_aes_128_gcm(); From d745d746bcbfa970fc9822e702713927f5b22022 Mon Sep 17 00:00:00 2001 From: Arne Welzel Date: Wed, 11 Dec 2024 12:51:23 +0100 Subject: [PATCH 89/91] QUIC/decrypt_crypto: Limit payload_length to 10k Given we dynamically allocate memory for decryption, employ a limit that is unlikely to be hit, but allows for large payloads produced by the fuzzer or jumbo frames. --- src/analyzer/protocol/quic/decrypt_crypto.cc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/analyzer/protocol/quic/decrypt_crypto.cc b/src/analyzer/protocol/quic/decrypt_crypto.cc index 693f77fdcc..efe83c5343 100644 --- a/src/analyzer/protocol/quic/decrypt_crypto.cc +++ b/src/analyzer/protocol/quic/decrypt_crypto.cc @@ -158,6 +158,11 @@ hilti::rt::Bytes decrypt(const std::vector& client_key, const hilti::rt throw hilti::rt::RuntimeError(hilti::rt::fmt("payload too small %ld < %ld", payload_length, decryptInfo.packet_number_length + AEAD_TAG_LENGTH)); + // Bail on large payloads, somewhat arbitrarily. 10k allows for Jumbo frames + // and sometimes the fuzzer produces packets up to that size as well. + if ( payload_length > 10000 ) + throw hilti::rt::RuntimeError(hilti::rt::fmt("payload_length too large %ld", payload_length)); + const uint8_t* encrypted_payload = data_as_uint8(all_data) + decryptInfo.unprotected_header.size(); int encrypted_payload_size = payload_length - decryptInfo.packet_number_length - AEAD_TAG_LENGTH; From c2f2388f1814e90e3ad6503825d40e259b9da170 Mon Sep 17 00:00:00 2001 From: Arne Welzel Date: Wed, 11 Dec 2024 13:04:45 +0100 Subject: [PATCH 90/91] QUIC/decrypt_crypto: Actually check if decryption was successful ...and bail if it wasn't. PCAP was produced using OSS-Fuzz input from issue 383379789. --- src/analyzer/protocol/quic/decrypt_crypto.cc | 5 +++-- .../analyzer.log.cut | 3 +++ .../conn.log.cut | 5 +++++ .../Traces/quic/383379789-decrypt-crash.pcap | Bin 0 -> 43734 bytes .../base/protocols/quic/decrypt-crash.zeek | 8 ++++++++ 5 files changed, 19 insertions(+), 2 deletions(-) create mode 100644 testing/btest/Baseline/scripts.base.protocols.quic.decrypt-crash/analyzer.log.cut create mode 100644 testing/btest/Baseline/scripts.base.protocols.quic.decrypt-crash/conn.log.cut create mode 100644 testing/btest/Traces/quic/383379789-decrypt-crash.pcap create mode 100644 testing/btest/scripts/base/protocols/quic/decrypt-crash.zeek diff --git a/src/analyzer/protocol/quic/decrypt_crypto.cc b/src/analyzer/protocol/quic/decrypt_crypto.cc index efe83c5343..fa496413ae 100644 --- a/src/analyzer/protocol/quic/decrypt_crypto.cc +++ b/src/analyzer/protocol/quic/decrypt_crypto.cc @@ -152,7 +152,7 @@ Function that calls the AEAD decryption routine, and returns the decrypted data. */ hilti::rt::Bytes decrypt(const std::vector& client_key, const hilti::rt::Bytes& all_data, uint64_t payload_length, const DecryptionInformation& decryptInfo) { - int out, out2, res; + int out, out2; if ( payload_length < decryptInfo.packet_number_length + AEAD_TAG_LENGTH ) throw hilti::rt::RuntimeError(hilti::rt::fmt("payload too small %ld < %ld", payload_length, @@ -202,7 +202,8 @@ hilti::rt::Bytes decrypt(const std::vector& client_key, const hilti::rt EVP_CipherUpdate(ctx, decrypt_buffer.data(), &out, encrypted_payload, encrypted_payload_size); // Validate whether the decryption was successful or not - EVP_CipherFinal_ex(ctx, NULL, &out2); + if ( EVP_CipherFinal_ex(ctx, NULL, &out2) == 0 ) + throw hilti::rt::RuntimeError("decryption failed"); // Copy the decrypted data from the decrypted buffer into a Bytes instance. return hilti::rt::Bytes(decrypt_buffer.data(), decrypt_buffer.data() + out); diff --git a/testing/btest/Baseline/scripts.base.protocols.quic.decrypt-crash/analyzer.log.cut b/testing/btest/Baseline/scripts.base.protocols.quic.decrypt-crash/analyzer.log.cut new file mode 100644 index 0000000000..1a3b7336c7 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.quic.decrypt-crash/analyzer.log.cut @@ -0,0 +1,3 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +ts uid cause analyzer_kind analyzer_name failure_reason +1733909795.417573 C4J4Th3PJpwUYZZ6gc violation protocol QUIC decryption failed (<...>/QUIC.spicy:) diff --git a/testing/btest/Baseline/scripts.base.protocols.quic.decrypt-crash/conn.log.cut b/testing/btest/Baseline/scripts.base.protocols.quic.decrypt-crash/conn.log.cut new file mode 100644 index 0000000000..e9151b0dee --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.quic.decrypt-crash/conn.log.cut @@ -0,0 +1,5 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +ts uid proto history service +XXXXXXXXXX.XXXXXX ClEkJM2Vm5giqnMf4h udp D - +XXXXXXXXXX.XXXXXX C4J4Th3PJpwUYZZ6gc udp D - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 tcp F ftp diff --git a/testing/btest/Traces/quic/383379789-decrypt-crash.pcap b/testing/btest/Traces/quic/383379789-decrypt-crash.pcap new file mode 100644 index 0000000000000000000000000000000000000000..aeb980850817a541f4956db12eada9abb9381664 GIT binary patch literal 43734 zcmeI*ziU%b6u|NG()3}Taqt%oE~3$tLUU1ZQ~W_H1%vpbA`+xJB&86dqDvmsW+)=~ z4-}jf9CT1{Dmdz*lcJl5OI-?1QluSP&%KTGXB4H@yu9y$`{=v5x$m4$r<9(X4=Ifi!00IagfB*srAbf&DS5lQI!N0D+|fd+fQqd6A3cuJlU}d? z)avv4Uc23wvmJ6+f40NL!ZE)YkuII8Z?=a5kNA4(uZ&N6FYH;oE5q)!cfgltN5l=c zV)ea7MC@ksdxhm!y3~_oV#3RK<7JVwed`vPv?mcKCJMLo&Mya@(^EkZJRQ5XF*|tN zt{@OVAie_I-p03fDn|eT1Q0*~0R#|0009ILKp+MJUt>@sB_erQL z{I;|FiR(CT)?wakUiWs5?6q|B&hxr1>Jr;|zNA~+rM2vmX*9)O*Lgc!{7vWi^f&#I zQhj2r)OY{QqE7n7o#)HD>-Ayw`M>O conn.log.cut +# @TEST-EXEC: zeek-cut -m ts uid cause analyzer_kind analyzer_name failure_reason < analyzer.log > analyzer.log.cut +# @TEST-EXEC: btest-diff conn.log.cut +# @TEST-EXEC: TEST_DIFF_CANONIFIER='sed -E "s/\((.+)\.spicy:[0-9]+:[0-9]+(-[0-9]+:[0-9]+)?\)/(\1.spicy:)/g" | $SCRIPTS/diff-remove-abspath' btest-diff analyzer.log.cut From 7c8a7680bae772a52ec9cca85e4f557a032245c8 Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Mon, 16 Dec 2024 11:12:33 -0700 Subject: [PATCH 91/91] Update CHANGES, VERSION, and NEWS for 7.0.5 release --- CHANGES | 4 ++++ NEWS | 21 +++++++++++++++++++++ VERSION | 2 +- 3 files changed, 26 insertions(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index 84a427778a..7307571637 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,7 @@ +7.0.5 | 2024-12-16 11:12:33 -0700 + + * Update CHANGES, VERSION, and NEWS for 7.0.5 release (Tim Wojtulewicz, Corelight) + 7.0.4-10 | 2024-12-16 10:21:46 -0700 * QUIC/decrypt_crypto: Actually check if decryption was successful (Arne Welzel, Corelight) diff --git a/NEWS b/NEWS index d9174642a0..25a19bc2ab 100644 --- a/NEWS +++ b/NEWS @@ -3,6 +3,27 @@ This document summarizes the most important changes in the current Zeek release. For an exhaustive list of changes, see the ``CHANGES`` file (note that submodules, such as Broker, come with their own ``CHANGES``.) +Zeek 7.0.5 +========== + +This release fixes the following security issues: + +- Large QUIC packets can cause Zeek to overflow memory and potentially + crash. Due to the possibility of receiving these packets from remote hosts, + this is a DoS risk. The fix included limits the payload length to 10000 bytes + and reports an error for those cases, as well as fixing the memory allocation + to not use a fixed-size buffer for all packets. + +This release fixes the following bugs: + +- The ZAM script optimization feature gained some fixes for some minor memory + leaks. + +- The ZeekJS submodule was updated to v0.14.0. In certain environment, ZeekJS + would fail to start a debugging thread due to limited stack size, producing + spurious log messages. This was fixed by not starting the debugging thread by + default. + Zeek 7.0.4 ========== diff --git a/VERSION b/VERSION index 0fdcca7814..2be8aeb6b1 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -7.0.4-10 +7.0.5