fix(crowdstrike): NG-SIEM detections are filed under thirdparty (1.6.2)
On a real tenant the Unified Detections raised from ingested FortiGate logs are product 'thirdparty'; 'ngsiem' matched nothing. The command now reads thirdparty and ngsiem by default (products input), and its mapper is rewritten from real payloads: source product/vendor, matched host, connection endpoints and ports, vendor signature id, Falcon priority, console link, and a description built from what fired on which connection. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VBnLYwQbUCaf5vpv77N14Q
This commit is contained in:
@@ -1,10 +1,12 @@
|
||||
name: "CrowdStrike Next-Gen SIEM Detections → OCSF"
|
||||
description: "First cut of the map of a Falcon Next-Gen SIEM detection (alerts/entities/alerts/v2 filtered on product 'ngsiem', results_path = resources) to OCSF. An NG-SIEM detection is raised by a correlation rule over ingested logs, not by the sensor: it carries no device, process or file block, so none of the EDR paths of search_detections apply. Only the fields every unified alert carries are mapped here; hosts, users, IPs and the source log come with the first real payload."
|
||||
description: "Map of a Falcon Next-Gen SIEM detection (alerts/entities/alerts/v2 on products 'thirdparty' and 'ngsiem', results_path = resources) to OCSF. Read from real FortiGate IPS detections: a third-party detection carries no sensor process or file block, but names its source product and vendor, the source and target endpoints with ports and protocol, the host Falcon matched it to (enriched_entities) and the vendor's own signature id. It has no description: the incident's is built from the source product, the signature and the connection."
|
||||
field_mappings:
|
||||
title: "name"
|
||||
# Plain path: the ingestion engine reads informational/low/medium/high/critical natively.
|
||||
severity: "severity_name"
|
||||
description: "description"
|
||||
# Third-party detections carry no description of their own; say what fired,
|
||||
# from which product, on which connection.
|
||||
description: "jsonata: description ? description : $join(source_products, ', ') & ' — ' & name & (source_endpoint_address_ip4 ? ' — ' & source_endpoint_address_ip4 & (local_port ? ':' & local_port : '') & ' → ' & target_endpoint_address_ip4 & (remote_port ? ':' & remote_port : '') & (protocol ? ' (' & protocol & ')' : '') : '')"
|
||||
# results_path = resources; source_path is JSONata over ONE alert object.
|
||||
# Paths absent from a given alert are skipped at ingestion, so extra entries are safe.
|
||||
ocsf:
|
||||
@@ -12,15 +14,38 @@ ocsf:
|
||||
- { source_path: "composite_id", ocsf_field: "finding_info.uid" }
|
||||
- { source_path: "name", ocsf_field: "finding_info.title" }
|
||||
- { source_path: "description", ocsf_field: "finding_info.desc" }
|
||||
- { source_path: "categorization", ocsf_field: "finding_info.types" }
|
||||
- { source_path: "data_domains", ocsf_field: "finding_info.data_sources" }
|
||||
- { source_path: "falcon_host_link", ocsf_field: "finding_info.src_url" }
|
||||
- { source_path: "created_timestamp", ocsf_field: "finding_info.created_time" }
|
||||
- { source_path: "created_timestamp", ocsf_field: "time" }
|
||||
- { source_path: "updated_timestamp", ocsf_field: "finding_info.modified_time" }
|
||||
- { source_path: "type", ocsf_field: "finding_info.types" }
|
||||
# `time` is when the source product saw the event (timestamp), ahead of
|
||||
# Falcon's own record of the detection (created_timestamp, ~20 s later).
|
||||
- { source_path: "timestamp", ocsf_field: "time" }
|
||||
# The vendor's signature id (FortiGate IPS 100012) identifies the rule;
|
||||
# pattern_id is Falcon's generic third-party bucket (300000 for all of them).
|
||||
- { source_path: "name", ocsf_field: "finding_info.analytic.name" }
|
||||
- { source_path: "vendor_pattern_id", ocsf_field: "finding_info.analytic.uid" }
|
||||
- { source_path: "confidence", ocsf_field: "confidence" }
|
||||
- { source_path: "priority_value", ocsf_field: "risk_score" }
|
||||
- { source_path: "status", ocsf_field: "status" }
|
||||
# ── Source product — the log the detection came from ──────────────
|
||||
- { source_path: "source_products[0]", ocsf_field: "metadata.product.name" }
|
||||
- { source_path: "source_vendors[0]", ocsf_field: "metadata.product.vendor_name" }
|
||||
- { source_path: "product", ocsf_field: "metadata.product.feature.name" }
|
||||
- { source_path: "cid", ocsf_field: "cloud.account.uid" }
|
||||
# ── MITRE ATT&CK ──────────────────────────────────────────────────
|
||||
# ── Host Falcon matched the detection to ──────────────────────────
|
||||
- { source_path: "agent_id", ocsf_field: "device.uid" }
|
||||
- { source_path: "enriched_entities.hostnames[0]", ocsf_field: "device.hostname" }
|
||||
# ── Connection ────────────────────────────────────────────────────
|
||||
- { source_path: "source_endpoint_address_ip4 ? source_endpoint_address_ip4 : source_ips[0]", ocsf_field: "src_endpoint.ip" }
|
||||
- { source_path: "source_hosts[0]", ocsf_field: "src_endpoint.hostname" }
|
||||
- { source_path: "$number(local_port)", ocsf_field: "src_endpoint.port" }
|
||||
- { source_path: "target_endpoint_address_ip4 ? target_endpoint_address_ip4 : destination_ips[0]", ocsf_field: "dst_endpoint.ip" }
|
||||
- { source_path: "$number(remote_port)", ocsf_field: "dst_endpoint.port" }
|
||||
- { source_path: "protocol", ocsf_field: "connection_info.protocol_name" }
|
||||
- { source_path: "users[0]", ocsf_field: "actor.user.name" }
|
||||
# ── MITRE ATT&CK (correlation rules that declare it) ──────────────
|
||||
- { source_path: "tactic", ocsf_field: "attacks.tactic.name" }
|
||||
- { source_path: "tactic_id", ocsf_field: "attacks.tactic.uid" }
|
||||
- { source_path: "technique", ocsf_field: "attacks.technique.name" }
|
||||
|
||||
Reference in New Issue
Block a user