{
  "technique_id": "T1195",
  "name": "Supply Chain Compromise",
  "priority": "medium",
  "status": "complete",
  "version": "0.1.0",
  "last_reviewed": "2026-07-23",
  "generated_by": "SOC Response Atlas by Basyrix",
  "tactics": [
    "Initial Access"
  ],
  "platforms": [
    "Linux",
    "Windows",
    "macOS",
    "SaaS"
  ],
  "summary": "Adversaries may manipulate products or product delivery mechanisms prior to receipt by a final consumer for the purpose of data or system compromise...",
  "soc_recommendation": "Investigate Supply Chain Compromise activity in the context of Initial Access: confirm scope, affected host/identity, and whether it matches expected administrative behaviour before deciding this is benign.",
  "d3fend_mappings": [
    {
      "id": "D3-RH",
      "name": "Radiation Hardening",
      "relationship": "harden",
      "practical_action": "Apply Radiation Hardening to reduce this technique's viability before an incident occurs.",
      "tooling": [
        "Defender for Endpoint"
      ]
    },
    {
      "id": "D3-RS",
      "name": "Restore Software",
      "relationship": "restore",
      "practical_action": "Use Restore Software to recover affected systems or data after containment.",
      "tooling": [
        "Defender for Endpoint"
      ]
    },
    {
      "id": "D3-HCI",
      "name": "Hardware Component Inventory",
      "relationship": "model",
      "practical_action": "Use Hardware Component Inventory to establish a baseline that makes this technique's deviations easier to spot.",
      "tooling": [
        "Defender for Endpoint"
      ]
    }
  ],
  "investigation_steps": {
    "microsoft": [
      "Confirm matching entities (user, host, IP) and validate data freshness in the lookback period.",
      "Check whether activity aligns with a planned change or approved business process.",
      "Identify all affected users/devices/resources over the prior 24 hours.",
      "Determine whether this is isolated or part of a broader campaign.",
      "Correlate with identity, endpoint, and email/cloud telemetry for related suspicious actions.",
      "Elevate severity if privileged identities, critical systems, or repeated activity is observed.",
      "Capture all evidence (query results, entities, timeline) in the incident record.",
      "Route to the appropriate response playbook and customer escalation path."
    ],
    "generic": [
      "Confirm whether the observed supply chain compromise activity matches expected administrative or application behaviour.",
      "Identify the host, account, or resource where the activity occurred and its business criticality.",
      "Check for related alerts before and after this activity to reconstruct the broader intrusion timeline.",
      "Real detection reference: \"SUNBURST and SUPERNOVA backdoor hashes (Normalized File Events)\" -- Identifies SolarWinds SUNBURST and SUPERNOVA backdoor file hash IOCs in File Events To use this analytics rule, make sure you have deployed the [ASIM normalization parsers](https://aka.ms/ASimFileEvent) References: - https://www.fireeye.com/blog/threat-research/2020/12/evasive-attacker-leverages-solarwinds-supply-chain-compromises-with-sunburst-backdoor.html - https://gist.github.com/olafhartong/71ffdd4cab4b6acd5cbcd1a0691ff82f"
    ]
  },
  "evidence_to_collect": [
    "Host or resource affected",
    "Account or identity involved",
    "Timestamp of the activity",
    "Related process, file, or network artifact",
    "Any preceding or follow-on alerts"
  ],
  "response_actions": [
    {
      "name": "Contain impacted identities/endpoints/sessions based on obse",
      "category": "Containment",
      "risk": "Low",
      "automation_safe": false,
      "approval_required": true,
      "tool": "See investigation guide",
      "notes": "Contain impacted identities/endpoints/sessions based on observed behavior."
    },
    {
      "name": "Block malicious indicators (IP, URL, domain, hash) where ava",
      "category": "Containment",
      "risk": "Medium",
      "automation_safe": false,
      "approval_required": true,
      "tool": "See investigation guide",
      "notes": "Block malicious indicators (IP, URL, domain, hash) where available."
    },
    {
      "name": "Complete blast radius analysis across related logs and entit",
      "category": "Eradication",
      "risk": "Low",
      "automation_safe": false,
      "approval_required": true,
      "tool": "See investigation guide",
      "notes": "Complete blast radius analysis across related logs and entities."
    },
    {
      "name": "Notify stakeholders according to incident priority and custo",
      "category": "Eradication",
      "risk": "Low",
      "automation_safe": true,
      "approval_required": false,
      "tool": "See investigation guide",
      "notes": "Notify stakeholders according to incident priority and customer SLA."
    },
    {
      "name": "Remove persistence or unauthorized access paths identified d",
      "category": "Recovery",
      "risk": "Low",
      "automation_safe": false,
      "approval_required": true,
      "tool": "See investigation guide",
      "notes": "Remove persistence or unauthorized access paths identified during investigation."
    },
    {
      "name": "Capture lessons learned and update rule tuning/watchlists.",
      "category": "Recovery",
      "risk": "Low",
      "automation_safe": false,
      "approval_required": true,
      "tool": "See investigation guide"
    }
  ],
  "queries": {
    "kql": [
      {
        "name": "bc5ffe2a-84d6-48fe-bc7b-1055100469bc — SUNBURST and SUPERNOVA backdoor hashes (Normalized File Events)",
        "description": "Identifies SolarWinds SUNBURST and SUPERNOVA backdoor file hash IOCs in File Events To use this analytics rule, make sure you have deployed the [ASIM normalization parsers](https://aka.ms/ASimFileEvent) References: - https://www.fireeye.com/blog/threat-research/2020/12/evasive-attacker-leverages-solarwinds-supply-chain-compromises-with-sunburst-backdoor.html - https://gist.github.com/olafhartong/71ffdd4cab4b6acd5cbcd1a0691ff82f (Source: Microsoft's official Azure-Sentinel Detections (MIT licensed).)",
        "query": "let SunburstMD5=dynamic([\"b91ce2fa41029f6955bff20079468448\",\"02af7cec58b9a5da1c542b5a32151ba1\",\"2c4a910a1299cdae2a4e55988a2f102e\",\"846e27a652a5e1bfbd0ddd38a16dc865\",\"4f2eb62fa529c0283b28d05ddd311fae\"]);\nlet SupernovaMD5=\"56ceb6d0011d87b6e4d7023d7ef85676\";\nimFileEvent\n| where TargetFileMD5 in (SunburstMD5) or TargetFileMD5 in (SupernovaMD5)\n| extend AccountName = tostring(split(User, @'\\')[1]), AccountNTDomain = tostring(split(User, @'\\')[0])\n| extend AlgorithmType = \"MD5\""
      },
      {
        "name": "e70fa6e0-796a-4e85-9420-98b17b0bb749 — Solorigate Defender Detections",
        "description": "Surfaces any Defender Alert for Solorigate Events. In Microsoft Sentinel the SecurityAlerts table includes only the Device Name of the affected device, this query joins the DeviceInfo table to clearly connect other information such as Device group, ip, logged on users etc. This way, the Microsoft Sentinel user can have all the pertinent device info in one view for all the the Solarigate Defender alerts.' (Source: Microsoft's official Azure-Sentinel Detections (MIT licensed).)",
        "query": "DeviceInfo\n| extend DeviceName = tolower(DeviceName)\n| join (SecurityAlert\n| where ProviderName =~ \"MDATP\"\n| extend ThreatName = tostring(parse_json(ExtendedProperties).ThreatName)\n| where ThreatName has \"Solorigate\"\n) on $left.DeviceName == $right.CompromisedEntity\n| project TimeGenerated, DisplayName, ThreatName, CompromisedEntity, PublicIP, MachineGroup, AlertSeverity, Description, LoggedOnUsers, DeviceId, TenantId\n| extend HostName = tostring(split(CompromisedEntity, \".\")[0]), DomainIndex = toint(indexof(CompromisedEntity, '.'))\n| extend HostNameDomain = iff(DomainIndex != -1, substring(CompromisedEntity, DomainIndex + 1), CompromisedEntity)\n| project-away DomainIndex"
      },
      {
        "name": "75491db8-eaf7-40bb-a46a-279872cc82f5 — Google DNS - Malicous Python packages",
        "description": "Detects requests to resources with malicious Python packages.' (Source: Microsoft's official Azure-Sentinel Detections (MIT licensed).)",
        "query": "GCPCloudDNS\n| where Query has_any ('psec.forward.io.global.prod.fastly.net', 'b0a0374cd1cb4305002e.d.requestbin.net', 'tornadodomain.000webhostapp.com', 'yxznlysc47wvrb9r9z211e1jbah15q')\n| extend DNSCustomEntity = Query, IPCustomEntity = SrcIpAddr"
      }
    ],
    "spl": [],
    "esql": [
      {
        "name": "d4e5f6a7-b8c9-7d0e-1f2a-3b4c5d6e7f8a — Elastic Defend Alert from GenAI Utility or Descendant",
        "description": "(ESQL) Detects Elastic Defend alerts (behavior, malicious file, memory signature, shellcode) where the alerted process or its direct parent is a GenAI coding or assistant utility (e.g. Cursor, Claude, Windsurf, Cody, Continue, Aider, OpenClaw, Moltbot, Clawdbot, Codeium, Tabnine, GitHub Copilot)... (Source: Elastic's official detection-rules repository (Elastic License v2).)",
        "query": "FROM logs-endpoint.alerts-*, logs-endpoint.events.process-* metadata _id, _version, _index \n| EVAL is_genai_spawn =  TO_LOWER(process.parent.name) IN (\n        \"claude\", \"claude.exe\", \"cursor\", \"cursor.exe\", \"cursor helper\", \"cursor helper (plugin)\",\n        \"codex\", \"codex.exe\", \"cody\", \"cody.exe\", \"copilot\", \"copilot.exe\", \"gemini-cli\", \"gemini-cli.exe\",\n        \"openai\", \"openai.exe\", \"ollama\", \"ollama.exe\", \"llm\", \"llm.exe\",\n        \"aider\", \"aider.exe\", \"cline\", \"cline.exe\", \"continue\", \"continue.exe\",\n        \"zed\", \"zed.exe\", \"windsurf\", \"windsurf.exe\",\n        \"tabnine\", \"tabnine.exe\", \"codeium\", \"codeium.exe\", \"bolt\", \"bolt.exe\",\n        \"devin\", \"devin.exe\", \"replit\", \"replit.exe\", \"ghostwriter\", \"ghostwriter.exe\", \"bito\", \"bito.exe\"\n    ),\n     is_openclaw_spawn = process.parent.name in (\"node\", \"node.exe\") and (process.parent.command_line like \"*openclaw*\" or process.parent.command_line like \"*moltbot*\" or process.parent.command_line like \"*clawdbot*\")\n| WHERE process.Ext.ancestry IS NOT NULL and \n   (data_stream.dataset == \"endpoint.alerts\" or is_genai_spawn or is_openclaw_spawn)\n// Identify GenAI tool spawn events and capture their entity_ids\n| EVAL genai_entity_id = CASE(is_genai_spawn or is_openclaw_spawn, process.parent.entity_id, NULL)\n\n// Collect ALL GenAI entity_ids globally across the dataset\n| INLINE STATS \n    all_genai_entity_ids = VALUES(genai_entity_id) WHERE genai_entity_id IS NOT NULL\n// Find which GenAI entity_ids appear in this process's ancestry\n| EVAL Esql.genai_ancestor_ids = MV_INTERSECTION(all_genai_entity_ids, process.Ext.ancestry)\n\n// Elastic Defend alerts from a GenAI grandparent \n| WHERE Esql.genai_ancestor_ids IS NOT NULL \n        AND data_stream.dataset == \"endpoint.alerts\" AND not rule.name in (\n            \"Persistence via GenAI Tool\",\n            \"Code Editor Untrusted or Unsigned Child Process Execution\",\n            \"Suspicious Credential Access via GenAI Tool\",\n            \"Credential Access via GenAI Tool Descendant\"\n        )\n\n| KEEP *"
      },
      {
        "name": "344e6c7d-ceb0-4f20-ba04-7c75569a7e38 — Elastic Defend Alert from Package Manager Install Ancestry",
        "description": "(ESQL) Detects Elastic Defend alerts (behavior, malicious file, memory signature, shellcode) where the alerted process has a package-manager install context in its ancestry: npm (Node.js), PyPI (pip / Python / uv), or Rust (cargo)... (Source: Elastic's official detection-rules repository (Elastic License v2).)",
        "query": "FROM logs-endpoint.alerts-*, logs-endpoint.events.process-* METADATA _id, _version, _index\n\n| EVAL is_pkg_install = CASE(\n    // npm  npx  yarn  pnpm (Node.js ecosystem)\n    process.parent.name IN (\"node\", \"node.exe\") AND (\n      process.parent.command_line LIKE \"*npm install*\" OR\n      process.parent.command_line LIKE \"*npm i *\" OR\n      ends_with(process.parent.command_line, \"npm i\") OR\n      process.parent.command_line LIKE \"*npx *\" OR\n      process.parent.command_line LIKE \"*yarn install*\" OR\n      process.parent.command_line LIKE \"*yarn add*\" OR\n      process.parent.command_line LIKE \"*pnpm install*\" OR\n      process.parent.command_line LIKE \"*pnpm add*\" OR\n      process.parent.command_line LIKE \"*npm-cli.js*install*\" OR\n      process.parent.command_line LIKE \"*setup.js*\"\n    ), true,\n\n    // pip  pip3 pipx poetry  uv (Python ecosystem)\n    ((process.parent.name like \"python*\" or process.parent.name like \"pip*\" or process.parent.name IN (\"uv\", \"uv.exe\") ) AND (\n      process.parent.command_line LIKE \"*pip install*\" OR\n      process.parent.command_line LIKE \"*pip3 install*\" OR\n      process.parent.command_line LIKE \"*-m pip install*\" OR\n      process.parent.command_line LIKE \"*setup.py install*\" OR\n      process.parent.command_line LIKE \"*setup.py develop*\" OR\n      process.parent.command_line LIKE \"*pipx install*\" OR\n      process.parent.command_line LIKE \"*poetry install*\" OR\n      process.parent.command_line LIKE \"*poetry add*\" OR\n      process.parent.command_line LIKE \"*uv pip install*\" OR\n      process.parent.command_line LIKE \"*uv add*\")), true,\n\n    // cargo (Rust / crates.io ecosystem)\n    process.parent.name IN (\"cargo\", \"cargo.exe\", \"rustc\", \"rustc.exe\") AND (\n      process.parent.command_line LIKE \"*cargo install*\" OR\n      process.parent.command_line LIKE \"*cargo build*\" OR\n      process.parent.command_line LIKE \"*cargo run*\" OR\n      process.parent.command_line LIKE \"*cargo fetch*\"), true,\n\n    false\n  )\n\n| WHERE process.Ext.ancestry IS NOT NULL AND (data_stream.dataset == \"endpoint.alerts\" OR is_pkg_install)\n\n// Capture entity_ids for package install parent processes\n| EVAL all_entity_id = CASE(is_pkg_install, process.parent.entity_id, \"null\")\n\n// Collect all package install entity_ids globally\n| INLINE STATS all_pkg_entity_ids = VALUES(all_entity_id) WHERE all_entity_id != \"null\"\n\n// Find which package install entity_ids appear in this process's ancestry\n| EVAL Esql.pkg_ancestor_ids = MV_INTERSECTION(all_pkg_entity_ids, process.Ext.ancestry)\n\n// Elastic Defend alerts descended from a package install process\n| WHERE Esql.pkg_ancestor_ids IS NOT NULL AND data_stream.dataset == \"endpoint.alerts\"\n\n| KEEP *"
      }
    ]
  },
  "automation": {
    "safe": [
      "Add recommendation as Sentinel incident comment.",
      "Run enrichment queries.",
      "Create ServiceNow SecOps task."
    ],
    "approval_required": [
      "Contain or disable the affected host/account.",
      "Any change to production configuration."
    ]
  },
  "escalation_criteria": [
    "Supply Chain Compromise activity observed on a privileged account or critical system.",
    "Activity follows or precedes other suspicious behaviour in the same investigation.",
    "Automated triage cannot confidently rule out malicious intent."
  ],
  "false_positive_considerations": [
    "Legitimate admin or business workflow — Activity maps to approved change tickets or known process owners",
    "Security testing or red-team exercise — Source identity/host matches approved test plan"
  ],
  "confluence": {
    "title": "T1195 - Supply Chain Compromise Response Guidance",
    "labels": [
      "mitre",
      "attack",
      "d3fend",
      "secops",
      "basyrix"
    ],
    "sections": [
      "summary",
      "d3fend_mappings",
      "investigation_steps",
      "response_actions",
      "queries",
      "automation",
      "escalation_criteria",
      "false_positive_considerations"
    ]
  }
}