From e83a43be0096717b6a40c2ba5127b83e856fd8e9 Mon Sep 17 00:00:00 2001 From: Scott Brumley Date: Sat, 15 Aug 2026 14:10:36 -0400 Subject: [PATCH 1/5] feat(nist-ir): enrich the identity contract for AI analysis MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit XDR Analytics never populates the mitre*name/*id fields the canonical rows read — it emits the fused mitreattck* form, present on every alert. Adds the detector's own metadata (action, detection_module, alert_domain, detection_details) and sources alert_source from the case, since sourceBrand reads MAGNIFIER on every analytics alert. Investigation.RiskScore/IssueCount/UserCount/HostCount/LinkedCount were declared as analysis reads in SOCFrameworkPhaseContract_V3 but had no writer; the case carries all of them. --- ...SOCFrameworkNormalizeMap_NIST_IR_data.json | 105 ++++++++++++++++++ .../SOCFrameworkNormalizeMap_NIST_IR.yaml | 31 ++++++ 2 files changed, 136 insertions(+) diff --git a/Packs/soc-framework-nist-ir/Lists/SOCFrameworkNormalizeMap_NIST_IR/SOCFrameworkNormalizeMap_NIST_IR_data.json b/Packs/soc-framework-nist-ir/Lists/SOCFrameworkNormalizeMap_NIST_IR/SOCFrameworkNormalizeMap_NIST_IR_data.json index e6861113..908c0fc0 100644 --- a/Packs/soc-framework-nist-ir/Lists/SOCFrameworkNormalizeMap_NIST_IR/SOCFrameworkNormalizeMap_NIST_IR_data.json +++ b/Packs/soc-framework-nist-ir/Lists/SOCFrameworkNormalizeMap_NIST_IR/SOCFrameworkNormalizeMap_NIST_IR_data.json @@ -1666,6 +1666,111 @@ "shape": "flat", "role": "canonical", "source_origin": "native" + }, + { + "target": "Artifacts.MITRE.Tactic", + "issue_field": "case.mitre_tactics_ids_and_names", + "shape": "structured", + "role": "canonical", + "source_origin": "native" + }, + { + "target": "Artifacts.MITRE.Technique", + "issue_field": "case.mitre_techniques_ids_and_names", + "shape": "structured", + "role": "canonical", + "source_origin": "native" + }, + { + "target": "Artifacts.MITRE.Tactic", + "issue_field": "mitreattcktactic", + "shape": "structured", + "role": "canonical", + "source_origin": "native" + }, + { + "target": "Artifacts.MITRE.Technique", + "issue_field": "mitreattcktechnique", + "shape": "structured", + "role": "canonical", + "source_origin": "native" + }, + { + "target": "Identity.alert_action", + "issue_field": "action", + "shape": "flat", + "role": "canonical", + "source_origin": "native" + }, + { + "target": "Identity.detection_module", + "issue_field": "detection_modules.[0]", + "shape": "flat", + "role": "canonical", + "source_origin": "native" + }, + { + "target": "Identity.alert_domain", + "issue_field": "alert_domain", + "shape": "flat", + "role": "canonical", + "source_origin": "native" + }, + { + "target": "Identity.alert_source", + "issue_field": "case.incident_sources.[0]", + "shape": "flat", + "role": "canonical", + "source_origin": "native" + }, + { + "target": "Identity.detection_details", + "issue_field": "details", + "shape": "flat", + "role": "canonical", + "source_origin": "native" + }, + { + "target": "Identity.detection_details", + "issue_field": "case.description", + "shape": "flat", + "role": "canonical", + "source_origin": "native" + }, + { + "target": "Investigation.RiskScore", + "issue_field": "case.aggregated_score", + "shape": "flat", + "role": "canonical", + "source_origin": "native" + }, + { + "target": "Investigation.IssueCount", + "issue_field": "case.alert_count", + "shape": "flat", + "role": "canonical", + "source_origin": "native" + }, + { + "target": "Investigation.UserCount", + "issue_field": "case.user_count", + "shape": "flat", + "role": "canonical", + "source_origin": "native" + }, + { + "target": "Investigation.HostCount", + "issue_field": "case.host_count", + "shape": "flat", + "role": "canonical", + "source_origin": "native" + }, + { + "target": "Investigation.LinkedCount", + "issue_field": "linkedCount", + "shape": "flat", + "role": "canonical", + "source_origin": "native" } ], "stamps": [ diff --git a/schemas/soc-framework/soc-framework-nist-ir/SOCFrameworkNormalizeMap_NIST_IR.yaml b/schemas/soc-framework/soc-framework-nist-ir/SOCFrameworkNormalizeMap_NIST_IR.yaml index 757ea6ba..3b9114bd 100644 --- a/schemas/soc-framework/soc-framework-nist-ir/SOCFrameworkNormalizeMap_NIST_IR.yaml +++ b/schemas/soc-framework/soc-framework-nist-ir/SOCFrameworkNormalizeMap_NIST_IR.yaml @@ -275,6 +275,37 @@ categories: - { target: Primary.Email, issue_field: email, shape: flat, role: canonical, source_origin: native } # on-prem AD wants bare sAMAccountName, not a UPN — its own key - { target: Primary.SamAccountName, issue_field: samaccountname, shape: flat, role: canonical, source_origin: native } + # ── Detection metadata ──────────────────────────────────────────────── + # XDR Analytics never populates the mitre*name/*id fields the canonical + # rows above read; it emits the fused "TA0006 - Credential Access" form + # under mitreattck*. Case rows first, issue rows last: the case MITRE is + # aggregated across every alert in the case, the issue MITRE describes + # this alert, and the more specific one should win. + - { target: Artifacts.MITRE.Tactic, issue_field: case.mitre_tactics_ids_and_names, shape: structured, role: canonical, source_origin: native } + - { target: Artifacts.MITRE.Technique, issue_field: case.mitre_techniques_ids_and_names, shape: structured, role: canonical, source_origin: native } + - { target: Artifacts.MITRE.Tactic, issue_field: mitreattcktactic, shape: structured, role: canonical, source_origin: native } + - { target: Artifacts.MITRE.Technique, issue_field: mitreattcktechnique, shape: structured, role: canonical, source_origin: native } + # The alert's own disposition and detector. Without these the reasoner + # cannot tell a detected-and-allowed event from a blocked one. + - { target: Identity.alert_action, issue_field: action, shape: flat, role: canonical, source_origin: native } + - { target: Identity.detection_module, issue_field: 'detection_modules.[0]', shape: flat, role: canonical, source_origin: native } + - { target: Identity.alert_domain, issue_field: alert_domain, shape: flat, role: canonical, source_origin: native } + # sourceBrand reads MAGNIFIER (the analytics engine) on every analytics + # alert, so it identifies nothing. The case names the detection source. + - { target: Identity.alert_source, issue_field: 'case.incident_sources.[0]', shape: flat, role: canonical, source_origin: native } + # Written narrative of what the detector observed — the highest-value + # free-text evidence available to the reasoner. + - { target: Identity.detection_details, issue_field: details, shape: flat, role: canonical, source_origin: native } + - { target: Identity.detection_details, issue_field: case.description, shape: flat, role: canonical, source_origin: native } + # ── Investigation scope ─────────────────────────────────────────────── + # Declared in SOCFrameworkPhaseContract_V3 as analysis reads, annotated + # as written by the enrichment pipeline — which never wrote them. The + # case carries all four. + - { target: Investigation.RiskScore, issue_field: case.aggregated_score, shape: flat, role: canonical, source_origin: native } + - { target: Investigation.IssueCount, issue_field: case.alert_count, shape: flat, role: canonical, source_origin: native } + - { target: Investigation.UserCount, issue_field: case.user_count, shape: flat, role: canonical, source_origin: native } + - { target: Investigation.HostCount, issue_field: case.host_count, shape: flat, role: canonical, source_origin: native } + - { target: Investigation.LinkedCount, issue_field: linkedCount, shape: flat, role: canonical, source_origin: native } stamps: - { target: Identity.normalization_source, value: identity } mirrors: From 075a979e1da2602ee31ac0689abcce118fdc6d08 Mon Sep 17 00:00:00 2001 From: Scott Brumley Date: Sat, 15 Aug 2026 14:20:22 -0400 Subject: [PATCH 2/5] fix(nist-ir): use the existing Artifacts.Source.* targets Artifacts.Source.{Action,Module,AlertDomain} already exist in the endpoint band and are what the prompts bind; the identity rows minted duplicates under new names that nothing reads. --- .../SOCFrameworkNormalizeMap_NIST_IR_data.json | 15 +++++++++++---- .../SOCFrameworkNormalizeMap_NIST_IR.yaml | 10 +++++++--- 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/Packs/soc-framework-nist-ir/Lists/SOCFrameworkNormalizeMap_NIST_IR/SOCFrameworkNormalizeMap_NIST_IR_data.json b/Packs/soc-framework-nist-ir/Lists/SOCFrameworkNormalizeMap_NIST_IR/SOCFrameworkNormalizeMap_NIST_IR_data.json index 908c0fc0..1feff507 100644 --- a/Packs/soc-framework-nist-ir/Lists/SOCFrameworkNormalizeMap_NIST_IR/SOCFrameworkNormalizeMap_NIST_IR_data.json +++ b/Packs/soc-framework-nist-ir/Lists/SOCFrameworkNormalizeMap_NIST_IR/SOCFrameworkNormalizeMap_NIST_IR_data.json @@ -1703,16 +1703,23 @@ "source_origin": "native" }, { - "target": "Identity.detection_module", + "target": "Artifacts.Source.Action", + "issue_field": "action", + "shape": "structured", + "role": "canonical", + "source_origin": "native" + }, + { + "target": "Artifacts.Source.Module", "issue_field": "detection_modules.[0]", - "shape": "flat", + "shape": "structured", "role": "canonical", "source_origin": "native" }, { - "target": "Identity.alert_domain", + "target": "Artifacts.Source.AlertDomain", "issue_field": "alert_domain", - "shape": "flat", + "shape": "structured", "role": "canonical", "source_origin": "native" }, diff --git a/schemas/soc-framework/soc-framework-nist-ir/SOCFrameworkNormalizeMap_NIST_IR.yaml b/schemas/soc-framework/soc-framework-nist-ir/SOCFrameworkNormalizeMap_NIST_IR.yaml index 3b9114bd..ea682ee6 100644 --- a/schemas/soc-framework/soc-framework-nist-ir/SOCFrameworkNormalizeMap_NIST_IR.yaml +++ b/schemas/soc-framework/soc-framework-nist-ir/SOCFrameworkNormalizeMap_NIST_IR.yaml @@ -286,10 +286,14 @@ categories: - { target: Artifacts.MITRE.Tactic, issue_field: mitreattcktactic, shape: structured, role: canonical, source_origin: native } - { target: Artifacts.MITRE.Technique, issue_field: mitreattcktechnique, shape: structured, role: canonical, source_origin: native } # The alert's own disposition and detector. Without these the reasoner - # cannot tell a detected-and-allowed event from a blocked one. + # cannot tell a detected-and-allowed event from a blocked one. Endpoint + # already owns Artifacts.Source.{Action,Module,AlertDomain} — reuse them + # rather than mint an identity-flavoured duplicate. Identity.alert_action + # is the flat twin of Endpoint.alert_action, which the prompts bind. - { target: Identity.alert_action, issue_field: action, shape: flat, role: canonical, source_origin: native } - - { target: Identity.detection_module, issue_field: 'detection_modules.[0]', shape: flat, role: canonical, source_origin: native } - - { target: Identity.alert_domain, issue_field: alert_domain, shape: flat, role: canonical, source_origin: native } + - { target: Artifacts.Source.Action, issue_field: action, shape: structured, role: canonical, source_origin: native } + - { target: Artifacts.Source.Module, issue_field: 'detection_modules.[0]', shape: structured, role: canonical, source_origin: native } + - { target: Artifacts.Source.AlertDomain, issue_field: alert_domain, shape: structured, role: canonical, source_origin: native } # sourceBrand reads MAGNIFIER (the analytics engine) on every analytics # alert, so it identifies nothing. The case names the detection source. - { target: Identity.alert_source, issue_field: 'case.incident_sources.[0]', shape: flat, role: canonical, source_origin: native } From 26bb51e9b10deccb190d66d6f93b229c2ed4f5da Mon Sep 17 00:00:00 2001 From: Scott Brumley Date: Sat, 15 Aug 2026 14:30:54 -0400 Subject: [PATCH 3/5] feat(nist-ir): apply the shared detection surface to every band MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The case scope counts, the case/issue MITRE, and the detector's own metadata carry the same meaning regardless of product category, but only endpoint and identity had any of them. Adds the block to all six bands. Artifacts.Source.Details replaces the category-flavoured Identity.detection_details — Artifacts.Source.* is already the shared detector namespace. --- ...SOCFrameworkNormalizeMap_NIST_IR_data.json | 585 ++++++++++++++++-- .../SOCFrameworkNormalizeMap_NIST_IR.yaml | 164 ++++- 2 files changed, 690 insertions(+), 59 deletions(-) diff --git a/Packs/soc-framework-nist-ir/Lists/SOCFrameworkNormalizeMap_NIST_IR/SOCFrameworkNormalizeMap_NIST_IR_data.json b/Packs/soc-framework-nist-ir/Lists/SOCFrameworkNormalizeMap_NIST_IR/SOCFrameworkNormalizeMap_NIST_IR_data.json index 1feff507..37d9d62c 100644 --- a/Packs/soc-framework-nist-ir/Lists/SOCFrameworkNormalizeMap_NIST_IR/SOCFrameworkNormalizeMap_NIST_IR_data.json +++ b/Packs/soc-framework-nist-ir/Lists/SOCFrameworkNormalizeMap_NIST_IR/SOCFrameworkNormalizeMap_NIST_IR_data.json @@ -753,6 +753,104 @@ "shape": "flat", "role": "canonical", "source_origin": "native" + }, + { + "target": "Artifacts.MITRE.Tactic", + "issue_field": "case.mitre_tactics_ids_and_names", + "shape": "structured", + "role": "canonical", + "source_origin": "native" + }, + { + "target": "Artifacts.MITRE.Technique", + "issue_field": "case.mitre_techniques_ids_and_names", + "shape": "structured", + "role": "canonical", + "source_origin": "native" + }, + { + "target": "Artifacts.MITRE.Tactic", + "issue_field": "mitreattcktactic", + "shape": "structured", + "role": "canonical", + "source_origin": "native" + }, + { + "target": "Artifacts.MITRE.Technique", + "issue_field": "mitreattcktechnique", + "shape": "structured", + "role": "canonical", + "source_origin": "native" + }, + { + "target": "Artifacts.Source.Action", + "issue_field": "action", + "shape": "structured", + "role": "canonical", + "source_origin": "native" + }, + { + "target": "Artifacts.Source.Module", + "issue_field": "detection_modules.[0]", + "shape": "structured", + "role": "canonical", + "source_origin": "native" + }, + { + "target": "Artifacts.Source.Details", + "issue_field": "details", + "shape": "structured", + "role": "canonical", + "source_origin": "native" + }, + { + "target": "Artifacts.Source.Details", + "issue_field": "case.description", + "shape": "structured", + "role": "canonical", + "source_origin": "native" + }, + { + "target": "Endpoint.alert_source", + "issue_field": "case.incident_sources.[0]", + "shape": "flat", + "role": "canonical", + "source_origin": "native" + }, + { + "target": "Investigation.RiskScore", + "issue_field": "case.aggregated_score", + "shape": "flat", + "role": "canonical", + "source_origin": "native" + }, + { + "target": "Investigation.IssueCount", + "issue_field": "case.alert_count", + "shape": "flat", + "role": "canonical", + "source_origin": "native" + }, + { + "target": "Investigation.UserCount", + "issue_field": "case.user_count", + "shape": "flat", + "role": "canonical", + "source_origin": "native" + }, + { + "target": "Investigation.HostCount", + "issue_field": "case.host_count", + "shape": "flat", + "role": "canonical", + "source_origin": "native" + }, + { + "target": "Investigation.LinkedCount", + "issue_field": "linkedCount", + "shape": "flat", + "role": "canonical", + "source_origin": "native" } ], "stamps": [ @@ -1212,6 +1310,111 @@ "shape": "structured", "role": "canonical", "source_origin": "native" + }, + { + "target": "Artifacts.MITRE.Tactic", + "issue_field": "case.mitre_tactics_ids_and_names", + "shape": "structured", + "role": "canonical", + "source_origin": "native" + }, + { + "target": "Artifacts.MITRE.Technique", + "issue_field": "case.mitre_techniques_ids_and_names", + "shape": "structured", + "role": "canonical", + "source_origin": "native" + }, + { + "target": "Artifacts.MITRE.Tactic", + "issue_field": "mitreattcktactic", + "shape": "structured", + "role": "canonical", + "source_origin": "native" + }, + { + "target": "Artifacts.MITRE.Technique", + "issue_field": "mitreattcktechnique", + "shape": "structured", + "role": "canonical", + "source_origin": "native" + }, + { + "target": "Artifacts.Source.Action", + "issue_field": "action", + "shape": "structured", + "role": "canonical", + "source_origin": "native" + }, + { + "target": "Artifacts.Source.Module", + "issue_field": "detection_modules.[0]", + "shape": "structured", + "role": "canonical", + "source_origin": "native" + }, + { + "target": "Artifacts.Source.AlertDomain", + "issue_field": "alert_domain", + "shape": "structured", + "role": "canonical", + "source_origin": "native" + }, + { + "target": "Artifacts.Source.Details", + "issue_field": "details", + "shape": "structured", + "role": "canonical", + "source_origin": "native" + }, + { + "target": "Artifacts.Source.Details", + "issue_field": "case.description", + "shape": "structured", + "role": "canonical", + "source_origin": "native" + }, + { + "target": "Email.alert_source", + "issue_field": "case.incident_sources.[0]", + "shape": "flat", + "role": "canonical", + "source_origin": "native" + }, + { + "target": "Investigation.RiskScore", + "issue_field": "case.aggregated_score", + "shape": "flat", + "role": "canonical", + "source_origin": "native" + }, + { + "target": "Investigation.IssueCount", + "issue_field": "case.alert_count", + "shape": "flat", + "role": "canonical", + "source_origin": "native" + }, + { + "target": "Investigation.UserCount", + "issue_field": "case.user_count", + "shape": "flat", + "role": "canonical", + "source_origin": "native" + }, + { + "target": "Investigation.HostCount", + "issue_field": "case.host_count", + "shape": "flat", + "role": "canonical", + "source_origin": "native" + }, + { + "target": "Investigation.LinkedCount", + "issue_field": "linkedCount", + "shape": "flat", + "role": "canonical", + "source_origin": "native" } ], "stamps": [ @@ -1695,13 +1898,6 @@ "role": "canonical", "source_origin": "native" }, - { - "target": "Identity.alert_action", - "issue_field": "action", - "shape": "flat", - "role": "canonical", - "source_origin": "native" - }, { "target": "Artifacts.Source.Action", "issue_field": "action", @@ -1724,22 +1920,22 @@ "source_origin": "native" }, { - "target": "Identity.alert_source", - "issue_field": "case.incident_sources.[0]", - "shape": "flat", + "target": "Artifacts.Source.Details", + "issue_field": "details", + "shape": "structured", "role": "canonical", "source_origin": "native" }, { - "target": "Identity.detection_details", - "issue_field": "details", - "shape": "flat", + "target": "Artifacts.Source.Details", + "issue_field": "case.description", + "shape": "structured", "role": "canonical", "source_origin": "native" }, { - "target": "Identity.detection_details", - "issue_field": "case.description", + "target": "Identity.alert_source", + "issue_field": "case.incident_sources.[0]", "shape": "flat", "role": "canonical", "source_origin": "native" @@ -2257,41 +2453,146 @@ "shape": "structured", "role": "canonical", "source_origin": "native" - } - ], - "stamps": [ - { - "target": "Network.normalization_source", - "value": "network" - } - ], - "mirrors": [ + }, { - "target": "Artifacts.Network.Destination.Country", - "source": "Network.destination_country", + "target": "Artifacts.MITRE.Tactic", + "issue_field": "case.mitre_tactics_ids_and_names", + "shape": "structured", "role": "canonical", - "shape": "structured" + "source_origin": "native" }, { - "target": "Artifacts.Network.Destination.Hostname", - "source": "Network.destination_hostname", + "target": "Artifacts.MITRE.Technique", + "issue_field": "case.mitre_techniques_ids_and_names", + "shape": "structured", "role": "canonical", - "shape": "structured" + "source_origin": "native" }, { - "target": "Artifacts.Network.Destination.IP", - "source": "Network.destination_ip", + "target": "Artifacts.MITRE.Tactic", + "issue_field": "mitreattcktactic", + "shape": "structured", "role": "canonical", - "shape": "structured" + "source_origin": "native" }, { - "target": "Artifacts.Network.Destination.Port", - "source": "Network.destination_port", + "target": "Artifacts.MITRE.Technique", + "issue_field": "mitreattcktechnique", + "shape": "structured", "role": "canonical", - "shape": "structured" + "source_origin": "native" }, { - "target": "Artifacts.Network.Destination.Zone", + "target": "Artifacts.Source.Action", + "issue_field": "action", + "shape": "structured", + "role": "canonical", + "source_origin": "native" + }, + { + "target": "Artifacts.Source.Module", + "issue_field": "detection_modules.[0]", + "shape": "structured", + "role": "canonical", + "source_origin": "native" + }, + { + "target": "Artifacts.Source.AlertDomain", + "issue_field": "alert_domain", + "shape": "structured", + "role": "canonical", + "source_origin": "native" + }, + { + "target": "Artifacts.Source.Details", + "issue_field": "details", + "shape": "structured", + "role": "canonical", + "source_origin": "native" + }, + { + "target": "Artifacts.Source.Details", + "issue_field": "case.description", + "shape": "structured", + "role": "canonical", + "source_origin": "native" + }, + { + "target": "Network.alert_source", + "issue_field": "case.incident_sources.[0]", + "shape": "flat", + "role": "canonical", + "source_origin": "native" + }, + { + "target": "Investigation.RiskScore", + "issue_field": "case.aggregated_score", + "shape": "flat", + "role": "canonical", + "source_origin": "native" + }, + { + "target": "Investigation.IssueCount", + "issue_field": "case.alert_count", + "shape": "flat", + "role": "canonical", + "source_origin": "native" + }, + { + "target": "Investigation.UserCount", + "issue_field": "case.user_count", + "shape": "flat", + "role": "canonical", + "source_origin": "native" + }, + { + "target": "Investigation.HostCount", + "issue_field": "case.host_count", + "shape": "flat", + "role": "canonical", + "source_origin": "native" + }, + { + "target": "Investigation.LinkedCount", + "issue_field": "linkedCount", + "shape": "flat", + "role": "canonical", + "source_origin": "native" + } + ], + "stamps": [ + { + "target": "Network.normalization_source", + "value": "network" + } + ], + "mirrors": [ + { + "target": "Artifacts.Network.Destination.Country", + "source": "Network.destination_country", + "role": "canonical", + "shape": "structured" + }, + { + "target": "Artifacts.Network.Destination.Hostname", + "source": "Network.destination_hostname", + "role": "canonical", + "shape": "structured" + }, + { + "target": "Artifacts.Network.Destination.IP", + "source": "Network.destination_ip", + "role": "canonical", + "shape": "structured" + }, + { + "target": "Artifacts.Network.Destination.Port", + "source": "Network.destination_port", + "role": "canonical", + "shape": "structured" + }, + { + "target": "Artifacts.Network.Destination.Zone", "source": "Network.destination_zone", "role": "canonical", "shape": "structured" @@ -2715,6 +3016,111 @@ "shape": "structured", "role": "canonical", "source_origin": "native" + }, + { + "target": "Artifacts.MITRE.Tactic", + "issue_field": "case.mitre_tactics_ids_and_names", + "shape": "structured", + "role": "canonical", + "source_origin": "native" + }, + { + "target": "Artifacts.MITRE.Technique", + "issue_field": "case.mitre_techniques_ids_and_names", + "shape": "structured", + "role": "canonical", + "source_origin": "native" + }, + { + "target": "Artifacts.MITRE.Tactic", + "issue_field": "mitreattcktactic", + "shape": "structured", + "role": "canonical", + "source_origin": "native" + }, + { + "target": "Artifacts.MITRE.Technique", + "issue_field": "mitreattcktechnique", + "shape": "structured", + "role": "canonical", + "source_origin": "native" + }, + { + "target": "Artifacts.Source.Action", + "issue_field": "action", + "shape": "structured", + "role": "canonical", + "source_origin": "native" + }, + { + "target": "Artifacts.Source.Module", + "issue_field": "detection_modules.[0]", + "shape": "structured", + "role": "canonical", + "source_origin": "native" + }, + { + "target": "Artifacts.Source.AlertDomain", + "issue_field": "alert_domain", + "shape": "structured", + "role": "canonical", + "source_origin": "native" + }, + { + "target": "Artifacts.Source.Details", + "issue_field": "details", + "shape": "structured", + "role": "canonical", + "source_origin": "native" + }, + { + "target": "Artifacts.Source.Details", + "issue_field": "case.description", + "shape": "structured", + "role": "canonical", + "source_origin": "native" + }, + { + "target": "Cloud.alert_source", + "issue_field": "case.incident_sources.[0]", + "shape": "flat", + "role": "canonical", + "source_origin": "native" + }, + { + "target": "Investigation.RiskScore", + "issue_field": "case.aggregated_score", + "shape": "flat", + "role": "canonical", + "source_origin": "native" + }, + { + "target": "Investigation.IssueCount", + "issue_field": "case.alert_count", + "shape": "flat", + "role": "canonical", + "source_origin": "native" + }, + { + "target": "Investigation.UserCount", + "issue_field": "case.user_count", + "shape": "flat", + "role": "canonical", + "source_origin": "native" + }, + { + "target": "Investigation.HostCount", + "issue_field": "case.host_count", + "shape": "flat", + "role": "canonical", + "source_origin": "native" + }, + { + "target": "Investigation.LinkedCount", + "issue_field": "linkedCount", + "shape": "flat", + "role": "canonical", + "source_origin": "native" } ], "stamps": [ @@ -3021,6 +3427,111 @@ "shape": "structured", "role": "canonical", "source_origin": "native" + }, + { + "target": "Artifacts.MITRE.Tactic", + "issue_field": "case.mitre_tactics_ids_and_names", + "shape": "structured", + "role": "canonical", + "source_origin": "native" + }, + { + "target": "Artifacts.MITRE.Technique", + "issue_field": "case.mitre_techniques_ids_and_names", + "shape": "structured", + "role": "canonical", + "source_origin": "native" + }, + { + "target": "Artifacts.MITRE.Tactic", + "issue_field": "mitreattcktactic", + "shape": "structured", + "role": "canonical", + "source_origin": "native" + }, + { + "target": "Artifacts.MITRE.Technique", + "issue_field": "mitreattcktechnique", + "shape": "structured", + "role": "canonical", + "source_origin": "native" + }, + { + "target": "Artifacts.Source.Action", + "issue_field": "action", + "shape": "structured", + "role": "canonical", + "source_origin": "native" + }, + { + "target": "Artifacts.Source.Module", + "issue_field": "detection_modules.[0]", + "shape": "structured", + "role": "canonical", + "source_origin": "native" + }, + { + "target": "Artifacts.Source.AlertDomain", + "issue_field": "alert_domain", + "shape": "structured", + "role": "canonical", + "source_origin": "native" + }, + { + "target": "Artifacts.Source.Details", + "issue_field": "details", + "shape": "structured", + "role": "canonical", + "source_origin": "native" + }, + { + "target": "Artifacts.Source.Details", + "issue_field": "case.description", + "shape": "structured", + "role": "canonical", + "source_origin": "native" + }, + { + "target": "Generic.alert_source", + "issue_field": "case.incident_sources.[0]", + "shape": "flat", + "role": "canonical", + "source_origin": "native" + }, + { + "target": "Investigation.RiskScore", + "issue_field": "case.aggregated_score", + "shape": "flat", + "role": "canonical", + "source_origin": "native" + }, + { + "target": "Investigation.IssueCount", + "issue_field": "case.alert_count", + "shape": "flat", + "role": "canonical", + "source_origin": "native" + }, + { + "target": "Investigation.UserCount", + "issue_field": "case.user_count", + "shape": "flat", + "role": "canonical", + "source_origin": "native" + }, + { + "target": "Investigation.HostCount", + "issue_field": "case.host_count", + "shape": "flat", + "role": "canonical", + "source_origin": "native" + }, + { + "target": "Investigation.LinkedCount", + "issue_field": "linkedCount", + "shape": "flat", + "role": "canonical", + "source_origin": "native" } ], "stamps": [ diff --git a/schemas/soc-framework/soc-framework-nist-ir/SOCFrameworkNormalizeMap_NIST_IR.yaml b/schemas/soc-framework/soc-framework-nist-ir/SOCFrameworkNormalizeMap_NIST_IR.yaml index ea682ee6..c9e2270f 100644 --- a/schemas/soc-framework/soc-framework-nist-ir/SOCFrameworkNormalizeMap_NIST_IR.yaml +++ b/schemas/soc-framework/soc-framework-nist-ir/SOCFrameworkNormalizeMap_NIST_IR.yaml @@ -133,6 +133,31 @@ categories: - { target: Endpoint.os, issue_field: hostos, shape: flat, role: canonical, source_origin: native } # native XDR agent: fixes Endpoint.os, dead on every source - { target: Endpoint.tactic, issue_field: mitreattcktactic, shape: flat, role: canonical, source_origin: native } # native XDR agent uses mitreattck* naming - { target: Endpoint.technique, issue_field: mitreattcktechnique, shape: flat, role: canonical, source_origin: native } # native XDR agent uses mitreattck* naming + # ── Shared detection surface (category-agnostic) ───────────────────── + # XDR Analytics emits the fused mitreattck* form, never mitre*name/*id. + # Case rows first, issue rows last: the case MITRE is aggregated across + # the whole case, the issue MITRE describes this alert, and the more + # specific one should win. + - { target: Artifacts.MITRE.Tactic, issue_field: case.mitre_tactics_ids_and_names, shape: structured, role: canonical, source_origin: native } + - { target: Artifacts.MITRE.Technique, issue_field: case.mitre_techniques_ids_and_names, shape: structured, role: canonical, source_origin: native } + - { target: Artifacts.MITRE.Tactic, issue_field: mitreattcktactic, shape: structured, role: canonical, source_origin: native } + - { target: Artifacts.MITRE.Technique, issue_field: mitreattcktechnique, shape: structured, role: canonical, source_origin: native } + # The detector's own metadata: what fired, what it did, what it wrote. + - { target: Artifacts.Source.Action, issue_field: action, shape: structured, role: canonical, source_origin: native } + - { target: Artifacts.Source.Module, issue_field: 'detection_modules.[0]', shape: structured, role: canonical, source_origin: native } + - { target: Artifacts.Source.Details, issue_field: details, shape: structured, role: canonical, source_origin: native } + - { target: Artifacts.Source.Details, issue_field: case.description, shape: structured, role: canonical, source_origin: native } + # sourceBrand reads MAGNIFIER on every analytics alert, so it names + # nothing. The case names the detection source. + - { target: Endpoint.alert_source, issue_field: 'case.incident_sources.[0]', shape: flat, role: canonical, source_origin: native } + # ── Investigation scope (case-level, identical in every band) ───────── + # Declared in SOCFrameworkPhaseContract_V3 as analysis reads but never + # written. Populated only on a grouped case. + - { target: Investigation.RiskScore, issue_field: case.aggregated_score, shape: flat, role: canonical, source_origin: native } + - { target: Investigation.IssueCount, issue_field: case.alert_count, shape: flat, role: canonical, source_origin: native } + - { target: Investigation.UserCount, issue_field: case.user_count, shape: flat, role: canonical, source_origin: native } + - { target: Investigation.HostCount, issue_field: case.host_count, shape: flat, role: canonical, source_origin: native } + - { target: Investigation.LinkedCount, issue_field: linkedCount, shape: flat, role: canonical, source_origin: native } stamps: - { target: Endpoint.normalization_source, value: endpoint } - { target: Artifacts.Process.Verdict, value: } @@ -202,6 +227,32 @@ categories: - { target: Artifacts.MITRE.TacticID, issue_field: mitretacticid, shape: structured, role: canonical, source_origin: native } - { target: Artifacts.MITRE.Technique, issue_field: mitretechniquename, shape: structured, role: canonical, source_origin: native } - { target: Artifacts.MITRE.TechniqueID, issue_field: mitretechniqueid, shape: structured, role: canonical, source_origin: native } + # ── Shared detection surface (category-agnostic) ───────────────────── + # XDR Analytics emits the fused mitreattck* form, never mitre*name/*id. + # Case rows first, issue rows last: the case MITRE is aggregated across + # the whole case, the issue MITRE describes this alert, and the more + # specific one should win. + - { target: Artifacts.MITRE.Tactic, issue_field: case.mitre_tactics_ids_and_names, shape: structured, role: canonical, source_origin: native } + - { target: Artifacts.MITRE.Technique, issue_field: case.mitre_techniques_ids_and_names, shape: structured, role: canonical, source_origin: native } + - { target: Artifacts.MITRE.Tactic, issue_field: mitreattcktactic, shape: structured, role: canonical, source_origin: native } + - { target: Artifacts.MITRE.Technique, issue_field: mitreattcktechnique, shape: structured, role: canonical, source_origin: native } + # The detector's own metadata: what fired, what it did, what it wrote. + - { target: Artifacts.Source.Action, issue_field: action, shape: structured, role: canonical, source_origin: native } + - { target: Artifacts.Source.Module, issue_field: 'detection_modules.[0]', shape: structured, role: canonical, source_origin: native } + - { target: Artifacts.Source.AlertDomain, issue_field: alert_domain, shape: structured, role: canonical, source_origin: native } + - { target: Artifacts.Source.Details, issue_field: details, shape: structured, role: canonical, source_origin: native } + - { target: Artifacts.Source.Details, issue_field: case.description, shape: structured, role: canonical, source_origin: native } + # sourceBrand reads MAGNIFIER on every analytics alert, so it names + # nothing. The case names the detection source. + - { target: Email.alert_source, issue_field: 'case.incident_sources.[0]', shape: flat, role: canonical, source_origin: native } + # ── Investigation scope (case-level, identical in every band) ───────── + # Declared in SOCFrameworkPhaseContract_V3 as analysis reads but never + # written. Populated only on a grouped case. + - { target: Investigation.RiskScore, issue_field: case.aggregated_score, shape: flat, role: canonical, source_origin: native } + - { target: Investigation.IssueCount, issue_field: case.alert_count, shape: flat, role: canonical, source_origin: native } + - { target: Investigation.UserCount, issue_field: case.user_count, shape: flat, role: canonical, source_origin: native } + - { target: Investigation.HostCount, issue_field: case.host_count, shape: flat, role: canonical, source_origin: native } + - { target: Investigation.LinkedCount, issue_field: linkedCount, shape: flat, role: canonical, source_origin: native } stamps: - { target: Email.normalization_source, value: email } - { target: Email.normalization_source, value: mail_listener } @@ -275,36 +326,27 @@ categories: - { target: Primary.Email, issue_field: email, shape: flat, role: canonical, source_origin: native } # on-prem AD wants bare sAMAccountName, not a UPN — its own key - { target: Primary.SamAccountName, issue_field: samaccountname, shape: flat, role: canonical, source_origin: native } - # ── Detection metadata ──────────────────────────────────────────────── - # XDR Analytics never populates the mitre*name/*id fields the canonical - # rows above read; it emits the fused "TA0006 - Credential Access" form - # under mitreattck*. Case rows first, issue rows last: the case MITRE is - # aggregated across every alert in the case, the issue MITRE describes - # this alert, and the more specific one should win. + # ── Shared detection surface (category-agnostic) ───────────────────── + # XDR Analytics emits the fused mitreattck* form, never mitre*name/*id. + # Case rows first, issue rows last: the case MITRE is aggregated across + # the whole case, the issue MITRE describes this alert, and the more + # specific one should win. - { target: Artifacts.MITRE.Tactic, issue_field: case.mitre_tactics_ids_and_names, shape: structured, role: canonical, source_origin: native } - { target: Artifacts.MITRE.Technique, issue_field: case.mitre_techniques_ids_and_names, shape: structured, role: canonical, source_origin: native } - { target: Artifacts.MITRE.Tactic, issue_field: mitreattcktactic, shape: structured, role: canonical, source_origin: native } - { target: Artifacts.MITRE.Technique, issue_field: mitreattcktechnique, shape: structured, role: canonical, source_origin: native } - # The alert's own disposition and detector. Without these the reasoner - # cannot tell a detected-and-allowed event from a blocked one. Endpoint - # already owns Artifacts.Source.{Action,Module,AlertDomain} — reuse them - # rather than mint an identity-flavoured duplicate. Identity.alert_action - # is the flat twin of Endpoint.alert_action, which the prompts bind. - - { target: Identity.alert_action, issue_field: action, shape: flat, role: canonical, source_origin: native } + # The detector's own metadata: what fired, what it did, what it wrote. - { target: Artifacts.Source.Action, issue_field: action, shape: structured, role: canonical, source_origin: native } - { target: Artifacts.Source.Module, issue_field: 'detection_modules.[0]', shape: structured, role: canonical, source_origin: native } - { target: Artifacts.Source.AlertDomain, issue_field: alert_domain, shape: structured, role: canonical, source_origin: native } - # sourceBrand reads MAGNIFIER (the analytics engine) on every analytics - # alert, so it identifies nothing. The case names the detection source. + - { target: Artifacts.Source.Details, issue_field: details, shape: structured, role: canonical, source_origin: native } + - { target: Artifacts.Source.Details, issue_field: case.description, shape: structured, role: canonical, source_origin: native } + # sourceBrand reads MAGNIFIER on every analytics alert, so it names + # nothing. The case names the detection source. - { target: Identity.alert_source, issue_field: 'case.incident_sources.[0]', shape: flat, role: canonical, source_origin: native } - # Written narrative of what the detector observed — the highest-value - # free-text evidence available to the reasoner. - - { target: Identity.detection_details, issue_field: details, shape: flat, role: canonical, source_origin: native } - - { target: Identity.detection_details, issue_field: case.description, shape: flat, role: canonical, source_origin: native } - # ── Investigation scope ─────────────────────────────────────────────── - # Declared in SOCFrameworkPhaseContract_V3 as analysis reads, annotated - # as written by the enrichment pipeline — which never wrote them. The - # case carries all four. + # ── Investigation scope (case-level, identical in every band) ───────── + # Declared in SOCFrameworkPhaseContract_V3 as analysis reads but never + # written. Populated only on a grouped case. - { target: Investigation.RiskScore, issue_field: case.aggregated_score, shape: flat, role: canonical, source_origin: native } - { target: Investigation.IssueCount, issue_field: case.alert_count, shape: flat, role: canonical, source_origin: native } - { target: Investigation.UserCount, issue_field: case.user_count, shape: flat, role: canonical, source_origin: native } @@ -383,6 +425,32 @@ categories: - { target: Artifacts.Endpoint.Hostname, issue_field: agent_hostname, shape: structured, role: canonical, source_origin: native } - { target: Artifacts.Endpoint.AgentID, issue_field: agent_id, shape: structured, role: canonical, source_origin: native } - { target: Artifacts.Endpoint.Domain, issue_field: agent_device_domain, shape: structured, role: canonical, source_origin: native } + # ── Shared detection surface (category-agnostic) ───────────────────── + # XDR Analytics emits the fused mitreattck* form, never mitre*name/*id. + # Case rows first, issue rows last: the case MITRE is aggregated across + # the whole case, the issue MITRE describes this alert, and the more + # specific one should win. + - { target: Artifacts.MITRE.Tactic, issue_field: case.mitre_tactics_ids_and_names, shape: structured, role: canonical, source_origin: native } + - { target: Artifacts.MITRE.Technique, issue_field: case.mitre_techniques_ids_and_names, shape: structured, role: canonical, source_origin: native } + - { target: Artifacts.MITRE.Tactic, issue_field: mitreattcktactic, shape: structured, role: canonical, source_origin: native } + - { target: Artifacts.MITRE.Technique, issue_field: mitreattcktechnique, shape: structured, role: canonical, source_origin: native } + # The detector's own metadata: what fired, what it did, what it wrote. + - { target: Artifacts.Source.Action, issue_field: action, shape: structured, role: canonical, source_origin: native } + - { target: Artifacts.Source.Module, issue_field: 'detection_modules.[0]', shape: structured, role: canonical, source_origin: native } + - { target: Artifacts.Source.AlertDomain, issue_field: alert_domain, shape: structured, role: canonical, source_origin: native } + - { target: Artifacts.Source.Details, issue_field: details, shape: structured, role: canonical, source_origin: native } + - { target: Artifacts.Source.Details, issue_field: case.description, shape: structured, role: canonical, source_origin: native } + # sourceBrand reads MAGNIFIER on every analytics alert, so it names + # nothing. The case names the detection source. + - { target: Network.alert_source, issue_field: 'case.incident_sources.[0]', shape: flat, role: canonical, source_origin: native } + # ── Investigation scope (case-level, identical in every band) ───────── + # Declared in SOCFrameworkPhaseContract_V3 as analysis reads but never + # written. Populated only on a grouped case. + - { target: Investigation.RiskScore, issue_field: case.aggregated_score, shape: flat, role: canonical, source_origin: native } + - { target: Investigation.IssueCount, issue_field: case.alert_count, shape: flat, role: canonical, source_origin: native } + - { target: Investigation.UserCount, issue_field: case.user_count, shape: flat, role: canonical, source_origin: native } + - { target: Investigation.HostCount, issue_field: case.host_count, shape: flat, role: canonical, source_origin: native } + - { target: Investigation.LinkedCount, issue_field: linkedCount, shape: flat, role: canonical, source_origin: native } stamps: - { target: Network.normalization_source, value: network } mirrors: @@ -454,6 +522,32 @@ categories: - { target: Artifacts.Endpoint.Hostname, issue_field: agent_hostname, shape: structured, role: canonical, source_origin: native } - { target: Artifacts.Endpoint.AgentID, issue_field: agent_id, shape: structured, role: canonical, source_origin: native } - { target: Artifacts.Endpoint.Domain, issue_field: agent_device_domain, shape: structured, role: canonical, source_origin: native } + # ── Shared detection surface (category-agnostic) ───────────────────── + # XDR Analytics emits the fused mitreattck* form, never mitre*name/*id. + # Case rows first, issue rows last: the case MITRE is aggregated across + # the whole case, the issue MITRE describes this alert, and the more + # specific one should win. + - { target: Artifacts.MITRE.Tactic, issue_field: case.mitre_tactics_ids_and_names, shape: structured, role: canonical, source_origin: native } + - { target: Artifacts.MITRE.Technique, issue_field: case.mitre_techniques_ids_and_names, shape: structured, role: canonical, source_origin: native } + - { target: Artifacts.MITRE.Tactic, issue_field: mitreattcktactic, shape: structured, role: canonical, source_origin: native } + - { target: Artifacts.MITRE.Technique, issue_field: mitreattcktechnique, shape: structured, role: canonical, source_origin: native } + # The detector's own metadata: what fired, what it did, what it wrote. + - { target: Artifacts.Source.Action, issue_field: action, shape: structured, role: canonical, source_origin: native } + - { target: Artifacts.Source.Module, issue_field: 'detection_modules.[0]', shape: structured, role: canonical, source_origin: native } + - { target: Artifacts.Source.AlertDomain, issue_field: alert_domain, shape: structured, role: canonical, source_origin: native } + - { target: Artifacts.Source.Details, issue_field: details, shape: structured, role: canonical, source_origin: native } + - { target: Artifacts.Source.Details, issue_field: case.description, shape: structured, role: canonical, source_origin: native } + # sourceBrand reads MAGNIFIER on every analytics alert, so it names + # nothing. The case names the detection source. + - { target: Cloud.alert_source, issue_field: 'case.incident_sources.[0]', shape: flat, role: canonical, source_origin: native } + # ── Investigation scope (case-level, identical in every band) ───────── + # Declared in SOCFrameworkPhaseContract_V3 as analysis reads but never + # written. Populated only on a grouped case. + - { target: Investigation.RiskScore, issue_field: case.aggregated_score, shape: flat, role: canonical, source_origin: native } + - { target: Investigation.IssueCount, issue_field: case.alert_count, shape: flat, role: canonical, source_origin: native } + - { target: Investigation.UserCount, issue_field: case.user_count, shape: flat, role: canonical, source_origin: native } + - { target: Investigation.HostCount, issue_field: case.host_count, shape: flat, role: canonical, source_origin: native } + - { target: Investigation.LinkedCount, issue_field: linkedCount, shape: flat, role: canonical, source_origin: native } stamps: - { target: Cloud.normalization_source, value: cloud } mirrors: @@ -502,6 +596,32 @@ categories: - { target: Artifacts.Endpoint.Hostname, issue_field: agent_hostname, shape: structured, role: canonical, source_origin: native } - { target: Artifacts.Endpoint.AgentID, issue_field: agent_id, shape: structured, role: canonical, source_origin: native } - { target: Artifacts.Endpoint.Domain, issue_field: agent_device_domain, shape: structured, role: canonical, source_origin: native } + # ── Shared detection surface (category-agnostic) ───────────────────── + # XDR Analytics emits the fused mitreattck* form, never mitre*name/*id. + # Case rows first, issue rows last: the case MITRE is aggregated across + # the whole case, the issue MITRE describes this alert, and the more + # specific one should win. + - { target: Artifacts.MITRE.Tactic, issue_field: case.mitre_tactics_ids_and_names, shape: structured, role: canonical, source_origin: native } + - { target: Artifacts.MITRE.Technique, issue_field: case.mitre_techniques_ids_and_names, shape: structured, role: canonical, source_origin: native } + - { target: Artifacts.MITRE.Tactic, issue_field: mitreattcktactic, shape: structured, role: canonical, source_origin: native } + - { target: Artifacts.MITRE.Technique, issue_field: mitreattcktechnique, shape: structured, role: canonical, source_origin: native } + # The detector's own metadata: what fired, what it did, what it wrote. + - { target: Artifacts.Source.Action, issue_field: action, shape: structured, role: canonical, source_origin: native } + - { target: Artifacts.Source.Module, issue_field: 'detection_modules.[0]', shape: structured, role: canonical, source_origin: native } + - { target: Artifacts.Source.AlertDomain, issue_field: alert_domain, shape: structured, role: canonical, source_origin: native } + - { target: Artifacts.Source.Details, issue_field: details, shape: structured, role: canonical, source_origin: native } + - { target: Artifacts.Source.Details, issue_field: case.description, shape: structured, role: canonical, source_origin: native } + # sourceBrand reads MAGNIFIER on every analytics alert, so it names + # nothing. The case names the detection source. + - { target: Generic.alert_source, issue_field: 'case.incident_sources.[0]', shape: flat, role: canonical, source_origin: native } + # ── Investigation scope (case-level, identical in every band) ───────── + # Declared in SOCFrameworkPhaseContract_V3 as analysis reads but never + # written. Populated only on a grouped case. + - { target: Investigation.RiskScore, issue_field: case.aggregated_score, shape: flat, role: canonical, source_origin: native } + - { target: Investigation.IssueCount, issue_field: case.alert_count, shape: flat, role: canonical, source_origin: native } + - { target: Investigation.UserCount, issue_field: case.user_count, shape: flat, role: canonical, source_origin: native } + - { target: Investigation.HostCount, issue_field: case.host_count, shape: flat, role: canonical, source_origin: native } + - { target: Investigation.LinkedCount, issue_field: linkedCount, shape: flat, role: canonical, source_origin: native } stamps: - { target: Generic.normalization_source, value: generic } mirrors: From ae9776ef231ac46fff2098b2f44d5f81daa56dc7 Mon Sep 17 00:00:00 2001 From: sbrumley Date: Mon, 17 Aug 2026 18:31:05 -0400 Subject: [PATCH 4/5] feat(nist-ir): extend the endpoint detection surface in the normalize map --- ...SOCFrameworkNormalizeMap_NIST_IR_data.json | 268 +++++++++++++++--- .../SOCFrameworkNormalizeMap_NIST_IR.yaml | 84 ++++-- 2 files changed, 292 insertions(+), 60 deletions(-) diff --git a/Packs/soc-framework-nist-ir/Lists/SOCFrameworkNormalizeMap_NIST_IR/SOCFrameworkNormalizeMap_NIST_IR_data.json b/Packs/soc-framework-nist-ir/Lists/SOCFrameworkNormalizeMap_NIST_IR/SOCFrameworkNormalizeMap_NIST_IR_data.json index 37d9d62c..f52cc108 100644 --- a/Packs/soc-framework-nist-ir/Lists/SOCFrameworkNormalizeMap_NIST_IR/SOCFrameworkNormalizeMap_NIST_IR_data.json +++ b/Packs/soc-framework-nist-ir/Lists/SOCFrameworkNormalizeMap_NIST_IR/SOCFrameworkNormalizeMap_NIST_IR_data.json @@ -34,6 +34,13 @@ "endpoint": { "status": "complete", "mappings": [ + { + "target": "Endpoint.alert_source", + "issue_field": "case.incident_sources.[0]", + "shape": "flat", + "role": "canonical", + "source_origin": "native" + }, { "target": "Endpoint.alert_name", "issue_field": "name", @@ -754,6 +761,190 @@ "role": "canonical", "source_origin": "native" }, + { + "target": "Artifacts.Process.Name", + "issue_field": "actor_process_image_name", + "shape": "structured", + "role": "canonical", + "source_origin": "native" + }, + { + "target": "Artifacts.Process.Path", + "issue_field": "actor_process_image_path", + "shape": "structured", + "role": "canonical", + "source_origin": "native" + }, + { + "target": "Artifacts.Process.SHA256", + "issue_field": "actor_process_image_sha256", + "shape": "structured", + "role": "canonical", + "source_origin": "native" + }, + { + "target": "Artifacts.Process.CommandLine", + "issue_field": "actor_process_command_line", + "shape": "structured", + "role": "canonical", + "source_origin": "native" + }, + { + "target": "Artifacts.Process.PID", + "issue_field": "actor_process_os_pid", + "shape": "structured", + "role": "canonical", + "source_origin": "native" + }, + { + "target": "Artifacts.Process.Signer", + "issue_field": "actor_process_signature_vendor", + "shape": "structured", + "role": "canonical", + "source_origin": "native" + }, + { + "target": "Artifacts.Process.Causality.ID", + "issue_field": "causality_actor_causality_id", + "shape": "structured", + "role": "canonical", + "source_origin": "native" + }, + { + "target": "Artifacts.Process.Parent.Name", + "issue_field": "parentprocessname", + "shape": "structured", + "role": "canonical", + "source_origin": "native" + }, + { + "target": "Artifacts.Process.Parent.Name", + "issue_field": "causality_actor_process_image_name", + "shape": "structured", + "role": "canonical", + "source_origin": "native" + }, + { + "target": "Artifacts.Process.Parent.Path", + "issue_field": "parentprocesspath", + "shape": "structured", + "role": "canonical", + "source_origin": "native" + }, + { + "target": "Artifacts.Process.Parent.Path", + "issue_field": "causality_actor_process_image_path", + "shape": "structured", + "role": "canonical", + "source_origin": "native" + }, + { + "target": "Artifacts.Process.Parent.SHA256", + "issue_field": "parentprocesssha256", + "shape": "structured", + "role": "canonical", + "source_origin": "native" + }, + { + "target": "Artifacts.Process.Parent.SHA256", + "issue_field": "causality_actor_process_image_sha256", + "shape": "structured", + "role": "canonical", + "source_origin": "native" + }, + { + "target": "Artifacts.Target.File", + "issue_field": "action_file_name", + "shape": "structured", + "role": "canonical", + "source_origin": "native" + }, + { + "target": "Artifacts.Target.Path", + "issue_field": "action_file_path", + "shape": "structured", + "role": "canonical", + "source_origin": "native" + }, + { + "target": "Artifacts.Target.SHA256", + "issue_field": "action_file_sha256", + "shape": "structured", + "role": "canonical", + "source_origin": "native" + }, + { + "target": "Artifacts.Network.IP", + "issue_field": "action_remote_ip", + "shape": "structured", + "role": "canonical", + "source_origin": "native" + }, + { + "target": "Artifacts.Identity.User.Name", + "issue_field": "actor_effective_username", + "shape": "structured", + "role": "canonical", + "source_origin": "native", + "lower": true + }, + { + "target": "Endpoint.file_path", + "issue_field": "action_file_path", + "shape": "flat", + "role": "canonical", + "source_origin": "native" + }, + { + "target": "Endpoint.file_sha256", + "issue_field": "action_file_sha256", + "shape": "flat", + "role": "canonical", + "source_origin": "native" + }, + { + "target": "Endpoint.process_name", + "issue_field": "actor_process_image_name", + "shape": "flat", + "role": "canonical", + "source_origin": "native" + }, + { + "target": "Endpoint.process_path", + "issue_field": "actor_process_image_path", + "shape": "flat", + "role": "canonical", + "source_origin": "native" + }, + { + "target": "Endpoint.process_sha256", + "issue_field": "actor_process_image_sha256", + "shape": "flat", + "role": "canonical", + "source_origin": "native" + }, + { + "target": "Endpoint.process_cmd", + "issue_field": "actor_process_command_line", + "shape": "flat", + "role": "canonical", + "source_origin": "native" + }, + { + "target": "Endpoint.process_pid", + "issue_field": "actor_process_os_pid", + "shape": "flat", + "role": "canonical", + "source_origin": "native" + }, + { + "target": "Endpoint.username", + "issue_field": "actor_effective_username", + "shape": "flat", + "role": "canonical", + "source_origin": "native", + "lower": true + }, { "target": "Artifacts.MITRE.Tactic", "issue_field": "case.mitre_tactics_ids_and_names", @@ -810,13 +1001,6 @@ "role": "canonical", "source_origin": "native" }, - { - "target": "Endpoint.alert_source", - "issue_field": "case.incident_sources.[0]", - "shape": "flat", - "role": "canonical", - "source_origin": "native" - }, { "target": "Investigation.RiskScore", "issue_field": "case.aggregated_score", @@ -872,6 +1056,13 @@ "email": { "status": "partial", "mappings": [ + { + "target": "Email.alert_source", + "issue_field": "case.incident_sources.[0]", + "shape": "flat", + "role": "canonical", + "source_origin": "native" + }, { "target": "Email.alert_name", "issue_field": "name", @@ -1374,13 +1565,6 @@ "role": "canonical", "source_origin": "native" }, - { - "target": "Email.alert_source", - "issue_field": "case.incident_sources.[0]", - "shape": "flat", - "role": "canonical", - "source_origin": "native" - }, { "target": "Investigation.RiskScore", "issue_field": "case.aggregated_score", @@ -1469,6 +1653,13 @@ "identity": { "status": "in-progress", "mappings": [ + { + "target": "Identity.alert_source", + "issue_field": "case.incident_sources.[0]", + "shape": "flat", + "role": "canonical", + "source_origin": "native" + }, { "target": "Identity.alert_name", "issue_field": "name", @@ -1933,13 +2124,6 @@ "role": "canonical", "source_origin": "native" }, - { - "target": "Identity.alert_source", - "issue_field": "case.incident_sources.[0]", - "shape": "flat", - "role": "canonical", - "source_origin": "native" - }, { "target": "Investigation.RiskScore", "issue_field": "case.aggregated_score", @@ -2055,6 +2239,13 @@ "network": { "status": "in-progress", "mappings": [ + { + "target": "Network.alert_source", + "issue_field": "case.incident_sources.[0]", + "shape": "flat", + "role": "canonical", + "source_origin": "native" + }, { "target": "Network.alert_name", "issue_field": "name", @@ -2517,13 +2708,6 @@ "role": "canonical", "source_origin": "native" }, - { - "target": "Network.alert_source", - "issue_field": "case.incident_sources.[0]", - "shape": "flat", - "role": "canonical", - "source_origin": "native" - }, { "target": "Investigation.RiskScore", "issue_field": "case.aggregated_score", @@ -2674,6 +2858,13 @@ "cloud": { "status": "complete", "mappings": [ + { + "target": "Cloud.alert_source", + "issue_field": "case.incident_sources.[0]", + "shape": "flat", + "role": "canonical", + "source_origin": "native" + }, { "target": "Cloud.alert_name", "issue_field": "name", @@ -3080,13 +3271,6 @@ "role": "canonical", "source_origin": "native" }, - { - "target": "Cloud.alert_source", - "issue_field": "case.incident_sources.[0]", - "shape": "flat", - "role": "canonical", - "source_origin": "native" - }, { "target": "Investigation.RiskScore", "issue_field": "case.aggregated_score", @@ -3134,6 +3318,13 @@ "generic": { "status": "complete", "mappings": [ + { + "target": "Generic.alert_source", + "issue_field": "case.incident_sources.[0]", + "shape": "flat", + "role": "canonical", + "source_origin": "native" + }, { "target": "Generic.primary_entity_type", "issue_field": "primaryusertype", @@ -3491,13 +3682,6 @@ "role": "canonical", "source_origin": "native" }, - { - "target": "Generic.alert_source", - "issue_field": "case.incident_sources.[0]", - "shape": "flat", - "role": "canonical", - "source_origin": "native" - }, { "target": "Investigation.RiskScore", "issue_field": "case.aggregated_score", diff --git a/schemas/soc-framework/soc-framework-nist-ir/SOCFrameworkNormalizeMap_NIST_IR.yaml b/schemas/soc-framework/soc-framework-nist-ir/SOCFrameworkNormalizeMap_NIST_IR.yaml index c9e2270f..595c12c0 100644 --- a/schemas/soc-framework/soc-framework-nist-ir/SOCFrameworkNormalizeMap_NIST_IR.yaml +++ b/schemas/soc-framework/soc-framework-nist-ir/SOCFrameworkNormalizeMap_NIST_IR.yaml @@ -28,6 +28,11 @@ categories: endpoint: status: complete mappings: + # Fallback only: the vendor's own alert_source wins when the + # source carries one. The case reports 'Correlation', which + # identifies nothing — it is here for sources like analytics + # alerts that name no vendor at all. + - { target: Endpoint.alert_source, issue_field: 'case.incident_sources.[0]', shape: flat, role: canonical, source_origin: native } - { target: Endpoint.alert_name, issue_field: name, shape: flat, role: canonical, source_origin: native } - { target: Endpoint.alert_source, issue_field: sourcebrand, shape: flat, role: canonical, source_origin: native } - { target: Endpoint.alert_action, issue_field: alertaction, shape: flat, role: canonical, source_origin: native } @@ -133,6 +138,42 @@ categories: - { target: Endpoint.os, issue_field: hostos, shape: flat, role: canonical, source_origin: native } # native XDR agent: fixes Endpoint.os, dead on every source - { target: Endpoint.tactic, issue_field: mitreattcktactic, shape: flat, role: canonical, source_origin: native } # native XDR agent uses mitreattck* naming - { target: Endpoint.technique, issue_field: mitreattcktechnique, shape: flat, role: canonical, source_origin: native } # native XDR agent uses mitreattck* naming + # ── XDM-named endpoint fields ───────────────────────────────────────── + # The rows above read the native XDR agent's initiator*/file* names. Any + # endpoint source feeding the XDM-named actor_*/action_* fields resolved + # nothing — no hash, no path, no command line reached the contract, so + # Eradication had no file to act on. These are XSIAM native alert fields, + # not one vendor's: whichever set a source populates, wins. + - { target: Artifacts.Process.Name, issue_field: actor_process_image_name, shape: structured, role: canonical, source_origin: native } + - { target: Artifacts.Process.Path, issue_field: actor_process_image_path, shape: structured, role: canonical, source_origin: native } + - { target: Artifacts.Process.SHA256, issue_field: actor_process_image_sha256, shape: structured, role: canonical, source_origin: native } + - { target: Artifacts.Process.CommandLine, issue_field: actor_process_command_line, shape: structured, role: canonical, source_origin: native } + - { target: Artifacts.Process.PID, issue_field: actor_process_os_pid, shape: structured, role: canonical, source_origin: native } + - { target: Artifacts.Process.Signer, issue_field: actor_process_signature_vendor, shape: structured, role: canonical, source_origin: native } + - { target: Artifacts.Process.Causality.ID, issue_field: causality_actor_causality_id, shape: structured, role: canonical, source_origin: native } + # Parent identity — Parent.PID and Parent.Signature already exist; the + # binary itself did not, so a parent process could be counted but never named. + - { target: Artifacts.Process.Parent.Name, issue_field: parentprocessname, shape: structured, role: canonical, source_origin: native } + - { target: Artifacts.Process.Parent.Name, issue_field: causality_actor_process_image_name, shape: structured, role: canonical, source_origin: native } + - { target: Artifacts.Process.Parent.Path, issue_field: parentprocesspath, shape: structured, role: canonical, source_origin: native } + - { target: Artifacts.Process.Parent.Path, issue_field: causality_actor_process_image_path, shape: structured, role: canonical, source_origin: native } + - { target: Artifacts.Process.Parent.SHA256, issue_field: parentprocesssha256, shape: structured, role: canonical, source_origin: native } + - { target: Artifacts.Process.Parent.SHA256, issue_field: causality_actor_process_image_sha256, shape: structured, role: canonical, source_origin: native } + # The file the alert acted on — what Eradication deletes or blocks. + - { target: Artifacts.Target.File, issue_field: action_file_name, shape: structured, role: canonical, source_origin: native } + - { target: Artifacts.Target.Path, issue_field: action_file_path, shape: structured, role: canonical, source_origin: native } + - { target: Artifacts.Target.SHA256, issue_field: action_file_sha256, shape: structured, role: canonical, source_origin: native } + - { target: Artifacts.Network.IP, issue_field: action_remote_ip, shape: structured, role: canonical, source_origin: native } + - { target: Artifacts.Identity.User.Name, issue_field: actor_effective_username, shape: structured, role: canonical, source_origin: native, lower: true } + # Flat twins of the same fields. + - { target: Endpoint.file_path, issue_field: action_file_path, shape: flat, role: canonical, source_origin: native } + - { target: Endpoint.file_sha256, issue_field: action_file_sha256, shape: flat, role: canonical, source_origin: native } + - { target: Endpoint.process_name, issue_field: actor_process_image_name, shape: flat, role: canonical, source_origin: native } + - { target: Endpoint.process_path, issue_field: actor_process_image_path, shape: flat, role: canonical, source_origin: native } + - { target: Endpoint.process_sha256, issue_field: actor_process_image_sha256, shape: flat, role: canonical, source_origin: native } + - { target: Endpoint.process_cmd, issue_field: actor_process_command_line, shape: flat, role: canonical, source_origin: native } + - { target: Endpoint.process_pid, issue_field: actor_process_os_pid, shape: flat, role: canonical, source_origin: native } + - { target: Endpoint.username, issue_field: actor_effective_username, shape: flat, role: canonical, source_origin: native, lower: true } # ── Shared detection surface (category-agnostic) ───────────────────── # XDR Analytics emits the fused mitreattck* form, never mitre*name/*id. # Case rows first, issue rows last: the case MITRE is aggregated across @@ -147,9 +188,6 @@ categories: - { target: Artifacts.Source.Module, issue_field: 'detection_modules.[0]', shape: structured, role: canonical, source_origin: native } - { target: Artifacts.Source.Details, issue_field: details, shape: structured, role: canonical, source_origin: native } - { target: Artifacts.Source.Details, issue_field: case.description, shape: structured, role: canonical, source_origin: native } - # sourceBrand reads MAGNIFIER on every analytics alert, so it names - # nothing. The case names the detection source. - - { target: Endpoint.alert_source, issue_field: 'case.incident_sources.[0]', shape: flat, role: canonical, source_origin: native } # ── Investigation scope (case-level, identical in every band) ───────── # Declared in SOCFrameworkPhaseContract_V3 as analysis reads but never # written. Populated only on a grouped case. @@ -168,6 +206,11 @@ categories: email: status: partial mappings: + # Fallback only: the vendor's own alert_source wins when the + # source carries one. The case reports 'Correlation', which + # identifies nothing — it is here for sources like analytics + # alerts that name no vendor at all. + - { target: Email.alert_source, issue_field: 'case.incident_sources.[0]', shape: flat, role: canonical, source_origin: native } - { target: Email.alert_name, issue_field: name, shape: flat, role: canonical, source_origin: native } - { target: Email.alert_source, issue_field: sourcebrand, shape: flat, role: canonical, source_origin: native } - { target: Email.attachment_name, issue_field: 'filename.[0]', shape: flat, role: canonical, source_origin: native } @@ -242,9 +285,6 @@ categories: - { target: Artifacts.Source.AlertDomain, issue_field: alert_domain, shape: structured, role: canonical, source_origin: native } - { target: Artifacts.Source.Details, issue_field: details, shape: structured, role: canonical, source_origin: native } - { target: Artifacts.Source.Details, issue_field: case.description, shape: structured, role: canonical, source_origin: native } - # sourceBrand reads MAGNIFIER on every analytics alert, so it names - # nothing. The case names the detection source. - - { target: Email.alert_source, issue_field: 'case.incident_sources.[0]', shape: flat, role: canonical, source_origin: native } # ── Investigation scope (case-level, identical in every band) ───────── # Declared in SOCFrameworkPhaseContract_V3 as analysis reads but never # written. Populated only on a grouped case. @@ -267,6 +307,11 @@ categories: identity: status: in-progress mappings: + # Fallback only: the vendor's own alert_source wins when the + # source carries one. The case reports 'Correlation', which + # identifies nothing — it is here for sources like analytics + # alerts that name no vendor at all. + - { target: Identity.alert_source, issue_field: 'case.incident_sources.[0]', shape: flat, role: canonical, source_origin: native } - { target: Identity.alert_name, issue_field: name, shape: flat, role: canonical, source_origin: native } - { target: Identity.alert_source, issue_field: sourcebrand, shape: flat, role: canonical, source_origin: native } - { target: Identity.client_ip, issue_field: localip, shape: flat, role: canonical, source_origin: native, dedup_key: true, dedup_match: json } @@ -341,9 +386,6 @@ categories: - { target: Artifacts.Source.AlertDomain, issue_field: alert_domain, shape: structured, role: canonical, source_origin: native } - { target: Artifacts.Source.Details, issue_field: details, shape: structured, role: canonical, source_origin: native } - { target: Artifacts.Source.Details, issue_field: case.description, shape: structured, role: canonical, source_origin: native } - # sourceBrand reads MAGNIFIER on every analytics alert, so it names - # nothing. The case names the detection source. - - { target: Identity.alert_source, issue_field: 'case.incident_sources.[0]', shape: flat, role: canonical, source_origin: native } # ── Investigation scope (case-level, identical in every band) ───────── # Declared in SOCFrameworkPhaseContract_V3 as analysis reads but never # written. Populated only on a grouped case. @@ -370,6 +412,11 @@ categories: network: status: in-progress mappings: + # Fallback only: the vendor's own alert_source wins when the + # source carries one. The case reports 'Correlation', which + # identifies nothing — it is here for sources like analytics + # alerts that name no vendor at all. + - { target: Network.alert_source, issue_field: 'case.incident_sources.[0]', shape: flat, role: canonical, source_origin: native } - { target: Network.alert_name, issue_field: name, shape: flat, role: canonical, source_origin: native } - { target: Network.alert_source, issue_field: sourcebrand, shape: flat, role: canonical, source_origin: native } - { target: Network.action, issue_field: action, shape: flat, role: canonical, source_origin: native } @@ -440,9 +487,6 @@ categories: - { target: Artifacts.Source.AlertDomain, issue_field: alert_domain, shape: structured, role: canonical, source_origin: native } - { target: Artifacts.Source.Details, issue_field: details, shape: structured, role: canonical, source_origin: native } - { target: Artifacts.Source.Details, issue_field: case.description, shape: structured, role: canonical, source_origin: native } - # sourceBrand reads MAGNIFIER on every analytics alert, so it names - # nothing. The case names the detection source. - - { target: Network.alert_source, issue_field: 'case.incident_sources.[0]', shape: flat, role: canonical, source_origin: native } # ── Investigation scope (case-level, identical in every band) ───────── # Declared in SOCFrameworkPhaseContract_V3 as analysis reads but never # written. Populated only on a grouped case. @@ -475,6 +519,11 @@ categories: cloud: status: complete # migrated verbatim from Foundation - Normalize Cloud_V3 mappings: + # Fallback only: the vendor's own alert_source wins when the + # source carries one. The case reports 'Correlation', which + # identifies nothing — it is here for sources like analytics + # alerts that name no vendor at all. + - { target: Cloud.alert_source, issue_field: 'case.incident_sources.[0]', shape: flat, role: canonical, source_origin: native } - { target: Cloud.alert_name, issue_field: name, shape: flat, role: canonical, source_origin: native } - { target: Cloud.alert_source, issue_field: sourcebrand, shape: flat, role: canonical, source_origin: native } - { target: Cloud.principal, issue_field: username, shape: flat, role: canonical, source_origin: native, dedup_key: true, dedup_match: json } @@ -537,9 +586,6 @@ categories: - { target: Artifacts.Source.AlertDomain, issue_field: alert_domain, shape: structured, role: canonical, source_origin: native } - { target: Artifacts.Source.Details, issue_field: details, shape: structured, role: canonical, source_origin: native } - { target: Artifacts.Source.Details, issue_field: case.description, shape: structured, role: canonical, source_origin: native } - # sourceBrand reads MAGNIFIER on every analytics alert, so it names - # nothing. The case names the detection source. - - { target: Cloud.alert_source, issue_field: 'case.incident_sources.[0]', shape: flat, role: canonical, source_origin: native } # ── Investigation scope (case-level, identical in every band) ───────── # Declared in SOCFrameworkPhaseContract_V3 as analysis reads but never # written. Populated only on a grouped case. @@ -556,6 +602,11 @@ categories: generic: status: complete # migrated verbatim from Foundation - Normalize Generic_V3 mappings: + # Fallback only: the vendor's own alert_source wins when the + # source carries one. The case reports 'Correlation', which + # identifies nothing — it is here for sources like analytics + # alerts that name no vendor at all. + - { target: Generic.alert_source, issue_field: 'case.incident_sources.[0]', shape: flat, role: canonical, source_origin: native } - { target: Generic.primary_entity_type, issue_field: primaryusertype, shape: flat, role: canonical, source_origin: native } - { target: Generic.primary_entity_value, issue_field: username, shape: flat, role: canonical, source_origin: native } - { target: Generic.hostname, issue_field: agent_hostname, shape: flat, role: canonical, source_origin: native } @@ -611,9 +662,6 @@ categories: - { target: Artifacts.Source.AlertDomain, issue_field: alert_domain, shape: structured, role: canonical, source_origin: native } - { target: Artifacts.Source.Details, issue_field: details, shape: structured, role: canonical, source_origin: native } - { target: Artifacts.Source.Details, issue_field: case.description, shape: structured, role: canonical, source_origin: native } - # sourceBrand reads MAGNIFIER on every analytics alert, so it names - # nothing. The case names the detection source. - - { target: Generic.alert_source, issue_field: 'case.incident_sources.[0]', shape: flat, role: canonical, source_origin: native } # ── Investigation scope (case-level, identical in every band) ───────── # Declared in SOCFrameworkPhaseContract_V3 as analysis reads but never # written. Populated only on a grouped case. From 65ca290973c1c7d071f2559ab7da3ed11c8dd0f3 Mon Sep 17 00:00:00 2001 From: sbrumley Date: Mon, 17 Aug 2026 18:31:05 -0400 Subject: [PATCH 5/5] test(scenarios): retarget the Abnormal + Defender chain at deathstar --- scenarios/turla_carbon_abnormal_mde.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scenarios/turla_carbon_abnormal_mde.yml b/scenarios/turla_carbon_abnormal_mde.yml index 842bdcda..aef20182 100644 --- a/scenarios/turla_carbon_abnormal_mde.yml +++ b/scenarios/turla_carbon_abnormal_mde.yml @@ -19,8 +19,8 @@ compress_window: 5m # < rules' 20m window minus */10 tick delay; email is earl sources: - name: Abnormal Security file: input_tsv/Abnormal-MITRE-Turla-Carbon-in-XSIAM.tsv - env: .env-brumxdr-abnormal + env: .env-deathstar-abnormal - name: Microsoft Defender file: input_tsv/MS-Defender-Turla-Carbon.tsv - env: .env-brumxdr-defender + env: .env-deathstar-defender