5cf870309f
The get_security_events and get_alerts mappers set an incident's description to alert_type alone — "sigma", "yara" — which says nothing an analyst can act on. It now takes msg, the rule's own account of what it detects and what to check, and falls back to the alert type only on alerts that carry no message. Folded into the unreleased 1.7.1. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CXFMuDDLohs4qnL12mBJoP
74 lines
6.4 KiB
YAML
74 lines
6.4 KiB
YAML
name: "HarfangLab Security Events → OCSF"
|
|
description: "Maps a HarfangLab EDR security event/alert (/api/data/alert/alert/Alert/, results_path = results) to OCSF. The matched process is the actor (actor.*). Process fields are best-effort; confirm against a live sample via the builder Test."
|
|
field_mappings:
|
|
title: "rule_name"
|
|
severity: "level = 'critical' ? 5 : (level = 'high' ? 4 : (level = 'medium' ? 3 : 2))"
|
|
# msg is the rule's own explanation of what it detects; the alert type
|
|
# (sigma, yara, ioc…) stands in only on the alerts that carry none.
|
|
description: "msg ? msg : 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).
|