mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 06:38:20 +00:00
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
This commit is contained in:
commit
822ca99e80
86 changed files with 1896 additions and 25 deletions
112
CHANGES
112
CHANGES
|
@ -1,3 +1,115 @@
|
||||||
|
6.2.0-dev.445 | 2024-01-23 18:01:50 +0100
|
||||||
|
|
||||||
|
* websocket: Handle breaking from WebSocket::configure_analyzer() (Arne Welzel, Corelight)
|
||||||
|
|
||||||
|
...and various nits from the review.
|
||||||
|
|
||||||
|
* websocket: Address review feedback for BinPac code (Arne Welzel, Corelight)
|
||||||
|
|
||||||
|
* Rename mask_ to masking_key_
|
||||||
|
* Fold FrameHeaderFixed into FrameHeader directly
|
||||||
|
* Drop WebSocket_FramePayloadUnmask type
|
||||||
|
|
||||||
|
Thanks a bunch @ckreibich!
|
||||||
|
|
||||||
|
* fuzzers: Add WebSocket fuzzer (Arne Welzel, Corelight)
|
||||||
|
|
||||||
|
It immediately found an issue with &transient, but fairly stable thereafter.
|
||||||
|
|
||||||
|
This is a separate fuzzer implementation as there's a custom Configure()
|
||||||
|
call for the analyzer as well as disabling all other analyzers so we
|
||||||
|
don't fuzz unrelated protocols.
|
||||||
|
|
||||||
|
* websocket: Fix crash for fragmented messages (Arne Welzel, Corelight)
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
* websocket: Verify Sec-WebSocket-Key/Accept headers and review feedback (Arne Welzel, Corelight)
|
||||||
|
|
||||||
|
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 };
|
||||||
|
|
||||||
|
* btest/websocket: Test for coalesced reply-ping (Arne Welzel, Corelight)
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
* HTTP/CONNECT: Also weird on extra data in reply (Arne Welzel, Corelight)
|
||||||
|
|
||||||
|
* HTTP/Upgrade: Weird when more data is available (Arne Welzel, Corelight)
|
||||||
|
|
||||||
|
After an HTTP upgrade to another protocol, create a weird if the packet
|
||||||
|
that contains the HTTP reply *also* contains some additional data
|
||||||
|
belonging to the upgraded to protocol already.
|
||||||
|
|
||||||
|
* ContentLine: Add GetDeliverStreamRemainingLength() accessor (Arne Welzel, Corelight)
|
||||||
|
|
||||||
|
Helper to get information from the ContentLine analyzer about
|
||||||
|
bytes still pending to be delivered. In certain cases this can
|
||||||
|
be a signal for weirdness.
|
||||||
|
|
||||||
|
* HTTP: Drain event queue after instantiating upgrade analyzer (Arne Welzel, Corelight)
|
||||||
|
|
||||||
|
With configurability through script-land comes the draw back
|
||||||
|
that we actually need to execute event handlers in the middle
|
||||||
|
of the parsing process: This might not be the best model, but
|
||||||
|
the script-side configurability it enables is kind of nice.
|
||||||
|
|
||||||
|
This explicit call only matters here when the HTTP reply is
|
||||||
|
directly followed by some WebSocket message data within the
|
||||||
|
same network packet, otherwise the queue is drained once the
|
||||||
|
packet has been completely processed anyhow.
|
||||||
|
|
||||||
|
* btest/http: Explain switching-protocols test change as comment (Arne Welzel, Corelight)
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
* GH-3424: WebSocket: Introduce new analyzer and log (Arne Welzel, Corelight)
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
* HTTP: Add mechanism to instantiate Upgrade analyzer (Arne Welzel, Corelight)
|
||||||
|
|
||||||
|
When a HTTP upgrade request/reply is detected, lookup an analyzer tag
|
||||||
|
from HTTP::upgrade_analyzers, or if nothing is found, attach PIA_TCP.
|
||||||
|
|
||||||
|
* Update doc submodule [nomail] [skip ci] (zeek-bot)
|
||||||
|
|
||||||
6.2.0-dev.430 | 2024-01-22 10:36:11 -0700
|
6.2.0-dev.430 | 2024-01-22 10:36:11 -0700
|
||||||
|
|
||||||
* Make BIFs just return ValPtr directly instead of BifReturnVal (Tim Wojtulewicz, Corelight)
|
* Make BIFs just return ValPtr directly instead of BifReturnVal (Tim Wojtulewicz, Corelight)
|
||||||
|
|
16
NEWS
16
NEWS
|
@ -101,6 +101,22 @@ New Functionality
|
||||||
Given this is the first iteration of this feature, feedback around usability and
|
Given this is the first iteration of this feature, feedback around usability and
|
||||||
use-cases that aren't covered are more than welcome.
|
use-cases that aren't covered are more than welcome.
|
||||||
|
|
||||||
|
- A WebSocket analyzer has been added together with a new ``websocket.log``.
|
||||||
|
|
||||||
|
The WebSocket analyzer is instantiated when a WebSocket handshake over HTTP is
|
||||||
|
recognized. By default, the payload of WebSocket messages is fed into Zeek's dynamic
|
||||||
|
protocol detection framework, possibly discovering and analyzing tunneled protocols.
|
||||||
|
|
||||||
|
The format of the log and the event semantics should be considered preliminary until
|
||||||
|
the arrival of the next long-term-stable release (7.0).
|
||||||
|
|
||||||
|
To disable the analyzer in case of fatal errors or unexpected resource usage,
|
||||||
|
use the ``Analyzer::disabled_analyzers`` pattern:
|
||||||
|
|
||||||
|
redef Analyzer::disabled_analyzers += {
|
||||||
|
Analyzer::ANALYZER_WEBSOCKET,
|
||||||
|
};
|
||||||
|
|
||||||
- The SMTP analyzer was extended to recognize and properly handle the BDAT command
|
- The SMTP analyzer was extended to recognize and properly handle the BDAT command
|
||||||
from RFC 3030. This improves visibility into the SMTP protocol when mail agents
|
from RFC 3030. This improves visibility into the SMTP protocol when mail agents
|
||||||
and servers support and use this extension.
|
and servers support and use this extension.
|
||||||
|
|
2
VERSION
2
VERSION
|
@ -1 +1 @@
|
||||||
6.2.0-dev.430
|
6.2.0-dev.445
|
||||||
|
|
|
@ -423,7 +423,6 @@ export {
|
||||||
## The full list of TCP Option fields parsed from a TCP header.
|
## The full list of TCP Option fields parsed from a TCP header.
|
||||||
type OptionList: vector of Option;
|
type OptionList: vector of Option;
|
||||||
}
|
}
|
||||||
module GLOBAL;
|
|
||||||
|
|
||||||
module Tunnel;
|
module Tunnel;
|
||||||
export {
|
export {
|
||||||
|
@ -449,6 +448,51 @@ export {
|
||||||
const max_changes_per_connection: count = 5 &redef;
|
const max_changes_per_connection: count = 5 &redef;
|
||||||
|
|
||||||
} # end export
|
} # end export
|
||||||
|
|
||||||
|
module HTTP;
|
||||||
|
export {
|
||||||
|
## Lookup table for Upgrade analyzers. First, a case sensitive lookup
|
||||||
|
## is done using the client's Upgrade header. If no match is found,
|
||||||
|
## the all lower-case value is used. If there's still no match Zeek
|
||||||
|
## uses dynamic protocol detection for the upgraded to protocol instead.
|
||||||
|
const upgrade_analyzers: table[string] of Analyzer::Tag &redef;
|
||||||
|
}
|
||||||
|
|
||||||
|
module WebSocket;
|
||||||
|
export {
|
||||||
|
## The WebSocket analyzer consumes and forwards
|
||||||
|
## frame payload in chunks to keep memory usage
|
||||||
|
## bounded. There should not be a reason to change
|
||||||
|
## this value except for debugging and
|
||||||
|
## testing reasons.
|
||||||
|
const payload_chunk_size = 8192 &redef;
|
||||||
|
|
||||||
|
## Whether to enable DPD on WebSocket frame payload by default.
|
||||||
|
const use_dpd_default = T &redef;
|
||||||
|
|
||||||
|
## Record type that is passed to :zeek:see:`WebSocket::configure_analyzer`.
|
||||||
|
##
|
||||||
|
## This record allows to configure the WebSocket analyzer given
|
||||||
|
## parameters collected from HTTP headers.
|
||||||
|
type AnalyzerConfig: record {
|
||||||
|
## The analyzer to attach for analysis of the WebSocket
|
||||||
|
## frame payload. See *use_dpd* below for the behavior
|
||||||
|
## when unset.
|
||||||
|
analyzer: Analyzer::Tag &optional;
|
||||||
|
|
||||||
|
## If *analyzer* is unset, determines whether to attach a
|
||||||
|
## PIA_TCP analyzer for dynamic protocol detection with
|
||||||
|
## WebSocket payload.
|
||||||
|
use_dpd: bool &default=use_dpd_default;
|
||||||
|
|
||||||
|
## The subprotocol as selected by the server, if any.
|
||||||
|
subprotocol: string &optional;
|
||||||
|
|
||||||
|
## The WebSocket extensions as selected by the server, if any.
|
||||||
|
server_extensions: vector of string &optional;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
module GLOBAL;
|
module GLOBAL;
|
||||||
|
|
||||||
## A type alias for a vector of encapsulating "connections", i.e. for when
|
## A type alias for a vector of encapsulating "connections", i.e. for when
|
||||||
|
|
|
@ -78,6 +78,7 @@
|
||||||
@load base/protocols/ssh
|
@load base/protocols/ssh
|
||||||
@load base/protocols/ssl
|
@load base/protocols/ssl
|
||||||
@load base/protocols/syslog
|
@load base/protocols/syslog
|
||||||
|
@load base/protocols/websocket
|
||||||
@load base/protocols/tunnels
|
@load base/protocols/tunnels
|
||||||
@load base/protocols/xmpp
|
@load base/protocols/xmpp
|
||||||
|
|
||||||
|
|
2
scripts/base/protocols/websocket/__load__.zeek
Normal file
2
scripts/base/protocols/websocket/__load__.zeek
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
@load ./consts.zeek
|
||||||
|
@load ./main.zeek
|
23
scripts/base/protocols/websocket/consts.zeek
Normal file
23
scripts/base/protocols/websocket/consts.zeek
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
##! WebSocket constants.
|
||||||
|
|
||||||
|
module WebSocket;
|
||||||
|
|
||||||
|
export {
|
||||||
|
const OPCODE_CONTINUATION = 0x00;
|
||||||
|
const OPCODE_TEXT = 0x01;
|
||||||
|
const OPCODE_BINARY = 0x02;
|
||||||
|
const OPCODE_CLOSE = 0x08;
|
||||||
|
const OPCODE_PING = 0x09;
|
||||||
|
const OPCODE_PONG = 0x0a;
|
||||||
|
|
||||||
|
const opcodes: table[count] of string = {
|
||||||
|
[OPCODE_CONTINUATION] = "continuation",
|
||||||
|
[OPCODE_TEXT] = "text",
|
||||||
|
[OPCODE_BINARY] = "binary",
|
||||||
|
[OPCODE_CLOSE] = "close",
|
||||||
|
[OPCODE_PING] = "ping",
|
||||||
|
[OPCODE_PONG] = "pong",
|
||||||
|
} &default=function(opcode: count): string { return fmt("unknown-%x", opcode); } &redef;
|
||||||
|
|
||||||
|
const HANDSHAKE_GUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
|
||||||
|
}
|
232
scripts/base/protocols/websocket/main.zeek
Normal file
232
scripts/base/protocols/websocket/main.zeek
Normal file
|
@ -0,0 +1,232 @@
|
||||||
|
##! Implements base functionality for WebSocket analysis.
|
||||||
|
##!
|
||||||
|
##! Upon a websocket_established() event, logs all gathered information into
|
||||||
|
##! websocket.log and configures the WebSocket analyzer with the headers
|
||||||
|
##! collected via http events.
|
||||||
|
|
||||||
|
@load base/protocols/http
|
||||||
|
|
||||||
|
@load ./consts
|
||||||
|
|
||||||
|
module WebSocket;
|
||||||
|
|
||||||
|
# Register the WebSocket analyzer as HTTP upgrade analyzer.
|
||||||
|
redef HTTP::upgrade_analyzers += {
|
||||||
|
["websocket"] = Analyzer::ANALYZER_WEBSOCKET,
|
||||||
|
};
|
||||||
|
|
||||||
|
export {
|
||||||
|
redef enum Log::ID += { LOG };
|
||||||
|
|
||||||
|
## The record type for the WebSocket log.
|
||||||
|
type Info: record {
|
||||||
|
## Timestamp
|
||||||
|
ts: time &log;
|
||||||
|
## Unique ID for the connection.
|
||||||
|
uid: string &log;
|
||||||
|
## The connection's 4-tuple of endpoint addresses/ports.
|
||||||
|
id: conn_id &log;
|
||||||
|
## Same as in the HTTP log.
|
||||||
|
host: string &log &optional;
|
||||||
|
## Same as in the HTTP log.
|
||||||
|
uri: string &log &optional;
|
||||||
|
## Same as in the HTTP log.
|
||||||
|
user_agent: string &log &optional;
|
||||||
|
## The WebSocket subprotocol as selected by the server.
|
||||||
|
subprotocol: string &log &optional;
|
||||||
|
## The protocols requested by the client, if any.
|
||||||
|
client_protocols: vector of string &log &optional;
|
||||||
|
## The extensions selected by the the server, if any.
|
||||||
|
server_extensions: vector of string &log &optional;
|
||||||
|
## The extensions requested by the client, if any.
|
||||||
|
client_extensions: vector of string &log &optional;
|
||||||
|
## The Sec-WebSocket-Key header from the client.
|
||||||
|
client_key: string &optional;
|
||||||
|
## The Sec-WebSocket-Accept header from the server.
|
||||||
|
server_accept: string &optional;
|
||||||
|
};
|
||||||
|
|
||||||
|
## Event that can be handled to access the WebSocket record as it is
|
||||||
|
## sent on to the logging framework.
|
||||||
|
global log_websocket: event(rec: Info);
|
||||||
|
|
||||||
|
## Log policy hook.
|
||||||
|
global log_policy: Log::PolicyHook;
|
||||||
|
|
||||||
|
## Experimental: Hook to intercept WebSocket analyzer configuration.
|
||||||
|
##
|
||||||
|
## Breaking from this hook disables the WebSocket analyzer immediately.
|
||||||
|
## To modify the configuration of the analyzer, use the
|
||||||
|
## :zeek:see:`WebSocket::AnalyzerConfig` type.
|
||||||
|
##
|
||||||
|
## While this API allows quite some flexibility currently, should be
|
||||||
|
## considered experimental and may change in the future with or
|
||||||
|
## without a deprecation phase.
|
||||||
|
##
|
||||||
|
## c: The connection
|
||||||
|
##
|
||||||
|
## aid: The analyzer ID for the WebSocket analyzer.
|
||||||
|
##
|
||||||
|
## config: The configuration record, also containing information
|
||||||
|
## about the subprotocol and extensions.
|
||||||
|
global configure_analyzer: hook(c: connection, aid: count, config: AnalyzerConfig);
|
||||||
|
}
|
||||||
|
|
||||||
|
redef record connection += {
|
||||||
|
websocket: Info &optional;
|
||||||
|
};
|
||||||
|
|
||||||
|
function set_websocket(c: connection)
|
||||||
|
{
|
||||||
|
c$websocket = Info(
|
||||||
|
$ts=network_time(),
|
||||||
|
$uid=c$uid,
|
||||||
|
$id=c$id,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function expected_accept_for(key: string): string
|
||||||
|
{
|
||||||
|
return encode_base64(hexstr_to_bytestring(sha1_hash(key + HANDSHAKE_GUID)));
|
||||||
|
}
|
||||||
|
|
||||||
|
event http_header(c: connection, is_orig: bool, name: string, value: string)
|
||||||
|
{
|
||||||
|
if ( ! starts_with(name, "SEC-WEBSOCKET-") )
|
||||||
|
return;
|
||||||
|
|
||||||
|
if ( ! c?$websocket )
|
||||||
|
set_websocket(c);
|
||||||
|
|
||||||
|
local ws = c$websocket;
|
||||||
|
|
||||||
|
if ( is_orig )
|
||||||
|
{
|
||||||
|
if ( name == "SEC-WEBSOCKET-PROTOCOL" )
|
||||||
|
{
|
||||||
|
if ( ! ws?$client_protocols )
|
||||||
|
ws$client_protocols = vector();
|
||||||
|
|
||||||
|
ws$client_protocols += split_string(value, / *, */);
|
||||||
|
}
|
||||||
|
|
||||||
|
else if ( name == "SEC-WEBSOCKET-EXTENSIONS" )
|
||||||
|
{
|
||||||
|
if ( ! ws?$client_extensions )
|
||||||
|
ws$client_extensions = vector();
|
||||||
|
|
||||||
|
ws$client_extensions += split_string(value, / *, */);
|
||||||
|
}
|
||||||
|
else if ( name == "SEC-WEBSOCKET-KEY" )
|
||||||
|
{
|
||||||
|
if ( ws?$client_key )
|
||||||
|
Reporter::conn_weird("websocket_multiple_key_headers", c, "", "WebSocket");
|
||||||
|
|
||||||
|
ws$client_key = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ( name == "SEC-WEBSOCKET-PROTOCOL" )
|
||||||
|
{
|
||||||
|
if ( ws?$subprotocol )
|
||||||
|
Reporter::conn_weird("websocket_multiple_protocol_headers", c, "", "WebSocket");
|
||||||
|
|
||||||
|
ws$subprotocol = value;
|
||||||
|
}
|
||||||
|
else if ( name == "SEC-WEBSOCKET-EXTENSIONS" )
|
||||||
|
{
|
||||||
|
if ( ! ws?$server_extensions )
|
||||||
|
ws$server_extensions = vector();
|
||||||
|
|
||||||
|
ws$server_extensions += split_string(value, / *, */);
|
||||||
|
}
|
||||||
|
else if ( name == "SEC-WEBSOCKET-ACCEPT" )
|
||||||
|
{
|
||||||
|
if ( ws?$server_accept )
|
||||||
|
Reporter::conn_weird("websocket_multiple_accept_headers", c, "", "WebSocket");
|
||||||
|
|
||||||
|
ws$server_accept = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
event http_request(c: connection, method: string, original_URI: string,
|
||||||
|
unescaped_URI: string, version: string)
|
||||||
|
{
|
||||||
|
# If we see a http_request and have websocket state, wipe it as
|
||||||
|
# we should've seen a websocket_established even on success and
|
||||||
|
# likely no more http events.
|
||||||
|
if ( ! c?$websocket )
|
||||||
|
delete c$websocket;
|
||||||
|
}
|
||||||
|
|
||||||
|
event websocket_established(c: connection, aid: count) &priority=5
|
||||||
|
{
|
||||||
|
if ( ! c?$websocket )
|
||||||
|
{
|
||||||
|
# This means we never saw a Sec-WebSocket-* header, weird.
|
||||||
|
Reporter::conn_weird("websocket_established_unexpected", c, "", "WebSocket");
|
||||||
|
set_websocket(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
local ws = c$websocket;
|
||||||
|
|
||||||
|
if ( ! ws?$client_key )
|
||||||
|
Reporter::conn_weird("websocket_missing_key_header", c, "", "WebSocket");
|
||||||
|
|
||||||
|
if ( ! ws?$server_accept )
|
||||||
|
Reporter::conn_weird("websocket_missing_accept_header", c, "", "WebSocket");
|
||||||
|
|
||||||
|
# Verify the Sec-WebSocket-Accept header's value given the Sec-WebSocket-Key header's value.
|
||||||
|
if ( ws?$client_key && ws?$server_accept )
|
||||||
|
{
|
||||||
|
local expected_accept = expected_accept_for(ws$client_key);
|
||||||
|
if ( ws$server_accept != expected_accept )
|
||||||
|
Reporter::conn_weird("websocket_wrong_accept_header", c,
|
||||||
|
fmt("expected=%s, found=%s", expected_accept, ws$server_accept),
|
||||||
|
"WebSocket");
|
||||||
|
}
|
||||||
|
|
||||||
|
# Replicate some information from the HTTP.log
|
||||||
|
if ( c?$http )
|
||||||
|
{
|
||||||
|
if ( c$http?$host )
|
||||||
|
ws$host = c$http$host;
|
||||||
|
|
||||||
|
if ( c$http?$uri )
|
||||||
|
ws$uri = c$http$uri;
|
||||||
|
|
||||||
|
if ( c$http?$user_agent )
|
||||||
|
ws$user_agent = c$http$user_agent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
event websocket_established(c: connection, aid: count) &priority=-5
|
||||||
|
{
|
||||||
|
local ws = c$websocket;
|
||||||
|
|
||||||
|
local config = AnalyzerConfig();
|
||||||
|
if ( ws?$subprotocol )
|
||||||
|
config$subprotocol = ws$subprotocol;
|
||||||
|
|
||||||
|
if ( ws?$server_extensions )
|
||||||
|
config$server_extensions = ws$server_extensions;
|
||||||
|
|
||||||
|
# Give other scripts a chance to modify the analyzer configuration.
|
||||||
|
#
|
||||||
|
# Breaking from this hook disables the new WebSocket analyzer
|
||||||
|
# completely instead of configuring it.
|
||||||
|
if ( hook WebSocket::configure_analyzer(c, aid, config) )
|
||||||
|
WebSocket::__configure_analyzer(c, aid, config);
|
||||||
|
else
|
||||||
|
disable_analyzer(c$id, aid);
|
||||||
|
|
||||||
|
ws$ts = network_time();
|
||||||
|
Log::write(LOG, ws);
|
||||||
|
}
|
||||||
|
|
||||||
|
event zeek_init()
|
||||||
|
{
|
||||||
|
Log::create_stream(LOG, [$columns=Info, $ev=log_websocket, $path="websocket", $policy=log_policy]);
|
||||||
|
}
|
|
@ -42,5 +42,6 @@ add_subdirectory(ssh)
|
||||||
add_subdirectory(ssl)
|
add_subdirectory(ssl)
|
||||||
add_subdirectory(syslog)
|
add_subdirectory(syslog)
|
||||||
add_subdirectory(tcp)
|
add_subdirectory(tcp)
|
||||||
|
add_subdirectory(websocket)
|
||||||
add_subdirectory(xmpp)
|
add_subdirectory(xmpp)
|
||||||
add_subdirectory(zip)
|
add_subdirectory(zip)
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
|
|
||||||
#include "zeek/Event.h"
|
#include "zeek/Event.h"
|
||||||
#include "zeek/NetVar.h"
|
#include "zeek/NetVar.h"
|
||||||
|
#include "zeek/analyzer/Manager.h"
|
||||||
#include "zeek/analyzer/protocol/http/events.bif.h"
|
#include "zeek/analyzer/protocol/http/events.bif.h"
|
||||||
#include "zeek/analyzer/protocol/mime/MIME.h"
|
#include "zeek/analyzer/protocol/mime/MIME.h"
|
||||||
#include "zeek/file_analysis/Manager.h"
|
#include "zeek/file_analysis/Manager.h"
|
||||||
|
@ -775,12 +776,9 @@ void HTTP_Analyzer::DeliverStream(int len, const u_char* data, bool is_orig) {
|
||||||
if ( TCP() && TCP()->IsPartial() )
|
if ( TCP() && TCP()->IsPartial() )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if ( upgraded )
|
if ( upgraded || pia ) {
|
||||||
return;
|
|
||||||
|
|
||||||
if ( pia ) {
|
|
||||||
// There will be a PIA instance if this connection has been identified
|
// There will be a PIA instance if this connection has been identified
|
||||||
// as a connect proxy.
|
// as a connect proxy, or a child analyzer if there was an upgrade.
|
||||||
ForwardStream(len, data, is_orig);
|
ForwardStream(len, data, is_orig);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -951,6 +949,19 @@ void HTTP_Analyzer::DeliverStream(int len, const u_char* data, bool is_orig) {
|
||||||
pia->FirstPacket(true, nullptr);
|
pia->FirstPacket(true, nullptr);
|
||||||
pia->FirstPacket(false, nullptr);
|
pia->FirstPacket(false, nullptr);
|
||||||
|
|
||||||
|
int remaining_in_content_line = content_line_resp->GetDeliverStreamRemainingLength();
|
||||||
|
if ( remaining_in_content_line > 0 ) {
|
||||||
|
// If there's immediately data following the empty line
|
||||||
|
// of a successful CONNECT reply, that's at least curious.
|
||||||
|
// Further, switch the responder's ContentLine analyzer
|
||||||
|
// into plain delivery mode so anything left is sent to
|
||||||
|
// PIA unaltered.
|
||||||
|
const char* addl = zeek::util::fmt("%d", remaining_in_content_line);
|
||||||
|
Weird("protocol_data_with_HTTP_CONNECT_reply", addl);
|
||||||
|
content_line_resp->SetPlainDelivery(remaining_in_content_line);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// This connection has transitioned to no longer
|
// This connection has transitioned to no longer
|
||||||
// being http and the content line support analyzers
|
// being http and the content line support analyzers
|
||||||
// need to be removed.
|
// need to be removed.
|
||||||
|
@ -1311,15 +1322,8 @@ void HTTP_Analyzer::ReplyMade(bool interrupted, const char* msg) {
|
||||||
reply_reason_phrase = nullptr;
|
reply_reason_phrase = nullptr;
|
||||||
|
|
||||||
// unanswered requests = 1 because there is no pop after 101.
|
// unanswered requests = 1 because there is no pop after 101.
|
||||||
if ( reply_code == 101 && unanswered_requests.size() == 1 && upgrade_connection && upgrade_protocol.size() ) {
|
if ( reply_code == 101 && unanswered_requests.size() == 1 && upgrade_connection && upgrade_protocol.size() )
|
||||||
// Upgraded connection that switches immediately - e.g. websocket.
|
HTTP_Upgrade();
|
||||||
upgraded = true;
|
|
||||||
RemoveSupportAnalyzer(content_line_orig);
|
|
||||||
RemoveSupportAnalyzer(content_line_resp);
|
|
||||||
|
|
||||||
if ( http_connection_upgrade )
|
|
||||||
EnqueueConnEvent(http_connection_upgrade, ConnVal(), make_intrusive<StringVal>(upgrade_protocol));
|
|
||||||
}
|
|
||||||
|
|
||||||
reply_code = 0;
|
reply_code = 0;
|
||||||
upgrade_connection = false;
|
upgrade_connection = false;
|
||||||
|
@ -1331,6 +1335,80 @@ void HTTP_Analyzer::ReplyMade(bool interrupted, const char* msg) {
|
||||||
reply_state = EXPECT_REPLY_LINE;
|
reply_state = EXPECT_REPLY_LINE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void HTTP_Analyzer::HTTP_Upgrade() {
|
||||||
|
// Upgraded connection that switches immediately - e.g. websocket.
|
||||||
|
|
||||||
|
int remaining_in_content_line = content_line_resp->GetDeliverStreamRemainingLength();
|
||||||
|
|
||||||
|
if ( remaining_in_content_line > 0 ) {
|
||||||
|
// We've seen a complete HTTP response for an upgrade request and there's
|
||||||
|
// more data buffered in the ContentLine analyzer. This means the next
|
||||||
|
// protocol's data is in the same packet as the HTTP reply. Log a weird
|
||||||
|
// as this seems not very likely to happen in the wild.
|
||||||
|
const char* addl = zeek::util::fmt("%d", remaining_in_content_line);
|
||||||
|
Weird("protocol_data_with_HTTP_upgrade_reply", addl);
|
||||||
|
|
||||||
|
// Switch the ContentLine analyzer to deliver anything remaining in
|
||||||
|
// plain mode so it can be forwarded to the upgrade analyzer.
|
||||||
|
content_line_resp->SetPlainDelivery(remaining_in_content_line);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Lookup an analyzer tag in the HTTP::upgrade_analyzer table.
|
||||||
|
static const auto& upgrade_analyzers = id::find_val<TableVal>("HTTP::upgrade_analyzers");
|
||||||
|
|
||||||
|
auto upgrade_protocol_val = make_intrusive<StringVal>(upgrade_protocol);
|
||||||
|
auto v = upgrade_analyzers->Find(upgrade_protocol_val);
|
||||||
|
if ( ! v ) {
|
||||||
|
// If not found, try the all lower version, too.
|
||||||
|
auto lower_upgrade_protocol = util::strtolower(upgrade_protocol);
|
||||||
|
upgrade_protocol_val = make_intrusive<StringVal>(lower_upgrade_protocol);
|
||||||
|
v = upgrade_analyzers->Find(upgrade_protocol_val);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( v ) {
|
||||||
|
auto analyzer_tag_val = cast_intrusive<EnumVal>(v);
|
||||||
|
DBG_LOG(DBG_ANALYZER, "Found %s in HTTP::upgrade_analyzers for %s",
|
||||||
|
analyzer_tag_val->GetType<EnumType>()->Lookup(analyzer_tag_val->AsEnum()),
|
||||||
|
upgrade_protocol_val->CheckString());
|
||||||
|
auto analyzer_tag = analyzer_mgr->GetComponentTag(analyzer_tag_val.get());
|
||||||
|
auto* analyzer = analyzer_mgr->InstantiateAnalyzer(analyzer_tag, Conn());
|
||||||
|
if ( analyzer ) {
|
||||||
|
AddChildAnalyzer(analyzer);
|
||||||
|
|
||||||
|
// The analyzer's Init() may have scheduled an event for analyzer configuration.
|
||||||
|
// Drain the event queue now to process it. This further ensures that other
|
||||||
|
// events already in the event queue (http_reply, http_header, ...) are drained
|
||||||
|
// as well and accessible when the configuration runs.
|
||||||
|
//
|
||||||
|
// Don't just copy this code into a new analyzer, there might be better and more
|
||||||
|
// more general approaches.
|
||||||
|
//
|
||||||
|
// Alternative proposal from Robin:
|
||||||
|
//
|
||||||
|
// Collect all HTTP headers (pattern/names configurable by script land)
|
||||||
|
// and forward the collected headers to the analyzer via a custom
|
||||||
|
// configuration method or some in-band channel.
|
||||||
|
event_mgr.Drain();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
DBG_LOG(DBG_ANALYZER, "No mapping for %s in HTTP::upgrade_analyzers, using PIA instead",
|
||||||
|
upgrade_protocol.c_str());
|
||||||
|
pia = new analyzer::pia::PIA_TCP(Conn());
|
||||||
|
if ( AddChildAnalyzer(pia) ) {
|
||||||
|
pia->FirstPacket(true, nullptr);
|
||||||
|
pia->FirstPacket(false, nullptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
upgraded = true;
|
||||||
|
RemoveSupportAnalyzer(content_line_orig);
|
||||||
|
RemoveSupportAnalyzer(content_line_resp);
|
||||||
|
|
||||||
|
if ( http_connection_upgrade )
|
||||||
|
EnqueueConnEvent(http_connection_upgrade, ConnVal(), make_intrusive<StringVal>(upgrade_protocol));
|
||||||
|
}
|
||||||
|
|
||||||
void HTTP_Analyzer::RequestClash(Val* /* clash_val */) {
|
void HTTP_Analyzer::RequestClash(Val* /* clash_val */) {
|
||||||
Weird("multiple_HTTP_request_elements");
|
Weird("multiple_HTTP_request_elements");
|
||||||
|
|
||||||
|
|
|
@ -220,6 +220,7 @@ protected:
|
||||||
|
|
||||||
void HTTP_Request();
|
void HTTP_Request();
|
||||||
void HTTP_Reply();
|
void HTTP_Reply();
|
||||||
|
void HTTP_Upgrade();
|
||||||
|
|
||||||
void RequestMade(bool interrupted, const char* msg);
|
void RequestMade(bool interrupted, const char* msg);
|
||||||
void ReplyMade(bool interrupted, const char* msg);
|
void ReplyMade(bool interrupted, const char* msg);
|
||||||
|
|
|
@ -30,6 +30,7 @@ void ContentLine_Analyzer::InitState() {
|
||||||
delivery_length = -1;
|
delivery_length = -1;
|
||||||
is_plain = false;
|
is_plain = false;
|
||||||
suppress_weirds = false;
|
suppress_weirds = false;
|
||||||
|
deliver_stream_remaining_length = 0;
|
||||||
|
|
||||||
InitBuffer(0);
|
InitBuffer(0);
|
||||||
}
|
}
|
||||||
|
@ -149,6 +150,7 @@ void ContentLine_Analyzer::DoDeliver(int len, const u_char* data) {
|
||||||
plain_delivery_length -= deliver_plain;
|
plain_delivery_length -= deliver_plain;
|
||||||
is_plain = true;
|
is_plain = true;
|
||||||
|
|
||||||
|
deliver_stream_remaining_length = len - deliver_plain;
|
||||||
ForwardStream(deliver_plain, data, IsOrig());
|
ForwardStream(deliver_plain, data, IsOrig());
|
||||||
|
|
||||||
is_plain = false;
|
is_plain = false;
|
||||||
|
@ -207,6 +209,7 @@ int ContentLine_Analyzer::DoDeliverOnce(int len, const u_char* data) {
|
||||||
int seq_len = data + 1 - data_start; \
|
int seq_len = data + 1 - data_start; \
|
||||||
seq_delivered_in_lines = seq + seq_len; \
|
seq_delivered_in_lines = seq + seq_len; \
|
||||||
last_char = c; \
|
last_char = c; \
|
||||||
|
deliver_stream_remaining_length = len - 1; \
|
||||||
ForwardStream(offset, buf, IsOrig()); \
|
ForwardStream(offset, buf, IsOrig()); \
|
||||||
offset = 0; \
|
offset = 0; \
|
||||||
return seq_len; \
|
return seq_len; \
|
||||||
|
|
|
@ -47,6 +47,11 @@ public:
|
||||||
int64_t GetPlainDeliveryLength() const { return plain_delivery_length; }
|
int64_t GetPlainDeliveryLength() const { return plain_delivery_length; }
|
||||||
bool IsPlainDelivery() { return is_plain; }
|
bool IsPlainDelivery() { return is_plain; }
|
||||||
|
|
||||||
|
// Helper to check how many bytes are still in-flight for the
|
||||||
|
// current DeliverStream() invocation. This can be called
|
||||||
|
// by the parent during its DeliverStream() invocation.
|
||||||
|
int GetDeliverStreamRemainingLength() const { return deliver_stream_remaining_length; }
|
||||||
|
|
||||||
// Skip <length> bytes after this line.
|
// Skip <length> bytes after this line.
|
||||||
// Can be used to skip HTTP data for performance considerations.
|
// Can be used to skip HTTP data for performance considerations.
|
||||||
void SkipBytesAfterThisLine(int64_t length);
|
void SkipBytesAfterThisLine(int64_t length);
|
||||||
|
@ -107,6 +112,8 @@ protected:
|
||||||
|
|
||||||
// Whether to skip partial conns.
|
// Whether to skip partial conns.
|
||||||
bool skip_partial;
|
bool skip_partial;
|
||||||
|
|
||||||
|
int deliver_stream_remaining_length;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace zeek::analyzer::tcp
|
} // namespace zeek::analyzer::tcp
|
||||||
|
|
15
src/analyzer/protocol/websocket/CMakeLists.txt
Normal file
15
src/analyzer/protocol/websocket/CMakeLists.txt
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
zeek_add_plugin(
|
||||||
|
Zeek
|
||||||
|
WebSocket
|
||||||
|
SOURCES
|
||||||
|
WebSocket.cc
|
||||||
|
Plugin.cc
|
||||||
|
BIFS
|
||||||
|
consts.bif
|
||||||
|
events.bif
|
||||||
|
functions.bif
|
||||||
|
types.bif
|
||||||
|
PAC
|
||||||
|
websocket.pac
|
||||||
|
websocket-analyzer.pac
|
||||||
|
websocket-protocol.pac)
|
24
src/analyzer/protocol/websocket/Plugin.cc
Normal file
24
src/analyzer/protocol/websocket/Plugin.cc
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
// See the file "COPYING" in the main distribution directory for copyright.
|
||||||
|
|
||||||
|
#include "zeek/plugin/Plugin.h"
|
||||||
|
|
||||||
|
#include "zeek/analyzer/Component.h"
|
||||||
|
|
||||||
|
#include "analyzer/protocol/websocket/WebSocket.h"
|
||||||
|
|
||||||
|
namespace zeek::plugin::detail::Zeek_WebSocket {
|
||||||
|
|
||||||
|
class Plugin : public zeek::plugin::Plugin {
|
||||||
|
public:
|
||||||
|
zeek::plugin::Configuration Configure() override {
|
||||||
|
AddComponent(
|
||||||
|
new zeek::analyzer::Component("WebSocket", zeek::analyzer::websocket::WebSocket_Analyzer::Instantiate));
|
||||||
|
|
||||||
|
zeek::plugin::Configuration config;
|
||||||
|
config.name = "Zeek::WebSocket";
|
||||||
|
config.description = "WebSocket analyzer";
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
} plugin;
|
||||||
|
|
||||||
|
} // namespace zeek::plugin::detail::Zeek_WebSocket
|
103
src/analyzer/protocol/websocket/WebSocket.cc
Normal file
103
src/analyzer/protocol/websocket/WebSocket.cc
Normal file
|
@ -0,0 +1,103 @@
|
||||||
|
// See the file in the main distribution directory for copyright.
|
||||||
|
|
||||||
|
#include "zeek/analyzer/protocol/websocket/WebSocket.h"
|
||||||
|
|
||||||
|
#include <string_view>
|
||||||
|
|
||||||
|
#include "zeek/analyzer/Manager.h"
|
||||||
|
#include "zeek/analyzer/protocol/pia/PIA.h"
|
||||||
|
#include "zeek/analyzer/protocol/websocket/events.bif.h"
|
||||||
|
|
||||||
|
namespace zeek::analyzer::websocket {
|
||||||
|
|
||||||
|
WebSocket_Analyzer::WebSocket_Analyzer(Connection* conn) : analyzer::tcp::TCP_ApplicationAnalyzer("WebSocket", conn) {
|
||||||
|
// TODO: Consider approaches dispatching to optionally use a
|
||||||
|
// Spicy analyzer here instead of the BinPac interpreter.
|
||||||
|
//
|
||||||
|
// E.g. we could instantiate a SPICY_WEBSOCKET analyzer and pass it the necessary
|
||||||
|
// information and call DeliverStream() directly on it.
|
||||||
|
interp = std::make_unique<binpac::WebSocket::WebSocket_Conn>(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WebSocket_Analyzer::Init() {
|
||||||
|
tcp::TCP_ApplicationAnalyzer::Init();
|
||||||
|
|
||||||
|
// This event gives scriptland a chance to log and configure the analyzer.
|
||||||
|
// The WebSocket analyzer ships with a handler that calls back into
|
||||||
|
// Configure(), via WebSocket::__configure_analyzer().
|
||||||
|
zeek::BifEvent::enqueue_websocket_established(this, Conn(), GetID());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WebSocket_Analyzer::Configure(zeek::RecordValPtr config) {
|
||||||
|
// TODO: Check extensions and modify parsing if needed, e.g. WebSocket frame
|
||||||
|
// compression extension: https://www.rfc-editor.org/rfc/rfc7692.html
|
||||||
|
//
|
||||||
|
// interp->SetExtensions(...)
|
||||||
|
//
|
||||||
|
// TODO: The Sec-WebSocket-Protocol header might provide some information
|
||||||
|
// that we could leverage to instantiate a more specific analyzer.
|
||||||
|
//
|
||||||
|
// For now, we just attach a PIA analyzer as child analyzer.
|
||||||
|
|
||||||
|
static const auto& config_type = id::find_type<zeek::RecordType>("WebSocket::AnalyzerConfig");
|
||||||
|
static int analyzer_idx = config_type->FieldOffset("analyzer");
|
||||||
|
static int use_dpd_idx = config_type->FieldOffset("use_dpd");
|
||||||
|
|
||||||
|
if ( config->HasField(analyzer_idx) ) {
|
||||||
|
const auto& analyzer_tag_val = config->GetField(analyzer_idx);
|
||||||
|
auto analyzer_tag = analyzer_mgr->GetComponentTag(analyzer_tag_val.get());
|
||||||
|
|
||||||
|
if ( analyzer_tag == zeek::Tag() ) {
|
||||||
|
reporter->InternalWarning("no component tag for enum '%s'",
|
||||||
|
analyzer_tag_val->GetType<EnumType>()->Lookup(analyzer_tag_val->AsEnum()));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
DBG_LOG(DBG_ANALYZER, "%s Configure() using analyzer %s", fmt_analyzer(this).c_str(),
|
||||||
|
analyzer_tag_val->GetType<EnumType>()->Lookup(analyzer_tag_val->AsEnum()));
|
||||||
|
|
||||||
|
auto* analyzer = analyzer_mgr->InstantiateAnalyzer(analyzer_tag, Conn());
|
||||||
|
if ( ! analyzer )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return AddChildAnalyzer(analyzer);
|
||||||
|
}
|
||||||
|
else if ( config->GetField(use_dpd_idx)->AsBool() ) {
|
||||||
|
DBG_LOG(DBG_ANALYZER, "%s Configure() enables DPD via PIA_TCP", fmt_analyzer(this).c_str());
|
||||||
|
|
||||||
|
auto* pia = new analyzer::pia::PIA_TCP(Conn());
|
||||||
|
if ( AddChildAnalyzer(pia) ) {
|
||||||
|
pia->FirstPacket(true, nullptr);
|
||||||
|
pia->FirstPacket(false, nullptr);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Neither analyzer nor dpd was enabled, success.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void WebSocket_Analyzer::DeliverStream(int len, const u_char* data, bool orig) {
|
||||||
|
analyzer::tcp::TCP_ApplicationAnalyzer::DeliverStream(len, data, orig);
|
||||||
|
if ( had_gap ) {
|
||||||
|
DBG_LOG(DBG_ANALYZER, "Skipping data after gap len=%d orig=%d", len, orig);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
interp->NewData(orig, data, data + len);
|
||||||
|
} catch ( const binpac::Exception& e ) {
|
||||||
|
AnalyzerViolation(e.c_msg(), reinterpret_cast<const char*>(data), len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void WebSocket_Analyzer::Undelivered(uint64_t seq, int len, bool orig) {
|
||||||
|
analyzer::tcp::TCP_ApplicationAnalyzer::Undelivered(seq, len, orig);
|
||||||
|
interp->NewGap(orig, len);
|
||||||
|
had_gap = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace zeek::analyzer::websocket
|
38
src/analyzer/protocol/websocket/WebSocket.h
Normal file
38
src/analyzer/protocol/websocket/WebSocket.h
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
// See the file "COPYING" in the main distribution directory for copyright.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#include "zeek/analyzer/protocol/tcp/TCP.h"
|
||||||
|
#include "zeek/analyzer/protocol/websocket/websocket_pac.h"
|
||||||
|
|
||||||
|
namespace zeek::analyzer::websocket {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A WebSocket analyzer to be used directly on top of HTTP.
|
||||||
|
*/
|
||||||
|
class WebSocket_Analyzer : public analyzer::tcp::TCP_ApplicationAnalyzer {
|
||||||
|
public:
|
||||||
|
WebSocket_Analyzer(zeek::Connection* conn);
|
||||||
|
~WebSocket_Analyzer() = default;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allows script land to configure the WebSocket analyzer before analysis.
|
||||||
|
*
|
||||||
|
* @param config Zeek value of type WebSocket::AnalyzerConfig
|
||||||
|
*/
|
||||||
|
bool Configure(zeek::RecordValPtr config);
|
||||||
|
|
||||||
|
void Init() override;
|
||||||
|
void DeliverStream(int len, const u_char* data, bool orig) override;
|
||||||
|
void Undelivered(uint64_t seq, int len, bool orig) override;
|
||||||
|
|
||||||
|
static zeek::analyzer::Analyzer* Instantiate(Connection* conn) { return new WebSocket_Analyzer(conn); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::unique_ptr<binpac::WebSocket::WebSocket_Conn> interp;
|
||||||
|
bool had_gap = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace zeek::analyzer::websocket
|
1
src/analyzer/protocol/websocket/consts.bif
Normal file
1
src/analyzer/protocol/websocket/consts.bif
Normal file
|
@ -0,0 +1 @@
|
||||||
|
const WebSocket::payload_chunk_size: count;
|
65
src/analyzer/protocol/websocket/events.bif
Normal file
65
src/analyzer/protocol/websocket/events.bif
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
## Generated when a WebSocket handshake completed.
|
||||||
|
##
|
||||||
|
## c: The WebSocket connection.
|
||||||
|
##
|
||||||
|
## aid: The analyzer identifier of the WebSocket analyzer.
|
||||||
|
##
|
||||||
|
## .. zeek:see:: WebSocket::__configure_analyzer WebSocket::configure_analyzer
|
||||||
|
event websocket_established%(c: connection, aid: count%);
|
||||||
|
|
||||||
|
## Generated for every WebSocket frame.
|
||||||
|
##
|
||||||
|
## c: The WebSocket connection.
|
||||||
|
##
|
||||||
|
## is_orig: True if the frame is from the originator, else false.
|
||||||
|
##
|
||||||
|
## fin: True if the fin bit is set, else false.
|
||||||
|
##
|
||||||
|
## rsv: The value of the RSV1, RSV2 and RSV3 bits.
|
||||||
|
##
|
||||||
|
## opcode: The frame's opcode.
|
||||||
|
##
|
||||||
|
## payload_len: The frame's payload length.
|
||||||
|
##
|
||||||
|
event websocket_frame%(c: connection, is_orig: bool, fin: bool, rsv: count, opcode: count, payload_len: count%);
|
||||||
|
|
||||||
|
## Generated for every chunk of WebSocket frame payload data.
|
||||||
|
##
|
||||||
|
## Do not use it to extract data from a WebSocket connection unless for testing
|
||||||
|
## or experimentation. Consider implementing a proper analyzer instead.
|
||||||
|
##
|
||||||
|
## c: The WebSocket connection.
|
||||||
|
##
|
||||||
|
## is_orig: True if the frame is from the originator, else false.
|
||||||
|
##
|
||||||
|
## data: One data chunk of frame payload. The length of is at most
|
||||||
|
## :zeek:see:`WebSocket::payload_chunk_size` bytes. A frame with
|
||||||
|
## a longer payload will result in multiple events events.
|
||||||
|
##
|
||||||
|
## .. zeek:see:: WebSocket::payload_chunk_size
|
||||||
|
event websocket_frame_data%(c: connection, is_orig: bool, data: string%);
|
||||||
|
|
||||||
|
|
||||||
|
## Generated for every completed WebSocket message.
|
||||||
|
##
|
||||||
|
## c: The WebSocket connection.
|
||||||
|
##
|
||||||
|
## is_orig: True if the frame is from the originator, else false.
|
||||||
|
##
|
||||||
|
## opcode: The first frame's opcode.
|
||||||
|
event websocket_message%(c: connection, is_orig: bool, opcode: count%);
|
||||||
|
|
||||||
|
## Generated for WebSocket Close frames.
|
||||||
|
##
|
||||||
|
## c: The WebSocket connection.
|
||||||
|
##
|
||||||
|
## is_orig: True if the frame is from the originator, else false.
|
||||||
|
##
|
||||||
|
## status: If the CloseFrame had no payload, this is 0, otherwise the value
|
||||||
|
## of the first two bytes in the frame's payload.
|
||||||
|
##
|
||||||
|
## reason: Remaining payload after *status*. This is capped at
|
||||||
|
## 2 bytes less than :zeek:see:`WebSocket::payload_chunk_size`.
|
||||||
|
##
|
||||||
|
## .. zeek:see:: WebSocket::payload_chunk_size
|
||||||
|
event websocket_close%(c: connection, is_orig: bool, status: count, reason: string%);
|
46
src/analyzer/protocol/websocket/functions.bif
Normal file
46
src/analyzer/protocol/websocket/functions.bif
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
%%{
|
||||||
|
#include "zeek/analyzer/protocol/websocket/WebSocket.h"
|
||||||
|
%%}
|
||||||
|
|
||||||
|
module WebSocket;
|
||||||
|
|
||||||
|
## Configure the WebSocket analyzer.
|
||||||
|
##
|
||||||
|
## Called during :zeek:see:`websocket_established` to configure
|
||||||
|
## the WebSocket analyzer given the selected protocol and extension
|
||||||
|
## as chosen by the server.
|
||||||
|
##
|
||||||
|
## c: The WebSocket connection.
|
||||||
|
#
|
||||||
|
## aid: The identifier for the WebSocket analyzer as provided to :zeek:see:`websocket_established`.
|
||||||
|
##
|
||||||
|
## server_protocol: The protocol as found in the server's Sec-WebSocket-Protocol HTTP header, or empty.
|
||||||
|
##
|
||||||
|
## server_extensions: The extension as selected by the server via the Sec-WebSocket-Extensions HTTP Header.
|
||||||
|
##
|
||||||
|
## .. zeek:see:: websocket_established
|
||||||
|
function __configure_analyzer%(c: connection, aid: count, config: WebSocket::AnalyzerConfig%): bool
|
||||||
|
%{
|
||||||
|
auto* analyzer = c->FindAnalyzer(aid);
|
||||||
|
auto* ws_analyzer = dynamic_cast<analyzer::websocket::WebSocket_Analyzer*>(analyzer);
|
||||||
|
if ( ! ws_analyzer )
|
||||||
|
{
|
||||||
|
reporter->Warning("WebSocket analyzer to configure not found");
|
||||||
|
return zeek::val_mgr->False();
|
||||||
|
}
|
||||||
|
|
||||||
|
static const auto& config_type = zeek::id::find_type<zeek::RecordType>("WebSocket::AnalyzerConfig");
|
||||||
|
|
||||||
|
if ( config->GetType() != config_type )
|
||||||
|
{
|
||||||
|
reporter->Warning("config has wrong type %s, expected %s",
|
||||||
|
config->GetType()->GetName().c_str(),
|
||||||
|
config_type->GetName().c_str());
|
||||||
|
return zeek::val_mgr->False();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ! ws_analyzer->Configure({zeek::NewRef{}, config->AsRecordVal()}) )
|
||||||
|
return zeek::val_mgr->False();
|
||||||
|
|
||||||
|
return zeek::val_mgr->True();
|
||||||
|
%}
|
4
src/analyzer/protocol/websocket/types.bif
Normal file
4
src/analyzer/protocol/websocket/types.bif
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
module WebSocket;
|
||||||
|
|
||||||
|
# A configuration record used for the WebSocket analyzer.
|
||||||
|
type AnalyzerConfig: record;
|
111
src/analyzer/protocol/websocket/websocket-analyzer.pac
Normal file
111
src/analyzer/protocol/websocket/websocket-analyzer.pac
Normal file
|
@ -0,0 +1,111 @@
|
||||||
|
# See the file "COPYING" in the main distribution directory for copyright.
|
||||||
|
#
|
||||||
|
# The WebSocket analyzer.
|
||||||
|
#
|
||||||
|
|
||||||
|
refine flow WebSocket_Flow += {
|
||||||
|
|
||||||
|
function process_message(msg: WebSocket_Message): bool
|
||||||
|
%{
|
||||||
|
connection()->zeek_analyzer()->AnalyzerConfirmation();
|
||||||
|
|
||||||
|
if ( websocket_message )
|
||||||
|
{
|
||||||
|
zeek::BifEvent::enqueue_websocket_message(connection()->zeek_analyzer(),
|
||||||
|
connection()->zeek_analyzer()->Conn(),
|
||||||
|
is_orig(),
|
||||||
|
${msg.opcode});
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
%}
|
||||||
|
|
||||||
|
function process_header(hdr: WebSocket_FrameHeader): bool
|
||||||
|
%{
|
||||||
|
if ( websocket_frame )
|
||||||
|
{
|
||||||
|
zeek::BifEvent::enqueue_websocket_frame(connection()->zeek_analyzer(),
|
||||||
|
connection()->zeek_analyzer()->Conn(),
|
||||||
|
is_orig(),
|
||||||
|
${hdr.fin},
|
||||||
|
${hdr.reserved},
|
||||||
|
${hdr.opcode},
|
||||||
|
${hdr.payload_len});
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
%}
|
||||||
|
|
||||||
|
function process_payload_close(close: WebSocket_FramePayloadClose): bool
|
||||||
|
%{
|
||||||
|
if ( websocket_close )
|
||||||
|
{
|
||||||
|
const auto& reason = ${close.reason};
|
||||||
|
auto reason_val = zeek::make_intrusive<zeek::StringVal>(reason.length(),
|
||||||
|
reinterpret_cast<const char*>(reason.data()));
|
||||||
|
zeek::BifEvent::enqueue_websocket_close(connection()->zeek_analyzer(),
|
||||||
|
connection()->zeek_analyzer()->Conn(),
|
||||||
|
is_orig(),
|
||||||
|
${close.status},
|
||||||
|
reason_val);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
%}
|
||||||
|
|
||||||
|
function process_empty_close(hdr: WebSocket_FrameHeader): bool
|
||||||
|
%{
|
||||||
|
if ( websocket_close )
|
||||||
|
{
|
||||||
|
zeek::BifEvent::enqueue_websocket_close(connection()->zeek_analyzer(),
|
||||||
|
connection()->zeek_analyzer()->Conn(),
|
||||||
|
is_orig(),
|
||||||
|
0, /* use placeholder status */
|
||||||
|
zeek::val_mgr->EmptyString());
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
%}
|
||||||
|
|
||||||
|
function process_payload_chunk(chunk: WebSocket_FramePayloadChunk): bool
|
||||||
|
%{
|
||||||
|
auto& data = ${chunk.data};
|
||||||
|
|
||||||
|
// In-place unmasking if frame payload is masked.
|
||||||
|
if ( has_mask_ )
|
||||||
|
{
|
||||||
|
auto *d = data.data();
|
||||||
|
for ( int i = 0; i < data.length(); i++ )
|
||||||
|
d[i] = d[i] ^ masking_key_[masking_key_idx_++ % masking_key_.size()];
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( websocket_frame_data )
|
||||||
|
{
|
||||||
|
auto data_val = zeek::make_intrusive<zeek::StringVal>(data.length(), reinterpret_cast<const char*>(data.data()));
|
||||||
|
zeek::BifEvent::enqueue_websocket_frame_data(connection()->zeek_analyzer(),
|
||||||
|
connection()->zeek_analyzer()->Conn(),
|
||||||
|
is_orig(),
|
||||||
|
data_val);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Forward text and binary data to downstream analyzers.
|
||||||
|
if ( ${chunk.hdr.opcode} == OPCODE_TEXT|| ${chunk.hdr.opcode} == OPCODE_BINARY)
|
||||||
|
connection()->zeek_analyzer()->ForwardStream(data.length(),
|
||||||
|
data.data(),
|
||||||
|
is_orig());
|
||||||
|
|
||||||
|
return true;
|
||||||
|
%}
|
||||||
|
};
|
||||||
|
|
||||||
|
refine typeattr WebSocket_Message += &let {
|
||||||
|
proc_message = $context.flow.process_message(this);
|
||||||
|
};
|
||||||
|
|
||||||
|
refine typeattr WebSocket_FrameHeader += &let {
|
||||||
|
proc_header = $context.flow.process_header(this);
|
||||||
|
};
|
||||||
|
|
||||||
|
refine typeattr WebSocket_FramePayloadClose += &let {
|
||||||
|
proc_payload_close = $context.flow.process_payload_close(this);
|
||||||
|
};
|
142
src/analyzer/protocol/websocket/websocket-protocol.pac
Normal file
142
src/analyzer/protocol/websocket/websocket-protocol.pac
Normal file
|
@ -0,0 +1,142 @@
|
||||||
|
# See the file "COPYING" in the main distribution directory for copyright.
|
||||||
|
#
|
||||||
|
# The WebSocket protocol.
|
||||||
|
#
|
||||||
|
# https://datatracker.ietf.org/doc/html/rfc6455
|
||||||
|
|
||||||
|
enum Opcodes {
|
||||||
|
OPCODE_CONTINUATION = 0x00,
|
||||||
|
OPCODE_TEXT = 0x01,
|
||||||
|
OPCODE_BINARY = 0x02,
|
||||||
|
OPCODE_CLOSE = 0x08,
|
||||||
|
OPCODE_PING = 0x09,
|
||||||
|
OPCODE_PONG = 0x0a,
|
||||||
|
}
|
||||||
|
|
||||||
|
type WebSocket_FrameHeader(first_frame: bool) = record {
|
||||||
|
first2: uint16 &enforce((first_frame && opcode != 0) || (!first_frame && opcode == 0));
|
||||||
|
maybe_more_len: case payload_len1 of {
|
||||||
|
126 -> payload_len2: uint16;
|
||||||
|
127 -> payload_len8: uint64;
|
||||||
|
default -> short_len: empty;
|
||||||
|
};
|
||||||
|
|
||||||
|
maybe_masking_key: case has_mask of {
|
||||||
|
true -> masking_key: bytestring &length=4;
|
||||||
|
false -> no_masking_key: empty;
|
||||||
|
};
|
||||||
|
} &let {
|
||||||
|
fin: bool = (first2 & 0x8000) ? true : false;
|
||||||
|
reserved: uint8 = ((first2 & 0x7000) >> 12);
|
||||||
|
opcode: uint8 = (first2 & 0x0f00) >> 8;
|
||||||
|
payload_len1: uint8 = (first2 & 0x007f);
|
||||||
|
has_mask: bool = (first2 & 0x0080) ? true : false;
|
||||||
|
|
||||||
|
# Derived fields.
|
||||||
|
rest_header_len: uint64 = (has_mask ? 4 : 0) + (payload_len1 < 126 ? 0 : (payload_len1 == 126 ? 2 : 8));
|
||||||
|
payload_len: uint64 = payload_len1 < 126 ? payload_len1 : (payload_len1 == 126 ? payload_len2 : payload_len8);
|
||||||
|
|
||||||
|
new_frame_payload = $context.flow.new_frame_payload(this);
|
||||||
|
} &length=2+rest_header_len;
|
||||||
|
|
||||||
|
type WebSocket_FramePayloadClose = record {
|
||||||
|
status: uint16;
|
||||||
|
reason: bytestring &restofdata;
|
||||||
|
} &byteorder=bigendian;
|
||||||
|
|
||||||
|
type WebSocket_FramePayloadChunk(len: uint64, hdr: WebSocket_FrameHeader) = record {
|
||||||
|
data: bytestring &restofdata;
|
||||||
|
} &let {
|
||||||
|
consumed_payload = $context.flow.consumed_chunk_len(len);
|
||||||
|
payload_chunk = $context.flow.process_payload_chunk(this); # unmasks if needed
|
||||||
|
close_payload: WebSocket_FramePayloadClose withinput data &length=len &if(hdr.opcode == OPCODE_CLOSE);
|
||||||
|
} &length=len;
|
||||||
|
|
||||||
|
type WebSocket_Frame(first_frame: bool, msg: WebSocket_Message) = record {
|
||||||
|
hdr: WebSocket_FrameHeader(first_frame);
|
||||||
|
|
||||||
|
# This is implementing frame payload chunking so that we do not
|
||||||
|
# attempt to buffer huge frames and forward data to downstream
|
||||||
|
# analyzers in chunks.
|
||||||
|
#
|
||||||
|
# I tried &chunked and it didn't do anything very useful.
|
||||||
|
chunks: WebSocket_FramePayloadChunk($context.flow.next_chunk_len(), hdr)[]
|
||||||
|
&until($context.flow.remaining_frame_payload_len() == 0)
|
||||||
|
&transient;
|
||||||
|
} &let {
|
||||||
|
# If we find a close frame without payload, raise the event here
|
||||||
|
# as the close won't have been parsed via chunks.
|
||||||
|
empty_close = $context.flow.process_empty_close(hdr) &if(hdr.opcode == OPCODE_CLOSE) && hdr.payload_len == 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
type WebSocket_Message = record {
|
||||||
|
first_frame: WebSocket_Frame(true, this);
|
||||||
|
optional_more_frames: case first_frame.hdr.fin of {
|
||||||
|
true -> no_more_frames: empty;
|
||||||
|
false -> more_frames: WebSocket_Frame(false, this)[] &until($element.hdr.fin);
|
||||||
|
};
|
||||||
|
} &let {
|
||||||
|
opcode = first_frame.hdr.opcode;
|
||||||
|
} &byteorder=bigendian;
|
||||||
|
|
||||||
|
flow WebSocket_Flow(is_orig: bool) {
|
||||||
|
flowunit = WebSocket_Message withcontext(connection, this);
|
||||||
|
|
||||||
|
%member{
|
||||||
|
bool has_mask_;
|
||||||
|
uint64_t masking_key_idx_;
|
||||||
|
uint64_t frame_payload_len_;
|
||||||
|
std::array<uint8_t, 4> masking_key_;
|
||||||
|
%}
|
||||||
|
|
||||||
|
%init{
|
||||||
|
has_mask_ = false;
|
||||||
|
masking_key_idx_ = 0;
|
||||||
|
frame_payload_len_ = 0;
|
||||||
|
%}
|
||||||
|
|
||||||
|
function new_frame_payload(hdr: WebSocket_FrameHeader): uint64
|
||||||
|
%{
|
||||||
|
if ( frame_payload_len_ > 0 )
|
||||||
|
connection()->zeek_analyzer()->Weird("websocket_frame_not_consumed");
|
||||||
|
|
||||||
|
frame_payload_len_ = ${hdr.payload_len};
|
||||||
|
has_mask_ = ${hdr.has_mask};
|
||||||
|
masking_key_idx_ = 0;
|
||||||
|
if ( has_mask_ ) {
|
||||||
|
assert(${hdr.masking_key}.length() == static_cast<int>(masking_key_.size()));
|
||||||
|
memcpy(masking_key_.data(), ${hdr.masking_key}.data(), masking_key_.size());
|
||||||
|
}
|
||||||
|
return frame_payload_len_;
|
||||||
|
%}
|
||||||
|
|
||||||
|
function remaining_frame_payload_len(): uint64
|
||||||
|
%{
|
||||||
|
return frame_payload_len_;
|
||||||
|
%}
|
||||||
|
|
||||||
|
function consumed_chunk_len(len: uint64): uint64
|
||||||
|
%{
|
||||||
|
if ( len > frame_payload_len_ ) {
|
||||||
|
connection()->zeek_analyzer()->Weird("websocket_frame_consuming_too_much");
|
||||||
|
len = frame_payload_len_;
|
||||||
|
}
|
||||||
|
|
||||||
|
frame_payload_len_ -= len;
|
||||||
|
return len;
|
||||||
|
%}
|
||||||
|
|
||||||
|
function next_chunk_len(): uint64
|
||||||
|
%{
|
||||||
|
uint64_t len = frame_payload_len_;
|
||||||
|
|
||||||
|
// It would be somewhat nicer if we could just consume
|
||||||
|
// anything still left to consume from the current packet,
|
||||||
|
// but couldn't figure out if that information can be pulled
|
||||||
|
// flow buffer.
|
||||||
|
if ( len > zeek::BifConst::WebSocket::payload_chunk_size )
|
||||||
|
len = zeek::BifConst::WebSocket::payload_chunk_size;
|
||||||
|
|
||||||
|
return len;
|
||||||
|
%}
|
||||||
|
};
|
24
src/analyzer/protocol/websocket/websocket.pac
Normal file
24
src/analyzer/protocol/websocket/websocket.pac
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
# See the file "COPYING" in the main distribution directory for copyright.
|
||||||
|
|
||||||
|
%include binpac.pac
|
||||||
|
%include zeek.pac
|
||||||
|
|
||||||
|
%extern{
|
||||||
|
#include <array>
|
||||||
|
|
||||||
|
#include "zeek/analyzer/protocol/websocket/consts.bif.h"
|
||||||
|
#include "zeek/analyzer/protocol/websocket/events.bif.h"
|
||||||
|
%}
|
||||||
|
|
||||||
|
analyzer WebSocket withcontext {
|
||||||
|
connection: WebSocket_Conn;
|
||||||
|
flow: WebSocket_Flow;
|
||||||
|
};
|
||||||
|
|
||||||
|
connection WebSocket_Conn(zeek_analyzer: ZeekAnalyzer) {
|
||||||
|
upflow = WebSocket_Flow(true);
|
||||||
|
downflow = WebSocket_Flow(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
%include websocket-protocol.pac
|
||||||
|
%include websocket-analyzer.pac
|
|
@ -94,6 +94,7 @@ target_link_libraries(zeek_fuzzer_shared PUBLIC ${zeek_fuzzer_shared_deps}
|
||||||
|
|
||||||
add_fuzz_target(packet)
|
add_fuzz_target(packet)
|
||||||
add_fuzz_target(dns)
|
add_fuzz_target(dns)
|
||||||
|
add_fuzz_target(websocket)
|
||||||
|
|
||||||
add_generic_analyzer_fuzz_target(ftp)
|
add_generic_analyzer_fuzz_target(ftp)
|
||||||
add_generic_analyzer_fuzz_target(http)
|
add_generic_analyzer_fuzz_target(http)
|
||||||
|
|
BIN
src/fuzzers/corpora/websocket-corpus.zip
Normal file
BIN
src/fuzzers/corpora/websocket-corpus.zip
Normal file
Binary file not shown.
107
src/fuzzers/websocket-fuzzer.cc
Normal file
107
src/fuzzers/websocket-fuzzer.cc
Normal file
|
@ -0,0 +1,107 @@
|
||||||
|
#include <binpac.h>
|
||||||
|
|
||||||
|
#include "zeek/Conn.h"
|
||||||
|
#include "zeek/ID.h"
|
||||||
|
#include "zeek/RunState.h"
|
||||||
|
#include "zeek/analyzer/Analyzer.h"
|
||||||
|
#include "zeek/analyzer/Manager.h"
|
||||||
|
#include "zeek/analyzer/protocol/pia/PIA.h"
|
||||||
|
#include "zeek/analyzer/protocol/tcp/TCP.h"
|
||||||
|
#include "zeek/analyzer/protocol/websocket/WebSocket.h"
|
||||||
|
#include "zeek/fuzzers/FuzzBuffer.h"
|
||||||
|
#include "zeek/fuzzers/fuzzer-setup.h"
|
||||||
|
#include "zeek/packet_analysis/protocol/tcp/TCPSessionAdapter.h"
|
||||||
|
#include "zeek/session/Manager.h"
|
||||||
|
|
||||||
|
static constexpr auto FUZZ_ANALYZER_NAME = "websocket";
|
||||||
|
|
||||||
|
static zeek::Connection* add_connection() {
|
||||||
|
static constexpr double network_time_start = 1439471031;
|
||||||
|
zeek::run_state::detail::update_network_time(network_time_start);
|
||||||
|
|
||||||
|
zeek::Packet p;
|
||||||
|
zeek::ConnTuple conn_id;
|
||||||
|
conn_id.src_addr = zeek::IPAddr("1.2.3.4");
|
||||||
|
conn_id.dst_addr = zeek::IPAddr("5.6.7.8");
|
||||||
|
conn_id.src_port = htons(23132);
|
||||||
|
conn_id.dst_port = htons(80);
|
||||||
|
conn_id.is_one_way = false;
|
||||||
|
conn_id.proto = TRANSPORT_TCP;
|
||||||
|
zeek::detail::ConnKey key(conn_id);
|
||||||
|
zeek::Connection* conn = new zeek::Connection(key, network_time_start, &conn_id, 1, &p);
|
||||||
|
conn->SetTransport(TRANSPORT_TCP);
|
||||||
|
zeek::session_mgr->Insert(conn);
|
||||||
|
return conn;
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::tuple<zeek::analyzer::Analyzer*, zeek::packet_analysis::IP::SessionAdapter*> add_analyzer(
|
||||||
|
zeek::Connection* conn, const zeek::Tag& analyzer_tag) {
|
||||||
|
auto* tcp = new zeek::packet_analysis::TCP::TCPSessionAdapter(conn);
|
||||||
|
auto* pia = new zeek::analyzer::pia::PIA_TCP(conn);
|
||||||
|
auto a = zeek::analyzer_mgr->InstantiateAnalyzer(analyzer_tag, conn);
|
||||||
|
tcp->AddChildAnalyzer(a);
|
||||||
|
tcp->AddChildAnalyzer(pia->AsAnalyzer());
|
||||||
|
conn->SetSessionAdapter(tcp, pia);
|
||||||
|
|
||||||
|
return {a, tcp};
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
|
||||||
|
static auto analyzer_tag = zeek::analyzer_mgr->GetComponentTag(FUZZ_ANALYZER_NAME);
|
||||||
|
if ( ! analyzer_tag ) {
|
||||||
|
std::fprintf(stderr, "Unable to find component tag for '%s'", FUZZ_ANALYZER_NAME);
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Would be nice to have that in LLVMFuzzerInitialize, oh well...
|
||||||
|
static bool one_time_setup = false;
|
||||||
|
if ( ! one_time_setup ) {
|
||||||
|
zeek::analyzer_mgr->DisableAllAnalyzers();
|
||||||
|
zeek::analyzer_mgr->EnableAnalyzer(analyzer_tag);
|
||||||
|
const auto& pia_tcp_tag = zeek::analyzer_mgr->GetComponentTag("PIA_TCP");
|
||||||
|
zeek::analyzer_mgr->EnableAnalyzer(pia_tcp_tag);
|
||||||
|
one_time_setup = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
zeek::detail::FuzzBuffer fb{data, size};
|
||||||
|
|
||||||
|
if ( ! fb.Valid() )
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
auto conn = add_connection();
|
||||||
|
if ( new_connection )
|
||||||
|
conn->Event(new_connection, nullptr);
|
||||||
|
|
||||||
|
auto [a, adapter] = add_analyzer(conn, analyzer_tag);
|
||||||
|
|
||||||
|
// WebSocket specific initialization. May also want to fuzz
|
||||||
|
// this in the future.
|
||||||
|
static const auto& config_type = zeek::id::find_type<zeek::RecordType>("WebSocket::AnalyzerConfig");
|
||||||
|
static const auto& config_rec = zeek::make_intrusive<zeek::RecordVal>(config_type);
|
||||||
|
auto wsa = static_cast<zeek::analyzer::websocket::WebSocket_Analyzer*>(a);
|
||||||
|
wsa->Configure(config_rec);
|
||||||
|
|
||||||
|
for ( ;; ) {
|
||||||
|
auto chunk = fb.Next();
|
||||||
|
|
||||||
|
if ( ! chunk )
|
||||||
|
break;
|
||||||
|
|
||||||
|
try {
|
||||||
|
a->NextStream(chunk->size, chunk->data.get(), chunk->is_orig);
|
||||||
|
} catch ( const binpac::Exception& e ) {
|
||||||
|
}
|
||||||
|
|
||||||
|
chunk = {}; // Release buffer before draining events.
|
||||||
|
zeek::event_mgr.Drain();
|
||||||
|
|
||||||
|
// Has the analyzer been disabled during event processing?
|
||||||
|
if ( ! adapter->HasChildAnalyzer(analyzer_tag) )
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
zeek::event_mgr.Drain();
|
||||||
|
zeek::detail::fuzzer_cleanup_one_input();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -244,6 +244,10 @@ scripts/base/init-frameworks-and-bifs.zeek
|
||||||
build/scripts/base/bif/plugins/Zeek_TCP.events.bif.zeek
|
build/scripts/base/bif/plugins/Zeek_TCP.events.bif.zeek
|
||||||
build/scripts/base/bif/plugins/Zeek_TCP.types.bif.zeek
|
build/scripts/base/bif/plugins/Zeek_TCP.types.bif.zeek
|
||||||
build/scripts/base/bif/plugins/Zeek_TCP.functions.bif.zeek
|
build/scripts/base/bif/plugins/Zeek_TCP.functions.bif.zeek
|
||||||
|
build/scripts/base/bif/plugins/Zeek_WebSocket.consts.bif.zeek
|
||||||
|
build/scripts/base/bif/plugins/Zeek_WebSocket.events.bif.zeek
|
||||||
|
build/scripts/base/bif/plugins/Zeek_WebSocket.functions.bif.zeek
|
||||||
|
build/scripts/base/bif/plugins/Zeek_WebSocket.types.bif.zeek
|
||||||
build/scripts/base/bif/plugins/Zeek_XMPP.events.bif.zeek
|
build/scripts/base/bif/plugins/Zeek_XMPP.events.bif.zeek
|
||||||
build/scripts/base/bif/plugins/Zeek_ARP.events.bif.zeek
|
build/scripts/base/bif/plugins/Zeek_ARP.events.bif.zeek
|
||||||
build/scripts/base/bif/plugins/Zeek_UDP.events.bif.zeek
|
build/scripts/base/bif/plugins/Zeek_UDP.events.bif.zeek
|
||||||
|
|
|
@ -244,6 +244,10 @@ scripts/base/init-frameworks-and-bifs.zeek
|
||||||
build/scripts/base/bif/plugins/Zeek_TCP.events.bif.zeek
|
build/scripts/base/bif/plugins/Zeek_TCP.events.bif.zeek
|
||||||
build/scripts/base/bif/plugins/Zeek_TCP.types.bif.zeek
|
build/scripts/base/bif/plugins/Zeek_TCP.types.bif.zeek
|
||||||
build/scripts/base/bif/plugins/Zeek_TCP.functions.bif.zeek
|
build/scripts/base/bif/plugins/Zeek_TCP.functions.bif.zeek
|
||||||
|
build/scripts/base/bif/plugins/Zeek_WebSocket.consts.bif.zeek
|
||||||
|
build/scripts/base/bif/plugins/Zeek_WebSocket.events.bif.zeek
|
||||||
|
build/scripts/base/bif/plugins/Zeek_WebSocket.functions.bif.zeek
|
||||||
|
build/scripts/base/bif/plugins/Zeek_WebSocket.types.bif.zeek
|
||||||
build/scripts/base/bif/plugins/Zeek_XMPP.events.bif.zeek
|
build/scripts/base/bif/plugins/Zeek_XMPP.events.bif.zeek
|
||||||
build/scripts/base/bif/plugins/Zeek_ARP.events.bif.zeek
|
build/scripts/base/bif/plugins/Zeek_ARP.events.bif.zeek
|
||||||
build/scripts/base/bif/plugins/Zeek_UDP.events.bif.zeek
|
build/scripts/base/bif/plugins/Zeek_UDP.events.bif.zeek
|
||||||
|
@ -465,6 +469,9 @@ scripts/base/init-default.zeek
|
||||||
scripts/base/protocols/syslog/spicy-events.zeek
|
scripts/base/protocols/syslog/spicy-events.zeek
|
||||||
scripts/base/protocols/syslog/consts.zeek
|
scripts/base/protocols/syslog/consts.zeek
|
||||||
scripts/base/protocols/syslog/main.zeek
|
scripts/base/protocols/syslog/main.zeek
|
||||||
|
scripts/base/protocols/websocket/__load__.zeek
|
||||||
|
scripts/base/protocols/websocket/consts.zeek
|
||||||
|
scripts/base/protocols/websocket/main.zeek
|
||||||
scripts/base/protocols/tunnels/__load__.zeek
|
scripts/base/protocols/tunnels/__load__.zeek
|
||||||
scripts/base/protocols/xmpp/__load__.zeek
|
scripts/base/protocols/xmpp/__load__.zeek
|
||||||
scripts/base/protocols/xmpp/main.zeek
|
scripts/base/protocols/xmpp/main.zeek
|
||||||
|
|
|
@ -65,6 +65,7 @@ telemetry_histogram
|
||||||
traceroute
|
traceroute
|
||||||
tunnel
|
tunnel
|
||||||
unknown_protocols
|
unknown_protocols
|
||||||
|
websocket
|
||||||
weird
|
weird
|
||||||
weird_stats
|
weird_stats
|
||||||
x509
|
x509
|
||||||
|
|
|
@ -884,4 +884,20 @@ connection {
|
||||||
}
|
}
|
||||||
* uid: string, log=F, optional=F
|
* uid: string, log=F, optional=F
|
||||||
* vlan: int, log=F, optional=T
|
* vlan: int, log=F, optional=T
|
||||||
|
* websocket: record WebSocket::Info, log=F, optional=T
|
||||||
|
WebSocket::Info {
|
||||||
|
* client_extensions: vector of string, log=T, optional=T
|
||||||
|
* client_key: string, log=F, optional=T
|
||||||
|
* client_protocols: vector of string, log=T, optional=T
|
||||||
|
* host: string, log=T, optional=T
|
||||||
|
* id: record conn_id, log=T, optional=F
|
||||||
|
conn_id { ... }
|
||||||
|
* server_accept: string, log=F, optional=T
|
||||||
|
* server_extensions: vector of string, log=T, optional=T
|
||||||
|
* subprotocol: string, log=T, optional=T
|
||||||
|
* ts: time, log=T, optional=F
|
||||||
|
* uid: string, log=T, optional=F
|
||||||
|
* uri: string, log=T, optional=T
|
||||||
|
* user_agent: string, log=T, optional=T
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -463,6 +463,10 @@
|
||||||
0.000000 MetaHookPost LoadFile(0, ./Zeek_Teredo.functions.bif.zeek, <...>/Zeek_Teredo.functions.bif.zeek) -> -1
|
0.000000 MetaHookPost LoadFile(0, ./Zeek_Teredo.functions.bif.zeek, <...>/Zeek_Teredo.functions.bif.zeek) -> -1
|
||||||
0.000000 MetaHookPost LoadFile(0, ./Zeek_UDP.events.bif.zeek, <...>/Zeek_UDP.events.bif.zeek) -> -1
|
0.000000 MetaHookPost LoadFile(0, ./Zeek_UDP.events.bif.zeek, <...>/Zeek_UDP.events.bif.zeek) -> -1
|
||||||
0.000000 MetaHookPost LoadFile(0, ./Zeek_VXLAN.events.bif.zeek, <...>/Zeek_VXLAN.events.bif.zeek) -> -1
|
0.000000 MetaHookPost LoadFile(0, ./Zeek_VXLAN.events.bif.zeek, <...>/Zeek_VXLAN.events.bif.zeek) -> -1
|
||||||
|
0.000000 MetaHookPost LoadFile(0, ./Zeek_WebSocket.consts.bif.zeek, <...>/Zeek_WebSocket.consts.bif.zeek) -> -1
|
||||||
|
0.000000 MetaHookPost LoadFile(0, ./Zeek_WebSocket.events.bif.zeek, <...>/Zeek_WebSocket.events.bif.zeek) -> -1
|
||||||
|
0.000000 MetaHookPost LoadFile(0, ./Zeek_WebSocket.functions.bif.zeek, <...>/Zeek_WebSocket.functions.bif.zeek) -> -1
|
||||||
|
0.000000 MetaHookPost LoadFile(0, ./Zeek_WebSocket.types.bif.zeek, <...>/Zeek_WebSocket.types.bif.zeek) -> -1
|
||||||
0.000000 MetaHookPost LoadFile(0, ./Zeek_X509.events.bif.zeek, <...>/Zeek_X509.events.bif.zeek) -> -1
|
0.000000 MetaHookPost LoadFile(0, ./Zeek_X509.events.bif.zeek, <...>/Zeek_X509.events.bif.zeek) -> -1
|
||||||
0.000000 MetaHookPost LoadFile(0, ./Zeek_X509.functions.bif.zeek, <...>/Zeek_X509.functions.bif.zeek) -> -1
|
0.000000 MetaHookPost LoadFile(0, ./Zeek_X509.functions.bif.zeek, <...>/Zeek_X509.functions.bif.zeek) -> -1
|
||||||
0.000000 MetaHookPost LoadFile(0, ./Zeek_X509.ocsp_events.bif.zeek, <...>/Zeek_X509.ocsp_events.bif.zeek) -> -1
|
0.000000 MetaHookPost LoadFile(0, ./Zeek_X509.ocsp_events.bif.zeek, <...>/Zeek_X509.ocsp_events.bif.zeek) -> -1
|
||||||
|
@ -752,6 +756,10 @@
|
||||||
0.000000 MetaHookPost LoadFileExtended(0, ./Zeek_Teredo.functions.bif.zeek, <...>/Zeek_Teredo.functions.bif.zeek) -> (-1, <no content>)
|
0.000000 MetaHookPost LoadFileExtended(0, ./Zeek_Teredo.functions.bif.zeek, <...>/Zeek_Teredo.functions.bif.zeek) -> (-1, <no content>)
|
||||||
0.000000 MetaHookPost LoadFileExtended(0, ./Zeek_UDP.events.bif.zeek, <...>/Zeek_UDP.events.bif.zeek) -> (-1, <no content>)
|
0.000000 MetaHookPost LoadFileExtended(0, ./Zeek_UDP.events.bif.zeek, <...>/Zeek_UDP.events.bif.zeek) -> (-1, <no content>)
|
||||||
0.000000 MetaHookPost LoadFileExtended(0, ./Zeek_VXLAN.events.bif.zeek, <...>/Zeek_VXLAN.events.bif.zeek) -> (-1, <no content>)
|
0.000000 MetaHookPost LoadFileExtended(0, ./Zeek_VXLAN.events.bif.zeek, <...>/Zeek_VXLAN.events.bif.zeek) -> (-1, <no content>)
|
||||||
|
0.000000 MetaHookPost LoadFileExtended(0, ./Zeek_WebSocket.consts.bif.zeek, <...>/Zeek_WebSocket.consts.bif.zeek) -> (-1, <no content>)
|
||||||
|
0.000000 MetaHookPost LoadFileExtended(0, ./Zeek_WebSocket.events.bif.zeek, <...>/Zeek_WebSocket.events.bif.zeek) -> (-1, <no content>)
|
||||||
|
0.000000 MetaHookPost LoadFileExtended(0, ./Zeek_WebSocket.functions.bif.zeek, <...>/Zeek_WebSocket.functions.bif.zeek) -> (-1, <no content>)
|
||||||
|
0.000000 MetaHookPost LoadFileExtended(0, ./Zeek_WebSocket.types.bif.zeek, <...>/Zeek_WebSocket.types.bif.zeek) -> (-1, <no content>)
|
||||||
0.000000 MetaHookPost LoadFileExtended(0, ./Zeek_X509.events.bif.zeek, <...>/Zeek_X509.events.bif.zeek) -> (-1, <no content>)
|
0.000000 MetaHookPost LoadFileExtended(0, ./Zeek_X509.events.bif.zeek, <...>/Zeek_X509.events.bif.zeek) -> (-1, <no content>)
|
||||||
0.000000 MetaHookPost LoadFileExtended(0, ./Zeek_X509.functions.bif.zeek, <...>/Zeek_X509.functions.bif.zeek) -> (-1, <no content>)
|
0.000000 MetaHookPost LoadFileExtended(0, ./Zeek_X509.functions.bif.zeek, <...>/Zeek_X509.functions.bif.zeek) -> (-1, <no content>)
|
||||||
0.000000 MetaHookPost LoadFileExtended(0, ./Zeek_X509.ocsp_events.bif.zeek, <...>/Zeek_X509.ocsp_events.bif.zeek) -> (-1, <no content>)
|
0.000000 MetaHookPost LoadFileExtended(0, ./Zeek_X509.ocsp_events.bif.zeek, <...>/Zeek_X509.ocsp_events.bif.zeek) -> (-1, <no content>)
|
||||||
|
@ -1389,6 +1397,10 @@
|
||||||
0.000000 MetaHookPre LoadFile(0, ./Zeek_Teredo.functions.bif.zeek, <...>/Zeek_Teredo.functions.bif.zeek)
|
0.000000 MetaHookPre LoadFile(0, ./Zeek_Teredo.functions.bif.zeek, <...>/Zeek_Teredo.functions.bif.zeek)
|
||||||
0.000000 MetaHookPre LoadFile(0, ./Zeek_UDP.events.bif.zeek, <...>/Zeek_UDP.events.bif.zeek)
|
0.000000 MetaHookPre LoadFile(0, ./Zeek_UDP.events.bif.zeek, <...>/Zeek_UDP.events.bif.zeek)
|
||||||
0.000000 MetaHookPre LoadFile(0, ./Zeek_VXLAN.events.bif.zeek, <...>/Zeek_VXLAN.events.bif.zeek)
|
0.000000 MetaHookPre LoadFile(0, ./Zeek_VXLAN.events.bif.zeek, <...>/Zeek_VXLAN.events.bif.zeek)
|
||||||
|
0.000000 MetaHookPre LoadFile(0, ./Zeek_WebSocket.consts.bif.zeek, <...>/Zeek_WebSocket.consts.bif.zeek)
|
||||||
|
0.000000 MetaHookPre LoadFile(0, ./Zeek_WebSocket.events.bif.zeek, <...>/Zeek_WebSocket.events.bif.zeek)
|
||||||
|
0.000000 MetaHookPre LoadFile(0, ./Zeek_WebSocket.functions.bif.zeek, <...>/Zeek_WebSocket.functions.bif.zeek)
|
||||||
|
0.000000 MetaHookPre LoadFile(0, ./Zeek_WebSocket.types.bif.zeek, <...>/Zeek_WebSocket.types.bif.zeek)
|
||||||
0.000000 MetaHookPre LoadFile(0, ./Zeek_X509.events.bif.zeek, <...>/Zeek_X509.events.bif.zeek)
|
0.000000 MetaHookPre LoadFile(0, ./Zeek_X509.events.bif.zeek, <...>/Zeek_X509.events.bif.zeek)
|
||||||
0.000000 MetaHookPre LoadFile(0, ./Zeek_X509.functions.bif.zeek, <...>/Zeek_X509.functions.bif.zeek)
|
0.000000 MetaHookPre LoadFile(0, ./Zeek_X509.functions.bif.zeek, <...>/Zeek_X509.functions.bif.zeek)
|
||||||
0.000000 MetaHookPre LoadFile(0, ./Zeek_X509.ocsp_events.bif.zeek, <...>/Zeek_X509.ocsp_events.bif.zeek)
|
0.000000 MetaHookPre LoadFile(0, ./Zeek_X509.ocsp_events.bif.zeek, <...>/Zeek_X509.ocsp_events.bif.zeek)
|
||||||
|
@ -1678,6 +1690,10 @@
|
||||||
0.000000 MetaHookPre LoadFileExtended(0, ./Zeek_Teredo.functions.bif.zeek, <...>/Zeek_Teredo.functions.bif.zeek)
|
0.000000 MetaHookPre LoadFileExtended(0, ./Zeek_Teredo.functions.bif.zeek, <...>/Zeek_Teredo.functions.bif.zeek)
|
||||||
0.000000 MetaHookPre LoadFileExtended(0, ./Zeek_UDP.events.bif.zeek, <...>/Zeek_UDP.events.bif.zeek)
|
0.000000 MetaHookPre LoadFileExtended(0, ./Zeek_UDP.events.bif.zeek, <...>/Zeek_UDP.events.bif.zeek)
|
||||||
0.000000 MetaHookPre LoadFileExtended(0, ./Zeek_VXLAN.events.bif.zeek, <...>/Zeek_VXLAN.events.bif.zeek)
|
0.000000 MetaHookPre LoadFileExtended(0, ./Zeek_VXLAN.events.bif.zeek, <...>/Zeek_VXLAN.events.bif.zeek)
|
||||||
|
0.000000 MetaHookPre LoadFileExtended(0, ./Zeek_WebSocket.consts.bif.zeek, <...>/Zeek_WebSocket.consts.bif.zeek)
|
||||||
|
0.000000 MetaHookPre LoadFileExtended(0, ./Zeek_WebSocket.events.bif.zeek, <...>/Zeek_WebSocket.events.bif.zeek)
|
||||||
|
0.000000 MetaHookPre LoadFileExtended(0, ./Zeek_WebSocket.functions.bif.zeek, <...>/Zeek_WebSocket.functions.bif.zeek)
|
||||||
|
0.000000 MetaHookPre LoadFileExtended(0, ./Zeek_WebSocket.types.bif.zeek, <...>/Zeek_WebSocket.types.bif.zeek)
|
||||||
0.000000 MetaHookPre LoadFileExtended(0, ./Zeek_X509.events.bif.zeek, <...>/Zeek_X509.events.bif.zeek)
|
0.000000 MetaHookPre LoadFileExtended(0, ./Zeek_X509.events.bif.zeek, <...>/Zeek_X509.events.bif.zeek)
|
||||||
0.000000 MetaHookPre LoadFileExtended(0, ./Zeek_X509.functions.bif.zeek, <...>/Zeek_X509.functions.bif.zeek)
|
0.000000 MetaHookPre LoadFileExtended(0, ./Zeek_X509.functions.bif.zeek, <...>/Zeek_X509.functions.bif.zeek)
|
||||||
0.000000 MetaHookPre LoadFileExtended(0, ./Zeek_X509.ocsp_events.bif.zeek, <...>/Zeek_X509.ocsp_events.bif.zeek)
|
0.000000 MetaHookPre LoadFileExtended(0, ./Zeek_X509.ocsp_events.bif.zeek, <...>/Zeek_X509.ocsp_events.bif.zeek)
|
||||||
|
@ -2314,6 +2330,10 @@
|
||||||
0.000000 | HookLoadFile ./Zeek_Teredo.functions.bif.zeek <...>/Zeek_Teredo.functions.bif.zeek
|
0.000000 | HookLoadFile ./Zeek_Teredo.functions.bif.zeek <...>/Zeek_Teredo.functions.bif.zeek
|
||||||
0.000000 | HookLoadFile ./Zeek_UDP.events.bif.zeek <...>/Zeek_UDP.events.bif.zeek
|
0.000000 | HookLoadFile ./Zeek_UDP.events.bif.zeek <...>/Zeek_UDP.events.bif.zeek
|
||||||
0.000000 | HookLoadFile ./Zeek_VXLAN.events.bif.zeek <...>/Zeek_VXLAN.events.bif.zeek
|
0.000000 | HookLoadFile ./Zeek_VXLAN.events.bif.zeek <...>/Zeek_VXLAN.events.bif.zeek
|
||||||
|
0.000000 | HookLoadFile ./Zeek_WebSocket.consts.bif.zeek <...>/Zeek_WebSocket.consts.bif.zeek
|
||||||
|
0.000000 | HookLoadFile ./Zeek_WebSocket.events.bif.zeek <...>/Zeek_WebSocket.events.bif.zeek
|
||||||
|
0.000000 | HookLoadFile ./Zeek_WebSocket.functions.bif.zeek <...>/Zeek_WebSocket.functions.bif.zeek
|
||||||
|
0.000000 | HookLoadFile ./Zeek_WebSocket.types.bif.zeek <...>/Zeek_WebSocket.types.bif.zeek
|
||||||
0.000000 | HookLoadFile ./Zeek_X509.events.bif.zeek <...>/Zeek_X509.events.bif.zeek
|
0.000000 | HookLoadFile ./Zeek_X509.events.bif.zeek <...>/Zeek_X509.events.bif.zeek
|
||||||
0.000000 | HookLoadFile ./Zeek_X509.functions.bif.zeek <...>/Zeek_X509.functions.bif.zeek
|
0.000000 | HookLoadFile ./Zeek_X509.functions.bif.zeek <...>/Zeek_X509.functions.bif.zeek
|
||||||
0.000000 | HookLoadFile ./Zeek_X509.ocsp_events.bif.zeek <...>/Zeek_X509.ocsp_events.bif.zeek
|
0.000000 | HookLoadFile ./Zeek_X509.ocsp_events.bif.zeek <...>/Zeek_X509.ocsp_events.bif.zeek
|
||||||
|
@ -2603,6 +2623,10 @@
|
||||||
0.000000 | HookLoadFileExtended ./Zeek_Teredo.functions.bif.zeek <...>/Zeek_Teredo.functions.bif.zeek
|
0.000000 | HookLoadFileExtended ./Zeek_Teredo.functions.bif.zeek <...>/Zeek_Teredo.functions.bif.zeek
|
||||||
0.000000 | HookLoadFileExtended ./Zeek_UDP.events.bif.zeek <...>/Zeek_UDP.events.bif.zeek
|
0.000000 | HookLoadFileExtended ./Zeek_UDP.events.bif.zeek <...>/Zeek_UDP.events.bif.zeek
|
||||||
0.000000 | HookLoadFileExtended ./Zeek_VXLAN.events.bif.zeek <...>/Zeek_VXLAN.events.bif.zeek
|
0.000000 | HookLoadFileExtended ./Zeek_VXLAN.events.bif.zeek <...>/Zeek_VXLAN.events.bif.zeek
|
||||||
|
0.000000 | HookLoadFileExtended ./Zeek_WebSocket.consts.bif.zeek <...>/Zeek_WebSocket.consts.bif.zeek
|
||||||
|
0.000000 | HookLoadFileExtended ./Zeek_WebSocket.events.bif.zeek <...>/Zeek_WebSocket.events.bif.zeek
|
||||||
|
0.000000 | HookLoadFileExtended ./Zeek_WebSocket.functions.bif.zeek <...>/Zeek_WebSocket.functions.bif.zeek
|
||||||
|
0.000000 | HookLoadFileExtended ./Zeek_WebSocket.types.bif.zeek <...>/Zeek_WebSocket.types.bif.zeek
|
||||||
0.000000 | HookLoadFileExtended ./Zeek_X509.events.bif.zeek <...>/Zeek_X509.events.bif.zeek
|
0.000000 | HookLoadFileExtended ./Zeek_X509.events.bif.zeek <...>/Zeek_X509.events.bif.zeek
|
||||||
0.000000 | HookLoadFileExtended ./Zeek_X509.functions.bif.zeek <...>/Zeek_X509.functions.bif.zeek
|
0.000000 | HookLoadFileExtended ./Zeek_X509.functions.bif.zeek <...>/Zeek_X509.functions.bif.zeek
|
||||||
0.000000 | HookLoadFileExtended ./Zeek_X509.ocsp_events.bif.zeek <...>/Zeek_X509.ocsp_events.bif.zeek
|
0.000000 | HookLoadFileExtended ./Zeek_X509.ocsp_events.bif.zeek <...>/Zeek_X509.ocsp_events.bif.zeek
|
||||||
|
|
|
@ -7,10 +7,10 @@
|
||||||
#open XXXX-XX-XX-XX-XX-XX
|
#open XXXX-XX-XX-XX-XX-XX
|
||||||
#fields ts fuid uid id.orig_h id.orig_p id.resp_h id.resp_p source depth analyzers mime_type filename duration local_orig is_orig seen_bytes total_bytes missing_bytes overflow_bytes timedout parent_fuid md5 sha1 sha256
|
#fields ts fuid uid id.orig_h id.orig_p id.resp_h id.resp_p source depth analyzers mime_type filename duration local_orig is_orig seen_bytes total_bytes missing_bytes overflow_bytes timedout parent_fuid md5 sha1 sha256
|
||||||
#types time string string addr port addr port string count set[string] string string interval bool bool count count count count bool string string string string
|
#types time string string addr port addr port string count set[string] string string interval bool bool count count count count bool string string string string
|
||||||
XXXXXXXXXX.XXXXXX FgN3AE3of2TRIqaeQe CHhAvVGS1DHFjwGM9 192.168.4.149 60623 74.125.239.129 443 SSL 0 SHA256,X509,SHA1,MD5 application/x-x509-user-cert - 0.000000 F F 1859 - 0 0 F - 7af07aca6d5c6e8e87fe4bb34786edc0 548b9e03bc183d1cd39f93a37985cb3950f8f06f 6bacfa4536150ed996f2b0c05ab6e345a257225f449aeb9d2018ccd88f4ede43
|
XXXXXXXXXX.XXXXXX FgN3AE3of2TRIqaeQe CHhAvVGS1DHFjwGM9 192.168.4.149 60623 74.125.239.129 443 SSL 0 X509,SHA256,SHA1,MD5 application/x-x509-user-cert - 0.000000 F F 1859 - 0 0 F - 7af07aca6d5c6e8e87fe4bb34786edc0 548b9e03bc183d1cd39f93a37985cb3950f8f06f 6bacfa4536150ed996f2b0c05ab6e345a257225f449aeb9d2018ccd88f4ede43
|
||||||
XXXXXXXXXX.XXXXXX Fv2Agc4z5boBOacQi6 CHhAvVGS1DHFjwGM9 192.168.4.149 60623 74.125.239.129 443 SSL 0 SHA256,X509,SHA1,MD5 application/x-x509-ca-cert - 0.000000 F F 1032 - 0 0 F - 9e4ac96474245129d9766700412a1f89 d83c1a7f4d0446bb2081b81a1670f8183451ca24 a047a37fa2d2e118a4f5095fe074d6cfe0e352425a7632bf8659c03919a6c81d
|
XXXXXXXXXX.XXXXXX Fv2Agc4z5boBOacQi6 CHhAvVGS1DHFjwGM9 192.168.4.149 60623 74.125.239.129 443 SSL 0 X509,SHA256,SHA1,MD5 application/x-x509-ca-cert - 0.000000 F F 1032 - 0 0 F - 9e4ac96474245129d9766700412a1f89 d83c1a7f4d0446bb2081b81a1670f8183451ca24 a047a37fa2d2e118a4f5095fe074d6cfe0e352425a7632bf8659c03919a6c81d
|
||||||
XXXXXXXXXX.XXXXXX Ftmyeg2qgI2V38Dt3g CHhAvVGS1DHFjwGM9 192.168.4.149 60623 74.125.239.129 443 SSL 0 SHA256,X509,SHA1,MD5 application/x-x509-ca-cert - 0.000000 F F 897 - 0 0 F - 2e7db2a31d0e3da4b25f49b9542a2e1a 7359755c6df9a0abc3060bce369564c8ec4542a3 3c35cc963eb004451323d3275d05b353235053490d9cd83729a2faf5e7ca1cc0
|
XXXXXXXXXX.XXXXXX Ftmyeg2qgI2V38Dt3g CHhAvVGS1DHFjwGM9 192.168.4.149 60623 74.125.239.129 443 SSL 0 X509,SHA256,SHA1,MD5 application/x-x509-ca-cert - 0.000000 F F 897 - 0 0 F - 2e7db2a31d0e3da4b25f49b9542a2e1a 7359755c6df9a0abc3060bce369564c8ec4542a3 3c35cc963eb004451323d3275d05b353235053490d9cd83729a2faf5e7ca1cc0
|
||||||
XXXXXXXXXX.XXXXXX FUFNf84cduA0IJCp07 ClEkJM2Vm5giqnMf4h 192.168.4.149 60624 74.125.239.129 443 SSL 0 SHA256,X509,SHA1,MD5 application/x-x509-user-cert - 0.000000 F F 1859 - 0 0 F - 7af07aca6d5c6e8e87fe4bb34786edc0 548b9e03bc183d1cd39f93a37985cb3950f8f06f 6bacfa4536150ed996f2b0c05ab6e345a257225f449aeb9d2018ccd88f4ede43
|
XXXXXXXXXX.XXXXXX FUFNf84cduA0IJCp07 ClEkJM2Vm5giqnMf4h 192.168.4.149 60624 74.125.239.129 443 SSL 0 X509,SHA256,SHA1,MD5 application/x-x509-user-cert - 0.000000 F F 1859 - 0 0 F - 7af07aca6d5c6e8e87fe4bb34786edc0 548b9e03bc183d1cd39f93a37985cb3950f8f06f 6bacfa4536150ed996f2b0c05ab6e345a257225f449aeb9d2018ccd88f4ede43
|
||||||
XXXXXXXXXX.XXXXXX F1H4bd2OKGbLPEdHm4 ClEkJM2Vm5giqnMf4h 192.168.4.149 60624 74.125.239.129 443 SSL 0 SHA256,X509,SHA1,MD5 application/x-x509-ca-cert - 0.000000 F F 1032 - 0 0 F - 9e4ac96474245129d9766700412a1f89 d83c1a7f4d0446bb2081b81a1670f8183451ca24 a047a37fa2d2e118a4f5095fe074d6cfe0e352425a7632bf8659c03919a6c81d
|
XXXXXXXXXX.XXXXXX F1H4bd2OKGbLPEdHm4 ClEkJM2Vm5giqnMf4h 192.168.4.149 60624 74.125.239.129 443 SSL 0 X509,SHA256,SHA1,MD5 application/x-x509-ca-cert - 0.000000 F F 1032 - 0 0 F - 9e4ac96474245129d9766700412a1f89 d83c1a7f4d0446bb2081b81a1670f8183451ca24 a047a37fa2d2e118a4f5095fe074d6cfe0e352425a7632bf8659c03919a6c81d
|
||||||
XXXXXXXXXX.XXXXXX Fgsbci2jxFXYMOHOhi ClEkJM2Vm5giqnMf4h 192.168.4.149 60624 74.125.239.129 443 SSL 0 SHA256,X509,SHA1,MD5 application/x-x509-ca-cert - 0.000000 F F 897 - 0 0 F - 2e7db2a31d0e3da4b25f49b9542a2e1a 7359755c6df9a0abc3060bce369564c8ec4542a3 3c35cc963eb004451323d3275d05b353235053490d9cd83729a2faf5e7ca1cc0
|
XXXXXXXXXX.XXXXXX Fgsbci2jxFXYMOHOhi ClEkJM2Vm5giqnMf4h 192.168.4.149 60624 74.125.239.129 443 SSL 0 X509,SHA256,SHA1,MD5 application/x-x509-ca-cert - 0.000000 F F 897 - 0 0 F - 2e7db2a31d0e3da4b25f49b9542a2e1a 7359755c6df9a0abc3060bce369564c8ec4542a3 3c35cc963eb004451323d3275d05b353235053490d9cd83729a2faf5e7ca1cc0
|
||||||
#close XXXX-XX-XX-XX-XX-XX
|
#close XXXX-XX-XX-XX-XX-XX
|
||||||
|
|
|
@ -1,2 +1,3 @@
|
||||||
### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63.
|
### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63.
|
||||||
|
WebSocket::configure_analyzer, CHhAvVGS1DHFjwGM9, 7, x-kaazing-handshake
|
||||||
Connection upgraded to websocket
|
Connection upgraded to websocket
|
||||||
|
|
|
@ -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 websocket
|
||||||
|
#open XXXX-XX-XX-XX-XX-XX
|
||||||
|
#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p host uri user_agent subprotocol client_protocols server_extensions client_extensions
|
||||||
|
#types time string addr port addr port string string string string vector[string] vector[string] vector[string]
|
||||||
|
XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 192.168.0.5 50798 54.148.114.85 80 sandbox.kaazing.net /echo?.kl=Y Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:54.0) Gecko/20100101 Firefox/54.0 x-kaazing-handshake x-kaazing-handshake - permessage-deflate
|
||||||
|
#close XXXX-XX-XX-XX-XX-XX
|
|
@ -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 history service
|
||||||
|
XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 ShADadfF websocket,http
|
|
@ -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 websocket
|
||||||
|
#open XXXX-XX-XX-XX-XX-XX
|
||||||
|
#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p host uri user_agent subprotocol client_protocols server_extensions client_extensions
|
||||||
|
#types time string addr port addr port string string string string vector[string] vector[string] vector[string]
|
||||||
|
XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 38776 127.0.0.1 27599 localhost:27599 /v1/messages/json Python/3.10 websockets/12.0 - - - permessage-deflate; client_max_window_bits
|
||||||
|
#close XXXX-XX-XX-XX-XX-XX
|
|
@ -0,0 +1,16 @@
|
||||||
|
### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63.
|
||||||
|
websocket_established, CHhAvVGS1DHFjwGM9, 7
|
||||||
|
websocket_frame, CHhAvVGS1DHFjwGM9, F, fin, T, rsv, 0, opcode, ping, payload_len, 4
|
||||||
|
websocket_frame_data, CHhAvVGS1DHFjwGM9, F, len, 4, data, Zeek
|
||||||
|
websocket_frame, CHhAvVGS1DHFjwGM9, T, fin, T, rsv, 0, opcode, pong, payload_len, 4
|
||||||
|
websocket_frame_data, CHhAvVGS1DHFjwGM9, T, len, 4, data, Zeek
|
||||||
|
websocket_frame, CHhAvVGS1DHFjwGM9, T, fin, T, rsv, 0, opcode, text, payload_len, 11
|
||||||
|
websocket_frame_data, CHhAvVGS1DHFjwGM9, T, len, 11, data, Hello Zeek!
|
||||||
|
websocket_frame, CHhAvVGS1DHFjwGM9, F, fin, T, rsv, 0, opcode, text, payload_len, 12
|
||||||
|
websocket_frame_data, CHhAvVGS1DHFjwGM9, F, len, 12, data, Hello there!
|
||||||
|
websocket_frame, CHhAvVGS1DHFjwGM9, T, fin, T, rsv, 0, opcode, close, payload_len, 2
|
||||||
|
websocket_frame_data, CHhAvVGS1DHFjwGM9, T, len, 2, data, \x03\xe8
|
||||||
|
websocket_close, CHhAvVGS1DHFjwGM9, T, status, 1000, reason,
|
||||||
|
websocket_frame, CHhAvVGS1DHFjwGM9, F, fin, T, rsv, 0, opcode, close, payload_len, 2
|
||||||
|
websocket_frame_data, CHhAvVGS1DHFjwGM9, F, len, 2, data, \x03\xe8
|
||||||
|
websocket_close, CHhAvVGS1DHFjwGM9, F, status, 1000, reason,
|
|
@ -0,0 +1,16 @@
|
||||||
|
### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63.
|
||||||
|
websocket_established, CHhAvVGS1DHFjwGM9, 7
|
||||||
|
websocket_frame, CHhAvVGS1DHFjwGM9, F, fin, T, rsv, 0, opcode, ping, payload_len, 4
|
||||||
|
websocket_frame_data, CHhAvVGS1DHFjwGM9, F, len, 4, data, Zeek
|
||||||
|
websocket_frame, CHhAvVGS1DHFjwGM9, T, fin, T, rsv, 0, opcode, pong, payload_len, 4
|
||||||
|
websocket_frame_data, CHhAvVGS1DHFjwGM9, T, len, 4, data, Zeek
|
||||||
|
websocket_frame, CHhAvVGS1DHFjwGM9, T, fin, T, rsv, 0, opcode, text, payload_len, 11
|
||||||
|
websocket_frame_data, CHhAvVGS1DHFjwGM9, T, len, 11, data, Hello Zeek!
|
||||||
|
websocket_frame, CHhAvVGS1DHFjwGM9, F, fin, T, rsv, 0, opcode, text, payload_len, 12
|
||||||
|
websocket_frame_data, CHhAvVGS1DHFjwGM9, F, len, 12, data, Hello there!
|
||||||
|
websocket_frame, CHhAvVGS1DHFjwGM9, T, fin, T, rsv, 0, opcode, close, payload_len, 2
|
||||||
|
websocket_frame_data, CHhAvVGS1DHFjwGM9, T, len, 2, data, \x03\xe8
|
||||||
|
websocket_close, CHhAvVGS1DHFjwGM9, T, status, 1000, reason,
|
||||||
|
websocket_frame, CHhAvVGS1DHFjwGM9, F, fin, T, rsv, 0, opcode, close, payload_len, 2
|
||||||
|
websocket_frame_data, CHhAvVGS1DHFjwGM9, F, len, 2, data, \x03\xe8
|
||||||
|
websocket_close, CHhAvVGS1DHFjwGM9, F, status, 1000, reason,
|
|
@ -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 45838 127.0.0.1 8080 protocol_data_with_HTTP_upgrade_reply 6 F zeek HTTP
|
||||||
|
#close XXXX-XX-XX-XX-XX-XX
|
|
@ -0,0 +1,128 @@
|
||||||
|
### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63.
|
||||||
|
jupyter-websocket.pcap
|
||||||
|
websocket_established, CHhAvVGS1DHFjwGM9, 7, [ts=XXXXXXXXXX.XXXXXX, uid=CHhAvVGS1DHFjwGM9, id=[orig_h=127.0.0.1, orig_p=40492/tcp, resp_h=127.0.0.1, resp_p=51185/tcp], host=192.168.122.182, uri=/user/christian/api/kernels/f8645ecd-0a76-4bb1-9e6e-cb464276bc69/channels?session_id=deeecee7-efc2-42a1-a7c1-e1c0569436e3, user_agent=Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/118.0, subprotocol=v1.kernel.websocket.jupyter.org, client_protocols=[v1.kernel.websocket.jupyter.org], server_extensions=<uninitialized>, client_extensions=[permessage-deflate], client_key=7K5Qx7HwJUsja5KzBhGvfQ==, server_accept=USseDip1PofjB67M6I5CNkbYbp0=]
|
||||||
|
websocket_frame, CHhAvVGS1DHFjwGM9, T, fin, T, rsv, 0, opcode, binary, payload_len, 262
|
||||||
|
websocket_frame_data, CHhAvVGS1DHFjwGM9, T, len, 262, data, \x06\x00\x00\x00\x00\x00\x00\x008\x00\x00\x00\x00\x00\x00\x00=\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x02\x01\x00\x00\x00\x00\x00\x00\x04\x01\x00\x00\x00\x00\x00\x00\x06\x01\x00\x00\x00\x00\x00\x00shell{"date":"2023-09-29T23:25:05.568Z","msg_id":"5af8fd02-14a1-
|
||||||
|
websocket_message, CHhAvVGS1DHFjwGM9, T, opcode, binary
|
||||||
|
websocket_frame, CHhAvVGS1DHFjwGM9, F, fin, T, rsv, 0, opcode, binary, payload_len, 539
|
||||||
|
websocket_frame_data, CHhAvVGS1DHFjwGM9, F, len, 539, data, \x06\x00\x00\x00\x00\x00\x00\x008\x00\x00\x00\x00\x00\x00\x00=\x00\x00\x00\x00\x00\x00\x00\x14\x01\x00\x00\x00\x00\x00\x00\xfe\x01\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x1b\x02\x00\x00\x00\x00\x00\x00iopub{"msg_id": "5accb611-84744090d18c920147a97eb5_25702_7", "ms
|
||||||
|
websocket_message, CHhAvVGS1DHFjwGM9, F, opcode, binary
|
||||||
|
websocket_frame, CHhAvVGS1DHFjwGM9, F, fin, T, rsv, 0, opcode, binary, payload_len, 527
|
||||||
|
websocket_frame_data, CHhAvVGS1DHFjwGM9, F, len, 527, data, \x06\x00\x00\x00\x00\x00\x00\x008\x00\x00\x00\x00\x00\x00\x00=\x00\x00\x00\x00\x00\x00\x00\x14\x01\x00\x00\x00\x00\x00\x00\xf2\x01\x00\x00\x00\x00\x00\x00\xf4\x01\x00\x00\x00\x00\x00\x00\x0f\x02\x00\x00\x00\x00\x00\x00iopub{"msg_id": "5accb611-84744090d18c920147a97eb5_25702_9", "ms
|
||||||
|
websocket_message, CHhAvVGS1DHFjwGM9, F, opcode, binary
|
||||||
|
websocket_frame, CHhAvVGS1DHFjwGM9, F, fin, T, rsv, 0, opcode, binary, payload_len, 1647
|
||||||
|
websocket_frame_data, CHhAvVGS1DHFjwGM9, F, len, 1647, data, \x06\x00\x00\x00\x00\x00\x00\x008\x00\x00\x00\x00\x00\x00\x00=\x00\x00\x00\x00\x00\x00\x00 \x01\x00\x00\x00\x00\x00\x00\xf1\x01\x00\x00\x00\x00\x00\x00\xf3\x01\x00\x00\x00\x00\x00\x00o\x06\x00\x00\x00\x00\x00\x00shell{"msg_id": "5accb611-84744090d18c920147a97eb5_25702_14", "m
|
||||||
|
websocket_message, CHhAvVGS1DHFjwGM9, F, opcode, binary
|
||||||
|
websocket_frame, CHhAvVGS1DHFjwGM9, F, fin, T, rsv, 0, opcode, binary, payload_len, 540
|
||||||
|
websocket_frame_data, CHhAvVGS1DHFjwGM9, F, len, 540, data, \x06\x00\x00\x00\x00\x00\x00\x008\x00\x00\x00\x00\x00\x00\x00=\x00\x00\x00\x00\x00\x00\x00\x15\x01\x00\x00\x00\x00\x00\x00\xff\x01\x00\x00\x00\x00\x00\x00\x01\x02\x00\x00\x00\x00\x00\x00\x1c\x02\x00\x00\x00\x00\x00\x00iopub{"msg_id": "5accb611-84744090d18c920147a97eb5_25702_10", "m
|
||||||
|
websocket_message, CHhAvVGS1DHFjwGM9, F, opcode, binary
|
||||||
|
websocket_frame, CHhAvVGS1DHFjwGM9, F, fin, T, rsv, 0, opcode, binary, payload_len, 540
|
||||||
|
websocket_frame_data, CHhAvVGS1DHFjwGM9, F, len, 540, data, \x06\x00\x00\x00\x00\x00\x00\x008\x00\x00\x00\x00\x00\x00\x00=\x00\x00\x00\x00\x00\x00\x00\x15\x01\x00\x00\x00\x00\x00\x00\xff\x01\x00\x00\x00\x00\x00\x00\x01\x02\x00\x00\x00\x00\x00\x00\x1c\x02\x00\x00\x00\x00\x00\x00iopub{"msg_id": "5accb611-84744090d18c920147a97eb5_25702_12", "m
|
||||||
|
websocket_message, CHhAvVGS1DHFjwGM9, F, opcode, binary
|
||||||
|
websocket_frame, CHhAvVGS1DHFjwGM9, F, fin, T, rsv, 0, opcode, binary, payload_len, 515
|
||||||
|
websocket_frame_data, CHhAvVGS1DHFjwGM9, F, len, 515, data, \x06\x00\x00\x00\x00\x00\x00\x008\x00\x00\x00\x00\x00\x00\x00=\x00\x00\x00\x00\x00\x00\x00\x15\x01\x00\x00\x00\x00\x00\x00\xe6\x01\x00\x00\x00\x00\x00\x00\xe8\x01\x00\x00\x00\x00\x00\x00\x03\x02\x00\x00\x00\x00\x00\x00iopub{"msg_id": "5accb611-84744090d18c920147a97eb5_25702_13", "m
|
||||||
|
websocket_message, CHhAvVGS1DHFjwGM9, F, opcode, binary
|
||||||
|
websocket_frame, CHhAvVGS1DHFjwGM9, F, fin, T, rsv, 0, opcode, binary, payload_len, 515
|
||||||
|
websocket_frame_data, CHhAvVGS1DHFjwGM9, F, len, 515, data, \x06\x00\x00\x00\x00\x00\x00\x008\x00\x00\x00\x00\x00\x00\x00=\x00\x00\x00\x00\x00\x00\x00\x15\x01\x00\x00\x00\x00\x00\x00\xe6\x01\x00\x00\x00\x00\x00\x00\xe8\x01\x00\x00\x00\x00\x00\x00\x03\x02\x00\x00\x00\x00\x00\x00iopub{"msg_id": "5accb611-84744090d18c920147a97eb5_25702_15", "m
|
||||||
|
websocket_message, CHhAvVGS1DHFjwGM9, F, opcode, binary
|
||||||
|
websocket_frame, CHhAvVGS1DHFjwGM9, F, fin, T, rsv, 0, opcode, binary, payload_len, 540
|
||||||
|
websocket_frame_data, CHhAvVGS1DHFjwGM9, F, len, 540, data, \x06\x00\x00\x00\x00\x00\x00\x008\x00\x00\x00\x00\x00\x00\x00=\x00\x00\x00\x00\x00\x00\x00\x15\x01\x00\x00\x00\x00\x00\x00\xff\x01\x00\x00\x00\x00\x00\x00\x01\x02\x00\x00\x00\x00\x00\x00\x1c\x02\x00\x00\x00\x00\x00\x00iopub{"msg_id": "5accb611-84744090d18c920147a97eb5_25702_16", "m
|
||||||
|
websocket_message, CHhAvVGS1DHFjwGM9, F, opcode, binary
|
||||||
|
websocket_frame, CHhAvVGS1DHFjwGM9, F, fin, T, rsv, 0, opcode, binary, payload_len, 540
|
||||||
|
websocket_frame_data, CHhAvVGS1DHFjwGM9, F, len, 540, data, \x06\x00\x00\x00\x00\x00\x00\x008\x00\x00\x00\x00\x00\x00\x00=\x00\x00\x00\x00\x00\x00\x00\x15\x01\x00\x00\x00\x00\x00\x00\xff\x01\x00\x00\x00\x00\x00\x00\x01\x02\x00\x00\x00\x00\x00\x00\x1c\x02\x00\x00\x00\x00\x00\x00iopub{"msg_id": "5accb611-84744090d18c920147a97eb5_25702_18", "m
|
||||||
|
websocket_message, CHhAvVGS1DHFjwGM9, F, opcode, binary
|
||||||
|
websocket_frame, CHhAvVGS1DHFjwGM9, F, fin, T, rsv, 0, opcode, binary, payload_len, 540
|
||||||
|
websocket_frame_data, CHhAvVGS1DHFjwGM9, F, len, 540, data, \x06\x00\x00\x00\x00\x00\x00\x008\x00\x00\x00\x00\x00\x00\x00=\x00\x00\x00\x00\x00\x00\x00\x15\x01\x00\x00\x00\x00\x00\x00\xff\x01\x00\x00\x00\x00\x00\x00\x01\x02\x00\x00\x00\x00\x00\x00\x1c\x02\x00\x00\x00\x00\x00\x00iopub{"msg_id": "5accb611-84744090d18c920147a97eb5_25702_20", "m
|
||||||
|
websocket_message, CHhAvVGS1DHFjwGM9, F, opcode, binary
|
||||||
|
websocket_frame, CHhAvVGS1DHFjwGM9, F, fin, T, rsv, 0, opcode, binary, payload_len, 540
|
||||||
|
websocket_frame_data, CHhAvVGS1DHFjwGM9, F, len, 540, data, \x06\x00\x00\x00\x00\x00\x00\x008\x00\x00\x00\x00\x00\x00\x00=\x00\x00\x00\x00\x00\x00\x00\x15\x01\x00\x00\x00\x00\x00\x00\xff\x01\x00\x00\x00\x00\x00\x00\x01\x02\x00\x00\x00\x00\x00\x00\x1c\x02\x00\x00\x00\x00\x00\x00iopub{"msg_id": "5accb611-84744090d18c920147a97eb5_25702_21", "m
|
||||||
|
websocket_message, CHhAvVGS1DHFjwGM9, F, opcode, binary
|
||||||
|
websocket_frame, CHhAvVGS1DHFjwGM9, T, fin, T, rsv, 0, opcode, close, payload_len, 0
|
||||||
|
websocket_close, CHhAvVGS1DHFjwGM9, T, status, 0, reason,
|
||||||
|
websocket_message, CHhAvVGS1DHFjwGM9, T, opcode, close
|
||||||
|
websocket_frame, CHhAvVGS1DHFjwGM9, F, fin, T, rsv, 0, opcode, close, payload_len, 0
|
||||||
|
websocket_close, CHhAvVGS1DHFjwGM9, F, status, 0, reason,
|
||||||
|
websocket_message, CHhAvVGS1DHFjwGM9, F, opcode, close
|
||||||
|
wstunnel-http.pcap
|
||||||
|
websocket_established, CHhAvVGS1DHFjwGM9, 7, [ts=XXXXXXXXXX.XXXXXX, uid=CHhAvVGS1DHFjwGM9, id=[orig_h=127.0.0.1, orig_p=51102/tcp, resp_h=127.0.0.1, resp_p=8888/tcp], host=localhost:8888, uri=/v1/events, user_agent=<uninitialized>, subprotocol=v1, client_protocols=[v1, authorization.bearer.eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6IjAxOGNmZWFiLWY5OWQtNzBmNy05NmFmLTBlOGJhNjk2YTFmNiIsInAiOiJUY3AiLCJyIjoiemVlay5vcmciLCJycCI6ODB9.FsquetBp_jsIDzBslWyyTPlS2hcMprVuWmbT2r57N0A], server_extensions=<uninitialized>, client_extensions=<uninitialized>, client_key=FdRecb4tsolqJgO+HrbUfg==, server_accept=PbXiEPoL5O2wxc6/MdNHnSOXy+c=]
|
||||||
|
websocket_frame, CHhAvVGS1DHFjwGM9, T, fin, T, rsv, 0, opcode, binary, payload_len, 72
|
||||||
|
websocket_frame_data, CHhAvVGS1DHFjwGM9, T, len, 72, data, GET / HTTP/1.1\x0d\x0aHost: zeek.org\x0d\x0aUser-Agent: curl/7.81.0\x0d\x0aAccept: */*\x0d\x0a\x0d\x0a
|
||||||
|
websocket_message, CHhAvVGS1DHFjwGM9, T, opcode, binary
|
||||||
|
websocket_frame, CHhAvVGS1DHFjwGM9, F, fin, T, rsv, 0, opcode, binary, payload_len, 409
|
||||||
|
websocket_frame_data, CHhAvVGS1DHFjwGM9, F, len, 409, data, HTTP/1.1 301 Moved Permanently\x0d\x0aServer: nginx\x0d\x0aDate: Fri, 12 Jan 2024 17:15:32 GMT\x0d\x0aContent-Type: text/html\x0d\x0aContent-Len
|
||||||
|
websocket_message, CHhAvVGS1DHFjwGM9, F, opcode, binary
|
||||||
|
websocket_frame, CHhAvVGS1DHFjwGM9, T, fin, T, rsv, 0, opcode, close, payload_len, 2
|
||||||
|
websocket_frame_data, CHhAvVGS1DHFjwGM9, T, len, 2, data, \x03\xe8
|
||||||
|
websocket_close, CHhAvVGS1DHFjwGM9, T, status, 1000, reason,
|
||||||
|
websocket_message, CHhAvVGS1DHFjwGM9, T, opcode, close
|
||||||
|
websocket_frame, CHhAvVGS1DHFjwGM9, F, fin, T, rsv, 0, opcode, close, payload_len, 2
|
||||||
|
websocket_frame_data, CHhAvVGS1DHFjwGM9, F, len, 2, data, \x03\xe8
|
||||||
|
websocket_close, CHhAvVGS1DHFjwGM9, F, status, 1000, reason,
|
||||||
|
websocket_message, CHhAvVGS1DHFjwGM9, F, opcode, close
|
||||||
|
broker-websocket.pcap
|
||||||
|
websocket_established, CHhAvVGS1DHFjwGM9, 7, [ts=XXXXXXXXXX.XXXXXX, uid=CHhAvVGS1DHFjwGM9, id=[orig_h=127.0.0.1, orig_p=38776/tcp, resp_h=127.0.0.1, resp_p=27599/tcp], host=localhost:27599, uri=/v1/messages/json, user_agent=Python/3.10 websockets/12.0, subprotocol=<uninitialized>, client_protocols=<uninitialized>, server_extensions=<uninitialized>, client_extensions=[permessage-deflate; client_max_window_bits], client_key=E58pVwft35HPkD/MFCjtEA==, server_accept=HxOmr1a2nvOOc4Qiv7Ou3wrCsJc=]
|
||||||
|
websocket_frame, CHhAvVGS1DHFjwGM9, T, fin, T, rsv, 0, opcode, text, payload_len, 24
|
||||||
|
websocket_frame_data, CHhAvVGS1DHFjwGM9, T, len, 24, data, ["/zeek/event/my_topic"]
|
||||||
|
websocket_message, CHhAvVGS1DHFjwGM9, T, opcode, text
|
||||||
|
websocket_frame, CHhAvVGS1DHFjwGM9, F, fin, T, rsv, 0, opcode, text, payload_len, 91
|
||||||
|
websocket_frame_data, CHhAvVGS1DHFjwGM9, F, len, 91, data, {"type": "ack", "endpoint": "cfc03c41-7983-5fe2-b22e-6894100e6305", "version": "2.8.0-dev"}
|
||||||
|
websocket_message, CHhAvVGS1DHFjwGM9, F, opcode, text
|
||||||
|
websocket_frame, CHhAvVGS1DHFjwGM9, F, fin, T, rsv, 0, opcode, text, payload_len, 533
|
||||||
|
websocket_frame_data, CHhAvVGS1DHFjwGM9, F, len, 533, data, {"type": "data-message", "topic": "/zeek/event/my_topic", "@data-type": "vector", "data": [{"@data-type": "count", "data
|
||||||
|
websocket_message, CHhAvVGS1DHFjwGM9, F, opcode, text
|
||||||
|
websocket_frame, CHhAvVGS1DHFjwGM9, T, fin, T, rsv, 0, opcode, text, payload_len, 361
|
||||||
|
websocket_frame_data, CHhAvVGS1DHFjwGM9, T, len, 361, data, {"type": "data-message", "topic": "/zeek/event/my_topic", "@data-type": "vector", "data": [{"@data-type": "count", "data
|
||||||
|
websocket_message, CHhAvVGS1DHFjwGM9, T, opcode, text
|
||||||
|
websocket_frame, CHhAvVGS1DHFjwGM9, F, fin, T, rsv, 0, opcode, text, payload_len, 533
|
||||||
|
websocket_frame_data, CHhAvVGS1DHFjwGM9, F, len, 533, data, {"type": "data-message", "topic": "/zeek/event/my_topic", "@data-type": "vector", "data": [{"@data-type": "count", "data
|
||||||
|
websocket_message, CHhAvVGS1DHFjwGM9, F, opcode, text
|
||||||
|
websocket_frame, CHhAvVGS1DHFjwGM9, T, fin, T, rsv, 0, opcode, text, payload_len, 361
|
||||||
|
websocket_frame_data, CHhAvVGS1DHFjwGM9, T, len, 361, data, {"type": "data-message", "topic": "/zeek/event/my_topic", "@data-type": "vector", "data": [{"@data-type": "count", "data
|
||||||
|
websocket_message, CHhAvVGS1DHFjwGM9, T, opcode, text
|
||||||
|
websocket_frame, CHhAvVGS1DHFjwGM9, F, fin, T, rsv, 0, opcode, text, payload_len, 533
|
||||||
|
websocket_frame_data, CHhAvVGS1DHFjwGM9, F, len, 533, data, {"type": "data-message", "topic": "/zeek/event/my_topic", "@data-type": "vector", "data": [{"@data-type": "count", "data
|
||||||
|
websocket_message, CHhAvVGS1DHFjwGM9, F, opcode, text
|
||||||
|
websocket_frame, CHhAvVGS1DHFjwGM9, T, fin, T, rsv, 0, opcode, text, payload_len, 361
|
||||||
|
websocket_frame_data, CHhAvVGS1DHFjwGM9, T, len, 361, data, {"type": "data-message", "topic": "/zeek/event/my_topic", "@data-type": "vector", "data": [{"@data-type": "count", "data
|
||||||
|
websocket_message, CHhAvVGS1DHFjwGM9, T, opcode, text
|
||||||
|
websocket_frame, CHhAvVGS1DHFjwGM9, T, fin, T, rsv, 0, opcode, close, payload_len, 2
|
||||||
|
websocket_frame_data, CHhAvVGS1DHFjwGM9, T, len, 2, data, \x03\xe8
|
||||||
|
websocket_close, CHhAvVGS1DHFjwGM9, T, status, 1000, reason,
|
||||||
|
websocket_message, CHhAvVGS1DHFjwGM9, T, opcode, close
|
||||||
|
message-too-big-status.pcap
|
||||||
|
websocket_established, CHhAvVGS1DHFjwGM9, 7, [ts=XXXXXXXXXX.XXXXXX, uid=CHhAvVGS1DHFjwGM9, id=[orig_h=127.0.0.1, orig_p=60956/tcp, resp_h=127.0.0.1, resp_p=8080/tcp], host=localhost:8080, uri=/, user_agent=Python/3.10 websockets/12.0, subprotocol=v1, client_protocols=[v1], server_extensions=<uninitialized>, client_extensions=[permessage-deflate; client_max_window_bits], client_key=iTel1Ova5Nhz/G7VlI2qKg==, server_accept=YsQYYLj7ZCpzTLsVLb+w/ydy79E=]
|
||||||
|
websocket_frame, CHhAvVGS1DHFjwGM9, F, fin, T, rsv, 0, opcode, ping, payload_len, 4
|
||||||
|
websocket_frame_data, CHhAvVGS1DHFjwGM9, F, len, 4, data, Zeek
|
||||||
|
websocket_message, CHhAvVGS1DHFjwGM9, F, opcode, ping
|
||||||
|
websocket_frame, CHhAvVGS1DHFjwGM9, T, fin, T, rsv, 0, opcode, close, payload_len, 31
|
||||||
|
websocket_frame_data, CHhAvVGS1DHFjwGM9, T, len, 31, data, \x03\xf1over size limit (4 > 2 bytes)
|
||||||
|
websocket_close, CHhAvVGS1DHFjwGM9, T, status, 1009, reason, over size limit (4 > 2 bytes)
|
||||||
|
websocket_message, CHhAvVGS1DHFjwGM9, T, opcode, close
|
||||||
|
websocket_frame, CHhAvVGS1DHFjwGM9, F, fin, T, rsv, 0, opcode, close, payload_len, 2
|
||||||
|
websocket_frame_data, CHhAvVGS1DHFjwGM9, F, len, 2, data, \x03\xe8
|
||||||
|
websocket_close, CHhAvVGS1DHFjwGM9, F, status, 1000, reason,
|
||||||
|
websocket_message, CHhAvVGS1DHFjwGM9, F, opcode, close
|
||||||
|
two-binary-fragments.pcap
|
||||||
|
websocket_established, CHhAvVGS1DHFjwGM9, 7, [ts=XXXXXXXXXX.XXXXXX, uid=CHhAvVGS1DHFjwGM9, id=[orig_h=127.0.0.1, orig_p=50198/tcp, resp_h=127.0.0.1, resp_p=8080/tcp], host=localhost:8080, uri=/, user_agent=Python/3.10 websockets/12.0, subprotocol=v1, client_protocols=[v1], server_extensions=<uninitialized>, client_extensions=[permessage-deflate; client_max_window_bits], client_key=cQGA5Z1nvyUJ9XOVIaLaQA==, server_accept=zWaHVUKxEGPDs+xJeKtzkE1bm54=]
|
||||||
|
websocket_frame, CHhAvVGS1DHFjwGM9, F, fin, T, rsv, 0, opcode, ping, payload_len, 4
|
||||||
|
websocket_frame_data, CHhAvVGS1DHFjwGM9, F, len, 4, data, Zeek
|
||||||
|
websocket_message, CHhAvVGS1DHFjwGM9, F, opcode, ping
|
||||||
|
websocket_frame, CHhAvVGS1DHFjwGM9, T, fin, T, rsv, 0, opcode, pong, payload_len, 4
|
||||||
|
websocket_frame_data, CHhAvVGS1DHFjwGM9, T, len, 4, data, Zeek
|
||||||
|
websocket_message, CHhAvVGS1DHFjwGM9, T, opcode, pong
|
||||||
|
websocket_frame, CHhAvVGS1DHFjwGM9, T, fin, T, rsv, 0, opcode, binary, payload_len, 11
|
||||||
|
websocket_frame_data, CHhAvVGS1DHFjwGM9, T, len, 11, data, Hello Zeek!
|
||||||
|
websocket_message, CHhAvVGS1DHFjwGM9, T, opcode, binary
|
||||||
|
websocket_frame, CHhAvVGS1DHFjwGM9, F, fin, F, rsv, 0, opcode, binary, payload_len, 5
|
||||||
|
websocket_frame_data, CHhAvVGS1DHFjwGM9, F, len, 5, data, Hello
|
||||||
|
websocket_frame, CHhAvVGS1DHFjwGM9, F, fin, T, rsv, 0, opcode, continuation, payload_len, 7
|
||||||
|
websocket_frame_data, CHhAvVGS1DHFjwGM9, F, len, 7, data, there!
|
||||||
|
websocket_message, CHhAvVGS1DHFjwGM9, F, opcode, binary
|
||||||
|
websocket_frame, CHhAvVGS1DHFjwGM9, T, fin, T, rsv, 0, opcode, close, payload_len, 2
|
||||||
|
websocket_frame_data, CHhAvVGS1DHFjwGM9, T, len, 2, data, \x03\xe8
|
||||||
|
websocket_close, CHhAvVGS1DHFjwGM9, T, status, 1000, reason,
|
||||||
|
websocket_message, CHhAvVGS1DHFjwGM9, T, opcode, close
|
||||||
|
websocket_frame, CHhAvVGS1DHFjwGM9, F, fin, T, rsv, 0, opcode, close, payload_len, 2
|
||||||
|
websocket_frame_data, CHhAvVGS1DHFjwGM9, F, len, 2, data, \x03\xe8
|
||||||
|
websocket_close, CHhAvVGS1DHFjwGM9, F, status, 1000, reason,
|
||||||
|
websocket_message, CHhAvVGS1DHFjwGM9, F, opcode, close
|
|
@ -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 history service
|
||||||
|
XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 ShADadfF websocket,http
|
|
@ -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 websocket
|
||||||
|
#open XXXX-XX-XX-XX-XX-XX
|
||||||
|
#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p host uri user_agent subprotocol client_protocols server_extensions client_extensions
|
||||||
|
#types time string addr port addr port string string string string vector[string] vector[string] vector[string]
|
||||||
|
XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 40492 127.0.0.1 51185 192.168.122.182 /user/christian/api/kernels/f8645ecd-0a76-4bb1-9e6e-cb464276bc69/channels?session_id=deeecee7-efc2-42a1-a7c1-e1c0569436e3 Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/118.0 v1.kernel.websocket.jupyter.org v1.kernel.websocket.jupyter.org - permessage-deflate
|
||||||
|
#close XXXX-XX-XX-XX-XX-XX
|
|
@ -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 websocket
|
||||||
|
#open XXXX-XX-XX-XX-XX-XX
|
||||||
|
#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p host uri user_agent subprotocol client_protocols server_extensions client_extensions
|
||||||
|
#types time string addr port addr port string string string string vector[string] vector[string] vector[string]
|
||||||
|
XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 53654 127.0.0.1 8080 localhost:8080 / Python/3.10 websockets/12.0 v1 v1 - permessage-deflate; client_max_window_bits
|
||||||
|
#close XXXX-XX-XX-XX-XX-XX
|
|
@ -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 53654 127.0.0.1 8080 websocket_wrong_accept_header expected=N8ntNYkX6Qerw4tK3s/CYzpSZNc=, found=N8ntNYkX6Qerw4tK3s/CYzpSZNc=-wrong F zeek WebSocket
|
||||||
|
#close XXXX-XX-XX-XX-XX-XX
|
|
@ -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 history service
|
||||||
|
XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 ShADadFR websocket,http
|
|
@ -0,0 +1,4 @@
|
||||||
|
### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63.
|
||||||
|
ts uid host uri status_code user_agent
|
||||||
|
XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 localhost:8888 /v1/events 301 -
|
||||||
|
XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 zeek.org / - curl/7.81.0
|
|
@ -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 websocket
|
||||||
|
#open XXXX-XX-XX-XX-XX-XX
|
||||||
|
#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p host uri user_agent subprotocol client_protocols server_extensions client_extensions
|
||||||
|
#types time string addr port addr port string string string string vector[string] vector[string] vector[string]
|
||||||
|
XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 51102 127.0.0.1 8888 localhost:8888 /v1/events - v1 v1,authorization.bearer.eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6IjAxOGNmZWFiLWY5OWQtNzBmNy05NmFmLTBlOGJhNjk2YTFmNiIsInAiOiJUY3AiLCJyIjoiemVlay5vcmciLCJycCI6ODB9.FsquetBp_jsIDzBslWyyTPlS2hcMprVuWmbT2r57N0A - -
|
||||||
|
#close XXXX-XX-XX-XX-XX-XX
|
|
@ -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 history service
|
||||||
|
XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 ShADadFR websocket,ssl,http
|
|
@ -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 version server_name ssl_history
|
||||||
|
XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 TLSv13 zeek.org CsiI
|
|
@ -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 websocket
|
||||||
|
#open XXXX-XX-XX-XX-XX-XX
|
||||||
|
#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p host uri user_agent subprotocol client_protocols server_extensions client_extensions
|
||||||
|
#types time string addr port addr port string string string string vector[string] vector[string] vector[string]
|
||||||
|
XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 39992 127.0.0.1 8888 localhost:8888 /v1/events - v1 v1,authorization.bearer.eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6IjAxOGQwNTY1LTlmZTItNzFkZS1iNjRlLTU5MzhmZTI0ZmIyZCIsInAiOiJUY3AiLCJyIjoiMTkyLjAuNzguMTUwIiwicnAiOjQ0M30.xyDNRR4kK4fQSGfEyGzuUINn0xBVltxrFVBieMlqwEI - -
|
||||||
|
#close XXXX-XX-XX-XX-XX-XX
|
|
@ -0,0 +1,4 @@
|
||||||
|
### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63.
|
||||||
|
ts uid history service
|
||||||
|
XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 ShADadR http
|
||||||
|
XXXXXXXXXX.XXXXXX ClEkJM2Vm5giqnMf4h ShADadR http
|
|
@ -0,0 +1,5 @@
|
||||||
|
### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63.
|
||||||
|
WebSocket::configure_analyzer, CHhAvVGS1DHFjwGM9, 7
|
||||||
|
disabling_analyzer, CHhAvVGS1DHFjwGM9, Analyzer::ANALYZER_WEBSOCKET, 7
|
||||||
|
WebSocket::configure_analyzer, ClEkJM2Vm5giqnMf4h, 14
|
||||||
|
disabling_analyzer, ClEkJM2Vm5giqnMf4h, Analyzer::ANALYZER_WEBSOCKET, 14
|
|
@ -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 websocket
|
||||||
|
#open XXXX-XX-XX-XX-XX-XX
|
||||||
|
#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p host uri user_agent subprotocol client_protocols server_extensions client_extensions
|
||||||
|
#types time string addr port addr port string string string string vector[string] vector[string] vector[string]
|
||||||
|
XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 42906 127.0.0.1 8888 localhost:8888 /v1/events - v1 v1,authorization.bearer.eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6IjAxOGQwNTVkLTQ5OTgtNzI5Zi04Yjg2LTMwZTBiZWEyZGE4ZiIsInAiOiJUY3AiLCJyIjoiMTk1LjIwMS4xNDguMjA5IiwicnAiOjIyfQ.jjTNJL12tQbAuhTB9p_geFXRkEHkxcvOS6zf76qDklQ - -
|
||||||
|
XXXXXXXXXX.XXXXXX ClEkJM2Vm5giqnMf4h 127.0.0.1 46796 127.0.0.1 8888 localhost:8888 /v1/events - v1 v1,authorization.bearer.eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6IjAxOGQwNTVkLTc4MWYtNzNiYi1hZDkwLTEzNjA5NzRjY2JmMyIsInAiOiJUY3AiLCJyIjoiMTk1LjIwMS4xNDguMjA5IiwicnAiOjIyfQ.2HQ4uC23p_OYIXnQWeSZCqdA3jc_lVVH7-T5xZDPrz4 - -
|
||||||
|
#close XXXX-XX-XX-XX-XX-XX
|
|
@ -0,0 +1,4 @@
|
||||||
|
### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63.
|
||||||
|
ts uid history service
|
||||||
|
XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 ShADadR websocket,http
|
||||||
|
XXXXXXXXXX.XXXXXX ClEkJM2Vm5giqnMf4h ShADadR websocket,http
|
|
@ -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 websocket
|
||||||
|
#open XXXX-XX-XX-XX-XX-XX
|
||||||
|
#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p host uri user_agent subprotocol client_protocols server_extensions client_extensions
|
||||||
|
#types time string addr port addr port string string string string vector[string] vector[string] vector[string]
|
||||||
|
XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 42906 127.0.0.1 8888 localhost:8888 /v1/events - v1 v1,authorization.bearer.eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6IjAxOGQwNTVkLTQ5OTgtNzI5Zi04Yjg2LTMwZTBiZWEyZGE4ZiIsInAiOiJUY3AiLCJyIjoiMTk1LjIwMS4xNDguMjA5IiwicnAiOjIyfQ.jjTNJL12tQbAuhTB9p_geFXRkEHkxcvOS6zf76qDklQ - -
|
||||||
|
XXXXXXXXXX.XXXXXX ClEkJM2Vm5giqnMf4h 127.0.0.1 46796 127.0.0.1 8888 localhost:8888 /v1/events - v1 v1,authorization.bearer.eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6IjAxOGQwNTVkLTc4MWYtNzNiYi1hZDkwLTEzNjA5NzRjY2JmMyIsInAiOiJUY3AiLCJyIjoiMTk1LjIwMS4xNDguMjA5IiwicnAiOjIyfQ.2HQ4uC23p_OYIXnQWeSZCqdA3jc_lVVH7-T5xZDPrz4 - -
|
||||||
|
#close XXXX-XX-XX-XX-XX-XX
|
|
@ -0,0 +1,4 @@
|
||||||
|
### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63.
|
||||||
|
ts uid history service
|
||||||
|
XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 ShADadR websocket,ssh,http
|
||||||
|
XXXXXXXXXX.XXXXXX ClEkJM2Vm5giqnMf4h ShADadR websocket,ssh,http
|
|
@ -0,0 +1,4 @@
|
||||||
|
### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63.
|
||||||
|
ts uid client server auth_success auth_attempts kex_alg host_key_alg
|
||||||
|
XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 SSH-2.0-OpenSSH_8.9p1 Ubuntu-3ubuntu0.6 SSH-2.0-OpenSSH_8.2p1 Ubuntu-4ubuntu0.5 F 4 curve25519-sha256 ssh-ed25519
|
||||||
|
XXXXXXXXXX.XXXXXX ClEkJM2Vm5giqnMf4h SSH-2.0-OpenSSH_8.9p1 Ubuntu-3ubuntu0.6 SSH-2.0-OpenSSH_8.2p1 Ubuntu-4ubuntu0.5 T 5 curve25519-sha256 ssh-ed25519
|
|
@ -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 websocket
|
||||||
|
#open XXXX-XX-XX-XX-XX-XX
|
||||||
|
#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p host uri user_agent subprotocol client_protocols server_extensions client_extensions
|
||||||
|
#types time string addr port addr port string string string string vector[string] vector[string] vector[string]
|
||||||
|
XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 42906 127.0.0.1 8888 localhost:8888 /v1/events - v1 v1,authorization.bearer.eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6IjAxOGQwNTVkLTQ5OTgtNzI5Zi04Yjg2LTMwZTBiZWEyZGE4ZiIsInAiOiJUY3AiLCJyIjoiMTk1LjIwMS4xNDguMjA5IiwicnAiOjIyfQ.jjTNJL12tQbAuhTB9p_geFXRkEHkxcvOS6zf76qDklQ - -
|
||||||
|
XXXXXXXXXX.XXXXXX ClEkJM2Vm5giqnMf4h 127.0.0.1 46796 127.0.0.1 8888 localhost:8888 /v1/events - v1 v1,authorization.bearer.eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6IjAxOGQwNTVkLTc4MWYtNzNiYi1hZDkwLTEzNjA5NzRjY2JmMyIsInAiOiJUY3AiLCJyIjoiMTk1LjIwMS4xNDguMjA5IiwicnAiOjIyfQ.2HQ4uC23p_OYIXnQWeSZCqdA3jc_lVVH7-T5xZDPrz4 - -
|
||||||
|
#close XXXX-XX-XX-XX-XX-XX
|
|
@ -0,0 +1,4 @@
|
||||||
|
### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63.
|
||||||
|
ts uid history service
|
||||||
|
XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 ShADadR http
|
||||||
|
XXXXXXXXXX.XXXXXX ClEkJM2Vm5giqnMf4h ShADadR http
|
|
@ -0,0 +1,4 @@
|
||||||
|
### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63.
|
||||||
|
ts uid history service
|
||||||
|
XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 ShADadR websocket,ssh,http
|
||||||
|
XXXXXXXXXX.XXXXXX ClEkJM2Vm5giqnMf4h ShADadR websocket,ssh,http
|
|
@ -0,0 +1,4 @@
|
||||||
|
### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63.
|
||||||
|
ts uid client server auth_success auth_attempts kex_alg host_key_alg
|
||||||
|
XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 SSH-2.0-OpenSSH_8.9p1 Ubuntu-3ubuntu0.6 SSH-2.0-OpenSSH_8.2p1 Ubuntu-4ubuntu0.5 F 4 curve25519-sha256 ssh-ed25519
|
||||||
|
XXXXXXXXXX.XXXXXX ClEkJM2Vm5giqnMf4h SSH-2.0-OpenSSH_8.9p1 Ubuntu-3ubuntu0.6 SSH-2.0-OpenSSH_8.2p1 Ubuntu-4ubuntu0.5 T 5 curve25519-sha256 ssh-ed25519
|
|
@ -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 websocket
|
||||||
|
#open XXXX-XX-XX-XX-XX-XX
|
||||||
|
#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p host uri user_agent subprotocol client_protocols server_extensions client_extensions
|
||||||
|
#types time string addr port addr port string string string string vector[string] vector[string] vector[string]
|
||||||
|
XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 42906 127.0.0.1 8888 localhost:8888 /v1/events - v1 v1,authorization.bearer.eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6IjAxOGQwNTVkLTQ5OTgtNzI5Zi04Yjg2LTMwZTBiZWEyZGE4ZiIsInAiOiJUY3AiLCJyIjoiMTk1LjIwMS4xNDguMjA5IiwicnAiOjIyfQ.jjTNJL12tQbAuhTB9p_geFXRkEHkxcvOS6zf76qDklQ - -
|
||||||
|
XXXXXXXXXX.XXXXXX ClEkJM2Vm5giqnMf4h 127.0.0.1 46796 127.0.0.1 8888 localhost:8888 /v1/events - v1 v1,authorization.bearer.eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6IjAxOGQwNTVkLTc4MWYtNzNiYi1hZDkwLTEzNjA5NzRjY2JmMyIsInAiOiJUY3AiLCJyIjoiMTk1LjIwMS4xNDguMjA5IiwicnAiOjIyfQ.2HQ4uC23p_OYIXnQWeSZCqdA3jc_lVVH7-T5xZDPrz4 - -
|
||||||
|
#close XXXX-XX-XX-XX-XX-XX
|
BIN
testing/btest/Traces/websocket/broker-websocket.pcap
Normal file
BIN
testing/btest/Traces/websocket/broker-websocket.pcap
Normal file
Binary file not shown.
BIN
testing/btest/Traces/websocket/jupyter-websocket.pcap
Normal file
BIN
testing/btest/Traces/websocket/jupyter-websocket.pcap
Normal file
Binary file not shown.
BIN
testing/btest/Traces/websocket/message-too-big-status.pcap
Normal file
BIN
testing/btest/Traces/websocket/message-too-big-status.pcap
Normal file
Binary file not shown.
BIN
testing/btest/Traces/websocket/reply-ping-coalesced.pcap
Normal file
BIN
testing/btest/Traces/websocket/reply-ping-coalesced.pcap
Normal file
Binary file not shown.
BIN
testing/btest/Traces/websocket/reply-ping-separate.pcap
Normal file
BIN
testing/btest/Traces/websocket/reply-ping-separate.pcap
Normal file
Binary file not shown.
BIN
testing/btest/Traces/websocket/two-binary-fragments.pcap
Normal file
BIN
testing/btest/Traces/websocket/two-binary-fragments.pcap
Normal file
Binary file not shown.
BIN
testing/btest/Traces/websocket/wrong-accept-header.pcap
Normal file
BIN
testing/btest/Traces/websocket/wrong-accept-header.pcap
Normal file
Binary file not shown.
BIN
testing/btest/Traces/websocket/wstunnel-http.pcap
Normal file
BIN
testing/btest/Traces/websocket/wstunnel-http.pcap
Normal file
Binary file not shown.
BIN
testing/btest/Traces/websocket/wstunnel-https.pcap
Normal file
BIN
testing/btest/Traces/websocket/wstunnel-https.pcap
Normal file
Binary file not shown.
BIN
testing/btest/Traces/websocket/wstunnel-ssh.pcap
Normal file
BIN
testing/btest/Traces/websocket/wstunnel-ssh.pcap
Normal file
Binary file not shown.
|
@ -1,13 +1,31 @@
|
||||||
# This tests that the HTTP analyzer does not generate a dpd error as a
|
# This tests that the HTTP analyzer upgrades to the WebSocket analyzer.
|
||||||
# result of seeing an upgraded connection.
|
#
|
||||||
|
# Further, we implement a WebSocket::configure_analyzer() hook to prevent
|
||||||
|
# DPD on the inner connection.
|
||||||
#
|
#
|
||||||
# @TEST-EXEC: zeek -r $TRACES/http/websocket.pcap %INPUT
|
# @TEST-EXEC: zeek -r $TRACES/http/websocket.pcap %INPUT
|
||||||
# @TEST-EXEC: test ! -f dpd.log
|
|
||||||
# @TEST-EXEC: test ! -f weird.log
|
# @TEST-EXEC: test ! -f weird.log
|
||||||
|
# @TEST-EXEC: test ! -f dpd.log
|
||||||
# @TEST-EXEC: btest-diff http.log
|
# @TEST-EXEC: btest-diff http.log
|
||||||
|
# @TEST-EXEC: btest-diff websocket.log
|
||||||
# @TEST-EXEC: btest-diff .stdout
|
# @TEST-EXEC: btest-diff .stdout
|
||||||
|
|
||||||
event http_connection_upgrade(c: connection, protocol: string)
|
event http_connection_upgrade(c: connection, protocol: string)
|
||||||
{
|
{
|
||||||
print fmt("Connection upgraded to %s", protocol);
|
print fmt("Connection upgraded to %s", protocol);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hook WebSocket::configure_analyzer(c: connection, aid: count, config: WebSocket::AnalyzerConfig)
|
||||||
|
{
|
||||||
|
if ( ! config?$subprotocol )
|
||||||
|
return;
|
||||||
|
|
||||||
|
print "WebSocket::configure_analyzer", c$uid, aid, config$subprotocol;
|
||||||
|
if ( config$subprotocol == "x-kaazing-handshake" )
|
||||||
|
# The originator's WebSocket frames match HTTP, so DPD would
|
||||||
|
# enable HTTP for the frame's payload, but the responder's frames
|
||||||
|
# contain some ack/status junk just before HTTP response that
|
||||||
|
# trigger a violation. Disable DPD for to prevent a dpd.log
|
||||||
|
# entry.
|
||||||
|
config$use_dpd = F;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
# @TEST-DOC: Test Broker WebSocket traffic.
|
||||||
|
#
|
||||||
|
# @TEST-EXEC: zeek -b -r $TRACES/websocket/broker-websocket.pcap %INPUT
|
||||||
|
#
|
||||||
|
# @TEST-EXEC: zeek-cut -m ts uid history service < conn.log > conn.log.cut
|
||||||
|
|
||||||
|
# @TEST-EXEC: btest-diff conn.log.cut
|
||||||
|
# @TEST-EXEC: btest-diff websocket.log
|
||||||
|
# @TEST-EXEC: test ! -f analyzer.log
|
||||||
|
# @TEST-EXEC: test ! -f weird.log
|
||||||
|
|
||||||
|
@load base/protocols/conn
|
||||||
|
@load base/protocols/websocket
|
|
@ -0,0 +1,33 @@
|
||||||
|
# @TEST-DOC: The reply-ping-coalesced pcap contains a WebSocket ping message right after the HTTP reply, in the same packet.
|
||||||
|
|
||||||
|
# @TEST-EXEC: zeek -b -r $TRACES/websocket/reply-ping-separate.pcap %INPUT >>out-separate
|
||||||
|
# @TEST-EXEC: test ! -f weird.log
|
||||||
|
#
|
||||||
|
# @TEST-EXEC: zeek -b -r $TRACES/websocket/reply-ping-coalesced.pcap %INPUT >>out-coalesced
|
||||||
|
# @TEST-EXEC: btest-diff out-separate
|
||||||
|
# @TEST-EXEC: btest-diff out-coalesced
|
||||||
|
# @TEST-EXEC: btest-diff weird.log
|
||||||
|
# @TEST-EXEC: diff out-separate out-coalesced
|
||||||
|
# @TEST-EXEC: test ! -f analyzer.log
|
||||||
|
|
||||||
|
@load base/protocols/websocket
|
||||||
|
|
||||||
|
event websocket_established(c: connection, aid: count)
|
||||||
|
{
|
||||||
|
print "websocket_established", c$uid, aid;
|
||||||
|
}
|
||||||
|
|
||||||
|
event websocket_frame(c: connection, is_orig: bool, fin: bool, rsv: count, opcode: count, payload_len: count)
|
||||||
|
{
|
||||||
|
print "websocket_frame", c$uid, is_orig, "fin", fin, "rsv", rsv, "opcode", WebSocket::opcodes[opcode], "payload_len", payload_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
event websocket_frame_data(c: connection, is_orig: bool, data: string)
|
||||||
|
{
|
||||||
|
print "websocket_frame_data", c$uid, is_orig, "len", |data|, "data", data[:120];
|
||||||
|
}
|
||||||
|
|
||||||
|
event websocket_close(c: connection, is_orig: bool, status: count, reason: string)
|
||||||
|
{
|
||||||
|
print "websocket_close", c$uid, is_orig, "status", status, "reason", reason;
|
||||||
|
}
|
42
testing/btest/scripts/base/protocols/websocket/events.zeek
Normal file
42
testing/btest/scripts/base/protocols/websocket/events.zeek
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
# @TEST-DOC: Test WebSocket events.
|
||||||
|
#
|
||||||
|
# @TEST-EXEC: echo "jupyter-websocket.pcap" >>out
|
||||||
|
# @TEST-EXEC: zeek -b -r $TRACES/websocket/jupyter-websocket.pcap %INPUT >>out
|
||||||
|
# @TEST-EXEC: echo "wstunnel-http.pcap" >>out
|
||||||
|
# @TEST-EXEC: zeek -b -r $TRACES/websocket/wstunnel-http.pcap %INPUT >>out
|
||||||
|
# @TEST-EXEC: echo "broker-websocket.pcap" >>out
|
||||||
|
# @TEST-EXEC: zeek -b -r $TRACES//websocket/broker-websocket.pcap %INPUT >>out
|
||||||
|
# @TEST-EXEC: echo "message-too-big-status.pcap" >>out
|
||||||
|
# @TEST-EXEC: zeek -b -r $TRACES//websocket/message-too-big-status.pcap %INPUT >>out
|
||||||
|
# @TEST-EXEC: echo "two-binary-fragments.pcap" >>out
|
||||||
|
# @TEST-EXEC: zeek -b -r $TRACES//websocket/two-binary-fragments.pcap %INPUT >>out
|
||||||
|
# @TEST-EXEC: btest-diff out
|
||||||
|
# @TEST-EXEC: test ! -f analyzer.log
|
||||||
|
# @TEST-EXEC: test ! -f weird.log
|
||||||
|
|
||||||
|
@load base/protocols/websocket
|
||||||
|
|
||||||
|
event websocket_established(c: connection, aid: count)
|
||||||
|
{
|
||||||
|
print "websocket_established", c$uid, aid, c$websocket;
|
||||||
|
}
|
||||||
|
|
||||||
|
event websocket_message(c: connection, is_orig: bool, opcode: count)
|
||||||
|
{
|
||||||
|
print "websocket_message", c$uid, is_orig, "opcode", WebSocket::opcodes[opcode];
|
||||||
|
}
|
||||||
|
|
||||||
|
event websocket_frame(c: connection, is_orig: bool, fin: bool, rsv: count, opcode: count, payload_len: count)
|
||||||
|
{
|
||||||
|
print "websocket_frame", c$uid, is_orig, "fin", fin, "rsv", rsv, "opcode", WebSocket::opcodes[opcode], "payload_len", payload_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
event websocket_frame_data(c: connection, is_orig: bool, data: string)
|
||||||
|
{
|
||||||
|
print "websocket_frame_data", c$uid, is_orig, "len", |data|, "data", data[:120];
|
||||||
|
}
|
||||||
|
|
||||||
|
event websocket_close(c: connection, is_orig: bool, status: count, reason: string)
|
||||||
|
{
|
||||||
|
print "websocket_close", c$uid, is_orig, "status", status, "reason", reason;
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
# @TEST-DOC: Testing Jupyter WebSocket traffic.
|
||||||
|
#
|
||||||
|
# @TEST-EXEC: zeek -b -r $TRACES/websocket/jupyter-websocket.pcap %INPUT
|
||||||
|
#
|
||||||
|
# @TEST-EXEC: zeek-cut -m ts uid history service < conn.log > conn.log.cut
|
||||||
|
#
|
||||||
|
# @TEST-EXEC: btest-diff conn.log.cut
|
||||||
|
# @TEST-EXEC: btest-diff websocket.log
|
||||||
|
# @TEST-EXEC: test ! -f analyzer.log
|
||||||
|
# @TEST-EXEC: test ! -f weird.log
|
||||||
|
|
||||||
|
@load base/protocols/conn
|
||||||
|
@load base/protocols/websocket
|
|
@ -0,0 +1,7 @@
|
||||||
|
# @TEST-DOC: Test weird generation when the Sec-WebSocket-Accept socket isn't as expected.
|
||||||
|
#
|
||||||
|
# @TEST-EXEC: zeek -b -r $TRACES/websocket/wrong-accept-header.pcap %INPUT
|
||||||
|
# @TEST-EXEC: btest-diff websocket.log
|
||||||
|
# @TEST-EXEC: btest-diff weird.log
|
||||||
|
|
||||||
|
@load base/protocols/websocket
|
|
@ -0,0 +1,16 @@
|
||||||
|
# @TEST-DOC: Test HTTP connection tunneled within WebSocket using wstunnel. Seems something in the HTTP scripts gets confused :-/
|
||||||
|
#
|
||||||
|
# @TEST-EXEC: zeek -b -r $TRACES/websocket/wstunnel-http.pcap %INPUT
|
||||||
|
#
|
||||||
|
# @TEST-EXEC: zeek-cut -m ts uid history service < conn.log > conn.log.cut
|
||||||
|
# @TEST-EXEC: zeek-cut -m ts uid host uri status_code user_agent < http.log > http.log.cut
|
||||||
|
|
||||||
|
# @TEST-EXEC: btest-diff conn.log.cut
|
||||||
|
# @TEST-EXEC: btest-diff http.log.cut
|
||||||
|
# @TEST-EXEC: btest-diff websocket.log
|
||||||
|
# @TEST-EXEC: test ! -f analyzer.log
|
||||||
|
# @TEST-EXEC: test ! -f weird.log
|
||||||
|
|
||||||
|
@load base/protocols/conn
|
||||||
|
@load base/protocols/ssh
|
||||||
|
@load base/protocols/websocket
|
|
@ -0,0 +1,16 @@
|
||||||
|
# @TEST-DOC: Test SSH connection tunneled within WebSocket using wstunnel.
|
||||||
|
#
|
||||||
|
# @TEST-EXEC: zeek -b -r $TRACES/websocket/wstunnel-https.pcap %INPUT
|
||||||
|
#
|
||||||
|
# @TEST-EXEC: zeek-cut -m ts uid history service < conn.log > conn.log.cut
|
||||||
|
# @TEST-EXEC: zeek-cut -m ts uid version server_name ssl_history < ssl.log > ssl.log.cut
|
||||||
|
|
||||||
|
# @TEST-EXEC: btest-diff conn.log.cut
|
||||||
|
# @TEST-EXEC: btest-diff ssl.log.cut
|
||||||
|
# @TEST-EXEC: btest-diff websocket.log
|
||||||
|
# @TEST-EXEC: test ! -f analyzer.log
|
||||||
|
# @TEST-EXEC: test ! -f weird.log
|
||||||
|
|
||||||
|
@load base/protocols/conn
|
||||||
|
@load base/protocols/ssl
|
||||||
|
@load base/protocols/websocket
|
|
@ -0,0 +1,33 @@
|
||||||
|
# @TEST-DOC: Test that breaking from configure_analyzer() removes the attached analyzer.
|
||||||
|
#
|
||||||
|
# @TEST-EXEC: zeek -b -r $TRACES/websocket/wstunnel-ssh.pcap %INPUT >out 2>&1
|
||||||
|
#
|
||||||
|
# @TEST-EXEC: zeek-cut -m ts uid history service < conn.log > conn.log.cut
|
||||||
|
|
||||||
|
# @TEST-EXEC: btest-diff out
|
||||||
|
# @TEST-EXEC: btest-diff conn.log.cut
|
||||||
|
# @TEST-EXEC: btest-diff websocket.log
|
||||||
|
# @TEST-EXEC: test ! -f ssh.log
|
||||||
|
# @TEST-EXEC: test ! -f analyzer.log
|
||||||
|
|
||||||
|
@load base/protocols/conn
|
||||||
|
@load base/protocols/http
|
||||||
|
@load base/protocols/ssh
|
||||||
|
@load base/protocols/websocket
|
||||||
|
|
||||||
|
hook WebSocket::configure_analyzer(c: connection, aid: count, config: WebSocket::AnalyzerConfig)
|
||||||
|
{
|
||||||
|
print "WebSocket::configure_analyzer", c$uid, aid;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
# These should never be raised
|
||||||
|
event websocket_message(c: connection, is_orig: bool, opcode: count)
|
||||||
|
{
|
||||||
|
print "ERROR: websocket_message", c$uid, is_orig, "opcode", WebSocket::opcodes[opcode];
|
||||||
|
}
|
||||||
|
|
||||||
|
hook Analyzer::disabling_analyzer(c: connection, atype: AllAnalyzers::Tag, aid: count)
|
||||||
|
{
|
||||||
|
print "disabling_analyzer", c$uid, atype, aid;
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
# @TEST-DOC: Test SSH connection tunneled within WebSocket using wstunnel, attaches HTTP analyzer instead of SSH.
|
||||||
|
#
|
||||||
|
# @TEST-EXEC: zeek -b -r $TRACES/websocket/wstunnel-ssh.pcap %INPUT
|
||||||
|
#
|
||||||
|
# @TEST-EXEC: zeek-cut -m ts uid history service < conn.log > conn.log.cut
|
||||||
|
|
||||||
|
# @TEST-EXEC: btest-diff conn.log.cut
|
||||||
|
# @TEST-EXEC: btest-diff websocket.log
|
||||||
|
# @TEST-EXEC: test ! -f ssh.log
|
||||||
|
# @TEST-EXEC: test ! -f analyzer.log
|
||||||
|
|
||||||
|
@load base/protocols/conn
|
||||||
|
@load base/protocols/http
|
||||||
|
@load base/protocols/ssh
|
||||||
|
@load base/protocols/websocket
|
||||||
|
|
||||||
|
hook WebSocket::configure_analyzer(c: connection, aid: count, config: WebSocket::AnalyzerConfig)
|
||||||
|
{
|
||||||
|
print "WebSocket::configure_analyzer", c$uid, aid;
|
||||||
|
config$analyzer = Analyzer::ANALYZER_HTTP; # this is obviously wrong :-)
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
# @TEST-DOC: Test SSH connection tunneled within WebSocket using wstunnel, configure SSH analyzer via hook explicitly.
|
||||||
|
#
|
||||||
|
# @TEST-EXEC: zeek -b -r $TRACES/websocket/wstunnel-ssh.pcap %INPUT
|
||||||
|
#
|
||||||
|
# @TEST-EXEC: zeek-cut -m ts uid history service < conn.log > conn.log.cut
|
||||||
|
# @TEST-EXEC: zeek-cut -m ts uid client server auth_success auth_attempts kex_alg host_key_alg < ssh.log > ssh.log.cut
|
||||||
|
|
||||||
|
# @TEST-EXEC: btest-diff conn.log.cut
|
||||||
|
# @TEST-EXEC: btest-diff ssh.log.cut
|
||||||
|
# @TEST-EXEC: btest-diff websocket.log
|
||||||
|
# @TEST-EXEC: test ! -f analyzer.log
|
||||||
|
# @TEST-EXEC: test ! -f weird.log
|
||||||
|
|
||||||
|
@load base/protocols/conn
|
||||||
|
@load base/protocols/ssh
|
||||||
|
@load base/protocols/websocket
|
||||||
|
|
||||||
|
hook WebSocket::configure_analyzer(c: connection, aid: count, config: WebSocket::AnalyzerConfig)
|
||||||
|
{
|
||||||
|
print "WebSocket::configure_analyzer", c$uid, aid;
|
||||||
|
config$analyzer = Analyzer::ANALYZER_SSH;
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
# @TEST-DOC: Test no analysis of tunneled WebSocket when the analyzer is globally disabled.
|
||||||
|
#
|
||||||
|
# @TEST-EXEC: zeek -b -r $TRACES/websocket/wstunnel-ssh.pcap %INPUT
|
||||||
|
#
|
||||||
|
# @TEST-EXEC: zeek-cut -m ts uid history service < conn.log > conn.log.cut
|
||||||
|
|
||||||
|
# @TEST-EXEC: btest-diff conn.log.cut
|
||||||
|
# @TEST-EXEC: test ! -f websocket.log
|
||||||
|
# @TEST-EXEC: test ! -f ssh.log
|
||||||
|
# @TEST-EXEC: test ! -f analyzer.log
|
||||||
|
# @TEST-EXEC: test ! -f weird.log
|
||||||
|
|
||||||
|
@load base/protocols/conn
|
||||||
|
@load base/protocols/ssh
|
||||||
|
@load base/protocols/websocket
|
||||||
|
|
||||||
|
redef Analyzer::disabled_analyzers += {
|
||||||
|
Analyzer::ANALYZER_WEBSOCKET,
|
||||||
|
};
|
|
@ -0,0 +1,16 @@
|
||||||
|
# @TEST-DOC: Test SSH connection tunneled within WebSocket using wstunnel.
|
||||||
|
#
|
||||||
|
# @TEST-EXEC: zeek -b -r $TRACES/websocket/wstunnel-ssh.pcap %INPUT
|
||||||
|
#
|
||||||
|
# @TEST-EXEC: zeek-cut -m ts uid history service < conn.log > conn.log.cut
|
||||||
|
# @TEST-EXEC: zeek-cut -m ts uid client server auth_success auth_attempts kex_alg host_key_alg < ssh.log > ssh.log.cut
|
||||||
|
|
||||||
|
# @TEST-EXEC: btest-diff conn.log.cut
|
||||||
|
# @TEST-EXEC: btest-diff ssh.log.cut
|
||||||
|
# @TEST-EXEC: btest-diff websocket.log
|
||||||
|
# @TEST-EXEC: test ! -f analyzer.log
|
||||||
|
# @TEST-EXEC: test ! -f weird.log
|
||||||
|
|
||||||
|
@load base/protocols/conn
|
||||||
|
@load base/protocols/ssh
|
||||||
|
@load base/protocols/websocket
|
Loading…
Add table
Add a link
Reference in a new issue