mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 06:38:20 +00:00
Merge branch 'topic/jgras/connection-packet-threshold' of https://github.com/J-Gras/zeek
* 'topic/jgras/connection-packet-threshold' of https://github.com/J-Gras/zeek: Add NEWS entry for generic packet thresholds Allow for multiple generic packet thresholds Add btest for conn_generic_packet_threshold_crossed event Update dump-events btest baseline Add conn_generic_packet_threshold_crossed event
This commit is contained in:
commit
0c60f2a70a
11 changed files with 140 additions and 2 deletions
18
CHANGES
18
CHANGES
|
@ -1,3 +1,21 @@
|
||||||
|
8.0.0-dev.615 | 2025-07-08 17:53:56 +0200
|
||||||
|
|
||||||
|
* Add NEWS entry for generic packet thresholds (Jan Grashoefer, Corelight)
|
||||||
|
|
||||||
|
* Allow for multiple generic packet thresholds (Jan Grashoefer, Corelight)
|
||||||
|
|
||||||
|
Co-authored-by: Arne Welzel <arne.welzel@corelight.com>
|
||||||
|
|
||||||
|
* Add btest for conn_generic_packet_threshold_crossed event (Jan Grashoefer, Corelight)
|
||||||
|
|
||||||
|
* Update dump-events btest baseline (Jan Grashoefer, Corelight)
|
||||||
|
|
||||||
|
Changes in endpoint stats are a side-effect caused by the ConnSize
|
||||||
|
analyzer updating the conn record triggering the threshold event. The
|
||||||
|
phenomenon is described in https://github.com/zeek/zeek/issues/4214.
|
||||||
|
|
||||||
|
* Add conn_generic_packet_threshold_crossed event (Jan Grashoefer, Corelight)
|
||||||
|
|
||||||
8.0.0-dev.609 | 2025-07-08 11:42:05 +0100
|
8.0.0-dev.609 | 2025-07-08 11:42:05 +0100
|
||||||
|
|
||||||
* PPPoE: don't forward more bytes than header indicates (Johanna Amann, Corelight)
|
* PPPoE: don't forward more bytes than header indicates (Johanna Amann, Corelight)
|
||||||
|
|
11
NEWS
11
NEWS
|
@ -218,6 +218,17 @@ New Functionality
|
||||||
|
|
||||||
get_tags_by_category("ANALYZER");
|
get_tags_by_category("ANALYZER");
|
||||||
|
|
||||||
|
- A new ``conn_generic_packet_threshold_crossed`` event was introduced. The event triggers
|
||||||
|
for any IP-based session that reaches a given threshold. Multiple packet thresholds can
|
||||||
|
be defined in ``ConnThreshold::generic_packet_thresholds``. The generic thresholds refer
|
||||||
|
to the total number of packets on a connection without taking direction into account
|
||||||
|
(i.e. the event also triggers on one-sided connections).
|
||||||
|
|
||||||
|
The event is intended as an alternative to the ``new_connection`` event that allows for
|
||||||
|
ignoring short-lived connections like DNS or scans. For example, it can be used to set
|
||||||
|
up traditional connection monitoring without introducing overhead for connections that
|
||||||
|
would never reach a larger threshold anyway.
|
||||||
|
|
||||||
Changed Functionality
|
Changed Functionality
|
||||||
---------------------
|
---------------------
|
||||||
|
|
||||||
|
|
2
VERSION
2
VERSION
|
@ -1 +1 @@
|
||||||
8.0.0-dev.609
|
8.0.0-dev.615
|
||||||
|
|
|
@ -6379,6 +6379,18 @@ export {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
module ConnThreshold;
|
||||||
|
|
||||||
|
export {
|
||||||
|
## Number of packets required to be observed on any IP-based session to
|
||||||
|
## trigger :zeek:id:`conn_generic_packet_threshold_crossed`. Note that the
|
||||||
|
## thresholds refers to the total number of packets transferred in both
|
||||||
|
## directions.
|
||||||
|
##
|
||||||
|
## .. zeek:see:: conn_generic_packet_threshold_crossed
|
||||||
|
const generic_packet_thresholds: set[count] = {} &redef;
|
||||||
|
}
|
||||||
|
|
||||||
module GLOBAL;
|
module GLOBAL;
|
||||||
|
|
||||||
@load base/bif/event.bif
|
@load base/bif/event.bif
|
||||||
|
|
|
@ -11,6 +11,8 @@
|
||||||
|
|
||||||
namespace zeek::analyzer::conn_size {
|
namespace zeek::analyzer::conn_size {
|
||||||
|
|
||||||
|
std::vector<uint64_t> ConnSize_Analyzer::generic_pkt_thresholds;
|
||||||
|
|
||||||
ConnSize_Analyzer::ConnSize_Analyzer(Connection* c) : Analyzer("CONNSIZE", c) { start_time = c->StartTime(); }
|
ConnSize_Analyzer::ConnSize_Analyzer(Connection* c) : Analyzer("CONNSIZE", c) { start_time = c->StartTime(); }
|
||||||
|
|
||||||
void ConnSize_Analyzer::Init() {
|
void ConnSize_Analyzer::Init() {
|
||||||
|
@ -25,6 +27,11 @@ void ConnSize_Analyzer::Init() {
|
||||||
orig_pkts_thresh = 0;
|
orig_pkts_thresh = 0;
|
||||||
resp_bytes_thresh = 0;
|
resp_bytes_thresh = 0;
|
||||||
resp_pkts_thresh = 0;
|
resp_pkts_thresh = 0;
|
||||||
|
|
||||||
|
generic_pkt_thresh = 0;
|
||||||
|
generic_pkt_thresh_next_idx = 0;
|
||||||
|
if ( conn_generic_packet_threshold_crossed )
|
||||||
|
NextGenericPacketThreshold();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConnSize_Analyzer::Done() { Analyzer::Done(); }
|
void ConnSize_Analyzer::Done() { Analyzer::Done(); }
|
||||||
|
@ -36,7 +43,21 @@ void ConnSize_Analyzer::ThresholdEvent(EventHandlerPtr f, uint64_t threshold, bo
|
||||||
EnqueueConnEvent(f, ConnVal(), val_mgr->Count(threshold), val_mgr->Bool(is_orig));
|
EnqueueConnEvent(f, ConnVal(), val_mgr->Count(threshold), val_mgr->Bool(is_orig));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ConnSize_Analyzer::NextGenericPacketThreshold() {
|
||||||
|
if ( generic_pkt_thresh_next_idx >= generic_pkt_thresholds.size() ) {
|
||||||
|
generic_pkt_thresh = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
generic_pkt_thresh = generic_pkt_thresholds[generic_pkt_thresh_next_idx++];
|
||||||
|
}
|
||||||
|
|
||||||
void ConnSize_Analyzer::CheckThresholds(bool is_orig) {
|
void ConnSize_Analyzer::CheckThresholds(bool is_orig) {
|
||||||
|
if ( generic_pkt_thresh && (orig_pkts + resp_pkts) == generic_pkt_thresh ) {
|
||||||
|
EnqueueConnEvent(conn_generic_packet_threshold_crossed, ConnVal(), val_mgr->Count(generic_pkt_thresh));
|
||||||
|
NextGenericPacketThreshold();
|
||||||
|
}
|
||||||
|
|
||||||
if ( is_orig ) {
|
if ( is_orig ) {
|
||||||
if ( orig_bytes_thresh && orig_bytes >= orig_bytes_thresh ) {
|
if ( orig_bytes_thresh && orig_bytes >= orig_bytes_thresh ) {
|
||||||
ThresholdEvent(conn_bytes_threshold_crossed, orig_bytes_thresh, is_orig);
|
ThresholdEvent(conn_bytes_threshold_crossed, orig_bytes_thresh, is_orig);
|
||||||
|
|
|
@ -26,9 +26,19 @@ public:
|
||||||
|
|
||||||
static analyzer::Analyzer* Instantiate(Connection* conn) { return new ConnSize_Analyzer(conn); }
|
static analyzer::Analyzer* Instantiate(Connection* conn) { return new ConnSize_Analyzer(conn); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the generic packet thresholds.
|
||||||
|
*
|
||||||
|
* @param thresholds The generic packet thresholds to set.
|
||||||
|
*/
|
||||||
|
static void SetGenericPacketThresholds(std::vector<uint64_t> thresholds) {
|
||||||
|
generic_pkt_thresholds = std::move(thresholds);
|
||||||
|
};
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void DeliverPacket(int len, const u_char* data, bool is_orig, uint64_t seq, const IP_Hdr* ip, int caplen) override;
|
void DeliverPacket(int len, const u_char* data, bool is_orig, uint64_t seq, const IP_Hdr* ip, int caplen) override;
|
||||||
void CheckThresholds(bool is_orig);
|
void CheckThresholds(bool is_orig);
|
||||||
|
void NextGenericPacketThreshold();
|
||||||
|
|
||||||
void ThresholdEvent(EventHandlerPtr f, uint64_t threshold, bool is_orig);
|
void ThresholdEvent(EventHandlerPtr f, uint64_t threshold, bool is_orig);
|
||||||
|
|
||||||
|
@ -42,8 +52,13 @@ protected:
|
||||||
uint64_t orig_pkts_thresh = 0;
|
uint64_t orig_pkts_thresh = 0;
|
||||||
uint64_t resp_pkts_thresh = 0;
|
uint64_t resp_pkts_thresh = 0;
|
||||||
|
|
||||||
|
uint64_t generic_pkt_thresh = 0;
|
||||||
|
size_t generic_pkt_thresh_next_idx = 0;
|
||||||
|
|
||||||
double start_time = 0.0;
|
double start_time = 0.0;
|
||||||
double duration_thresh = 0.0;
|
double duration_thresh = 0.0;
|
||||||
|
|
||||||
|
static std::vector<uint64_t> generic_pkt_thresholds;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Exposed to make it available to script optimization.
|
// Exposed to make it available to script optimization.
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
#include "zeek/plugin/Plugin.h"
|
#include "zeek/plugin/Plugin.h"
|
||||||
|
|
||||||
|
#include "zeek/Val.h"
|
||||||
#include "zeek/analyzer/Component.h"
|
#include "zeek/analyzer/Component.h"
|
||||||
#include "zeek/analyzer/protocol/conn-size/ConnSize.h"
|
#include "zeek/analyzer/protocol/conn-size/ConnSize.h"
|
||||||
|
|
||||||
|
@ -18,6 +19,20 @@ public:
|
||||||
config.description = "Connection size analyzer";
|
config.description = "Connection size analyzer";
|
||||||
return config;
|
return config;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void InitPostScript() override {
|
||||||
|
// Load generic_packet_thresholds at InitPostScript() time.
|
||||||
|
auto t = id::find_const<TableVal>("ConnThreshold::generic_packet_thresholds");
|
||||||
|
std::vector<uint64_t> thresholds;
|
||||||
|
thresholds.reserve(t->Size());
|
||||||
|
|
||||||
|
auto lv = t->ToPureListVal();
|
||||||
|
for ( auto i = 0; i < lv->Length(); i++ )
|
||||||
|
thresholds.emplace_back(lv->Idx(i)->AsCount());
|
||||||
|
std::sort(thresholds.begin(), thresholds.end());
|
||||||
|
|
||||||
|
zeek::analyzer::conn_size::ConnSize_Analyzer::SetGenericPacketThresholds(thresholds);
|
||||||
|
}
|
||||||
} plugin;
|
} plugin;
|
||||||
|
|
||||||
} // namespace zeek::plugin::detail::Zeek_ConnSize
|
} // namespace zeek::plugin::detail::Zeek_ConnSize
|
||||||
|
|
|
@ -46,3 +46,12 @@ event conn_packets_threshold_crossed%(c: connection, threshold: count, is_orig:
|
||||||
## get_current_conn_bytes_threshold get_current_conn_packets_threshold
|
## get_current_conn_bytes_threshold get_current_conn_packets_threshold
|
||||||
## set_current_conn_duration_threshold get_current_conn_duration_threshold
|
## set_current_conn_duration_threshold get_current_conn_duration_threshold
|
||||||
event conn_duration_threshold_crossed%(c: connection, threshold: interval, is_orig: bool%);
|
event conn_duration_threshold_crossed%(c: connection, threshold: interval, is_orig: bool%);
|
||||||
|
|
||||||
|
## Generated for any IP-based session once :zeek:id:`ConnThreshold::generic_packet_thresholds` packets have been
|
||||||
|
## observed. Only one endpoint sending traffic is sufficient to trigger the event. This allows to handle new
|
||||||
|
## connections, while short interactions, like scans consisting of only a few packets, are ignored.
|
||||||
|
##
|
||||||
|
## c: the connection.
|
||||||
|
##
|
||||||
|
## threshold: the threshold that was set
|
||||||
|
event conn_generic_packet_threshold_crossed%(c: connection, threshold: count%);
|
|
@ -106,7 +106,8 @@ event network_time_init%(%);
|
||||||
##
|
##
|
||||||
## Handling this event is potentially expensive. For example, during a SYN
|
## Handling this event is potentially expensive. For example, during a SYN
|
||||||
## flooding attack, every spoofed SYN packet will lead to a new
|
## flooding attack, every spoofed SYN packet will lead to a new
|
||||||
## event.
|
## event. Consider to use events like :zeek:id:`connection_established` or
|
||||||
|
## :zeek:id:`conn_generic_packet_threshold_crossed` instead.
|
||||||
event new_connection%(c: connection%);
|
event new_connection%(c: connection%);
|
||||||
|
|
||||||
## Generated for a connection whose tunneling has changed. This could
|
## Generated for a connection whose tunneling has changed. This could
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63.
|
||||||
|
=== Generic threshold crossed ===
|
||||||
|
new_connection: [orig_h=141.142.228.5, orig_p=59856/tcp, resp_h=192.150.187.43, resp_p=80/tcp, proto=6, ctx=[]]
|
||||||
|
conn_generic_packet_threshold_crossed: [orig_h=141.142.228.5, orig_p=59856/tcp, resp_h=192.150.187.43, resp_p=80/tcp, proto=6, ctx=[]] at 5
|
||||||
|
new_connection: [orig_h=192.168.170.8, orig_p=32795/udp, resp_h=192.168.170.20, resp_p=53/udp, proto=17, ctx=[]]
|
||||||
|
conn_generic_packet_threshold_crossed: [orig_h=192.168.170.8, orig_p=32795/udp, resp_h=192.168.170.20, resp_p=53/udp, proto=17, ctx=[]] at 5
|
||||||
|
new_connection: [orig_h=192.168.170.8, orig_p=32795/udp, resp_h=192.168.170.20, resp_p=53/udp, proto=17, ctx=[]]
|
||||||
|
conn_generic_packet_threshold_crossed: [orig_h=192.168.170.8, orig_p=32795/udp, resp_h=192.168.170.20, resp_p=53/udp, proto=17, ctx=[]] at 5
|
||||||
|
new_connection: [orig_h=192.168.170.8, orig_p=0/unknown, resp_h=192.168.170.56, resp_p=0/unknown, proto=132, ctx=[]]
|
||||||
|
conn_generic_packet_threshold_crossed: [orig_h=192.168.170.8, orig_p=0/unknown, resp_h=192.168.170.56, resp_p=0/unknown, proto=132, ctx=[]] at 5
|
||||||
|
new_connection: [orig_h=141.142.228.5, orig_p=59856/tcp, resp_h=192.150.187.43, resp_p=80/tcp, proto=6, ctx=[]]
|
||||||
|
conn_generic_packet_threshold_crossed: [orig_h=141.142.228.5, orig_p=59856/tcp, resp_h=192.150.187.43, resp_p=80/tcp, proto=6, ctx=[]] at 5
|
||||||
|
conn_generic_packet_threshold_crossed: [orig_h=141.142.228.5, orig_p=59856/tcp, resp_h=192.150.187.43, resp_p=80/tcp, proto=6, ctx=[]] at 10
|
||||||
|
=== Generic threshold not crossed ===
|
||||||
|
new_connection: [orig_h=141.142.228.5, orig_p=59856/tcp, resp_h=192.150.187.43, resp_p=80/tcp, proto=6, ctx=[]]
|
||||||
|
new_connection: [orig_h=10.87.3.74, orig_p=51871/udp, resp_h=10.87.1.10, resp_p=53/udp, proto=17, ctx=[]]
|
||||||
|
new_connection: [orig_h=141.142.228.5, orig_p=59856/tcp, resp_h=192.150.187.43, resp_p=80/tcp, proto=6, ctx=[]]
|
19
testing/btest/core/conn-generic-packet-threshold.zeek
Normal file
19
testing/btest/core/conn-generic-packet-threshold.zeek
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
# @TEST-EXEC: echo "=== Generic threshold crossed ===" > out
|
||||||
|
# @TEST-EXEC: zeek -b -C -r $TRACES/http/get.trace %INPUT >> out
|
||||||
|
# @TEST-EXEC: zeek -b -C -r $TRACES/dns/long-connection.pcap %INPUT >> out
|
||||||
|
# @TEST-EXEC: zeek -b -C -r $TRACES/communityid/sctp.pcap %INPUT >> out
|
||||||
|
# @TEST-EXEC: zeek -b -C -r $TRACES/http/get.trace %INPUT ConnThreshold::generic_packet_thresholds+={10} >> out
|
||||||
|
# @TEST-EXEC: echo "=== Generic threshold not crossed ===" >> out
|
||||||
|
# @TEST-EXEC: zeek -b -C -r $TRACES/tcp/syn.pcap %INPUT >> out
|
||||||
|
# @TEST-EXEC: zeek -b -C -r $TRACES/dns/dns-binds.pcap %INPUT >> out
|
||||||
|
# @TEST-EXEC: zeek -b -C -r $TRACES/http/get.trace %INPUT ConnThreshold::generic_packet_thresholds={15} >> out
|
||||||
|
|
||||||
|
# @TEST-EXEC: btest-diff out
|
||||||
|
|
||||||
|
redef ConnThreshold::generic_packet_thresholds = {5};
|
||||||
|
|
||||||
|
event new_connection(c: connection)
|
||||||
|
{ print fmt("new_connection: %s", c$id); }
|
||||||
|
|
||||||
|
event conn_generic_packet_threshold_crossed(c: connection, threshold: count)
|
||||||
|
{ print fmt("conn_generic_packet_threshold_crossed: %s at %d", c$id, threshold); }
|
Loading…
Add table
Add a link
Reference in a new issue