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:
Johanna Amann 2024-08-27 13:42:03 +01:00
commit c186726bfa
29 changed files with 404 additions and 57 deletions

77
CHANGES
View file

@ -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)

View file

@ -1 +1 @@
7.1.0-dev.209 7.1.0-dev.222

2
doc

@ -1 +1 @@
Subproject commit 2f14aee921e8f7df417423079f9341e1e72c5d7e Subproject commit fc15fea160a40c88ca9868a21203097b3a2b9b71

View file

@ -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);

View file

@ -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)

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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;
}; };

View file

@ -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);
} }
} }

View file

@ -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);
} }
} }
} }

View file

@ -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); }

View file

@ -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) {

View file

@ -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,

View file

@ -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

View file

@ -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()});

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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.

View file

@ -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"

View 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
}

View file

@ -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);

View 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;

View 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

View 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

View file

@ -1 +1 @@
4f808b8e1a4e99e738af85f15a5534c0ee99cdba ff3bb79aca72f79ca9cfb35de4cf779d0a6802e3

View file

@ -1 +1 @@
3df94cb39ab9c0079e82a7f2cd5edb561c2ec07b 4a2735a9768b124d290a1692d47a25fd8d365320