Commit graph

1465 commits

Author SHA1 Message Date
Arne Welzel
822ca99e80 Merge remote-tracking branch 'origin/topic/awelzel/3424-http-upgrade-websocket-v1'
* origin/topic/awelzel/3424-http-upgrade-websocket-v1:
  websocket: Handle breaking from WebSocket::configure_analyzer()
  websocket: Address review feedback for BinPac code
  fuzzers: Add WebSocket fuzzer
  websocket: Fix crash for fragmented messages
  websocket: Verify Sec-WebSocket-Key/Accept headers and review feedback
  btest/websocket: Test for coalesced reply-ping
  HTTP/CONNECT: Also weird on extra data in reply
  HTTP/Upgrade: Weird when more data is available
  ContentLine: Add GetDeliverStreamRemainingLength() accessor
  HTTP: Drain event queue after instantiating upgrade analyzer
  btest/http: Explain switching-protocols test change as comment
  WebSocket: Introduce new analyzer and log
  HTTP: Add mechanism to instantiate Upgrade analyzer
2024-01-23 18:17:50 +01:00
Arne Welzel
9654226075 websocket: Handle breaking from WebSocket::configure_analyzer()
...and various nits from the review.
2024-01-22 18:54:41 +01:00
Arne Welzel
5eb380d74a websocket: Fix crash for fragmented messages
The &transient attribute does not work well with $element as that won't
be available within &until anymore apparently.

Found after a few seconds building out the fuzzer.
2024-01-22 18:54:38 +01:00
Arne Welzel
e17655be61 websocket: Verify Sec-WebSocket-Key/Accept headers and review feedback
Don't log them, they are random and arbitrary in the normal case. Users
can do the following to log them if wanted.

    redef += WebSocket::Info$client_key += { &log };
    redef += WebSocket::Info$server_accept += { &log };
2024-01-22 18:54:38 +01:00
Arne Welzel
a6c1d12206 btest/websocket: Test for coalesced reply-ping
Add a constructed PCAP where the HTTP/websocket server send a WebSocket
ping message directly with the packet of the HTTP reply. Ensure this is
interpreted the same as if the WebSocket message is in a separate packet
following the HTTP reply.

For the server side this should work, for the client side we'd need to
synchronize suspend parsing the client side as we currently cannot quite
know whether it's a pipelined HTTP request following, or upgraded protocol
data and we don't have "suspend parsing" functionality here.
2024-01-22 18:54:38 +01:00
Arne Welzel
37521f58e5 btest/http: Explain switching-protocols test change as comment
DPD enables HTTP based on the content of the WebSocket frames. However,
it's not HTTP, the protocol is x-kaazing-handshake and the server sends
some form of status/acknowledge to the client first, so the HTTP and the
HTTP analyzer receives that as the first bytes of the response and
bails, oh well.
2024-01-22 18:54:38 +01:00
Arne Welzel
efc2681152 WebSocket: Introduce new analyzer and log
This adds a new WebSocket analyzer that is enabled with the HTTP upgrade
mechanism introduced previously. It is a first implementation in BinPac with
manual chunking of frame payload. Configuration of the analyzer is sketched
via the new websocket_handshake() event and a configuration BiF called
WebSocket::__configure_analyzer(). In short, script land collects WebSocket
related HTTP headers and can forward these to the analyzer to change its
parsing behavior at websocket_handshake() time. For now, however, there's
no actual logic that would change behavior based on agreed upon extensions
exchanged via HTTP headers (e.g. frame compression). WebSocket::Configure()
simply attaches a PIA_TCP analyzer to the WebSocket analyzer for dynamic
protocol detection (or a custom analyzer if set). The added pcaps show this
in action for tunneled ssh, http and https using wstunnel. One test pcap is
Broker's WebSocket traffic from our own test suite, the other is the
Jupyter websocket traffic from the ticket/discussion.

This commit further adds a basic websocket.log that aggregates the WebSocket
specific headers (Sec-WebSocket-*) headers into a single log.

Closes #3424
2024-01-22 18:54:38 +01:00
Tim Wojtulewicz
13fde341d2 Merge remote-tracking branch 'security/topic/awelzel/topic/awelzel/208-http-mime-nested-v2'
* security/topic/awelzel/topic/awelzel/208-http-mime-nested-v2:
  MIME: Cap nested MIME analysis depth to 100
2024-01-21 19:31:14 -07:00
Arne Welzel
e1ed709243 SMTP/BDAT: Use strtoull and bail on UULONG_MAX values 2024-01-19 13:24:07 +01:00
Arne Welzel
c23d605286 SMTP/BDAT: Fix int/int64_t/uint64_t confusion
The BDAT analyzer should be supporting uint64_t sized chunks reasonably well,
but the ContentLine analyzer does not, And also, I totally got types for
RemainingChunkSize() and in DeliverStream() wrong, resulting in overflows
and segfaults when very large chunk sizes were used.

Tickled by OSS-Fuzz. Actually running the fuzzer locally only took a
few minutes to find the crash, too. Embarrassing.
2024-01-19 13:05:26 +01:00
Arne Welzel
2a858d252e MIME: Cap nested MIME analysis depth to 100
OSS-Fuzz managed to produce a MIME multipart message construction with
thousands of nested entities (or that's what Zeek makes out of it anyhow).
Prevent such deep analysis by capping at a nesting depth of 100,
preventing unnecessary resource usage. A new weird named exceeded_mime_max_depth
is reported when this limit is reached.

This change reduces the runtime of the OSS-Fuzz reproducer from ~45 seconds
to ~2.5 seconds.

The test PCAP was produced from a Python script using the email package
and sending the rendered version via POST to a HTTP server.

Closes #208
2024-01-17 10:18:13 -07:00
Arne Welzel
ae2a5c83a4 SMTP: No state update for bad BDAT commands
OSS-Fuzz found that providing an invalid BDAT line would tickle an
assert in UpdateState(). The BDAT state was never initialized, but
within UpdateState() that was expected.

This also removes the AnalyzerViolation() call for bad BDAT commands
and instead raises a weird. The SMTP analyzer is very lax and not triggering
the violation allows to parse the server's response to such an invalid
command.

PCAP files produced by a custom Python SMTP client against Postfix.
2024-01-15 18:25:41 +01:00
Arne Welzel
00e7977732 btest/smtp: Test with smtp-bdat-pipeline-8bitmime.pcap
Not sure about the origin of this pcap, so adding it in a separate
commit, but it seems a nice real-world test case.
2024-01-12 10:18:14 +01:00
Arne Welzel
14949941ce SMTP: Add BDAT support
Closes #3264
2024-01-12 10:18:07 +01:00
Arne Welzel
ec9ed81250 quic: Handle and log unhandled_version 2024-01-09 17:10:11 +01:00
Arne Welzel
6a6cc7f551 ldap: Fix substring filter parsing and rendering
The initial (prefix) and final (suffix) strings are specified individually
with a variable number of "any" matches that can occur between these.
The previous implementation assumed a single string and rendered it
as *<string>*.

Reported and PCAP provided by @martinvanhensbergen, thanks!

Closes zeek/spicy-ldap#27
2024-01-05 16:06:23 +01:00
Arne Welzel
0796a191c6 quic: tests: Require have-spicy 2024-01-05 11:37:35 +01:00
Arne Welzel
50cdac922f quic: analyzer: Recognize and report unknown versions better
This makes the analyzer.log entry more informative by including the
actual version and also allows to handle this scenario in script land
if needed.
2024-01-05 11:37:03 +01:00
Arne Welzel
727091ed67 quic: tests: Add QUIC v2 test cases
Produced using examples from the go-quic project, patching the clients
to force QUIC v2.
2024-01-05 11:36:57 +01:00
Arne Welzel
4ebd81fb23 Merge remote-tracking branch 'origin/topic/awelzel/3504-ldap-logs-scalars'
* origin/topic/awelzel/3504-ldap-logs-scalars:
  Update external baselines
  ldap: Use scalar values in logs where appropriate
  ldap: Rename LDAP::search_result to LDAP::search_result_entry
2024-01-03 12:35:51 +01:00
Arne Welzel
242db4981d ldap: Use scalar values in logs where appropriate
Skimming through the RFC, the previous approach of having containers for most
fields seems unfounded for normal protocol operation. The new weirds could just
as well be considered protocol violations. Outside of duplicated or missed data
they just shouldn't happen for well-behaved client/server behavior.
Additionally, with non-conformant traffic it would be trivial to cause
unbounded state growth and immense log record sizes.

Unfortunately, things have become a bit clunky now.

Closes #3504
2024-01-03 11:57:31 +01:00
Arne Welzel
3f7881a57b segment_profiling: Remove SegmentProfiler and load_sample event
While it seems interesting functionality, this hasn't been documented,
maintained or knowingly leveraged for many years.

There are various other approaches today, too:

* We track the number of event handler invocations regardless of
  profiling. It's possible to approximate a load_sample event by
  comparing the result of two get_event_stats() calls. Or, visualize
  the corresponding counters in a Prometheus setup to get an idea of
  event/s broken down by event names.

* HookCallFunction() allows to intercept script execution, including
  measuring the time execution takes.

* The global call_stack and g_frame_stack can be used from plugins
  (and even external processes) to walk the Zeek script stack at certain
  points to implement a sampling profiler.

* USDT probes or more plugin hooks will likely be preferred over Zeek
  builtin functionality in the future.

Relates to #3458
2024-01-03 11:55:54 +01:00
Arne Welzel
28eef9e4b2 Merge remote-tracking branch 'origin/topic/awelzel/log-write-delay-3'
* origin/topic/awelzel/log-write-delay-3:
  logging: ref() to record_ref() renaming
  logging: Fix typos from review
  logging/Manager: Make LogDelayExpiredTimer an implementation detail
  logging/WriteToFilters: Use range-based for loop
  testing/btest: Log::delay() from JavaScript
  NEWS: Entry for delayed log writes
  Bump doc submodule to branch
  logging: Do not keep delay state persistent
  logging: delay documentation polishing
  logging: Better error messages for invalid Log::delay() calls
  logging/Manager: Implement DelayTokenType as an actual opaque
  logging: Implement get_delay_queue_size()
  logging: Introduce Log::delay() and Log::delay_finish()
  logging/Manager: zeek::detail'ify
  logging/Manager: Split Write()
  Timer: Add LOG_DELAY_EXPIRE timer type
  Ascii: Remove extra include
2023-12-01 12:05:02 +01:00
Arne Welzel
e2ce929fa4 logging: Better error messages for invalid Log::delay() calls
Add a test for Log::delay() usage within filter policy hooks, too.
2023-11-29 11:53:11 +01:00
Arne Welzel
5e046eee58 logging/Manager: Implement DelayTokenType as an actual opaque
With a bit of tweaking in the JavaScript plugin to support opaque types, this
will allow the delay functionality to work there, too.

Making the LogDelayToken an actual opaque seems reasonable, too. It's not
supposed to be user inspected.
2023-11-29 11:53:11 +01:00
Arne Welzel
2dbb467ba2 logging: Implement get_delay_queue_size()
Primarily for introspection given that re-delaying may exceed
queue sizes.
2023-11-29 11:53:11 +01:00
Arne Welzel
f0e67022fd logging: Introduce Log::delay() and Log::delay_finish()
This is a verbose, opinionated and fairly restrictive version of the log delay idea.
Main drivers are explicitly, foot-gun-avoidance and implementation simplicity.

Calling the new Log::delay() function is only allowed within the execution
of a Log::log_stream_policy() hook for the currently active log write.

Conceptually, the delay is placed between the execution of the global stream
policy hook and the individual filter policy hooks. A post delay callback
can be registered with every Log::delay() invocation. Post delay callbacks
can (1) modify a log record as they see fit, (2) veto the forwarding of the
log record to the log filters and (3) extend the delay duration by calling
Log::delay() again. The last point allows to delay a record by an indefinite
amount of time, rather than a fixed maximum amount. This should be rare and
is therefore explicit.

Log::delay() increases an internal reference count and returns an opaque
token value to be passed to Log::delay_finish() to release a delay reference.
Once all references are released, the record is forwarded to all filters
attached to a stream when the delay completes.

This functionality separates Log::log_stream_policy() and individual filter
policy hooks. One consequence is that a common use-case of filter policy hooks,
removing unproductive log records, may run after a record was delayed. Users
can lift their filtering logic to the stream level (or replicate the condition
before the delay decision). The main motivation here is that deciding on a
stream-level delay in per-filter hooks is too late. Attaching multiple filters
to a stream can additionally result in hard to understand behavior.

On the flip side, filter policy hooks are guaranteed to run after the delay
and can be used for further mangling or filtering of a delayed record.
2023-11-29 11:53:11 +01:00
Arne Welzel
aa5d7f5a73 OpaqueVal: Register TelemetryVals, too
Even if they are not serializable, OpaqueMgr::TypeID() is called
during BuildJSON() for them and that previously just aborted.

Closes #3473
2023-11-28 09:21:31 +01:00
Arne Welzel
81aa6b14fd DNS: Add Ed25519 and Ed448 enum values to parser
We already had these declared in dns/const.zeek, so extend the parser
as well to avoid raising weirds and add some test pcaps:

   $ dig @8.8.8.8 DNSKEY ed448.no
   $ dig @8.8.8.8 ed448.no +dnssec

And the same for the ed25519.no domain.

Closes #3453
2023-11-17 19:56:47 +01:00
Arne Welzel
b0a200a5dc Merge remote-tracking branch 'origin/topic/vern/zam-EH-coalesce'
* origin/topic/vern/zam-EH-coalesce:
  BTest updates to accommodate event handler coalescence differences
  BTests for testing that event handler coalescence operates as expected
  coalescing of event handlers (ZAM optimization)

Minor fixups during merge as commented on the PR.
2023-11-17 18:05:32 +01:00
Vern Paxson
fc2796a5a4 BTest updates to accommodate event handler coalescence differences 2023-11-16 13:04:35 -08:00
Arne Welzel
d88b147ac9 cluster: Deprecate the Cluster::Node$interface field
This field isn't required by a worker and it's certainly not used by a
worker to listen on that specific interface. It also isn't required to
be set consistently and its use in-tree limited to the old load-balancing
script.

There's a bif called packet_source() which on a worker will provide
information about the actually used packet source.

Relates to zeek/zeek#2877.
2023-11-07 16:06:16 +01:00
Johanna Amann
ff27eb5a69 SSL: Add new extension types and ECH test
This commit adds a multitude of new extension types that were added in
the last few years; it also adds grease values to extensions, curves,
and ciphersuites.

Furthermore, it adds a test that contains a encrypted-client-hello
key-exchange (which uses several extension types that we do not have in
our baseline so far).
2023-10-30 14:19:16 +00:00
Tim Wojtulewicz
091c849abe Merge remote-tracking branch 'security/topic/awelzel/200-pop-fuzzer-timeout'
* security/topic/awelzel/200-pop-fuzzer-timeout:
  ssl: Prevent unbounded ssl_history growth
  ssl: Cap number of alerts parsed from SSL record
2023-10-27 11:04:03 -07:00
Arne Welzel
560f8a4a84 ssl: Prevent unbounded ssl_history growth
The ssl_history field may grow unbounded (e.g., ssl_alert event). Prevent this
by capping using a configurable limit (default 100) and raise a weird once reached.
2023-10-25 09:35:45 +02:00
Arne Welzel
54a08a74da base/frameworks/spicy: Do not load base/misc/version
Unsure what it's used for today and also results in the situation that on
some platforms we generate a reporter.log in bare mode, while on others
where spicy is disabled, we do not.

If we want base/frameworks/version loaded by default, should put it into
init-bare.zeek and possibly remove the loading of the reporter framework
from it - Reporter::error() would still work and be visible on stderr,
just not create a reporter.log.
2023-10-24 13:15:21 +02:00
Arne Welzel
ebb8780d6a quic: Skip new test if have-quic is false 2023-10-20 20:57:19 +02:00
Arne Welzel
6604010a05 quic: Bump maximum history length, make configurable
From zeek/spicy-quic#15
2023-10-20 20:42:30 +02:00
Tim Wojtulewicz
738c39379f Start of 6.2.0 development 2023-10-13 10:58:29 -07:00
Arne Welzel
1774a25f00 ci/btest: Remove spicy-quic helper, disable Spicy on CentOS 7
The have-quic pattern wasn't great and it wouldn't scale.
2023-10-11 17:17:23 +02:00
Arne Welzel
3f99aa7996 testing/quic: Fixups and simplification after Zeek integration 2023-10-11 14:10:22 +02:00
Arne Welzel
359f8d2ae6 quic: Squashed follow-ups: quic.log, tests, various fixes, performance 2023-10-11 14:10:22 +02:00
Joost
44d7c45723 quic: Initial implementation 2023-10-11 14:10:22 +02:00
Benjamin Bannier
3a60a60619 Pluralize container names in LDAP types 2023-10-10 18:49:25 +02:00
Benjamin Bannier
c43bc52e18 Name LDAP::Message and LDAP::Search *Info 2023-10-10 18:28:13 +02:00
Benjamin Bannier
c0daacfbd1 Require have-spicy for tests which log spicy-ldap information 2023-10-10 09:21:57 +02:00
Benjamin Bannier
53d4052d68 Fix LDAP analyzer setup for when Spicy analyzers are disabled 2023-10-10 09:21:57 +02:00
Benjamin Bannier
d7db52dff6 Integrate spicy-ldap test suite 2023-10-10 09:21:57 +02:00
Arne Welzel
88bb527026 btest/dump-events: Run in bare mode, load conn and smtp scripts only
The dump-events baseline changes are pure noise and have spurred confusion
for internal and external contributors. For example, adding new
analyzers have perturbed orderings of sets holding analyzer tags.

Running in non-bare mode, the baselines change almost whenever any of the
record types attached to connections change in the default scripts. This
causes continuous and seemingly little useful updates to the baselines.

This change switches the test to run in bare mode and explicitly loads
just base/protocols/conn and base/protocols/smtp. The primary intention
of the test should be testing the functionality of the misc/dump-events
script, not the raised events of all loaded default scripts (for that the
used PCAP is too narrow).

Protocol specific scripts that do want to leverage misc/dump-events for
baseline creation of their or their analyzer's events can add additional
specific tests with suitable PCAP files.
2023-10-09 12:20:10 +02:00
Benjamin Bannier
a4c4a23ba7 Use unique port for test scripts.base.utils.active-http 2023-09-26 12:49:59 +02:00