diff --git a/integrations/harfanglab/mappers/get_alerts.yaml b/integrations/harfanglab/mappers/get_alerts.yaml new file mode 100644 index 0000000..c1b7a2d --- /dev/null +++ b/integrations/harfanglab/mappers/get_alerts.yaml @@ -0,0 +1,71 @@ +name: "HarfangLab Alerts → OCSF" +description: "Maps a HarfangLab EDR alert (/api/data/alert/alert/Alert/, results_path = results) to OCSF. The matched process is the actor (actor.*). Detail sub-objects are only present for their event kind; absent paths are skipped at ingestion." +field_mappings: + title: "rule_name" + severity: "level = 'critical' ? 5 : (level = 'high' ? 4 : (level = 'medium' ? 3 : 2))" + description: "alert_type" +# results_path = results; source_path is JSONata over ONE alert object. +# Paths absent from a given alert are skipped at ingestion, so extra entries are safe. +ocsf: + # ── Endpoint ────────────────────────────────────────────────────── + - { source_path: "agent.hostname", ocsf_field: "src_endpoint.hostname" } + - { source_path: "agent.domainname", ocsf_field: "src_endpoint.domain" } + - { source_path: "agent.osproducttype", ocsf_field: "src_endpoint.os.name" } + - { source_path: "agent.ostype", ocsf_field: "src_endpoint.os.type" } + - { source_path: "agent.osversion", ocsf_field: "device.os.version" } + - { source_path: "agent.agentid", ocsf_field: "device.uid" } + # ── Finding ─────────────────────────────────────────────────────── + - { source_path: "id", ocsf_field: "finding_info.uid" } + - { source_path: "alert_unique_id", ocsf_field: "metadata.uid" } + - { source_path: "rule_name", ocsf_field: "finding_info.title" } + - { source_path: "msg", ocsf_field: "finding_info.desc" } + - { source_path: "alert_time", ocsf_field: "finding_info.created_time" } + - { source_path: "detection_date", ocsf_field: "finding_info.first_seen_time" } + - { source_path: "last_update", ocsf_field: "finding_info.modified_time" } + - { source_path: "ingestion_date", ocsf_field: "metadata.logged_time" } + - { source_path: "alert_type", ocsf_field: "finding_info.analytic.type" } + - { source_path: "rule_id", ocsf_field: "finding_info.analytic.uid" } + - { source_path: "rule_content", ocsf_field: "finding_info.analytic.desc" } + - { source_path: "detection_origin", ocsf_field: "finding_info.analytic.category" } + - { source_path: "status", ocsf_field: "status" } + - { source_path: "maturity", ocsf_field: "status_detail" } + - { source_path: "score", ocsf_field: "risk_score" } + - { source_path: "confidence_int", ocsf_field: "confidence_score" } + - { source_path: "threat_key", ocsf_field: "finding_info.uid_alt" } # threat aggregation key + - { source_path: "mitre_cells", ocsf_field: "attacks" } # ["TAxxxx:Tyyyy", ...] best-effort + - { source_path: "tags", ocsf_field: "metadata.labels" } + - { source_path: "log_type", ocsf_field: "metadata.log_name" } + # ── Matched process — the actor ─────────────────────────────────── + - { source_path: "process.process_name", ocsf_field: "actor.process.name" } + - { source_path: "process.image_name", ocsf_field: "actor.process.file.path" } + - { source_path: "process.commandline", ocsf_field: "actor.process.cmd_line" } + - { source_path: "process.username", ocsf_field: "actor.user.name" } + - { source_path: "process.integrity_level", ocsf_field: "actor.process.integrity" } + - { source_path: "process.pid", ocsf_field: "actor.process.pid" } + - { source_path: "process.hashes.sha256", ocsf_field: "actor.process.file.hashes.sha256" } + - { source_path: "process.hashes.sha1", ocsf_field: "actor.process.file.hashes.sha1" } + - { source_path: "process.hashes.md5", ocsf_field: "actor.process.file.hashes.md5" } + - { source_path: "process.parent_image", ocsf_field: "actor.process.parent_process.name" } + - { source_path: "process.parent_commandline", ocsf_field: "actor.process.parent_process.cmd_line" } + # ── Event details: network connection ───────────────────────────── + - { source_path: "details_connection.SourceIp", ocsf_field: "src_endpoint.ip" } + - { source_path: "details_connection.SourcePort", ocsf_field: "src_endpoint.port" } + - { source_path: "details_connection.DestinationIp", ocsf_field: "dst_endpoint.ip" } + - { source_path: "details_connection.DestinationPort", ocsf_field: "dst_endpoint.port" } + - { source_path: "details_connection.Protocol", ocsf_field: "connection_info.protocol_name" } + # ── Event details: DNS ──────────────────────────────────────────── + - { source_path: "details_dns_resolution.requested_name", ocsf_field: "query.hostname" } + - { source_path: "details_dns_resolution.query_type", ocsf_field: "query.type" } + # ── Event details: file ─────────────────────────────────────────── + - { source_path: "details_file.target_filename", ocsf_field: "file.path" } + # ── Event details: registry ─────────────────────────────────────── + - { source_path: "details_registry.target_object", ocsf_field: "reg_key.path" } + - { source_path: "details_registry.registry_value_type", ocsf_field: "reg_value.type" } + - { source_path: "details_registry.data_string_added", ocsf_field: "reg_value.data" } + # ── Event details: URL request ──────────────────────────────────── + - { source_path: "details_url_request.url", ocsf_field: "url.url_string" } + - { source_path: "details_url_request.host", ocsf_field: "url.hostname" } + - { source_path: "details_url_request.user_agent", ocsf_field: "http_request.user_agent" } + - { source_path: "details_url_request.verb", ocsf_field: "http_request.http_method" } +# Alert fields deliberately left unmapped: `username` (actor.user.name is taken by the +# more specific process.username), remaining details_* sub-objects (no clean OCSF home). diff --git a/integrations/harfanglab/mappers/get_security_events.yaml b/integrations/harfanglab/mappers/get_security_events.yaml index 971c9ac..aabd495 100644 --- a/integrations/harfanglab/mappers/get_security_events.yaml +++ b/integrations/harfanglab/mappers/get_security_events.yaml @@ -15,13 +15,26 @@ ocsf: - { source_path: "agent.osversion", ocsf_field: "device.os.version" } - { source_path: "agent.agentid", ocsf_field: "device.uid" } # ── Finding ─────────────────────────────────────────────────────── - - { source_path: "id", ocsf_field: "finding_info.uid" } - - { source_path: "rule_name", ocsf_field: "finding_info.title" } - - { source_path: "alert_time", ocsf_field: "finding_info.created_time" } - - { source_path: "last_update", ocsf_field: "finding_info.modified_time" } - - { source_path: "alert_type", ocsf_field: "finding_info.analytic.type" } - - { source_path: "status", ocsf_field: "status" } - - { source_path: "maturity", ocsf_field: "status_detail" } + - { source_path: "id", ocsf_field: "finding_info.uid" } + - { source_path: "alert_unique_id", ocsf_field: "metadata.uid" } + - { source_path: "rule_name", ocsf_field: "finding_info.title" } + - { source_path: "msg", ocsf_field: "finding_info.desc" } + - { source_path: "alert_time", ocsf_field: "finding_info.created_time" } + - { source_path: "detection_date", ocsf_field: "finding_info.first_seen_time" } + - { source_path: "last_update", ocsf_field: "finding_info.modified_time" } + - { source_path: "ingestion_date", ocsf_field: "metadata.logged_time" } + - { source_path: "alert_type", ocsf_field: "finding_info.analytic.type" } + - { source_path: "rule_id", ocsf_field: "finding_info.analytic.uid" } + - { source_path: "rule_content", ocsf_field: "finding_info.analytic.desc" } + - { source_path: "detection_origin", ocsf_field: "finding_info.analytic.category" } + - { source_path: "status", ocsf_field: "status" } + - { source_path: "maturity", ocsf_field: "status_detail" } + - { source_path: "score", ocsf_field: "risk_score" } + - { source_path: "confidence_int", ocsf_field: "confidence_score" } + - { source_path: "threat_key", ocsf_field: "finding_info.uid_alt" } # threat aggregation key + - { source_path: "mitre_cells", ocsf_field: "attacks" } # ["TAxxxx:Tyyyy", ...] best-effort + - { source_path: "tags", ocsf_field: "metadata.labels" } + - { source_path: "log_type", ocsf_field: "metadata.log_name" } # ── Matched process — the actor ─────────────────────────────────── - { source_path: "process.process_name", ocsf_field: "actor.process.name" } - { source_path: "process.image_name", ocsf_field: "actor.process.file.path" } @@ -34,3 +47,25 @@ ocsf: - { source_path: "process.hashes.md5", ocsf_field: "actor.process.file.hashes.md5" } - { source_path: "process.parent_image", ocsf_field: "actor.process.parent_process.name" } - { source_path: "process.parent_commandline", ocsf_field: "actor.process.parent_process.cmd_line" } + # ── Event details: network connection ───────────────────────────── + - { source_path: "details_connection.SourceIp", ocsf_field: "src_endpoint.ip" } + - { source_path: "details_connection.SourcePort", ocsf_field: "src_endpoint.port" } + - { source_path: "details_connection.DestinationIp", ocsf_field: "dst_endpoint.ip" } + - { source_path: "details_connection.DestinationPort", ocsf_field: "dst_endpoint.port" } + - { source_path: "details_connection.Protocol", ocsf_field: "connection_info.protocol_name" } + # ── Event details: DNS ──────────────────────────────────────────── + - { source_path: "details_dns_resolution.requested_name", ocsf_field: "query.hostname" } + - { source_path: "details_dns_resolution.query_type", ocsf_field: "query.type" } + # ── Event details: file ─────────────────────────────────────────── + - { source_path: "details_file.target_filename", ocsf_field: "file.path" } + # ── Event details: registry ─────────────────────────────────────── + - { source_path: "details_registry.target_object", ocsf_field: "reg_key.path" } + - { source_path: "details_registry.registry_value_type", ocsf_field: "reg_value.type" } + - { source_path: "details_registry.data_string_added", ocsf_field: "reg_value.data" } + # ── Event details: URL request ──────────────────────────────────── + - { source_path: "details_url_request.url", ocsf_field: "url.url_string" } + - { source_path: "details_url_request.host", ocsf_field: "url.hostname" } + - { source_path: "details_url_request.user_agent", ocsf_field: "http_request.user_agent" } + - { source_path: "details_url_request.verb", ocsf_field: "http_request.http_method" } +# Alert fields deliberately left unmapped: `username` (actor.user.name is taken by the +# more specific process.username), remaining details_* sub-objects (no clean OCSF home).