mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 14:48:21 +00:00
Merge remote-tracking branch 'origin/master' into topic/johanna/spicy-tls
* origin/master: Update doc submodule [nomail] [skip ci] Analyzer: Do not add child analyzers when finished Fix parsing of version field in SSLv2 client hello TCP_Reassembler: Fix IsOrig() position in Match() call Spicy: Register well-known ports through an event handler. Update doc submodule [nomail] [skip ci] Revert "Remove deprecated port/ports fields for spicy analyzers" Make ssl_history work for SSLv2 handshakes/connections
This commit is contained in:
commit
c186726bfa
29 changed files with 404 additions and 57 deletions
77
CHANGES
77
CHANGES
|
@ -1,3 +1,80 @@
|
||||||
|
7.1.0-dev.222 | 2024-08-27 13:29:12 +0100
|
||||||
|
|
||||||
|
* Fix parsing of version field in SSLv2 client hello (Johanna Amann, Corelight)
|
||||||
|
|
||||||
|
It turns out that, for probably a long time, we have reported an
|
||||||
|
incorrect version when parsing an SSLv2 client hello. We always reported
|
||||||
|
this as SSLv2, no matter which version the client hello actually
|
||||||
|
contained.
|
||||||
|
|
||||||
|
This bug probably went unnoticed for a long time, as SSLv2 is
|
||||||
|
essentially unused nowadays, and as this field does not show up in the
|
||||||
|
default logs.
|
||||||
|
|
||||||
|
This was found due to a baseline difference when writing the Spicy SSL
|
||||||
|
analyzer.
|
||||||
|
|
||||||
|
7.1.0-dev.219 | 2024-08-23 14:18:35 +0200
|
||||||
|
|
||||||
|
* Analyzer: Do not add child analyzers when finished (Arne Welzel, Corelight)
|
||||||
|
|
||||||
|
Depending on an analyzer's implementation, its Done() method may
|
||||||
|
attempt to access analyzer or connection state when executing.
|
||||||
|
When this happens in the destructor of the parent analyzer during
|
||||||
|
the process of destructing a connection, this state may have been
|
||||||
|
deleted, resulting in use-after-free crashes or worse memory
|
||||||
|
corruption.
|
||||||
|
|
||||||
|
The following cases have been observed in the wild for when this happens.
|
||||||
|
|
||||||
|
* PIA matching during Done() for undelivered TCP data enables a Spicy
|
||||||
|
based analyzer which in turn attempts to raise an analyzer violation
|
||||||
|
during Done()->EndOfData().
|
||||||
|
|
||||||
|
* Spicy analyzers attaching new analyzers during their Done() processing
|
||||||
|
which in turn attempt to use TCP() (to call FindChild()) during Done()
|
||||||
|
while the analyzer tree / connection is being destructed.
|
||||||
|
|
||||||
|
The second scenario was previously found to happen in the HTTP analyzer
|
||||||
|
and fixed with 6ef9423f3cff13e6c73f97eb6a3a27d6f64cc320.
|
||||||
|
|
||||||
|
Plug these scenarios by short-circuiting AddChildAnalyzer() if the analyzer
|
||||||
|
or connection have finished or are being finished.
|
||||||
|
|
||||||
|
7.1.0-dev.217 | 2024-08-23 09:40:53 +0200
|
||||||
|
|
||||||
|
* TCP_Reassembler: Fix IsOrig() position in Match() call (Arne Welzel, Corelight)
|
||||||
|
|
||||||
|
Found during a debug session with @rsmmr. Undelivered TCP data
|
||||||
|
would only be matched for the responder and eol set to IsOrig().
|
||||||
|
|
||||||
|
* Spicy: Register well-known ports through an event handler. (Robin Sommer, Corelight)
|
||||||
|
|
||||||
|
This avoids the earlier problem of not tracking ports correctly in
|
||||||
|
scriptland, while still supporting `port` in EVT files and `%port` in
|
||||||
|
Spicy files.
|
||||||
|
|
||||||
|
As it turns out we are already following the same approach for file
|
||||||
|
analyzers' MIME types, so I'm applying the same pattern: it's one
|
||||||
|
event per port, without further customization points. That leaves the
|
||||||
|
patch pretty small after all while fixing the original issue.
|
||||||
|
|
||||||
|
* Revert "Remove deprecated port/ports fields for spicy analyzers" (Robin Sommer, Corelight)
|
||||||
|
|
||||||
|
This reverts commit 15d404dd191a723960e4efd956eec22739d3f1c2.
|
||||||
|
|
||||||
|
7.1.0-dev.211 | 2024-08-20 11:38:48 +0100
|
||||||
|
|
||||||
|
* Make ssl_history work for SSLv2 handshakes/connections (Johanna Amann, Corelight)
|
||||||
|
|
||||||
|
It turns out that the ssl_history field never was populated with C/S for
|
||||||
|
SSLv2 connections, or connections using the SSLv2 handshake. In our
|
||||||
|
testcases, the latter is especially common - with connections up to TLS1
|
||||||
|
using the old SSLv2 client hello for backwards compatibility.
|
||||||
|
|
||||||
|
This change resolves this issue. As the history is not by default
|
||||||
|
enabled in a lot of locations, baseline impact is minor.
|
||||||
|
|
||||||
7.1.0-dev.209 | 2024-08-20 10:10:46 +0200
|
7.1.0-dev.209 | 2024-08-20 10:10:46 +0200
|
||||||
|
|
||||||
* broker: Deprecate MakeEvent(ValPList*) (Arne Welzel, Corelight)
|
* broker: Deprecate MakeEvent(ValPList*) (Arne Welzel, Corelight)
|
||||||
|
|
2
VERSION
2
VERSION
|
@ -1 +1 @@
|
||||||
7.1.0-dev.209
|
7.1.0-dev.222
|
||||||
|
|
2
doc
2
doc
|
@ -1 +1 @@
|
||||||
Subproject commit 2f14aee921e8f7df417423079f9341e1e72c5d7e
|
Subproject commit fc15fea160a40c88ca9868a21203097b3a2b9b71
|
|
@ -47,12 +47,18 @@ export {
|
||||||
|
|
||||||
# Marked with &is_used to suppress complaints when there aren't any
|
# Marked with &is_used to suppress complaints when there aren't any
|
||||||
# Spicy file analyzers loaded, and hence this event can't be generated.
|
# Spicy file analyzers loaded, and hence this event can't be generated.
|
||||||
# The attribute is only supported for Zeek 5.0 and higher.
|
|
||||||
event spicy_analyzer_for_mime_type(a: Files::Tag, mt: string) &is_used
|
event spicy_analyzer_for_mime_type(a: Files::Tag, mt: string) &is_used
|
||||||
{
|
{
|
||||||
Files::register_for_mime_type(a, mt);
|
Files::register_for_mime_type(a, mt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Marked with &is_used to suppress complaints when there aren't any
|
||||||
|
# Spicy protocol analyzers loaded, and hence this event can't be generated.
|
||||||
|
event spicy_analyzer_for_port(a: Analyzer::Tag, p: port) &is_used
|
||||||
|
{
|
||||||
|
Analyzer::register_for_port(a, p);
|
||||||
|
}
|
||||||
|
|
||||||
function enable_protocol_analyzer(tag: Analyzer::Tag) : bool
|
function enable_protocol_analyzer(tag: Analyzer::Tag) : bool
|
||||||
{
|
{
|
||||||
return Spicy::__toggle_analyzer(tag, T);
|
return Spicy::__toggle_analyzer(tag, T);
|
||||||
|
|
|
@ -282,6 +282,13 @@ event ssl_client_hello(c: connection, version: count, record_version: count, pos
|
||||||
c$ssl$session_id = bytestring_to_hexstr(session_id);
|
c$ssl$session_id = bytestring_to_hexstr(session_id);
|
||||||
c$ssl$client_ticket_empty_session_seen = F;
|
c$ssl$client_ticket_empty_session_seen = F;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# add manually for SSLv2 client hello, since the handshake_message event is not raised, as there is no handshake protocol.
|
||||||
|
# We don't really have a direction in that case.
|
||||||
|
# SSLv2 client hello is signified by a record_layer version of 0, as the client-hello itself can indicate
|
||||||
|
# a higher supported maximum version
|
||||||
|
if ( record_version == 0 )
|
||||||
|
add_to_history(c, T, "c");
|
||||||
}
|
}
|
||||||
|
|
||||||
event ssl_server_hello(c: connection, version: count, record_version: count, possible_ts: time, server_random: string, session_id: string, cipher: count, comp_method: count) &priority=5
|
event ssl_server_hello(c: connection, version: count, record_version: count, possible_ts: time, server_random: string, session_id: string, cipher: count, comp_method: count) &priority=5
|
||||||
|
@ -302,6 +309,11 @@ event ssl_server_hello(c: connection, version: count, record_version: count, pos
|
||||||
|
|
||||||
if ( c$ssl?$session_id && c$ssl$session_id == bytestring_to_hexstr(session_id) && c$ssl$version_num/0xFF != 0x7F && c$ssl$version_num != TLSv13 )
|
if ( c$ssl?$session_id && c$ssl$session_id == bytestring_to_hexstr(session_id) && c$ssl$version_num/0xFF != 0x7F && c$ssl$version_num != TLSv13 )
|
||||||
c$ssl$resumed = T;
|
c$ssl$resumed = T;
|
||||||
|
|
||||||
|
# add manually for SSLv2, since the handshake_message event is not raised, as there is no handshake protocol.
|
||||||
|
# We don't really have a direction in that case
|
||||||
|
if ( version == 2 )
|
||||||
|
add_to_history(c, F, "s");
|
||||||
}
|
}
|
||||||
|
|
||||||
event ssl_extension_supported_versions(c: connection, is_client: bool, versions: index_vec)
|
event ssl_extension_supported_versions(c: connection, is_client: bool, versions: index_vec)
|
||||||
|
|
|
@ -18,7 +18,7 @@ type ZeekTypeTag = enum {
|
||||||
} &cxxname="::zeek::spicy::rt::ZeekTypeTag";
|
} &cxxname="::zeek::spicy::rt::ZeekTypeTag";
|
||||||
|
|
||||||
declare public void register_spicy_module_begin(string name, string description) &cxxname="zeek::spicy::rt::register_spicy_module_begin";
|
declare public void register_spicy_module_begin(string name, string description) &cxxname="zeek::spicy::rt::register_spicy_module_begin";
|
||||||
declare public void register_protocol_analyzer(string name, hilti::Protocol protocol, string parser_orig, string parser_resp, string replaces, string linker_scope) &cxxname="zeek::spicy::rt::register_protocol_analyzer" &have_prototype;
|
declare public void register_protocol_analyzer(string name, hilti::Protocol protocol, vector<PortRange> ports, string parser_orig, string parser_resp, string replaces, string linker_scope) &cxxname="zeek::spicy::rt::register_protocol_analyzer" &have_prototype;
|
||||||
declare public void register_file_analyzer(string name, vector<string> mime_types, string parser, string replaces, string linker_scope) &cxxname="zeek::spicy::rt::register_file_analyzer" &have_prototype;
|
declare public void register_file_analyzer(string name, vector<string> mime_types, string parser, string replaces, string linker_scope) &cxxname="zeek::spicy::rt::register_file_analyzer" &have_prototype;
|
||||||
declare public void register_packet_analyzer(string name, string parser, string replaces, string linker_scope) &cxxname="zeek::spicy::rt::register_packet_analyzer" &have_prototype;
|
declare public void register_packet_analyzer(string name, string parser, string replaces, string linker_scope) &cxxname="zeek::spicy::rt::register_packet_analyzer" &have_prototype;
|
||||||
declare public void register_type(string ns, string id, BroType t) &cxxname="zeek::spicy::rt::register_type" &have_prototype;
|
declare public void register_type(string ns, string id, BroType t) &cxxname="zeek::spicy::rt::register_type" &have_prototype;
|
||||||
|
|
|
@ -195,6 +195,9 @@ public:
|
||||||
|
|
||||||
bool PermitWeird(const char* name, uint64_t threshold, uint64_t rate, double duration);
|
bool PermitWeird(const char* name, uint64_t threshold, uint64_t rate, double duration);
|
||||||
|
|
||||||
|
// Returns true once Done() is called.
|
||||||
|
bool IsFinished() { return finished; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class session::detail::Timer;
|
friend class session::detail::Timer;
|
||||||
|
|
||||||
|
|
|
@ -113,19 +113,7 @@ void Analyzer::CtorInit(const zeek::Tag& arg_tag, Connection* arg_conn) {
|
||||||
|
|
||||||
Analyzer::~Analyzer() {
|
Analyzer::~Analyzer() {
|
||||||
assert(finished);
|
assert(finished);
|
||||||
|
assert(new_children.empty());
|
||||||
// Make sure any late entries into the analyzer tree are handled (e.g.
|
|
||||||
// from some Done() implementation).
|
|
||||||
LOOP_OVER_GIVEN_CHILDREN(i, new_children) {
|
|
||||||
if ( ! (*i)->finished )
|
|
||||||
(*i)->Done();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Deletion of new_children done in separate loop in case a Done()
|
|
||||||
// implementation tries to inspect analyzer tree w/ assumption that
|
|
||||||
// all analyzers are still valid.
|
|
||||||
LOOP_OVER_GIVEN_CHILDREN(i, new_children)
|
|
||||||
delete *i;
|
|
||||||
|
|
||||||
LOOP_OVER_CHILDREN(i)
|
LOOP_OVER_CHILDREN(i)
|
||||||
delete *i;
|
delete *i;
|
||||||
|
@ -330,6 +318,30 @@ void Analyzer::ForwardEndOfData(bool orig) {
|
||||||
bool Analyzer::AddChildAnalyzer(Analyzer* analyzer, bool init) {
|
bool Analyzer::AddChildAnalyzer(Analyzer* analyzer, bool init) {
|
||||||
auto t = analyzer->GetAnalyzerTag();
|
auto t = analyzer->GetAnalyzerTag();
|
||||||
|
|
||||||
|
// Prevent attaching child analyzers to analyzer subtrees where
|
||||||
|
// either the parent has finished or is being removed. Further,
|
||||||
|
// don't attach analyzers when the connection has finished or is
|
||||||
|
// currently being finished (executing Done()).
|
||||||
|
//
|
||||||
|
// Scenarios in which analyzers have been observed that late in
|
||||||
|
// analyzer / connection lifetime are:
|
||||||
|
//
|
||||||
|
// * A DPD signature match on undelivered TCP data that is flushed
|
||||||
|
// during Connection::Done(). The PIA analyzer activates a new
|
||||||
|
// analyzer adding it to the TCP analyzer.
|
||||||
|
//
|
||||||
|
// * Analyzers flushing buffered state during Done(), resulting
|
||||||
|
// in new analyzers being created.
|
||||||
|
//
|
||||||
|
// Analyzers added during Done() are problematic as calling Done()
|
||||||
|
// within the parent's destructor isn't safe, so we prevent these
|
||||||
|
// situations.
|
||||||
|
if ( Removing() || IsFinished() || Conn()->IsFinished() ) {
|
||||||
|
analyzer->Done();
|
||||||
|
delete analyzer;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if ( HasChildAnalyzer(t) || IsPreventedChildAnalyzer(t) ) {
|
if ( HasChildAnalyzer(t) || IsPreventedChildAnalyzer(t) ) {
|
||||||
analyzer->Done();
|
analyzer->Done();
|
||||||
delete analyzer;
|
delete analyzer;
|
||||||
|
|
|
@ -8,24 +8,24 @@ type SSLRecord(is_orig: bool) = record {
|
||||||
head2 : uint8;
|
head2 : uint8;
|
||||||
head3 : uint8;
|
head3 : uint8;
|
||||||
head4 : uint8;
|
head4 : uint8;
|
||||||
rec : RecordText(this)[] &length=length, &requires(version,content_type,raw_tls_version);
|
rec : RecordText(this)[] &length=length, &requires(record_layer_version,content_type,raw_tls_version);
|
||||||
} &length = length+5, &byteorder=bigendian,
|
} &length = length+5, &byteorder=bigendian,
|
||||||
&let {
|
&let {
|
||||||
version : int =
|
record_layer_version : int =
|
||||||
$context.connection.determine_ssl_record_layer(head0, head1, head2, head3, head4, is_orig);
|
$context.connection.determine_ssl_record_layer(head0, head1, head2, head3, head4, is_orig);
|
||||||
|
|
||||||
# unmodified tls record layer version of this packet. Do not use this if you are parsing SSLv2
|
# unmodified tls record layer version of this packet. Do not use this if you are parsing SSLv2
|
||||||
raw_tls_version: uint16 = case version of {
|
raw_tls_version: uint16 = case record_layer_version of {
|
||||||
SSLv20 -> 0;
|
SSLv20 -> 0;
|
||||||
default -> (head1<<8) | head2;
|
default -> (head1<<8) | head2;
|
||||||
} &requires(version);
|
} &requires(version);
|
||||||
|
|
||||||
content_type : int = case version of {
|
content_type : int = case record_layer_version of {
|
||||||
SSLv20 -> head2+300;
|
SSLv20 -> head2+300;
|
||||||
default -> head0;
|
default -> head0;
|
||||||
} &requires(version);
|
} &requires(version);
|
||||||
|
|
||||||
length : int = case version of {
|
length : int = case record_layer_version of {
|
||||||
# fail analyzer if the packet cannot be recognized as TLS.
|
# fail analyzer if the packet cannot be recognized as TLS.
|
||||||
UNKNOWN_VERSION -> 0;
|
UNKNOWN_VERSION -> 0;
|
||||||
SSLv20 -> (((head0 & 0x7f) << 8) | head1) - 3;
|
SSLv20 -> (((head0 & 0x7f) << 8) | head1) - 3;
|
||||||
|
@ -77,7 +77,7 @@ type V2ClientHello(rec: SSLRecord) = record {
|
||||||
session_id : uint8[session_len];
|
session_id : uint8[session_len];
|
||||||
challenge : bytestring &length = chal_len;
|
challenge : bytestring &length = chal_len;
|
||||||
} &length = 6 + csuit_len + session_len + chal_len, &let {
|
} &length = 6 + csuit_len + session_len + chal_len, &let {
|
||||||
client_version : int = rec.version;
|
client_version : int = (rec.head3 << 8) | rec.head4;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -273,7 +273,12 @@ void TCP_Reassembler::MatchUndelivered(uint64_t up_to_seq, bool use_last_upper)
|
||||||
if ( b.upper > last_reassem_seq )
|
if ( b.upper > last_reassem_seq )
|
||||||
break;
|
break;
|
||||||
|
|
||||||
tcp_analyzer->Conn()->Match(zeek::detail::Rule::PAYLOAD, b.block, b.Size(), false, false, IsOrig(), false);
|
// Note: Even though this passes bol=false, at the point where
|
||||||
|
// this code runs, the matcher is re-initialized resulting in
|
||||||
|
// undelivered data implicitly being bol-anchored. It's unclear
|
||||||
|
// if that was intended, but there's hardly a right way here,
|
||||||
|
// so that seems ok.
|
||||||
|
tcp_analyzer->Conn()->Match(zeek::detail::Rule::PAYLOAD, b.block, b.Size(), IsOrig(), false, false, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include <glob.h>
|
#include <glob.h>
|
||||||
|
|
||||||
#include <exception>
|
#include <exception>
|
||||||
|
#include <iterator>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
|
@ -32,6 +33,7 @@
|
||||||
#include "zeek/spicy/file-analyzer.h"
|
#include "zeek/spicy/file-analyzer.h"
|
||||||
#include "zeek/spicy/packet-analyzer.h"
|
#include "zeek/spicy/packet-analyzer.h"
|
||||||
#include "zeek/spicy/protocol-analyzer.h"
|
#include "zeek/spicy/protocol-analyzer.h"
|
||||||
|
#include "zeek/spicy/runtime-support.h"
|
||||||
#include "zeek/zeek-config-paths.h"
|
#include "zeek/zeek-config-paths.h"
|
||||||
|
|
||||||
using namespace zeek;
|
using namespace zeek;
|
||||||
|
@ -61,6 +63,7 @@ void Manager::registerSpicyModuleEnd() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Manager::registerProtocolAnalyzer(const std::string& name, hilti::rt::Protocol proto,
|
void Manager::registerProtocolAnalyzer(const std::string& name, hilti::rt::Protocol proto,
|
||||||
|
const hilti::rt::Vector<::zeek::spicy::rt::PortRange>& ports,
|
||||||
const std::string& parser_orig, const std::string& parser_resp,
|
const std::string& parser_orig, const std::string& parser_resp,
|
||||||
const std::string& replaces, const std::string& linker_scope) {
|
const std::string& replaces, const std::string& linker_scope) {
|
||||||
SPICY_DEBUG(hilti::rt::fmt("Have Spicy protocol analyzer %s", name));
|
SPICY_DEBUG(hilti::rt::fmt("Have Spicy protocol analyzer %s", name));
|
||||||
|
@ -75,6 +78,11 @@ void Manager::registerProtocolAnalyzer(const std::string& name, hilti::rt::Proto
|
||||||
info.protocol = proto;
|
info.protocol = proto;
|
||||||
info.linker_scope = linker_scope;
|
info.linker_scope = linker_scope;
|
||||||
|
|
||||||
|
// Store ports in a deterministic order. We can't (easily) sort the
|
||||||
|
// `hilti::rt::Vector` unfortunately.
|
||||||
|
std::copy(ports.begin(), ports.end(), std::back_inserter(info.ports));
|
||||||
|
std::sort(info.ports.begin(), info.ports.end());
|
||||||
|
|
||||||
// We may have that analyzer already iff it was previously pre-registered
|
// We may have that analyzer already iff it was previously pre-registered
|
||||||
// without a linker scope. We'll then only set the scope now.
|
// without a linker scope. We'll then only set the scope now.
|
||||||
if ( auto t = _analyzer_name_to_tag_type.find(info.name_zeek); t != _analyzer_name_to_tag_type.end() ) {
|
if ( auto t = _analyzer_name_to_tag_type.find(info.name_zeek); t != _analyzer_name_to_tag_type.end() ) {
|
||||||
|
@ -699,6 +707,36 @@ void Manager::InitPostScript() {
|
||||||
if ( ! tag )
|
if ( ! tag )
|
||||||
reporter->InternalError("cannot get analyzer tag for '%s'", p.name_analyzer.c_str());
|
reporter->InternalError("cannot get analyzer tag for '%s'", p.name_analyzer.c_str());
|
||||||
|
|
||||||
|
auto register_analyzer_for_port = [&](auto tag, const hilti::rt::Port& port_) {
|
||||||
|
SPICY_DEBUG(hilti::rt::fmt(" Scheduling analyzer for port %s", port_));
|
||||||
|
|
||||||
|
// Well-known ports are registered in scriptland, so we'll raise an
|
||||||
|
// event that will do it for us through a predefined handler.
|
||||||
|
zeek::Args vals = Args();
|
||||||
|
vals.emplace_back(tag.AsVal());
|
||||||
|
vals.emplace_back(zeek::spicy::rt::to_val(port_, base_type(TYPE_PORT)));
|
||||||
|
EventHandlerPtr handler = event_registry->Register("spicy_analyzer_for_port");
|
||||||
|
event_mgr.Enqueue(handler, vals);
|
||||||
|
};
|
||||||
|
|
||||||
|
for ( const auto& ports : p.ports ) {
|
||||||
|
const auto proto = ports.begin.protocol();
|
||||||
|
|
||||||
|
// Port ranges are closed intervals.
|
||||||
|
for ( auto port = ports.begin.port(); port <= ports.end.port(); ++port ) {
|
||||||
|
const auto port_ = hilti::rt::Port(port, proto);
|
||||||
|
register_analyzer_for_port(tag, port_);
|
||||||
|
|
||||||
|
// Don't double register in case of single-port ranges.
|
||||||
|
if ( ports.begin.port() == ports.end.port() )
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Explicitly prevent overflow.
|
||||||
|
if ( port == std::numeric_limits<decltype(port)>::max() )
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if ( p.parser_resp ) {
|
if ( p.parser_resp ) {
|
||||||
for ( auto port : p.parser_resp->ports ) {
|
for ( auto port : p.parser_resp->ports ) {
|
||||||
if ( port.direction != ::spicy::rt::Direction::Both &&
|
if ( port.direction != ::spicy::rt::Direction::Both &&
|
||||||
|
@ -706,7 +744,7 @@ void Manager::InitPostScript() {
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
SPICY_DEBUG(hilti::rt::fmt(" Scheduling analyzer for port %s", port.port));
|
SPICY_DEBUG(hilti::rt::fmt(" Scheduling analyzer for port %s", port.port));
|
||||||
analyzer_mgr->RegisterAnalyzerForPort(tag, transport_protocol(port.port), port.port.port());
|
register_analyzer_for_port(tag, port.port);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -85,6 +85,7 @@ public:
|
||||||
*
|
*
|
||||||
* @param name name of the analyzer as defined in its EVT file
|
* @param name name of the analyzer as defined in its EVT file
|
||||||
* @param proto analyzer's transport-layer protocol
|
* @param proto analyzer's transport-layer protocol
|
||||||
|
* @param ports well-known ports for the analyzer; it'll be activated automatically for these
|
||||||
* @param parser_orig name of the Spicy parser for the originator side; must match the name that
|
* @param parser_orig name of the Spicy parser for the originator side; must match the name that
|
||||||
* Spicy registers the unit's parser with
|
* Spicy registers the unit's parser with
|
||||||
* @param parser_resp name of the Spicy parser for the originator side; must match the name that
|
* @param parser_resp name of the Spicy parser for the originator side; must match the name that
|
||||||
|
@ -94,9 +95,10 @@ public:
|
||||||
* @param linker_scope scope of current HLTO file, which will restrict visibility of the
|
* @param linker_scope scope of current HLTO file, which will restrict visibility of the
|
||||||
* registration
|
* registration
|
||||||
*/
|
*/
|
||||||
void registerProtocolAnalyzer(const std::string& name, hilti::rt::Protocol proto, const std::string& parser_orig,
|
void registerProtocolAnalyzer(const std::string& name, hilti::rt::Protocol proto,
|
||||||
const std::string& parser_resp, const std::string& replaces,
|
const hilti::rt::Vector<::zeek::spicy::rt::PortRange>& ports,
|
||||||
const std::string& linker_scope);
|
const std::string& parser_orig, const std::string& parser_resp,
|
||||||
|
const std::string& replaces, const std::string& linker_scope);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Runtime method to register a file analyzer with its Zeek-side
|
* Runtime method to register a file analyzer with its Zeek-side
|
||||||
|
@ -341,6 +343,7 @@ private:
|
||||||
std::string name_parser_resp;
|
std::string name_parser_resp;
|
||||||
std::string name_replaces;
|
std::string name_replaces;
|
||||||
hilti::rt::Protocol protocol = hilti::rt::Protocol::Undef;
|
hilti::rt::Protocol protocol = hilti::rt::Protocol::Undef;
|
||||||
|
std::vector<::zeek::spicy::rt::PortRange> ports; // we keep this sorted
|
||||||
std::string linker_scope;
|
std::string linker_scope;
|
||||||
|
|
||||||
// Computed and available once the analyzer has been registered.
|
// Computed and available once the analyzer has been registered.
|
||||||
|
@ -354,7 +357,7 @@ private:
|
||||||
bool operator==(const ProtocolAnalyzerInfo& other) const {
|
bool operator==(const ProtocolAnalyzerInfo& other) const {
|
||||||
return name_analyzer == other.name_analyzer && name_parser_orig == other.name_parser_orig &&
|
return name_analyzer == other.name_analyzer && name_parser_orig == other.name_parser_orig &&
|
||||||
name_parser_resp == other.name_parser_resp && name_replaces == other.name_replaces &&
|
name_parser_resp == other.name_parser_resp && name_replaces == other.name_replaces &&
|
||||||
protocol == other.protocol && linker_scope == other.linker_scope;
|
protocol == other.protocol && ports == other.ports && linker_scope == other.linker_scope;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator!=(const ProtocolAnalyzerInfo& other) const { return ! (*this == other); }
|
bool operator!=(const ProtocolAnalyzerInfo& other) const { return ! (*this == other); }
|
||||||
|
|
|
@ -19,6 +19,11 @@ struct PortRange {
|
||||||
|
|
||||||
hilti::rt::Port begin; /**< first port in the range */
|
hilti::rt::Port begin; /**< first port in the range */
|
||||||
hilti::rt::Port end; /**< last port in the range */
|
hilti::rt::Port end; /**< last port in the range */
|
||||||
|
|
||||||
|
bool operator<(const PortRange& other) const {
|
||||||
|
// Just get us a deterministic order.
|
||||||
|
return std::tie(begin, end) < std::tie(other.begin, other.end);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
inline bool operator==(const PortRange& a, const PortRange& b) {
|
inline bool operator==(const PortRange& a, const PortRange& b) {
|
||||||
|
|
|
@ -26,11 +26,12 @@ void rt::register_spicy_module_begin(const std::string& name, const std::string&
|
||||||
|
|
||||||
void rt::register_spicy_module_end() { spicy_mgr->registerSpicyModuleEnd(); }
|
void rt::register_spicy_module_end() { spicy_mgr->registerSpicyModuleEnd(); }
|
||||||
|
|
||||||
void rt::register_protocol_analyzer(const std::string& name, hilti::rt::Protocol proto, const std::string& parser_orig,
|
void rt::register_protocol_analyzer(const std::string& name, hilti::rt::Protocol proto,
|
||||||
const std::string& parser_resp, const std::string& replaces,
|
const hilti::rt::Vector<::zeek::spicy::rt::PortRange>& ports,
|
||||||
const std::string& linker_scope) {
|
const std::string& parser_orig, const std::string& parser_resp,
|
||||||
|
const std::string& replaces, const std::string& linker_scope) {
|
||||||
auto _ = hilti::rt::profiler::start("zeek/rt/register_protocol_analyzer");
|
auto _ = hilti::rt::profiler::start("zeek/rt/register_protocol_analyzer");
|
||||||
spicy_mgr->registerProtocolAnalyzer(name, proto, parser_orig, parser_resp, replaces, linker_scope);
|
spicy_mgr->registerProtocolAnalyzer(name, proto, ports, parser_orig, parser_resp, replaces, linker_scope);
|
||||||
}
|
}
|
||||||
|
|
||||||
void rt::register_file_analyzer(const std::string& name, const hilti::rt::Vector<std::string>& mime_types,
|
void rt::register_file_analyzer(const std::string& name, const hilti::rt::Vector<std::string>& mime_types,
|
||||||
|
|
|
@ -106,9 +106,10 @@ void register_spicy_module_begin(const std::string& id, const std::string& descr
|
||||||
* Registers a Spicy protocol analyzer with its EVT meta information with the
|
* Registers a Spicy protocol analyzer with its EVT meta information with the
|
||||||
* plugin's runtime.
|
* plugin's runtime.
|
||||||
*/
|
*/
|
||||||
void register_protocol_analyzer(const std::string& id, hilti::rt::Protocol proto, const std::string& parser_orig,
|
void register_protocol_analyzer(const std::string& id, hilti::rt::Protocol proto,
|
||||||
const std::string& parser_resp, const std::string& replaces,
|
const hilti::rt::Vector<::zeek::spicy::rt::PortRange>& ports,
|
||||||
const std::string& linker_scope);
|
const std::string& parser_orig, const std::string& parser_resp,
|
||||||
|
const std::string& replaces, const std::string& linker_scope);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Registers a Spicy file analyzer with its EVT meta information with the
|
* Registers a Spicy file analyzer with its EVT meta information with the
|
||||||
|
|
|
@ -260,6 +260,79 @@ static std::string extract_expr(const std::string& chunk, size_t* i) {
|
||||||
return expr;
|
return expr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static hilti::rt::Port extract_port(const std::string& chunk, size_t* i) {
|
||||||
|
eat_spaces(chunk, i);
|
||||||
|
|
||||||
|
std::string s;
|
||||||
|
size_t j = *i;
|
||||||
|
|
||||||
|
while ( j < chunk.size() && isdigit(chunk[j]) )
|
||||||
|
++j;
|
||||||
|
|
||||||
|
if ( *i == j )
|
||||||
|
throw ParseError("cannot parse port specification");
|
||||||
|
|
||||||
|
hilti::rt::Protocol proto;
|
||||||
|
uint64_t port = std::numeric_limits<uint64_t>::max();
|
||||||
|
|
||||||
|
s = chunk.substr(*i, j - *i);
|
||||||
|
hilti::util::atoi_n(s.begin(), s.end(), 10, &port);
|
||||||
|
|
||||||
|
if ( port > 65535 )
|
||||||
|
throw ParseError("port outside of valid range");
|
||||||
|
|
||||||
|
*i = j;
|
||||||
|
|
||||||
|
if ( chunk[*i] != '/' )
|
||||||
|
throw ParseError("cannot parse port specification");
|
||||||
|
|
||||||
|
(*i)++;
|
||||||
|
|
||||||
|
if ( looking_at(chunk, *i, "tcp") ) {
|
||||||
|
proto = hilti::rt::Protocol::TCP;
|
||||||
|
eat_token(chunk, i, "tcp");
|
||||||
|
}
|
||||||
|
|
||||||
|
else if ( looking_at(chunk, *i, "udp") ) {
|
||||||
|
proto = hilti::rt::Protocol::UDP;
|
||||||
|
eat_token(chunk, i, "udp");
|
||||||
|
}
|
||||||
|
|
||||||
|
else if ( looking_at(chunk, *i, "icmp") ) {
|
||||||
|
proto = hilti::rt::Protocol::ICMP;
|
||||||
|
eat_token(chunk, i, "icmp");
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
throw ParseError("cannot parse port specification");
|
||||||
|
|
||||||
|
return {static_cast<uint16_t>(port), proto};
|
||||||
|
}
|
||||||
|
|
||||||
|
static ::zeek::spicy::rt::PortRange extract_port_range(const std::string& chunk, size_t* i) {
|
||||||
|
auto start = extract_port(chunk, i);
|
||||||
|
auto end = std::optional<hilti::rt::Port>();
|
||||||
|
|
||||||
|
if ( looking_at(chunk, *i, "-") ) {
|
||||||
|
eat_token(chunk, i, "-");
|
||||||
|
end = extract_port(chunk, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( end ) {
|
||||||
|
if ( start.protocol() != end->protocol() )
|
||||||
|
throw ParseError("start and end of port range must have same protocol");
|
||||||
|
|
||||||
|
if ( start.port() > end->port() )
|
||||||
|
throw ParseError("start of port range cannot be after its end");
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ! end )
|
||||||
|
// EVT port ranges are a closed.
|
||||||
|
end = hilti::rt::Port(start.port(), start.protocol());
|
||||||
|
|
||||||
|
return {start, *end};
|
||||||
|
}
|
||||||
|
|
||||||
void GlueCompiler::init(Driver* driver, int zeek_version) {
|
void GlueCompiler::init(Driver* driver, int zeek_version) {
|
||||||
_driver = driver;
|
_driver = driver;
|
||||||
_zeek_version = zeek_version;
|
_zeek_version = zeek_version;
|
||||||
|
@ -631,11 +704,25 @@ glue::ProtocolAnalyzer GlueCompiler::parseProtocolAnalyzer(const std::string& ch
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else if ( looking_at(chunk, i, "ports") || looking_at(chunk, i, "port") ) {
|
else if ( looking_at(chunk, i, "ports") ) {
|
||||||
throw ParseError(hilti::rt::fmt(
|
eat_token(chunk, &i, "ports");
|
||||||
"Analyzer %s is using the removed 'port' or 'ports' keyword to register "
|
eat_token(chunk, &i, "{");
|
||||||
"well-known ports. Use Analyzer::register_for_ports() in the accompanying Zeek script instead.",
|
|
||||||
a.name));
|
while ( true ) {
|
||||||
|
a.ports.push_back(extract_port_range(chunk, &i));
|
||||||
|
|
||||||
|
if ( looking_at(chunk, i, "}") ) {
|
||||||
|
eat_token(chunk, &i, "}");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
eat_token(chunk, &i, ",");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else if ( looking_at(chunk, i, "port") ) {
|
||||||
|
eat_token(chunk, &i, "port");
|
||||||
|
a.ports.push_back(extract_port_range(chunk, &i));
|
||||||
}
|
}
|
||||||
|
|
||||||
else if ( looking_at(chunk, i, "replaces") ) {
|
else if ( looking_at(chunk, i, "replaces") ) {
|
||||||
|
@ -939,6 +1026,13 @@ bool GlueCompiler::compile() {
|
||||||
|
|
||||||
preinit_body.addCall("zeek_rt::register_protocol_analyzer",
|
preinit_body.addCall("zeek_rt::register_protocol_analyzer",
|
||||||
{builder()->stringMutable(a.name.str()), builder()->id(protocol),
|
{builder()->stringMutable(a.name.str()), builder()->id(protocol),
|
||||||
|
builder()->vector(
|
||||||
|
hilti::util::transform(a.ports,
|
||||||
|
[this](const auto& p) -> hilti::Expression* {
|
||||||
|
return builder()->call("zeek_rt::make_port_range",
|
||||||
|
{builder()->port(p.begin),
|
||||||
|
builder()->port(p.end)});
|
||||||
|
})),
|
||||||
builder()->stringMutable(a.unit_name_orig.str()),
|
builder()->stringMutable(a.unit_name_orig.str()),
|
||||||
builder()->stringMutable(a.unit_name_resp.str()), builder()->stringMutable(a.replaces),
|
builder()->stringMutable(a.unit_name_resp.str()), builder()->stringMutable(a.replaces),
|
||||||
builder()->scope()});
|
builder()->scope()});
|
||||||
|
|
|
@ -45,6 +45,7 @@ struct ProtocolAnalyzer {
|
||||||
hilti::Location location; /**< Location where the analyzer was defined. */
|
hilti::Location location; /**< Location where the analyzer was defined. */
|
||||||
hilti::ID name; /**< Name of the analyzer. */
|
hilti::ID name; /**< Name of the analyzer. */
|
||||||
hilti::rt::Protocol protocol = hilti::rt::Protocol::Undef; /**< The transport layer the analyzer uses. */
|
hilti::rt::Protocol protocol = hilti::rt::Protocol::Undef; /**< The transport layer the analyzer uses. */
|
||||||
|
std::vector<::zeek::spicy::rt::PortRange> ports; /**< The ports associated with the analyzer. */
|
||||||
hilti::ID unit_name_orig; /**< The fully-qualified name of the unit type to parse the originator
|
hilti::ID unit_name_orig; /**< The fully-qualified name of the unit type to parse the originator
|
||||||
side. */
|
side. */
|
||||||
hilti::ID unit_name_resp; /**< The fully-qualified name of the unit type to parse the originator
|
hilti::ID unit_name_resp; /**< The fully-qualified name of the unit type to parse the originator
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
Start test run
|
Start test run
|
||||||
Client hello, 192.168.4.149, 91.227.4.92, 2
|
Client hello, 192.168.4.149, 91.227.4.92, 2
|
||||||
Start test run
|
Start test run
|
||||||
Client hello, 192.150.187.164, 194.127.84.106, 2
|
Client hello, 192.150.187.164, 194.127.84.106, 769
|
||||||
Client hello, 192.150.187.164, 194.127.84.106, 769
|
Client hello, 192.150.187.164, 194.127.84.106, 769
|
||||||
Client hello, 192.150.187.164, 194.127.84.106, 769
|
Client hello, 192.150.187.164, 194.127.84.106, 769
|
||||||
Start test run
|
Start test run
|
||||||
|
|
|
@ -27,7 +27,7 @@ XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 192.168.18.50 56981 74.125.239.97 443 TLSv12
|
||||||
#open XXXX-XX-XX-XX-XX-XX
|
#open XXXX-XX-XX-XX-XX-XX
|
||||||
#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p version cipher curve server_name resumed last_alert next_protocol established ssl_history cert_chain_fps client_cert_chain_fps sni_matches_cert client_record_version client_random client_cipher_suites server_record_version server_random server_dh_p server_dh_q server_dh_Ys server_ecdh_point server_signature_sig_alg server_signature_hash_alg server_signature server_cert_sha1 client_rsa_pms client_dh_Yc client_ecdh_point
|
#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p version cipher curve server_name resumed last_alert next_protocol established ssl_history cert_chain_fps client_cert_chain_fps sni_matches_cert client_record_version client_random client_cipher_suites server_record_version server_random server_dh_p server_dh_q server_dh_Ys server_ecdh_point server_signature_sig_alg server_signature_hash_alg server_signature server_cert_sha1 client_rsa_pms client_dh_Yc client_ecdh_point
|
||||||
#types time string addr port addr port string string string string bool string string bool string vector[string] vector[string] bool string string string string string string string string string count count string string string string string
|
#types time string addr port addr port string string string string bool string string bool string vector[string] vector[string] bool string string string string string string string string string count count string string string string string
|
||||||
XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 192.150.187.164 58868 194.127.84.106 443 TLSv10 TLS_RSA_WITH_RC4_128_MD5 - - F - - T sxnGIi ddd0218a34972ceab3d200b78959bd2b4c95eadf37399df35bfd68a5b658bc78,ba352de8d8faa0ecfdbeee560fa308fe192023d3b18d83a68845933bebf28360 (empty) - unknown-0 e6b8efdf91cf44f7eae43c83398fdcb2 TLS_DHE_RSA_WITH_AES_256_CBC_SHA,TLS_DHE_DSS_WITH_AES_256_CBC_SHA,TLS_RSA_WITH_AES_256_CBC_SHA,TLS_DHE_RSA_WITH_AES_128_CBC_SHA,TLS_DHE_DSS_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_RC4_128_MD5,TLS_RSA_WITH_RC4_128_SHA,TLS_RSA_WITH_AES_128_CBC_SHA,TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA,TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA,SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA,TLS_RSA_WITH_3DES_EDE_CBC_SHA,TLS_DHE_RSA_WITH_DES_CBC_SHA,TLS_DHE_DSS_WITH_DES_CBC_SHA,SSL_RSA_FIPS_WITH_DES_CBC_SHA,TLS_RSA_WITH_DES_CBC_SHA,TLS_RSA_EXPORT1024_WITH_RC4_56_SHA,TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA,TLS_RSA_EXPORT_WITH_RC4_40_MD5,TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5 TLSv10 45c7bb492b658d5183bbaedbf35e8f126ff926b14979cd703d242aea996a5fda - - - - - - - 2c322ae2b7fe91391345e070b63668978bb1c9da 008057aaeea52e6d030e54fa9328781fda6f8de80ed8531946bfa8adc4b51ca7502cbce62bae6949f6b865d7125e256643b5ede4dd4cf42107cfa73c418f10881edf38a75f968b507f08f9c1089ef26bfd322cf44c0b746b8e3dff731f2585dcf26abb048d55e661e1d2868ccc9c338e451c30431239f96a00e4843b6aa00ba51785 - -
|
XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 192.150.187.164 58868 194.127.84.106 443 TLSv10 TLS_RSA_WITH_RC4_128_MD5 - - F - - T CsxnGIi ddd0218a34972ceab3d200b78959bd2b4c95eadf37399df35bfd68a5b658bc78,ba352de8d8faa0ecfdbeee560fa308fe192023d3b18d83a68845933bebf28360 (empty) - unknown-0 e6b8efdf91cf44f7eae43c83398fdcb2 TLS_DHE_RSA_WITH_AES_256_CBC_SHA,TLS_DHE_DSS_WITH_AES_256_CBC_SHA,TLS_RSA_WITH_AES_256_CBC_SHA,TLS_DHE_RSA_WITH_AES_128_CBC_SHA,TLS_DHE_DSS_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_RC4_128_MD5,TLS_RSA_WITH_RC4_128_SHA,TLS_RSA_WITH_AES_128_CBC_SHA,TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA,TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA,SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA,TLS_RSA_WITH_3DES_EDE_CBC_SHA,TLS_DHE_RSA_WITH_DES_CBC_SHA,TLS_DHE_DSS_WITH_DES_CBC_SHA,SSL_RSA_FIPS_WITH_DES_CBC_SHA,TLS_RSA_WITH_DES_CBC_SHA,TLS_RSA_EXPORT1024_WITH_RC4_56_SHA,TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA,TLS_RSA_EXPORT_WITH_RC4_40_MD5,TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5 TLSv10 45c7bb492b658d5183bbaedbf35e8f126ff926b14979cd703d242aea996a5fda - - - - - - - 2c322ae2b7fe91391345e070b63668978bb1c9da 008057aaeea52e6d030e54fa9328781fda6f8de80ed8531946bfa8adc4b51ca7502cbce62bae6949f6b865d7125e256643b5ede4dd4cf42107cfa73c418f10881edf38a75f968b507f08f9c1089ef26bfd322cf44c0b746b8e3dff731f2585dcf26abb048d55e661e1d2868ccc9c338e451c30431239f96a00e4843b6aa00ba51785 - -
|
||||||
XXXXXXXXXX.XXXXXX ClEkJM2Vm5giqnMf4h 192.150.187.164 58869 194.127.84.106 443 TLSv10 TLS_RSA_WITH_RC4_128_MD5 - - F - - T CsxnGIi ddd0218a34972ceab3d200b78959bd2b4c95eadf37399df35bfd68a5b658bc78,ba352de8d8faa0ecfdbeee560fa308fe192023d3b18d83a68845933bebf28360 (empty) - TLSv10 a8a2ab739a64abb4e68cfcfc3470ff6269b1a86858501fbbd1327ed8 TLS_DHE_RSA_WITH_AES_256_CBC_SHA,TLS_DHE_DSS_WITH_AES_256_CBC_SHA,TLS_RSA_WITH_AES_256_CBC_SHA,TLS_DHE_RSA_WITH_AES_128_CBC_SHA,TLS_DHE_DSS_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_RC4_128_MD5,TLS_RSA_WITH_RC4_128_SHA,TLS_RSA_WITH_AES_128_CBC_SHA,TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA,TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA,SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA,TLS_RSA_WITH_3DES_EDE_CBC_SHA,TLS_DHE_RSA_WITH_DES_CBC_SHA,TLS_DHE_DSS_WITH_DES_CBC_SHA,SSL_RSA_FIPS_WITH_DES_CBC_SHA,TLS_RSA_WITH_DES_CBC_SHA,TLS_RSA_EXPORT1024_WITH_RC4_56_SHA,TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA,TLS_RSA_EXPORT_WITH_RC4_40_MD5,TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5 TLSv10 45c7bb4c0fac7f7823587c68438c87876533af7b0baa2a8f1078eb8d182247e9 - - - - - - - 2c322ae2b7fe91391345e070b63668978bb1c9da 0080891c1b6b5f0ec9da1b38d5ba6efe9c0380219d1ac4e63a0e8993306cddc6944a57c9292beb5652794181f747d0e868b84dca7dfe9783d1baa2ef3bb68d929b2818c5b58b8f47663220f9781fa469fea7e7d17d410d3979aa15a7be651c9f16fbf1a04f87a95e742c3fe20ca6faf0d2e950708533fd3346e17e410f0f86c01f52 - -
|
XXXXXXXXXX.XXXXXX ClEkJM2Vm5giqnMf4h 192.150.187.164 58869 194.127.84.106 443 TLSv10 TLS_RSA_WITH_RC4_128_MD5 - - F - - T CsxnGIi ddd0218a34972ceab3d200b78959bd2b4c95eadf37399df35bfd68a5b658bc78,ba352de8d8faa0ecfdbeee560fa308fe192023d3b18d83a68845933bebf28360 (empty) - TLSv10 a8a2ab739a64abb4e68cfcfc3470ff6269b1a86858501fbbd1327ed8 TLS_DHE_RSA_WITH_AES_256_CBC_SHA,TLS_DHE_DSS_WITH_AES_256_CBC_SHA,TLS_RSA_WITH_AES_256_CBC_SHA,TLS_DHE_RSA_WITH_AES_128_CBC_SHA,TLS_DHE_DSS_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_RC4_128_MD5,TLS_RSA_WITH_RC4_128_SHA,TLS_RSA_WITH_AES_128_CBC_SHA,TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA,TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA,SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA,TLS_RSA_WITH_3DES_EDE_CBC_SHA,TLS_DHE_RSA_WITH_DES_CBC_SHA,TLS_DHE_DSS_WITH_DES_CBC_SHA,SSL_RSA_FIPS_WITH_DES_CBC_SHA,TLS_RSA_WITH_DES_CBC_SHA,TLS_RSA_EXPORT1024_WITH_RC4_56_SHA,TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA,TLS_RSA_EXPORT_WITH_RC4_40_MD5,TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5 TLSv10 45c7bb4c0fac7f7823587c68438c87876533af7b0baa2a8f1078eb8d182247e9 - - - - - - - 2c322ae2b7fe91391345e070b63668978bb1c9da 0080891c1b6b5f0ec9da1b38d5ba6efe9c0380219d1ac4e63a0e8993306cddc6944a57c9292beb5652794181f747d0e868b84dca7dfe9783d1baa2ef3bb68d929b2818c5b58b8f47663220f9781fa469fea7e7d17d410d3979aa15a7be651c9f16fbf1a04f87a95e742c3fe20ca6faf0d2e950708533fd3346e17e410f0f86c01f52 - -
|
||||||
XXXXXXXXXX.XXXXXX C4J4Th3PJpwUYZZ6gc 192.150.187.164 58870 194.127.84.106 443 TLSv10 TLS_RSA_WITH_RC4_128_MD5 - - F - - T CsxnGIi ddd0218a34972ceab3d200b78959bd2b4c95eadf37399df35bfd68a5b658bc78,ba352de8d8faa0ecfdbeee560fa308fe192023d3b18d83a68845933bebf28360 (empty) - TLSv10 240604be2f5644c8dfd2e51cc2b3a30171bd58853ed7c6e3fcd18846 TLS_DHE_RSA_WITH_AES_256_CBC_SHA,TLS_DHE_DSS_WITH_AES_256_CBC_SHA,TLS_RSA_WITH_AES_256_CBC_SHA,TLS_DHE_RSA_WITH_AES_128_CBC_SHA,TLS_DHE_DSS_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_RC4_128_MD5,TLS_RSA_WITH_RC4_128_SHA,TLS_RSA_WITH_AES_128_CBC_SHA,TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA,TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA,SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA,TLS_RSA_WITH_3DES_EDE_CBC_SHA,TLS_DHE_RSA_WITH_DES_CBC_SHA,TLS_DHE_DSS_WITH_DES_CBC_SHA,SSL_RSA_FIPS_WITH_DES_CBC_SHA,TLS_RSA_WITH_DES_CBC_SHA,TLS_RSA_EXPORT1024_WITH_RC4_56_SHA,TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA,TLS_RSA_EXPORT_WITH_RC4_40_MD5,TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5 TLSv10 45c7bb4ffd1b8c1308a2caac010fcb76e9bd21987d897cb6c028cdb3176d5904 - - - - - - - 2c322ae2b7fe91391345e070b63668978bb1c9da 008032a6f5fd530f342e4d5b4043765005ba018f488800f897c259b005ad2a544f5800e99812d9a6336e84b07e4595d1b8ae00a582d91804fe715c132d1bdb112e66361db80a57a441fc8ea784ea76ec44b9f3a0f9ddc29be68010ff3bcfffc285a294511991d7952cbbfee88a869818bae31f32f7099b0754d9ce75b8fea887e1b8 - -
|
XXXXXXXXXX.XXXXXX C4J4Th3PJpwUYZZ6gc 192.150.187.164 58870 194.127.84.106 443 TLSv10 TLS_RSA_WITH_RC4_128_MD5 - - F - - T CsxnGIi ddd0218a34972ceab3d200b78959bd2b4c95eadf37399df35bfd68a5b658bc78,ba352de8d8faa0ecfdbeee560fa308fe192023d3b18d83a68845933bebf28360 (empty) - TLSv10 240604be2f5644c8dfd2e51cc2b3a30171bd58853ed7c6e3fcd18846 TLS_DHE_RSA_WITH_AES_256_CBC_SHA,TLS_DHE_DSS_WITH_AES_256_CBC_SHA,TLS_RSA_WITH_AES_256_CBC_SHA,TLS_DHE_RSA_WITH_AES_128_CBC_SHA,TLS_DHE_DSS_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_RC4_128_MD5,TLS_RSA_WITH_RC4_128_SHA,TLS_RSA_WITH_AES_128_CBC_SHA,TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA,TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA,SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA,TLS_RSA_WITH_3DES_EDE_CBC_SHA,TLS_DHE_RSA_WITH_DES_CBC_SHA,TLS_DHE_DSS_WITH_DES_CBC_SHA,SSL_RSA_FIPS_WITH_DES_CBC_SHA,TLS_RSA_WITH_DES_CBC_SHA,TLS_RSA_EXPORT1024_WITH_RC4_56_SHA,TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA,TLS_RSA_EXPORT_WITH_RC4_40_MD5,TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5 TLSv10 45c7bb4ffd1b8c1308a2caac010fcb76e9bd21987d897cb6c028cdb3176d5904 - - - - - - - 2c322ae2b7fe91391345e070b63668978bb1c9da 008032a6f5fd530f342e4d5b4043765005ba018f488800f897c259b005ad2a544f5800e99812d9a6336e84b07e4595d1b8ae00a582d91804fe715c132d1bdb112e66361db80a57a441fc8ea784ea76ec44b9f3a0f9ddc29be68010ff3bcfffc285a294511991d7952cbbfee88a869818bae31f32f7099b0754d9ce75b8fea887e1b8 - -
|
||||||
#close XXXX-XX-XX-XX-XX-XX
|
#close XXXX-XX-XX-XX-XX-XX
|
||||||
|
|
|
@ -27,7 +27,7 @@ XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 192.168.18.50 56981 74.125.239.97 443 TLSv12
|
||||||
#open XXXX-XX-XX-XX-XX-XX
|
#open XXXX-XX-XX-XX-XX-XX
|
||||||
#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p version cipher curve server_name resumed last_alert next_protocol established ssl_history cert_chain_fps client_cert_chain_fps sni_matches_cert server_version client_version client_ciphers ssl_client_exts ssl_server_exts ticket_lifetime_hint dh_param_size point_formats client_curves orig_alpn client_supported_versions server_supported_version psk_key_exchange_modes client_key_share_groups server_key_share_group client_comp_methods sigalgs hashalgs
|
#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p version cipher curve server_name resumed last_alert next_protocol established ssl_history cert_chain_fps client_cert_chain_fps sni_matches_cert server_version client_version client_ciphers ssl_client_exts ssl_server_exts ticket_lifetime_hint dh_param_size point_formats client_curves orig_alpn client_supported_versions server_supported_version psk_key_exchange_modes client_key_share_groups server_key_share_group client_comp_methods sigalgs hashalgs
|
||||||
#types time string addr port addr port string string string string bool string string bool string vector[string] vector[string] bool count count vector[count] vector[count] vector[count] count count vector[count] vector[count] vector[string] vector[count] count vector[count] vector[count] count vector[count] vector[count] vector[count]
|
#types time string addr port addr port string string string string bool string string bool string vector[string] vector[string] bool count count vector[count] vector[count] vector[count] count count vector[count] vector[count] vector[string] vector[count] count vector[count] vector[count] count vector[count] vector[count] vector[count]
|
||||||
XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 192.150.187.164 58868 194.127.84.106 443 TLSv10 TLS_RSA_WITH_RC4_128_MD5 - - F - - T sxnGIi ddd0218a34972ceab3d200b78959bd2b4c95eadf37399df35bfd68a5b658bc78,ba352de8d8faa0ecfdbeee560fa308fe192023d3b18d83a68845933bebf28360 (empty) - 769 2 57,56,53,51,50,4,5,47,22,19,65279,10,21,18,65278,9,100,98,3,6 - - - - - - - - - - - - (empty) - -
|
XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 192.150.187.164 58868 194.127.84.106 443 TLSv10 TLS_RSA_WITH_RC4_128_MD5 - - F - - T CsxnGIi ddd0218a34972ceab3d200b78959bd2b4c95eadf37399df35bfd68a5b658bc78,ba352de8d8faa0ecfdbeee560fa308fe192023d3b18d83a68845933bebf28360 (empty) - 769 769 57,56,53,51,50,4,5,47,22,19,65279,10,21,18,65278,9,100,98,3,6 - - - - - - - - - - - - (empty) - -
|
||||||
XXXXXXXXXX.XXXXXX ClEkJM2Vm5giqnMf4h 192.150.187.164 58869 194.127.84.106 443 TLSv10 TLS_RSA_WITH_RC4_128_MD5 - - F - - T CsxnGIi ddd0218a34972ceab3d200b78959bd2b4c95eadf37399df35bfd68a5b658bc78,ba352de8d8faa0ecfdbeee560fa308fe192023d3b18d83a68845933bebf28360 (empty) - 769 769 57,56,53,51,50,4,5,47,22,19,65279,10,21,18,65278,9,100,98,3,6 - - - - - - - - - - - - 0 - -
|
XXXXXXXXXX.XXXXXX ClEkJM2Vm5giqnMf4h 192.150.187.164 58869 194.127.84.106 443 TLSv10 TLS_RSA_WITH_RC4_128_MD5 - - F - - T CsxnGIi ddd0218a34972ceab3d200b78959bd2b4c95eadf37399df35bfd68a5b658bc78,ba352de8d8faa0ecfdbeee560fa308fe192023d3b18d83a68845933bebf28360 (empty) - 769 769 57,56,53,51,50,4,5,47,22,19,65279,10,21,18,65278,9,100,98,3,6 - - - - - - - - - - - - 0 - -
|
||||||
XXXXXXXXXX.XXXXXX C4J4Th3PJpwUYZZ6gc 192.150.187.164 58870 194.127.84.106 443 TLSv10 TLS_RSA_WITH_RC4_128_MD5 - - F - - T CsxnGIi ddd0218a34972ceab3d200b78959bd2b4c95eadf37399df35bfd68a5b658bc78,ba352de8d8faa0ecfdbeee560fa308fe192023d3b18d83a68845933bebf28360 (empty) - 769 769 57,56,53,51,50,4,5,47,22,19,65279,10,21,18,65278,9,100,98,3,6 - - - - - - - - - - - - 0 - -
|
XXXXXXXXXX.XXXXXX C4J4Th3PJpwUYZZ6gc 192.150.187.164 58870 194.127.84.106 443 TLSv10 TLS_RSA_WITH_RC4_128_MD5 - - F - - T CsxnGIi ddd0218a34972ceab3d200b78959bd2b4c95eadf37399df35bfd68a5b658bc78,ba352de8d8faa0ecfdbeee560fa308fe192023d3b18d83a68845933bebf28360 (empty) - 769 769 57,56,53,51,50,4,5,47,22,19,65279,10,21,18,65278,9,100,98,3,6 - - - - - - - - - - - - 0 - -
|
||||||
#close XXXX-XX-XX-XX-XX-XX
|
#close XXXX-XX-XX-XX-XX-XX
|
||||||
|
|
|
@ -1,2 +0,0 @@
|
||||||
### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63.
|
|
||||||
[warning] <...>/udp-test.evt:4: Remove in v7.1: Analyzer spicy::TEST is using the deprecated 'port' or 'ports' keyword to register well-known ports. Use Analyzer::register_for_ports() in the accompanying Zeek script instead.
|
|
|
@ -1,3 +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.
|
||||||
[error] <...>/port-fail.evt:9: port outside of valid range
|
[error] <...>/port-fail.evt:7: port outside of valid range
|
||||||
[error] error loading EVT file "<...>/port-fail.evt"
|
[error] error loading EVT file "<...>/port-fail.evt"
|
||||||
|
|
19
testing/btest/Baseline/spicy.port/output
Normal file
19
testing/btest/Baseline/spicy.port/output
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63.
|
||||||
|
Analyzer::ANALYZER_SPICY_TEST, 11337/udp
|
||||||
|
Analyzer::ANALYZER_SPICY_TEST, 11338/udp
|
||||||
|
Analyzer::ANALYZER_SPICY_TEST, 11339/udp
|
||||||
|
Analyzer::ANALYZER_SPICY_TEST, 11340/udp
|
||||||
|
Analyzer::ANALYZER_SPICY_TEST, 31337/udp
|
||||||
|
Analyzer::ANALYZER_SPICY_TEST, 31338/udp
|
||||||
|
Analyzer::ANALYZER_SPICY_TEST, 31339/udp
|
||||||
|
Analyzer::ANALYZER_SPICY_TEST, 31340/udp
|
||||||
|
{
|
||||||
|
31339/udp,
|
||||||
|
31337/udp,
|
||||||
|
31338/udp,
|
||||||
|
11339/udp,
|
||||||
|
11338/udp,
|
||||||
|
11340/udp,
|
||||||
|
31340/udp,
|
||||||
|
11337/udp
|
||||||
|
}
|
|
@ -25,7 +25,8 @@ type Y = unit {
|
||||||
|
|
||||||
# @TEST-START-FILE foo.evt
|
# @TEST-START-FILE foo.evt
|
||||||
protocol analyzer spicy::foo over UDP:
|
protocol analyzer spicy::foo over UDP:
|
||||||
parse with foo::X;
|
parse with foo::X,
|
||||||
|
ports { 12345/udp, 31337/udp };
|
||||||
|
|
||||||
import foo;
|
import foo;
|
||||||
|
|
||||||
|
@ -35,13 +36,6 @@ on foo::X -> event foo::X($conn, $is_orig, self.y);
|
||||||
# @TEST-END-FILE
|
# @TEST-END-FILE
|
||||||
|
|
||||||
# @TEST-START-FILE foo.zeek
|
# @TEST-START-FILE foo.zeek
|
||||||
const foo_ports = { 12345/udp, 31337/udp};
|
|
||||||
|
|
||||||
event zeek_init()
|
|
||||||
{
|
|
||||||
Analyzer::register_for_ports(Analyzer::ANALYZER_SPICY_FOO, foo_ports);
|
|
||||||
}
|
|
||||||
|
|
||||||
event foo::X(c: connection, is_orig: bool, y: foo::Y)
|
event foo::X(c: connection, is_orig: bool, y: foo::Y)
|
||||||
{
|
{
|
||||||
print fmt("is_orig=%d y=%s", is_orig, y);
|
print fmt("is_orig=%d y=%s", is_orig, y);
|
||||||
|
|
22
testing/btest/spicy/port-fail.evt
Normal file
22
testing/btest/spicy/port-fail.evt
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
# @TEST-REQUIRES: have-spicy
|
||||||
|
#
|
||||||
|
# @TEST-EXEC-FAIL: spicyz %INPUT -d -o x.hlto >output 2>&1
|
||||||
|
# @TEST-EXEC: TEST_DIFF_CANONIFIER=diff-canonifier-spicy btest-diff output
|
||||||
|
|
||||||
|
protocol analyzer spicy::SSH over TCP:
|
||||||
|
port 123456/udp;
|
||||||
|
|
||||||
|
@TEST-START-NEXT
|
||||||
|
|
||||||
|
protocol analyzer spicy::SSH over TCP:
|
||||||
|
port -1/udp;
|
||||||
|
|
||||||
|
@TEST-START-NEXT
|
||||||
|
|
||||||
|
protocol analyzer spicy::SSH over TCP:
|
||||||
|
port 1/udp-2/tcp;
|
||||||
|
|
||||||
|
@TEST-START-NEXT
|
||||||
|
|
||||||
|
protocol analyzer spicy::SSH over TCP:
|
||||||
|
port 2/udp-1/udp;
|
24
testing/btest/spicy/port-range-one-port.zeek
Normal file
24
testing/btest/spicy/port-range-one-port.zeek
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
# @TEST-REQUIRES: have-spicy
|
||||||
|
#
|
||||||
|
# @TEST-EXEC: spicyz -o test.hlto udp-test.spicy ./udp-test.evt
|
||||||
|
# @TEST-EXEC: HILTI_DEBUG=zeek zeek -Cr ${TRACES}/udp-packet.pcap test.hlto %INPUT >out 2>&1
|
||||||
|
# @TEST-EXEC: grep -e 'Scheduling analyzer' -e 'error during parsing' < out > out.filtered
|
||||||
|
# @TEST-EXEC: btest-diff out.filtered
|
||||||
|
|
||||||
|
# @TEST-DOC: Expect a single 'Scheduling analyzer ...' message in the debug output and no parsing errors. There was a bug that 'port 31336/udp' would be wrongly interpreted as a 31336/udp-31337/udp port range. Regression test for #3278.
|
||||||
|
|
||||||
|
# @TEST-START-FILE udp-test.spicy
|
||||||
|
module UDPTest;
|
||||||
|
|
||||||
|
public type Message = unit {
|
||||||
|
data: bytes &eod {
|
||||||
|
assert False: "not reached";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
# @TEST-END-FILE
|
||||||
|
|
||||||
|
# @TEST-START-FILE udp-test.evt
|
||||||
|
protocol analyzer spicy::UDP_TEST over UDP:
|
||||||
|
parse with UDPTest::Message,
|
||||||
|
port 31336/udp;
|
||||||
|
# @TEST-END-FILE
|
32
testing/btest/spicy/port.zeek
Normal file
32
testing/btest/spicy/port.zeek
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
# @TEST-REQUIRES: have-spicy
|
||||||
|
#
|
||||||
|
# @TEST-EXEC: spicyz -d -o test.hlto test.spicy test.evt
|
||||||
|
# @TEST-EXEC: zeek test.hlto %INPUT >output
|
||||||
|
# @TEST-EXEC: btest-diff output
|
||||||
|
#
|
||||||
|
# @TEST-DOC: Check that we raise port events for Spicy analyzers, and that the ports get correctly registered.
|
||||||
|
|
||||||
|
event spicy_analyzer_for_port(a: Analyzer::Tag, p: port){
|
||||||
|
print a, p;
|
||||||
|
}
|
||||||
|
|
||||||
|
event zeek_done() {
|
||||||
|
print Analyzer::ports[Analyzer::ANALYZER_SPICY_TEST];
|
||||||
|
}
|
||||||
|
|
||||||
|
# @TEST-START-FILE test.spicy
|
||||||
|
module Test;
|
||||||
|
|
||||||
|
import zeek;
|
||||||
|
|
||||||
|
public type Message = unit {
|
||||||
|
data: bytes &eod {}
|
||||||
|
};
|
||||||
|
# @TEST-END-FILE
|
||||||
|
|
||||||
|
# @TEST-START-FILE test.evt
|
||||||
|
protocol analyzer spicy::Test over UDP:
|
||||||
|
parse with Test::Message,
|
||||||
|
port 11337/udp-11340/udp,
|
||||||
|
ports {31337/udp-31340/udp};
|
||||||
|
# @TEST-END-FILE
|
2
testing/external/commit-hash.zeek-testing
vendored
2
testing/external/commit-hash.zeek-testing
vendored
|
@ -1 +1 @@
|
||||||
4f808b8e1a4e99e738af85f15a5534c0ee99cdba
|
ff3bb79aca72f79ca9cfb35de4cf779d0a6802e3
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
3df94cb39ab9c0079e82a7f2cd5edb561c2ec07b
|
4a2735a9768b124d290a1692d47a25fd8d365320
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue