diff --git a/tenzir/changelog/unreleased/ocsf-network-detection-operators.md b/tenzir/changelog/unreleased/ocsf-network-detection-operators.md new file mode 100644 index 00000000..1438b307 --- /dev/null +++ b/tenzir/changelog/unreleased/ocsf-network-detection-operators.md @@ -0,0 +1,35 @@ +--- +title: OCSF network detection operators +type: feature +authors: + - mavam + - codex +prs: + - 172 +created: 2026-08-07T20:53:58.221185Z +--- + +The `tenzir` package now turns OCSF Network Activity streams into Detection +Findings for scan fan-out, beacon cadence, long connections, and outbound volume +bursts. + +Run any detector as a user-defined operator between your normalized stream and +the findings topic: + +```tql +subscribe "ocsf" +tenzir::detect::network::beacon_cadence +publish "findings" +``` + +Each operator exposes its time window, late-event tolerance, and detection +thresholds as named arguments for environment-specific tuning. + +The beacon and volume detectors measure originator traffic via +`traffic.bytes_out`, the source-to-destination byte count that the NetFlow, +Zeek, and Suricata mappings populate consistently. + +Detectors live in the `tenzir::detect::network` namespace, leaving room for +future detector families over other OCSF classes. Every finding carries MITRE +ATT&CK tactic and technique mappings in `finding_info.attacks` and a versioned +analytic identity for traceability. diff --git a/tenzir/examples/detect-beacon-cadence.tql b/tenzir/examples/detect-beacon-cadence.tql new file mode 100644 index 00000000..a13a8f82 --- /dev/null +++ b/tenzir/examples/detect-beacon-cadence.tql @@ -0,0 +1,9 @@ +--- +name: Detect beacon cadence +description: | + Detects periodic network activity and publishes OCSF Detection Findings. +--- + +subscribe "ocsf" +tenzir::detect::network::beacon_cadence +publish "findings" diff --git a/tenzir/operators/detect/network/beacon_cadence.tql b/tenzir/operators/detect/network/beacon_cadence.tql new file mode 100644 index 00000000..03b613e9 --- /dev/null +++ b/tenzir/operators/detect/network/beacon_cadence.tql @@ -0,0 +1,116 @@ +--- +description: Detects periodic network activity with robust timing and size statistics. +args: + named: + - name: window_size + type: duration + default: 30min + description: Event-time window over which to measure cadence. + - name: tolerance + type: duration + default: 1min + description: Maximum expected lateness for out-of-order events. + - name: idle_timeout + type: duration + default: 5min + description: Inactivity after which the current window closes. + - name: min_samples + type: int + default: 8 + description: Minimum number of flows for one tuple. + - name: min_period + type: duration + default: 10s + description: Minimum median inter-arrival interval. + - name: max_period + type: duration + default: 3min + description: Maximum median inter-arrival interval. + - name: max_interval_dispersion + type: float + default: 0.2 + description: Maximum interval MAD as a fraction of the median. + - name: max_size + type: int + default: 4096 + description: Maximum median flow size in bytes. + - name: max_size_dispersion + type: float + default: 0.35 + description: Maximum size MAD as a fraction of the median. + - name: max_skew + type: float + default: 0.6 + description: Maximum absolute Bowley skewness for timing and size. +--- + +where class_uid == 4001 and activity_id == 6 +window size=$window_size, on=time, tolerance=$tolerance, + idle_timeout=$idle_timeout { + group { + src_ip: src_endpoint.ip, + dst_ip: dst_endpoint.ip, + dst_port: dst_endpoint.port, + } { + sort time + summarize times=collect(time), + sizes=collect(traffic.bytes_out), + samples=count() + intervals = times.deltas() + interval_median = intervals.median() + interval_mad = intervals.mad() + interval_skew = intervals.skewness(method="bowley") + size_median = sizes.median() + size_mad = sizes.mad() + size_skew = sizes.skewness(method="bowley") + src_ip = $group.src_ip + dst_ip = $group.dst_ip + dst_port = $group.dst_port + start = $window.start + end = $window.end + drop times, sizes, intervals + } +} +where samples >= $min_samples and + interval_median >= $min_period and interval_median <= $max_period and + interval_mad <= interval_median * $max_interval_dispersion and + abs(interval_skew) <= $max_skew and + size_median <= $max_size and + size_mad <= size_median * $max_size_dispersion and + abs(size_skew) <= $max_skew +this = { + time: now(), + metadata: { + product: {name: "Tenzir", vendor_name: "Tenzir"}, + uid: uuid(), + version: "1.9.0", + }, + category_uid: 2, + class_uid: 2004, + activity_id: 1, + type_uid: 200401, + severity_id: 3, + status_id: 1, + is_alert: true, + start_time: start, + end_time: end, + finding_info: { + uid: uuid(), + title: f"Periodic network activity from {src_ip} to {dst_ip}:{dst_port}", + desc: f"{samples} flows; interval median {interval_median}, MAD {interval_mad}", + analytic: { + name: "Beacon cadence", + uid: "tenzir::detect::network::beacon_cadence", + type_id: 3, + version: "1.0", + }, + attacks: [{ + tactic: {uid: "TA0011", name: "Command and Control"}, + technique: {uid: "T1071", name: "Application Layer Protocol"}, + }], + }, + evidences: [{ + src_endpoint: {ip: src_ip}, + dst_endpoint: {ip: dst_ip, port: dst_port}, + }], +} diff --git a/tenzir/operators/detect/network/long_connection.tql b/tenzir/operators/detect/network/long_connection.tql new file mode 100644 index 00000000..1c48b984 --- /dev/null +++ b/tenzir/operators/detect/network/long_connection.tql @@ -0,0 +1,75 @@ +--- +description: Detects long-lived network connections split across flow observations. +args: + named: + - name: window_size + type: duration + default: 1h + description: Event-time window over which to sum observed duration. + - name: tolerance + type: duration + default: 1min + description: Maximum expected lateness for out-of-order events. + - name: idle_timeout + type: duration + default: 15min + description: Inactivity after which the current window closes. + - name: min_observed + type: duration + default: 45min + description: Minimum accumulated connection duration. +--- + +where class_uid == 4001 and activity_id == 6 +window size=$window_size, on=time, tolerance=$tolerance, + idle_timeout=$idle_timeout { + group { + src_ip: src_endpoint.ip, + dst_ip: dst_endpoint.ip, + dst_port: dst_endpoint.port, + } { + summarize observed_ms=sum(traffic.timespan.duration), flows=count() + src_ip = $group.src_ip + dst_ip = $group.dst_ip + dst_port = $group.dst_port + start = $window.start + end = $window.end + } +} +where observed_ms >= count_milliseconds($min_observed) +this = { + time: now(), + metadata: { + product: {name: "Tenzir", vendor_name: "Tenzir"}, + uid: uuid(), + version: "1.9.0", + }, + category_uid: 2, + class_uid: 2004, + activity_id: 1, + type_uid: 200401, + severity_id: 3, + status_id: 1, + is_alert: true, + start_time: start, + end_time: end, + finding_info: { + uid: uuid(), + title: f"Long network connection from {src_ip} to {dst_ip}:{dst_port}", + desc: f"{flows} flow observations cover {observed_ms}ms", + analytic: { + name: "Long network connection", + uid: "tenzir::detect::network::long_connection", + type_id: 1, + version: "1.0", + }, + attacks: [{ + tactic: {uid: "TA0011", name: "Command and Control"}, + technique: {uid: "T1071", name: "Application Layer Protocol"}, + }], + }, + evidences: [{ + src_endpoint: {ip: src_ip}, + dst_endpoint: {ip: dst_ip, port: dst_port}, + }], +} diff --git a/tenzir/operators/detect/network/outbound_volume_burst.tql b/tenzir/operators/detect/network/outbound_volume_burst.tql new file mode 100644 index 00000000..4b4a3bc6 --- /dev/null +++ b/tenzir/operators/detect/network/outbound_volume_burst.tql @@ -0,0 +1,69 @@ +--- +description: Detects outbound byte volume from an internal asset above a fixed threshold. +args: + named: + - name: window_size + type: duration + default: 15min + description: Event-time window over which to sum outbound bytes. + - name: tolerance + type: duration + default: 1min + description: Maximum expected lateness for out-of-order events. + - name: idle_timeout + type: duration + default: 5min + description: Inactivity after which the current window closes. + - name: min_bytes_out + type: int + default: 500M + description: Minimum outbound bytes from one internal asset. +--- + +where class_uid == 4001 and activity_id == 6 +where src_endpoint.network_scope_id == 1 and + dst_endpoint.network_scope_id == 2 +window size=$window_size, on=time, tolerance=$tolerance, + idle_timeout=$idle_timeout { + group src_endpoint.ip { + summarize bytes_out=sum(traffic.bytes_out), + destinations=count_distinct(dst_endpoint.ip) + asset = $group + start = $window.start + end = $window.end + } +} +where bytes_out >= $min_bytes_out +this = { + time: now(), + metadata: { + product: {name: "Tenzir", vendor_name: "Tenzir"}, + uid: uuid(), + version: "1.9.0", + }, + category_uid: 2, + class_uid: 2004, + activity_id: 1, + type_uid: 200401, + severity_id: 3, + status_id: 1, + is_alert: true, + start_time: start, + end_time: end, + finding_info: { + uid: uuid(), + title: f"Outbound volume burst from {asset}", + desc: f"{asset} sent {bytes_out} bytes to {destinations} external destinations", + analytic: { + name: "Outbound volume threshold", + uid: "tenzir::detect::network::outbound_volume_burst", + type_id: 1, + version: "1.0", + }, + attacks: [{ + tactic: {uid: "TA0010", name: "Exfiltration"}, + technique: {uid: "T1030", name: "Data Transfer Size Limits"}, + }], + }, + evidences: [{src_endpoint: {ip: asset, network_scope_id: 1}}], +} diff --git a/tenzir/operators/detect/network/scan_fan_out.tql b/tenzir/operators/detect/network/scan_fan_out.tql new file mode 100644 index 00000000..b0ed0f65 --- /dev/null +++ b/tenzir/operators/detect/network/scan_fan_out.tql @@ -0,0 +1,94 @@ +--- +description: Detects scan fan-out from small flows and unanswered TCP attempts. +args: + named: + - name: window_size + type: duration + default: 5min + description: Event-time window over which to measure fan-out. + - name: tolerance + type: duration + default: 30s + description: Maximum expected lateness for out-of-order events. + - name: idle_timeout + type: duration + default: 2min + description: Inactivity after which the current window closes. + - name: min_flows + type: int + default: 5 + description: Minimum number of flows from one source. + - name: max_packets_per_flow + type: float + default: 5.0 + description: Maximum average number of packets per flow. + - name: min_fanout + type: int + default: 5 + description: Minimum number of distinct destination hosts or ports. + - name: min_unanswered_share + type: float + default: 0.8 + description: Minimum share of TCP flows whose flags contain no ACK. +--- + +where class_uid == 4001 and activity_id == 6 +window size=$window_size, on=time, tolerance=$tolerance, + idle_timeout=$idle_timeout { + group src_endpoint.ip { + summarize flows=count(), + targets=count_distinct(dst_endpoint.ip), + ports=count_distinct(dst_endpoint.port), + avg_packets=mean(traffic.packets), + tcp_flows=count(connection_info.tcp_flags), + unanswered=count_if(connection_info.tcp_flags, + flags => bit_and(flags, 16) == 0) + src_ip = $group + start = $window.start + end = $window.end + } +} +where flows >= $min_flows and + avg_packets <= $max_packets_per_flow and + (targets >= $min_fanout or ports >= $min_fanout) and + (tcp_flows == 0 or + unanswered >= tcp_flows * $min_unanswered_share) +this = { + time: now(), + metadata: { + product: {name: "Tenzir", vendor_name: "Tenzir"}, + uid: uuid(), + version: "1.9.0", + }, + category_uid: 2, + class_uid: 2004, + activity_id: 1, + type_uid: 200401, + severity_id: 3, + status_id: 1, + is_alert: true, + start_time: start, + end_time: end, + finding_info: { + uid: uuid(), + title: f"Scan fan-out from {src_ip}", + desc: f"{flows} flows reached {targets} hosts across {ports} ports", + analytic: { + name: "Scan fan-out", + uid: "tenzir::detect::network::scan_fan_out", + type_id: 1, + version: "1.0", + }, + attacks: [ + { + tactic: {uid: "TA0007", name: "Discovery"}, + technique: {uid: "T1046", name: "Network Service Discovery"}, + }, + { + tactic: {uid: "TA0043", name: "Reconnaissance"}, + technique: {uid: "T1595", name: "Active Scanning"}, + }, + ], + }, + evidences: [{src_endpoint: {ip: src_ip}}], +} diff --git a/tenzir/package.yaml b/tenzir/package.yaml index 0ca1842c..30997940 100644 --- a/tenzir/package.yaml +++ b/tenzir/package.yaml @@ -7,8 +7,10 @@ package_icon: https://raw.githubusercontent.com/tenzir/library/main/tenzir/packa description: | Utility operators maintained by Tenzir for common event-processing tasks. - This package currently provides helpers for enriching OCSF-shaped events with - OSINT objects and trimming OCSF events for downstream storage or transport. + This package provides helpers for enriching OCSF-shaped events with OSINT + objects, trimming OCSF events for downstream storage or transport, and + detecting scan fan-out, beacon cadence, long connections, and outbound volume + bursts in OCSF Network Activity streams. categories: - contexts diff --git a/tenzir/tests/detect/network/beacon_cadence.tql b/tenzir/tests/detect/network/beacon_cadence.tql new file mode 100644 index 00000000..33bda553 --- /dev/null +++ b/tenzir/tests/detect/network/beacon_cadence.tql @@ -0,0 +1,11 @@ +from {time: 2024-01-01T10:00:00Z, class_uid: 4001, activity_id: 6, src_endpoint: {ip: 10.0.0.9}, dst_endpoint: {ip: 203.0.113.5, port: 443}, traffic: {bytes_out: 512}}, + {time: 2024-01-01T10:01:00Z, class_uid: 4001, activity_id: 6, src_endpoint: {ip: 10.0.0.9}, dst_endpoint: {ip: 203.0.113.5, port: 443}, traffic: {bytes_out: 498}}, + {time: 2024-01-01T10:01:59Z, class_uid: 4001, activity_id: 6, src_endpoint: {ip: 10.0.0.9}, dst_endpoint: {ip: 203.0.113.5, port: 443}, traffic: {bytes_out: 505}}, + {time: 2024-01-01T10:03:00Z, class_uid: 4001, activity_id: 6, src_endpoint: {ip: 10.0.0.9}, dst_endpoint: {ip: 203.0.113.5, port: 443}, traffic: {bytes_out: 510}}, + {time: 2024-01-01T10:13:00Z, class_uid: 4001, activity_id: 6, src_endpoint: {ip: 10.0.0.9}, dst_endpoint: {ip: 203.0.113.5, port: 443}, traffic: {bytes_out: 502}}, + {time: 2024-01-01T10:14:00Z, class_uid: 4001, activity_id: 6, src_endpoint: {ip: 10.0.0.9}, dst_endpoint: {ip: 203.0.113.5, port: 443}, traffic: {bytes_out: 508}}, + {time: 2024-01-01T10:14:59Z, class_uid: 4001, activity_id: 6, src_endpoint: {ip: 10.0.0.9}, dst_endpoint: {ip: 203.0.113.5, port: 443}, traffic: {bytes_out: 495}}, + {time: 2024-01-01T10:16:00Z, class_uid: 4001, activity_id: 6, src_endpoint: {ip: 10.0.0.9}, dst_endpoint: {ip: 203.0.113.5, port: 443}, traffic: {bytes_out: 515}} +tenzir::detect::network::beacon_cadence max_interval_dispersion=0.2 +ocsf::cast +drop time, metadata.uid, finding_info.uid diff --git a/tenzir/tests/detect/network/beacon_cadence.txt b/tenzir/tests/detect/network/beacon_cadence.txt new file mode 100644 index 00000000..716a955f --- /dev/null +++ b/tenzir/tests/detect/network/beacon_cadence.txt @@ -0,0 +1,51 @@ +{ + activity_id: 1, + category_uid: 2, + class_uid: 2004, + end_time: 2024-01-01T10:30:00Z, + evidences: [ + { + dst_endpoint: { + ip: 203.0.113.5, + port: 443, + }, + src_endpoint: { + ip: 10.0.0.9, + }, + }, + ], + finding_info: { + analytic: { + name: "Beacon cadence", + type_id: 3, + uid: "tenzir::detect::network::beacon_cadence", + version: "1.0", + }, + attacks: [ + { + tactic: { + name: "Command and Control", + uid: "TA0011", + }, + technique: { + name: "Application Layer Protocol", + uid: "T1071", + }, + }, + ], + desc: "8 flows; interval median 1min, MAD 1s", + title: "Periodic network activity from 10.0.0.9 to 203.0.113.5:443", + }, + is_alert: true, + metadata: { + product: { + name: "Tenzir", + vendor_name: "Tenzir", + }, + version: "1.9.0", + }, + severity_id: 3, + start_time: 2024-01-01T10:00:00Z, + status_id: 1, + type_uid: 200401, +} diff --git a/tenzir/tests/detect/network/long_connection.tql b/tenzir/tests/detect/network/long_connection.tql new file mode 100644 index 00000000..f367b820 --- /dev/null +++ b/tenzir/tests/detect/network/long_connection.tql @@ -0,0 +1,8 @@ +from {time: 2024-01-01T10:00:00Z, class_uid: 4001, activity_id: 6, src_endpoint: {ip: 10.0.0.9}, dst_endpoint: {ip: 203.0.113.5, port: 8443}, traffic: {timespan: {duration: 900000}}}, + {time: 2024-01-01T10:15:00Z, class_uid: 4001, activity_id: 6, src_endpoint: {ip: 10.0.0.9}, dst_endpoint: {ip: 203.0.113.5, port: 8443}, traffic: {timespan: {duration: 900000}}}, + {time: 2024-01-01T10:30:00Z, class_uid: 4001, activity_id: 6, src_endpoint: {ip: 10.0.0.9}, dst_endpoint: {ip: 203.0.113.5, port: 8443}, traffic: {timespan: {duration: 900000}}}, + {time: 2024-01-01T10:45:00Z, class_uid: 4001, activity_id: 6, src_endpoint: {ip: 10.0.0.9}, dst_endpoint: {ip: 203.0.113.5, port: 8443}, traffic: {timespan: {duration: 900000}}}, + {time: 2024-01-01T10:20:00Z, class_uid: 4001, activity_id: 6, src_endpoint: {ip: 10.0.0.4}, dst_endpoint: {ip: 198.51.100.7, port: 443}, traffic: {timespan: {duration: 2000}}} +tenzir::detect::network::long_connection min_observed=45min +ocsf::cast +drop time, metadata.uid, finding_info.uid diff --git a/tenzir/tests/detect/network/long_connection.txt b/tenzir/tests/detect/network/long_connection.txt new file mode 100644 index 00000000..f67d5c8e --- /dev/null +++ b/tenzir/tests/detect/network/long_connection.txt @@ -0,0 +1,51 @@ +{ + activity_id: 1, + category_uid: 2, + class_uid: 2004, + end_time: 2024-01-01T11:00:00Z, + evidences: [ + { + dst_endpoint: { + ip: 203.0.113.5, + port: 8443, + }, + src_endpoint: { + ip: 10.0.0.9, + }, + }, + ], + finding_info: { + analytic: { + name: "Long network connection", + type_id: 1, + uid: "tenzir::detect::network::long_connection", + version: "1.0", + }, + attacks: [ + { + tactic: { + name: "Command and Control", + uid: "TA0011", + }, + technique: { + name: "Application Layer Protocol", + uid: "T1071", + }, + }, + ], + desc: "4 flow observations cover 3600000ms", + title: "Long network connection from 10.0.0.9 to 203.0.113.5:8443", + }, + is_alert: true, + metadata: { + product: { + name: "Tenzir", + vendor_name: "Tenzir", + }, + version: "1.9.0", + }, + severity_id: 3, + start_time: 2024-01-01T10:00:00Z, + status_id: 1, + type_uid: 200401, +} diff --git a/tenzir/tests/detect/network/outbound_volume_burst.tql b/tenzir/tests/detect/network/outbound_volume_burst.tql new file mode 100644 index 00000000..1e73500c --- /dev/null +++ b/tenzir/tests/detect/network/outbound_volume_burst.tql @@ -0,0 +1,6 @@ +from {time: 2024-01-01T10:00:00Z, class_uid: 4001, activity_id: 6, src_endpoint: {ip: 10.0.0.9, network_scope_id: 1}, dst_endpoint: {ip: 203.0.113.5, network_scope_id: 2}, traffic: {bytes_out: 400000000}}, + {time: 2024-01-01T10:04:00Z, class_uid: 4001, activity_id: 6, src_endpoint: {ip: 10.0.0.9, network_scope_id: 1}, dst_endpoint: {ip: 203.0.113.6, network_scope_id: 2}, traffic: {bytes_out: 250000000}}, + {time: 2024-01-01T10:07:00Z, class_uid: 4001, activity_id: 6, src_endpoint: {ip: 10.0.0.4, network_scope_id: 1}, dst_endpoint: {ip: 203.0.113.7, network_scope_id: 2}, traffic: {bytes_out: 12000000}} +tenzir::detect::network::outbound_volume_burst min_bytes_out=500M +ocsf::cast +drop time, metadata.uid, finding_info.uid diff --git a/tenzir/tests/detect/network/outbound_volume_burst.txt b/tenzir/tests/detect/network/outbound_volume_burst.txt new file mode 100644 index 00000000..b59b49eb --- /dev/null +++ b/tenzir/tests/detect/network/outbound_volume_burst.txt @@ -0,0 +1,48 @@ +{ + activity_id: 1, + category_uid: 2, + class_uid: 2004, + end_time: 2024-01-01T10:15:00Z, + evidences: [ + { + src_endpoint: { + ip: 10.0.0.9, + network_scope_id: 1, + }, + }, + ], + finding_info: { + analytic: { + name: "Outbound volume threshold", + type_id: 1, + uid: "tenzir::detect::network::outbound_volume_burst", + version: "1.0", + }, + attacks: [ + { + tactic: { + name: "Exfiltration", + uid: "TA0010", + }, + technique: { + name: "Data Transfer Size Limits", + uid: "T1030", + }, + }, + ], + desc: "10.0.0.9 sent 650000000 bytes to 2 external destinations", + title: "Outbound volume burst from 10.0.0.9", + }, + is_alert: true, + metadata: { + product: { + name: "Tenzir", + vendor_name: "Tenzir", + }, + version: "1.9.0", + }, + severity_id: 3, + start_time: 2024-01-01T10:00:00Z, + status_id: 1, + type_uid: 200401, +} diff --git a/tenzir/tests/detect/network/scan_fan_out.tql b/tenzir/tests/detect/network/scan_fan_out.tql new file mode 100644 index 00000000..f58231b2 --- /dev/null +++ b/tenzir/tests/detect/network/scan_fan_out.tql @@ -0,0 +1,9 @@ +from {time: 2024-01-01T10:00:00Z, class_uid: 4001, activity_id: 6, src_endpoint: {ip: 10.0.0.9}, dst_endpoint: {ip: 10.0.1.1, port: 22}, traffic: {packets: 1}, connection_info: {tcp_flags: 2}}, + {time: 2024-01-01T10:00:05Z, class_uid: 4001, activity_id: 6, src_endpoint: {ip: 10.0.0.9}, dst_endpoint: {ip: 10.0.1.2, port: 22}, traffic: {packets: 1}, connection_info: {tcp_flags: 2}}, + {time: 2024-01-01T10:00:10Z, class_uid: 4001, activity_id: 6, src_endpoint: {ip: 10.0.0.9}, dst_endpoint: {ip: 10.0.1.3, port: 22}, traffic: {packets: 1}, connection_info: {tcp_flags: 2}}, + {time: 2024-01-01T10:00:15Z, class_uid: 4001, activity_id: 6, src_endpoint: {ip: 10.0.0.9}, dst_endpoint: {ip: 10.0.1.4, port: 445}, traffic: {packets: 2}, connection_info: {tcp_flags: 6}}, + {time: 2024-01-01T10:00:20Z, class_uid: 4001, activity_id: 6, src_endpoint: {ip: 10.0.0.9}, dst_endpoint: {ip: 10.0.1.5, port: 445}, traffic: {packets: 1}, connection_info: {tcp_flags: 2}}, + {time: 2024-01-01T10:00:25Z, class_uid: 4001, activity_id: 6, src_endpoint: {ip: 10.0.0.4}, dst_endpoint: {ip: 10.0.2.1, port: 443}, traffic: {packets: 48}, connection_info: {tcp_flags: 27}} +tenzir::detect::network::scan_fan_out min_fanout=5 +ocsf::cast +drop time, metadata.uid, finding_info.uid diff --git a/tenzir/tests/detect/network/scan_fan_out.txt b/tenzir/tests/detect/network/scan_fan_out.txt new file mode 100644 index 00000000..393ae66c --- /dev/null +++ b/tenzir/tests/detect/network/scan_fan_out.txt @@ -0,0 +1,57 @@ +{ + activity_id: 1, + category_uid: 2, + class_uid: 2004, + end_time: 2024-01-01T10:05:00Z, + evidences: [ + { + src_endpoint: { + ip: 10.0.0.9, + }, + }, + ], + finding_info: { + analytic: { + name: "Scan fan-out", + type_id: 1, + uid: "tenzir::detect::network::scan_fan_out", + version: "1.0", + }, + attacks: [ + { + tactic: { + name: "Discovery", + uid: "TA0007", + }, + technique: { + name: "Network Service Discovery", + uid: "T1046", + }, + }, + { + tactic: { + name: "Reconnaissance", + uid: "TA0043", + }, + technique: { + name: "Active Scanning", + uid: "T1595", + }, + }, + ], + desc: "5 flows reached 5 hosts across 2 ports", + title: "Scan fan-out from 10.0.0.9", + }, + is_alert: true, + metadata: { + product: { + name: "Tenzir", + vendor_name: "Tenzir", + }, + version: "1.9.0", + }, + severity_id: 3, + start_time: 2024-01-01T10:00:00Z, + status_id: 1, + type_uid: 200401, +}