From 3e97ec39b8be63dfada60f7494caec45bb0d3553 Mon Sep 17 00:00:00 2001 From: Christian Kreibich Date: Tue, 21 May 2024 23:55:53 -0700 Subject: [PATCH 1/3] Add BiF for looking up a connection's numeric protocol analyzer IDs This adds a new lookup_connection_analyzer_id() BiF to find a given connection's numeric identifier for a given protocol analyzer (as defined by the underlying Analyzer::id_counter). This enables users to call disable_analyzer(), which requires a numeric analyzer ID, outside of analyzer_confirmation_info and analyzer_violation_info events handlers. --- NEWS | 20 ++++++++++++++++++++ src/zeek.bif | 28 ++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+) diff --git a/NEWS b/NEWS index eb0ee24ea6..663de15ebb 100644 --- a/NEWS +++ b/NEWS @@ -39,6 +39,26 @@ New Functionality - SMB2 packets containing multiple PDUs now correctly parse all of the headers, instead of just the first one and ignoring the rest. +- The new built-in function ``lookup_connection_analyzer_id()`` retrieves the + numeric identifier of an analyzer associated with a connection. This enables + the use of the ``disable_analyzer()`` BiF outside of the analyzer + confirmation/violation events that have so far been the only providers of + those identifiers. For example, this allows the suppression of an analyzer + from the outset for specific connections: + + event connection_established(c: connection): + { + if ( no_http_for_this_conn_wanted(c) ) + { + local aid = lookup_connection_analyzer_id(c$id, Analyzer::ANALYZER_HTTP); + if ( aid > 0 ) + disable_analyzer(c$id, aid, T, T); + } + } + + Use ``Analyzer::get_tag()`` if you need to obtain an analyzer's tag from its + name (such as "HTTP"). + Changed Functionality --------------------- diff --git a/src/zeek.bif b/src/zeek.bif index 4134e72847..a3d3ff3670 100644 --- a/src/zeek.bif +++ b/src/zeek.bif @@ -4121,6 +4121,34 @@ function file_mode%(mode: count%): string #include "zeek/analyzer/Manager.h" %%} +## Returns the numeric ID of the requested protocol analyzer for the given +## connection. +## +## cid: The connection identifier. +## +## atype: The analyzer tag, such as ``Analyzer::ANALYZER_HTTP``. +## +## Returns: a numeric identifier for the analyzer, valid for the given +## connection. When no such analyzer exists the function returns +## 0, which is never a valid analyzer ID value. +## +## .. zeek:see:: disable_analyzer Analyzer::disabling_analyzer +function lookup_connection_analyzer_id%(cid: conn_id, atype: AllAnalyzers::Tag%): count + %{ + Connection* c = session_mgr->FindConnection(cid); + if ( ! c ) + { + zeek::emit_builtin_error("connection ID not a known connection", cid); + return zeek::val_mgr->Count(0); + } + + analyzer::Analyzer* a = c->FindAnalyzer(analyzer_mgr->GetComponentTag(atype)); + if ( ! a ) + return zeek::val_mgr->Count(0); + + return zeek::val_mgr->Count(a->GetID()); + %} + ## Disables the analyzer which raised the current event (if the analyzer ## belongs to the given connection). ## From 09b70879b0beb4276f13fd550b90f6a61b1ac4ec Mon Sep 17 00:00:00 2001 From: Christian Kreibich Date: Thu, 23 May 2024 17:15:02 -0700 Subject: [PATCH 2/3] Add btests for the lookup_connection_analyzer_id() BiF. --- .../bifs.disable_analyzer-for-conn-2/output | 1 + .../bifs.disable_analyzer-for-conn-3/output | 1 + .../bifs.disable_analyzer-for-conn/output | 3 ++ .../btest/bifs/disable_analyzer-for-conn.zeek | 51 +++++++++++++++++++ 4 files changed, 56 insertions(+) create mode 100644 testing/btest/Baseline/bifs.disable_analyzer-for-conn-2/output create mode 100644 testing/btest/Baseline/bifs.disable_analyzer-for-conn-3/output create mode 100644 testing/btest/Baseline/bifs.disable_analyzer-for-conn/output create mode 100644 testing/btest/bifs/disable_analyzer-for-conn.zeek diff --git a/testing/btest/Baseline/bifs.disable_analyzer-for-conn-2/output b/testing/btest/Baseline/bifs.disable_analyzer-for-conn-2/output new file mode 100644 index 0000000000..49d861c74c --- /dev/null +++ b/testing/btest/Baseline/bifs.disable_analyzer-for-conn-2/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/Baseline/bifs.disable_analyzer-for-conn-3/output b/testing/btest/Baseline/bifs.disable_analyzer-for-conn-3/output new file mode 100644 index 0000000000..49d861c74c --- /dev/null +++ b/testing/btest/Baseline/bifs.disable_analyzer-for-conn-3/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/Baseline/bifs.disable_analyzer-for-conn/output b/testing/btest/Baseline/bifs.disable_analyzer-for-conn/output new file mode 100644 index 0000000000..bb88a2d5b0 --- /dev/null +++ b/testing/btest/Baseline/bifs.disable_analyzer-for-conn/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. +Analyzer::ANALYZER_HTTP +Analyzer::ANALYZER_HTTP diff --git a/testing/btest/bifs/disable_analyzer-for-conn.zeek b/testing/btest/bifs/disable_analyzer-for-conn.zeek new file mode 100644 index 0000000000..18143e9030 --- /dev/null +++ b/testing/btest/bifs/disable_analyzer-for-conn.zeek @@ -0,0 +1,51 @@ +# Verifies analyzer ID retrieval from a connection. +# +# @TEST-EXEC: zeek -b -r ${TRACES}/ssh/ssh-on-port-80.trace %INPUT >output +# @TEST-EXEC: btest-diff output + +# This first test should trigger two analyzer violations since the given pcap +# has non-HTTP content on port 80, which triggers one violation each for the +# missing request and response lines. + +@load base/protocols/http + +event analyzer_violation_info(atype: AllAnalyzers::Tag, info: AnalyzerViolationInfo) + { + print atype; + } + +# @TEST-START-NEXT + +# This one should not trigger violations since we suppress HTTP analysis when +# the TCP connection establishes. + +@load base/protocols/http + +event analyzer_violation_info(atype: AllAnalyzers::Tag, info: AnalyzerViolationInfo) + { + print atype; + } + +event connection_established(c: connection) + { + local aid = lookup_connection_analyzer_id(c$id, Analyzer::ANALYZER_HTTP); + if ( aid > 0 ) + disable_analyzer(c$id, aid, T, T); + } + +# @TEST-START-NEXT + +# This one validates the return values of analyzer ID lookup calls for valid & +# invalid connection IDs and analyzers. + +@load base/protocols/http + +event connection_established(c: connection) + { + assert lookup_connection_analyzer_id(c$id, Analyzer::ANALYZER_HTTP) != 0; + + local wrong_cid = copy(c$id); + wrong_cid$orig_h = 1.2.3.4; + + assert lookup_connection_analyzer_id(wrong_cid, Analyzer::ANALYZER_HTTP) == 0; + } From a599fe04384d00373056026e3b293028e7efa232 Mon Sep 17 00:00:00 2001 From: Christian Kreibich Date: Fri, 24 May 2024 11:01:00 -0700 Subject: [PATCH 3/3] More precise error reporting for the disable_analyzer() BiF This replaces generic reporter->Error() calls with the builtin-specific variety, which gives better context in the resulting error messages (such as the script and line causing it). Includes corresponding baseline update in one affected btest. --- src/zeek.bif | 6 +- .../bifs.disable_analyzer-invalid-aid/out | 68 +++++++++---------- .../bifs/disable_analyzer-invalid-aid.zeek | 2 +- 3 files changed, 38 insertions(+), 38 deletions(-) diff --git a/src/zeek.bif b/src/zeek.bif index a3d3ff3670..2d3d73fcda 100644 --- a/src/zeek.bif +++ b/src/zeek.bif @@ -4172,7 +4172,7 @@ function disable_analyzer%(cid: conn_id, aid: count, err_if_no_conn: bool &defau Connection* c = session_mgr->FindConnection(cid); if ( ! c ) { - zeek::reporter->Error("cannot find connection"); + zeek::emit_builtin_error("connection ID not a known connection", cid); return zeek::val_mgr->False(); } @@ -4180,7 +4180,7 @@ function disable_analyzer%(cid: conn_id, aid: count, err_if_no_conn: bool &defau if ( ! a ) { if ( err_if_no_conn ) - zeek::reporter->Error("connection does not have analyzer specified to disable"); + zeek::emit_builtin_error("connection does not have analyzer specified to disable"); return zeek::val_mgr->False(); } @@ -4190,7 +4190,7 @@ function disable_analyzer%(cid: conn_id, aid: count, err_if_no_conn: bool &defau // of a root analyzer without probing for it. if ( ! a->Parent() ) { - zeek::reporter->Error("root analyzer %s cannot be removed", a->GetAnalyzerName()); + zeek::emit_builtin_error(zeek::util::fmt("root analyzer %s cannot be removed", a->GetAnalyzerName())); return zeek::val_mgr->False(); } diff --git a/testing/btest/Baseline/bifs.disable_analyzer-invalid-aid/out b/testing/btest/Baseline/bifs.disable_analyzer-invalid-aid/out index 13952f2a52..1777b67d52 100644 --- a/testing/btest/Baseline/bifs.disable_analyzer-invalid-aid/out +++ b/testing/btest/Baseline/bifs.disable_analyzer-invalid-aid/out @@ -1,35 +1,35 @@ ### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. -XXXXXXXXXX.XXXXXX error: root analyzer UDP cannot be removed -XXXXXXXXXX.XXXXXX error: root analyzer UDP cannot be removed -XXXXXXXXXX.XXXXXX error: root analyzer UDP cannot be removed -XXXXXXXXXX.XXXXXX error: root analyzer TCP cannot be removed -XXXXXXXXXX.XXXXXX error: root analyzer TCP cannot be removed -XXXXXXXXXX.XXXXXX error: root analyzer UDP cannot be removed -XXXXXXXXXX.XXXXXX error: root analyzer UDP cannot be removed -XXXXXXXXXX.XXXXXX error: root analyzer UDP cannot be removed -XXXXXXXXXX.XXXXXX error: root analyzer TCP cannot be removed -XXXXXXXXXX.XXXXXX error: root analyzer TCP cannot be removed -XXXXXXXXXX.XXXXXX error: root analyzer UDP cannot be removed -XXXXXXXXXX.XXXXXX error: root analyzer UDP cannot be removed -XXXXXXXXXX.XXXXXX error: root analyzer UDP cannot be removed -XXXXXXXXXX.XXXXXX error: root analyzer TCP cannot be removed -XXXXXXXXXX.XXXXXX error: root analyzer UDP cannot be removed -XXXXXXXXXX.XXXXXX error: root analyzer UDP cannot be removed -XXXXXXXXXX.XXXXXX error: root analyzer UDP cannot be removed -XXXXXXXXXX.XXXXXX error: root analyzer TCP cannot be removed -XXXXXXXXXX.XXXXXX error: root analyzer TCP cannot be removed -XXXXXXXXXX.XXXXXX error: root analyzer UDP cannot be removed -XXXXXXXXXX.XXXXXX error: root analyzer UDP cannot be removed -XXXXXXXXXX.XXXXXX error: root analyzer UDP cannot be removed -XXXXXXXXXX.XXXXXX error: root analyzer TCP cannot be removed -XXXXXXXXXX.XXXXXX error: root analyzer UDP cannot be removed -XXXXXXXXXX.XXXXXX error: root analyzer UDP cannot be removed -XXXXXXXXXX.XXXXXX error: root analyzer TCP cannot be removed -XXXXXXXXXX.XXXXXX error: root analyzer TCP cannot be removed -XXXXXXXXXX.XXXXXX error: root analyzer UDP cannot be removed -XXXXXXXXXX.XXXXXX error: root analyzer UDP cannot be removed -XXXXXXXXXX.XXXXXX error: root analyzer UDP cannot be removed -XXXXXXXXXX.XXXXXX error: root analyzer UDP cannot be removed -XXXXXXXXXX.XXXXXX error: root analyzer UDP cannot be removed -XXXXXXXXXX.XXXXXX error: root analyzer UDP cannot be removed -XXXXXXXXXX.XXXXXX error: root analyzer UDP cannot be removed +XXXXXXXXXX.XXXXXX error in <...>/disable_analyzer-invalid-aid.zeek, line 12: root analyzer UDP cannot be removed (disable_analyzer(c$id, i, F, T)) +XXXXXXXXXX.XXXXXX error in <...>/disable_analyzer-invalid-aid.zeek, line 12: root analyzer UDP cannot be removed (disable_analyzer(c$id, i, F, T)) +XXXXXXXXXX.XXXXXX error in <...>/disable_analyzer-invalid-aid.zeek, line 12: root analyzer UDP cannot be removed (disable_analyzer(c$id, i, F, T)) +XXXXXXXXXX.XXXXXX error in <...>/disable_analyzer-invalid-aid.zeek, line 12: root analyzer TCP cannot be removed (disable_analyzer(c$id, i, F, T)) +XXXXXXXXXX.XXXXXX error in <...>/disable_analyzer-invalid-aid.zeek, line 12: root analyzer TCP cannot be removed (disable_analyzer(c$id, i, F, T)) +XXXXXXXXXX.XXXXXX error in <...>/disable_analyzer-invalid-aid.zeek, line 12: root analyzer UDP cannot be removed (disable_analyzer(c$id, i, F, T)) +XXXXXXXXXX.XXXXXX error in <...>/disable_analyzer-invalid-aid.zeek, line 12: root analyzer UDP cannot be removed (disable_analyzer(c$id, i, F, T)) +XXXXXXXXXX.XXXXXX error in <...>/disable_analyzer-invalid-aid.zeek, line 12: root analyzer UDP cannot be removed (disable_analyzer(c$id, i, F, T)) +XXXXXXXXXX.XXXXXX error in <...>/disable_analyzer-invalid-aid.zeek, line 12: root analyzer TCP cannot be removed (disable_analyzer(c$id, i, F, T)) +XXXXXXXXXX.XXXXXX error in <...>/disable_analyzer-invalid-aid.zeek, line 12: root analyzer TCP cannot be removed (disable_analyzer(c$id, i, F, T)) +XXXXXXXXXX.XXXXXX error in <...>/disable_analyzer-invalid-aid.zeek, line 12: root analyzer UDP cannot be removed (disable_analyzer(c$id, i, F, T)) +XXXXXXXXXX.XXXXXX error in <...>/disable_analyzer-invalid-aid.zeek, line 12: root analyzer UDP cannot be removed (disable_analyzer(c$id, i, F, T)) +XXXXXXXXXX.XXXXXX error in <...>/disable_analyzer-invalid-aid.zeek, line 12: root analyzer UDP cannot be removed (disable_analyzer(c$id, i, F, T)) +XXXXXXXXXX.XXXXXX error in <...>/disable_analyzer-invalid-aid.zeek, line 12: root analyzer TCP cannot be removed (disable_analyzer(c$id, i, F, T)) +XXXXXXXXXX.XXXXXX error in <...>/disable_analyzer-invalid-aid.zeek, line 12: root analyzer UDP cannot be removed (disable_analyzer(c$id, i, F, T)) +XXXXXXXXXX.XXXXXX error in <...>/disable_analyzer-invalid-aid.zeek, line 12: root analyzer UDP cannot be removed (disable_analyzer(c$id, i, F, T)) +XXXXXXXXXX.XXXXXX error in <...>/disable_analyzer-invalid-aid.zeek, line 12: root analyzer UDP cannot be removed (disable_analyzer(c$id, i, F, T)) +XXXXXXXXXX.XXXXXX error in <...>/disable_analyzer-invalid-aid.zeek, line 12: root analyzer TCP cannot be removed (disable_analyzer(c$id, i, F, T)) +XXXXXXXXXX.XXXXXX error in <...>/disable_analyzer-invalid-aid.zeek, line 12: root analyzer TCP cannot be removed (disable_analyzer(c$id, i, F, T)) +XXXXXXXXXX.XXXXXX error in <...>/disable_analyzer-invalid-aid.zeek, line 12: root analyzer UDP cannot be removed (disable_analyzer(c$id, i, F, T)) +XXXXXXXXXX.XXXXXX error in <...>/disable_analyzer-invalid-aid.zeek, line 12: root analyzer UDP cannot be removed (disable_analyzer(c$id, i, F, T)) +XXXXXXXXXX.XXXXXX error in <...>/disable_analyzer-invalid-aid.zeek, line 12: root analyzer UDP cannot be removed (disable_analyzer(c$id, i, F, T)) +XXXXXXXXXX.XXXXXX error in <...>/disable_analyzer-invalid-aid.zeek, line 12: root analyzer TCP cannot be removed (disable_analyzer(c$id, i, F, T)) +XXXXXXXXXX.XXXXXX error in <...>/disable_analyzer-invalid-aid.zeek, line 12: root analyzer UDP cannot be removed (disable_analyzer(c$id, i, F, T)) +XXXXXXXXXX.XXXXXX error in <...>/disable_analyzer-invalid-aid.zeek, line 12: root analyzer UDP cannot be removed (disable_analyzer(c$id, i, F, T)) +XXXXXXXXXX.XXXXXX error in <...>/disable_analyzer-invalid-aid.zeek, line 12: root analyzer TCP cannot be removed (disable_analyzer(c$id, i, F, T)) +XXXXXXXXXX.XXXXXX error in <...>/disable_analyzer-invalid-aid.zeek, line 12: root analyzer TCP cannot be removed (disable_analyzer(c$id, i, F, T)) +XXXXXXXXXX.XXXXXX error in <...>/disable_analyzer-invalid-aid.zeek, line 12: root analyzer UDP cannot be removed (disable_analyzer(c$id, i, F, T)) +XXXXXXXXXX.XXXXXX error in <...>/disable_analyzer-invalid-aid.zeek, line 12: root analyzer UDP cannot be removed (disable_analyzer(c$id, i, F, T)) +XXXXXXXXXX.XXXXXX error in <...>/disable_analyzer-invalid-aid.zeek, line 12: root analyzer UDP cannot be removed (disable_analyzer(c$id, i, F, T)) +XXXXXXXXXX.XXXXXX error in <...>/disable_analyzer-invalid-aid.zeek, line 12: root analyzer UDP cannot be removed (disable_analyzer(c$id, i, F, T)) +XXXXXXXXXX.XXXXXX error in <...>/disable_analyzer-invalid-aid.zeek, line 12: root analyzer UDP cannot be removed (disable_analyzer(c$id, i, F, T)) +XXXXXXXXXX.XXXXXX error in <...>/disable_analyzer-invalid-aid.zeek, line 12: root analyzer UDP cannot be removed (disable_analyzer(c$id, i, F, T)) +XXXXXXXXXX.XXXXXX error in <...>/disable_analyzer-invalid-aid.zeek, line 12: root analyzer UDP cannot be removed (disable_analyzer(c$id, i, F, T)) diff --git a/testing/btest/bifs/disable_analyzer-invalid-aid.zeek b/testing/btest/bifs/disable_analyzer-invalid-aid.zeek index 5738a80575..9643cfa6d1 100644 --- a/testing/btest/bifs/disable_analyzer-invalid-aid.zeek +++ b/testing/btest/bifs/disable_analyzer-invalid-aid.zeek @@ -1,5 +1,5 @@ # @TEST-EXEC: zeek -b -r $TRACES/wikipedia.trace %INPUT >out 2>&1 -# @TEST-EXEC: btest-diff out +# @TEST-EXEC: TEST_DIFF_CANONIFIER='$SCRIPTS/diff-canonifier | $SCRIPTS/diff-remove-abspath' btest-diff out # @TEST-DOC: Validates that one can use disable_analyzer even for analyzers without parent. This is a regression test for #3071. event new_connection(c: connection)