{
  "hunt": {
    "meta": {
      "tlp": "clear",
      "hunt": {
        "handoff": "promote-to-detection",
        "trigger": "intel-report",
        "methodology": "model-assisted",
        "applicability": "campaign-specific",
        "justification": "The abuse of Microsoft Teams for social engineering bypasses many email-based controls; detecting the resulting Node.js implant and subsequent WinRM pivoting is critical to preventing enterprise-wide compromise."
      },
      "name": "Node.js Backdoor and Lateral Movement",
      "type": "investigation",
      "labels": [
        "hunt",
        "attack.t1059.001",
        "attack.t1071",
        "attack.t1041",
        "attack.t1555",
        "attack.t1218.011",
        "attack.t1090.003",
        "attack.t1566.003"
      ],
      "series": {
        "slug": "impersonating-it-support-how-threat-actors-turn-a-remote-session-into-enterprise-wide-access",
        "index": 2,
        "title": "Impersonating IT support: how threat actors turn a remote session into enterprise-wide access",
        "total": 2
      },
      "related": [
        {
          "hunt": "initial-access-teams-vishing",
          "reason": "That hunt covers the Teams ingress and social engineering; this hunt focuses on the post-access technical footprint.",
          "relation": "out-of-scope-alternative"
        },
        {
          "hunt": "it-support-impersonation-remote-access",
          "relation": "follows"
        }
      ],
      "targets": {
        "hunter": {
          "name": "Hunt agent",
          "agent": true
        },
        "analyst": {
          "name": "Tier-2 analyst",
          "role": "analyst"
        },
        "network": {
          "name": "Network telemetry",
          "category": "network",
          "telemetry": [
            "network"
          ]
        },
        "endpoint": {
          "name": "Endpoint telemetry (hb_ surfaces)",
          "category": "endpoint",
          "telemetry": [
            "endpoint"
          ]
        }
      },
      "analysis": "A single rule for the EdgeUpdate key is easily bypassed by changing a string. This hunt identifies the structural behavior of the attack: staging a runtime in a user path, rare persistence mechanisms, and follow-on lateral movement that crosses network and process boundaries.",
      "coverage": [
        {
          "stage": "nodejs-implant-persistence",
          "steps": [
            "scope-node-in-localappdata",
            "run-key-localappdata",
            "nonstandard-file-prevalence"
          ],
          "status": "covered"
        },
        {
          "stage": "c2-recon-and-tasking",
          "steps": [
            "recon-and-rundll32"
          ],
          "status": "covered"
        },
        {
          "stage": "lateral-movement-winrm",
          "steps": [
            "winrm-lateral-movement"
          ],
          "status": "covered"
        },
        {
          "stage": "execution-rundll32-dlls",
          "steps": [
            "recon-and-rundll32"
          ],
          "status": "covered"
        },
        {
          "stage": "initial-access-teams-vishing",
          "reason": "Belongs to another part of the 'Impersonating IT support: how threat actors turn a remote session into enterprise-wide access' series.",
          "status": "out_of_scope"
        },
        {
          "stage": "remote-session-msi-delivery",
          "reason": "Belongs to another part of the 'Impersonating IT support: how threat actors turn a remote session into enterprise-wide access' series.",
          "status": "out_of_scope"
        }
      ],
      "scenario": {
        "stages": [
          {
            "name": "IT Support Impersonation via Teams",
            "slug": "initial-access-teams-vishing",
            "tactic": "initial-access",
            "techniques": [
              "T1566.003"
            ],
            "observables": [
              "Microsoft Teams external tenant collaboration",
              "Accept/Block prompts in Teams",
              "Quick Assist connection code usage",
              "Lures: 'Microsoft Security Update', 'Spam Filter Update', 'Account Verification'",
              "Vishing (voice phishing) used to layer trust"
            ]
          },
          {
            "name": "Remote Session and MSI Delivery",
            "slug": "remote-session-msi-delivery",
            "tactic": "execution",
            "techniques": [
              "T1059.001"
            ],
            "observables": [
              "Quick Assist or remote support tool process tree",
              "PowerShell downloading MSI from cloud storage",
              "msiexec.exe /qn (silent installation)",
              "MSI filenames: 'devfix.msi', 'Hotfix.msi'"
            ]
          },
          {
            "name": "Node.js Implant Staging and Persistence",
            "slug": "nodejs-implant-persistence",
            "tactic": "persistence",
            "techniques": [
              "T1059.001"
            ],
            "observables": [
              "Portable Node.js runtime downloaded from official distribution",
              "Files staged in LocalAppData randomly named directories",
              "Nonstandard file extensions: .tmp, .ini, .dat, .bin, .cfg",
              "HKCU Run key 'EdgeUpdate'",
              "Startup folder shortcut 'EdgeUpdate.lnk'",
              "Renamed Node.js binaries with original metadata 'node.exe'"
            ]
          },
          {
            "name": "C2 Communication and Reconnaissance",
            "slug": "c2-recon-and-tasking",
            "tactic": "command-and-control",
            "techniques": [
              "T1071",
              "T1041",
              "T1555"
            ],
            "observables": [
              "Randomized HTTPS long-polling to C2 server",
              "Discovery of antivirus products and virtualization",
              "ADSI (Active Directory Service Interfaces) queries",
              "Screen captures encoded in Base64 and saved to temporary files",
              "Host hardware and locale enumeration"
            ]
          },
          {
            "name": "Lateral Movement via WinRM",
            "slug": "lateral-movement-winrm",
            "tactic": "lateral-movement",
            "techniques": [
              "T1059.001"
            ],
            "observables": [
              "WinRM connections over TCP port 5985",
              "Pivoting toward Domain Controllers and Certificate Authorities",
              "Native Windows Remote Management execution"
            ]
          },
          {
            "name": "Follow-on Payload Execution",
            "slug": "execution-rundll32-dlls",
            "tactic": "defense-evasion",
            "techniques": [
              "T1218.011"
            ],
            "observables": [
              "rundll32.exe loading threat actor-supplied DLLs",
              "Short-lived cmd.exe and PowerShell child processes of Node.js"
            ]
          }
        ],
        "summary": "A human-operated campaign impersonates IT support via Microsoft Teams to trick users into granting remote access through tools like Quick Assist. Once access is established, the attackers deploy a persistent Node.js-based implant to perform extensive reconnaissance and move laterally via WinRM toward high-value infrastructure like domain controllers."
      },
      "severity": "high",
      "rationale": "Focus on workstations without developer roles first, as Node.js in LocalAppData is highly anomalous there. Use the early triage hosts and users to populate the scoping parameters for follow-on queries.",
      "guardrails": {
        "claims": "no_unsupported",
        "evidence": "citation_required",
        "telemetry": "untrusted",
        "missing_data": "not_benign"
      },
      "hypothesis": "An intruder is using a portable Node.js runtime and an obfuscated implant staged in LocalAppData to move laterally via WinRM after initial social engineering via Microsoft Teams.",
      "parameters": {
        "scope_hosts": {
          "type": "list[host]",
          "default": [],
          "description": "Hostnames flagged in the early triage stage to narrow follow-on queries."
        },
        "scope_users": {
          "type": "list[string]",
          "default": [],
          "description": "Usernames flagged in the early triage stage to narrow follow-on queries."
        },
        "lookback_days": {
          "type": "number",
          "default": "14",
          "description": "Days of history to examine."
        },
        "nonstandard_extensions": {
          "type": "list[string]",
          "default": [
            ".tmp",
            ".ini",
            ".dat",
            ".bin",
            ".cfg"
          ],
          "description": "Extensions used for encrypted implants and loaders."
        }
      },
      "provenance": {
        "authors": [
          {
            "org": "huntbase.io",
            "name": "Huntbase hunt generation"
          }
        ],
        "generated": {
          "by": "huntbase-hunt-generation",
          "from": "https://www.microsoft.com/en-us/security/blog/2026/09/02/impersonating-it-support-threat-actors-turn-remote-session-into-enterprise-wide-access/",
          "gates": [
            "dry-run",
            "lint"
          ],
          "model": "hb_google/gemini-3-flash-preview"
        }
      },
      "references": [
        {
          "url": "https://www.microsoft.com/en-us/security/blog/2026/09/02/impersonating-it-support-threat-actors-turn-remote-session-into-enterprise-wide-access/",
          "name": "Microsoft Security Blog \u2014 Impersonating IT support: how threat actors turn a remote session into enterprise-wide access"
        }
      ],
      "blind_spots": [
        {
          "id": "no-network-telemetry",
          "risk": "Without outbound socket data, the hunt cannot track the movement from the beachhead to sensitive identity servers.",
          "stage": "lateral-movement-winrm",
          "question": "Did the actor pivot to other hosts via WinRM?",
          "requires": "hb_network_connection with destination port"
        },
        {
          "id": "ephemeral-js-implants",
          "risk": "Node.js implants often execute tasking in memory or temporary files that are immediately deleted, hiding the specific data stolen or tools used.",
          "stage": "nodejs-implant-persistence",
          "question": "What specific tasks did the C2 provide?",
          "requires": "hb_file_activity with content capture"
        }
      ]
    },
    "name": "Node.js Backdoor and Lateral Movement",
    "description": "This hunt targets the technical footprint of a human-operated intrusion campaign that deploys a Node.js-based implant. It identifies the staging of a portable Node.js runtime, non-standard file extensions for loaders, and per-user registry persistence. The hunt then pivots to investigate follow-on reconnaissance and lateral movement over WinRM (port 5985), focusing on activity originating from the compromised beachhead. By examining the process tree and network connections together, the hunt distinguishes legitimate administrative work from malicious interactive tasking."
  },
  "nodes": [
    {
      "id": "hypothesis",
      "type": "hypothesis",
      "label": "Hypothesis",
      "config": {
        "tags": [],
        "series": {
          "slug": "impersonating-it-support-how-threat-actors-turn-a-remote-session-into-enterprise-wide-access",
          "index": 2,
          "title": "Impersonating IT support: how threat actors turn a remote session into enterprise-wide access",
          "total": 2
        },
        "coverage": [
          {
            "stage": "nodejs-implant-persistence",
            "steps": [
              "scope-node-in-localappdata",
              "run-key-localappdata",
              "nonstandard-file-prevalence"
            ],
            "status": "covered"
          },
          {
            "stage": "c2-recon-and-tasking",
            "steps": [
              "recon-and-rundll32"
            ],
            "status": "covered"
          },
          {
            "stage": "lateral-movement-winrm",
            "steps": [
              "winrm-lateral-movement"
            ],
            "status": "covered"
          },
          {
            "stage": "execution-rundll32-dlls",
            "steps": [
              "recon-and-rundll32"
            ],
            "status": "covered"
          },
          {
            "stage": "initial-access-teams-vishing",
            "reason": "Belongs to another part of the 'Impersonating IT support: how threat actors turn a remote session into enterprise-wide access' series.",
            "status": "out_of_scope"
          },
          {
            "stage": "remote-session-msi-delivery",
            "reason": "Belongs to another part of the 'Impersonating IT support: how threat actors turn a remote session into enterprise-wide access' series.",
            "status": "out_of_scope"
          }
        ],
        "rationale": "An intruder is using a portable Node.js runtime and an obfuscated implant staged in LocalAppData to move laterally via WinRM after initial social engineering via Microsoft Teams.",
        "blind_spots": [
          {
            "id": "no-network-telemetry",
            "risk": "Without outbound socket data, the hunt cannot track the movement from the beachhead to sensitive identity servers.",
            "stage": "lateral-movement-winrm",
            "question": "Did the actor pivot to other hosts via WinRM?",
            "requires": "hb_network_connection with destination port"
          },
          {
            "id": "ephemeral-js-implants",
            "risk": "Node.js implants often execute tasking in memory or temporary files that are immediately deleted, hiding the specific data stolen or tools used.",
            "stage": "nodejs-implant-persistence",
            "question": "What specific tasks did the C2 provide?",
            "requires": "hb_file_activity with content capture"
          }
        ],
        "scoping_notes": "Focus on workstations without developer roles first, as Node.js in LocalAppData is highly anomalous there. Use the early triage hosts and users to populate the scoping parameters for follow-on queries.",
        "beyond_detection": "A single rule for the EdgeUpdate key is easily bypassed by changing a string. This hunt identifies the structural behavior of the attack: staging a runtime in a user path, rare persistence mechanisms, and follow-on lateral movement that crosses network and process boundaries."
      }
    },
    {
      "id": "scope-node-in-localappdata",
      "type": "query",
      "label": "Scope Node.js in LocalAppData",
      "config": {
        "dsl": "sqlite",
        "role": "scoping",
        "source": "endpoint",
        "content": "SELECT device_hostname, user_name, process_name, process_path, process_cmd_line, time FROM hb_process_activity WHERE (LOWER(process_path) LIKE '%\\\\appdata\\\\local\\\\%' OR LOWER(process_cmd_line) LIKE '%\\\\appdata\\\\local\\\\%') AND (LOWER(process_name) LIKE '%node%' OR LOWER(process_file_description) LIKE '%node.js%') AND time >= datetime('now', '-{{lookback_days}} days')",
        "surface": "hb_process_activity",
        "description": "Identify hosts running Node.js or renamed copies from a user-writable path, indicating the staging of a portable runtime.",
        "expected_signal": "Hosts where Node.js is running from a user profile directory. Silence suggests no portable Node.js runtime has been launched in this way."
      },
      "parents": [
        {
          "id": "hypothesis"
        }
      ],
      "primitive_config": {
        "dsl": "sqlite",
        "role": "scoping",
        "label": "Scope Node.js in LocalAppData",
        "reads": [
          "device_hostname",
          "user_name",
          "process_name",
          "process_path",
          "process_cmd_line",
          "time"
        ],
        "source": "hb_process_activity",
        "target": "endpoint",
        "content": "SELECT device_hostname, user_name, process_name, process_path, process_cmd_line, time FROM hb_process_activity WHERE (LOWER(process_path) LIKE '%\\\\appdata\\\\local\\\\%' OR LOWER(process_cmd_line) LIKE '%\\\\appdata\\\\local\\\\%') AND (LOWER(process_name) LIKE '%node%' OR LOWER(process_file_description) LIKE '%node.js%') AND time >= datetime('now', '-{{lookback_days}} days')",
        "silence": "not_evidence_of_absence",
        "expected": "Hosts where Node.js is running from a user profile directory. Silence suggests no portable Node.js runtime has been launched in this way.",
        "verified": "dry-run",
        "verified_at": "2026-09-24"
      }
    },
    {
      "id": "run-key-localappdata",
      "type": "query",
      "label": "Run key persistence in LocalAppData",
      "config": {
        "dsl": "sqlite",
        "role": "detection-candidate",
        "source": "endpoint",
        "content": "SELECT device_hostname, reg_target, reg_value_data, time FROM hb_registry_activity WHERE LOWER(reg_target) LIKE '%\\\\currentversion\\\\run%' AND LOWER(reg_value_data) LIKE '%\\\\appdata\\\\local\\\\%' AND time >= datetime('now', '-{{lookback_days}} days')",
        "surface": "hb_registry_activity",
        "description": "Identify any registry Run key pointing to executable code within LocalAppData, which is a common persistence method for this implant.",
        "expected_signal": "A Run key pointing to a binary or script in a user's LocalAppData. This is a durable signal of staging."
      },
      "parents": [
        {
          "id": "scope-node-in-localappdata"
        }
      ],
      "primitive_config": {
        "dsl": "sqlite",
        "role": "detection-candidate",
        "label": "Run key persistence in LocalAppData",
        "reads": [
          "device_hostname",
          "reg_target",
          "reg_value_data",
          "time"
        ],
        "source": "hb_registry_activity",
        "target": "endpoint",
        "content": "SELECT device_hostname, reg_target, reg_value_data, time FROM hb_registry_activity WHERE LOWER(reg_target) LIKE '%\\\\currentversion\\\\run%' AND LOWER(reg_value_data) LIKE '%\\\\appdata\\\\local\\\\%' AND time >= datetime('now', '-{{lookback_days}} days')",
        "silence": "not_evidence_of_absence",
        "expected": "A Run key pointing to a binary or script in a user's LocalAppData. This is a durable signal of staging.",
        "verified": "dry-run",
        "verified_at": "2026-09-24"
      }
    },
    {
      "id": "nonstandard-file-prevalence",
      "type": "query",
      "label": "Rare files with non-standard extensions",
      "config": {
        "dsl": "sqlite",
        "role": "baseline",
        "source": "endpoint",
        "content": "SELECT device_hostname, file_path, file_name, COUNT(DISTINCT device_hostname) AS hosts, MIN(time) AS first_seen FROM hb_file_activity WHERE LOWER(file_path) LIKE '%\\\\appdata\\\\local\\\\%' AND instr(',' || '{{nonstandard_extensions}}' || ',', ',' || substr(LOWER(file_name), instr(LOWER(file_name), '.')) || ',') > 0 AND time >= datetime('now', '-{{lookback_days}} days') GROUP BY file_path, file_name HAVING hosts <= 5",
        "surface": "hb_file_activity",
        "description": "Find rare files in user profiles matching the report's extension list to identify encrypted payloads using a suffix-based filter.",
        "expected_signal": "Files with extensions like .tmp or .cfg appearing in a LocalAppData folder that are rare across the fleet. Silence proves these specific extensions were not used."
      },
      "parents": [
        {
          "id": "scope-node-in-localappdata"
        }
      ],
      "primitive_config": {
        "dsl": "sqlite",
        "role": "baseline",
        "label": "Rare files with non-standard extensions",
        "reads": [
          "device_hostname",
          "file_path",
          "file_name",
          "time"
        ],
        "source": "hb_file_activity",
        "target": "endpoint",
        "content": "SELECT device_hostname, file_path, file_name, COUNT(DISTINCT device_hostname) AS hosts, MIN(time) AS first_seen FROM hb_file_activity WHERE LOWER(file_path) LIKE '%\\\\appdata\\\\local\\\\%' AND instr(',' || '{{nonstandard_extensions}}' || ',', ',' || substr(LOWER(file_name), instr(LOWER(file_name), '.')) || ',') > 0 AND time >= datetime('now', '-{{lookback_days}} days') GROUP BY file_path, file_name HAVING hosts <= 5",
        "silence": "evidence_of_absence",
        "baseline": {
          "window": "{{lookback_days}}d",
          "compare": "first_seen"
        },
        "expected": "Files with extensions like .tmp or .cfg appearing in a LocalAppData folder that are rare across the fleet. Silence proves these specific extensions were not used.",
        "verified": "dry-run",
        "prevalence": {
          "by": "device_hostname",
          "key": [
            "file_name"
          ],
          "rare_below": 5
        },
        "verified_at": "2026-09-24"
      }
    },
    {
      "id": "triage-early-footprint",
      "type": "analytic",
      "label": "Triage early implant staging",
      "config": {
        "cite": "required",
        "tools": [
          "endpoint",
          "network"
        ],
        "context": [
          "scope-node-in-localappdata",
          "run-key-localappdata",
          "nonstandard-file-prevalence"
        ],
        "objective": "Determine which hosts show evidence of a Node.js implant staging, citing the process location, Run key values, and clusters of rare staging files.",
        "description": "Consolidate process, registry, and file evidence to confirm which hosts and users are acting as beachheads.",
        "max_iterations": 4,
        "expected_signal": "A list of compromised hosts and users citing the overlap of Node.js execution and profile-based persistence.",
        "success_criteria": "A per-host verdict of malicious | suspicious | benign, naming the user and host."
      },
      "parents": [
        {
          "id": "run-key-localappdata",
          "kind": "merge"
        },
        {
          "id": "nonstandard-file-prevalence",
          "kind": "merge"
        }
      ]
    },
    {
      "id": "winrm-lateral-movement",
      "type": "query",
      "label": "WinRM lateral movement (Port 5985)",
      "config": {
        "dsl": "sqlite",
        "role": "triage",
        "source": "network",
        "content": "SELECT device_hostname, dst_endpoint_ip, dst_endpoint_port, time FROM hb_network_connection WHERE dst_endpoint_port = 5985 AND direction = 'outbound' AND ('{{scope_hosts}}' = '' OR instr(',' || '{{scope_hosts}}' || ',', ',' || device_hostname || ',') > 0) AND time >= datetime('now', '-{{lookback_days}} days')",
        "surface": "hb_network_connection",
        "description": "Identify outbound WinRM connections from the beachheads. Populate scope_hosts with results from triage-early-footprint to automate the pivot.",
        "expected_signal": "Outbound connections to 5985 originating from a suspected beachhead host. This indicates an attempt to move laterally."
      },
      "parents": [
        {
          "id": "triage-early-footprint"
        }
      ],
      "primitive_config": {
        "dsl": "sqlite",
        "role": "triage",
        "label": "WinRM lateral movement (Port 5985)",
        "reads": [
          "device_hostname",
          "dst_endpoint_ip",
          "dst_endpoint_port",
          "time"
        ],
        "source": "hb_network_connection",
        "target": "network",
        "content": "SELECT device_hostname, dst_endpoint_ip, dst_endpoint_port, time FROM hb_network_connection WHERE dst_endpoint_port = 5985 AND direction = 'outbound' AND ('{{scope_hosts}}' = '' OR instr(',' || '{{scope_hosts}}' || ',', ',' || device_hostname || ',') > 0) AND time >= datetime('now', '-{{lookback_days}} days')",
        "silence": "not_evidence_of_absence",
        "expected": "Outbound connections to 5985 originating from a suspected beachhead host. This indicates an attempt to move laterally.",
        "verified": "dry-run",
        "verified_at": "2026-09-24"
      }
    },
    {
      "id": "recon-and-rundll32",
      "type": "query",
      "label": "Discovery and rundll32 payloads",
      "config": {
        "dsl": "sqlite",
        "role": "enrichment",
        "source": "endpoint",
        "content": "SELECT device_hostname, user_name, process_name, process_cmd_line, time FROM hb_process_activity WHERE (LOWER(process_cmd_line) LIKE '%adsi%' OR LOWER(process_cmd_line) LIKE '%get-ad%' OR LOWER(process_name) LIKE '%rundll32.exe%') AND ('{{scope_hosts}}' = '' OR instr(',' || '{{scope_hosts}}' || ',', ',' || device_hostname || ',') > 0) AND ('{{scope_users}}' = '' OR instr(',' || '{{scope_users}}' || ',', ',' || user_name || ',') > 0) AND time >= datetime('now', '-{{lookback_days}} days')",
        "surface": "hb_process_activity",
        "description": "Detect Active Directory discovery and follow-on rundll32 execution, scoped to the specific users and hosts flagged in the early triage to minimize administrative noise.",
        "expected_signal": "Process command lines performing domain enumeration or rundll32 loading actor-supplied DLLs, scoped to the flagged beachhead."
      },
      "parents": [
        {
          "id": "triage-early-footprint"
        }
      ],
      "primitive_config": {
        "dsl": "sqlite",
        "role": "enrichment",
        "label": "Discovery and rundll32 payloads",
        "reads": [
          "device_hostname",
          "user_name",
          "process_name",
          "process_cmd_line",
          "time"
        ],
        "source": "hb_process_activity",
        "target": "endpoint",
        "content": "SELECT device_hostname, user_name, process_name, process_cmd_line, time FROM hb_process_activity WHERE (LOWER(process_cmd_line) LIKE '%adsi%' OR LOWER(process_cmd_line) LIKE '%get-ad%' OR LOWER(process_name) LIKE '%rundll32.exe%') AND ('{{scope_hosts}}' = '' OR instr(',' || '{{scope_hosts}}' || ',', ',' || device_hostname || ',') > 0) AND ('{{scope_users}}' = '' OR instr(',' || '{{scope_users}}' || ',', ',' || user_name || ',') > 0) AND time >= datetime('now', '-{{lookback_days}} days')",
        "silence": "not_evidence_of_absence",
        "expected": "Process command lines performing domain enumeration or rundll32 loading actor-supplied DLLs, scoped to the flagged beachhead.",
        "verified": "dry-run",
        "verified_at": "2026-09-24"
      }
    },
    {
      "id": "triage-intrusion-scope",
      "type": "analytic",
      "label": "Triage enterprise intrusion",
      "config": {
        "cite": "required",
        "tools": [
          "endpoint",
          "network"
        ],
        "context": [
          "triage-early-footprint",
          "winrm-lateral-movement",
          "recon-and-rundll32"
        ],
        "objective": "Weigh the evidence from both phases: does the host with the Node.js implant also show WinRM lateral movement or AD discovery? Determine the full scope of the intrusion.",
        "description": "Confirm the multi-stage breach by weighing the early staging evidence against the lateral movement results.",
        "max_iterations": 4,
        "expected_signal": "A comprehensive per-host verdict that links the implant to the subsequent network pivoting and reconnaissance.",
        "success_criteria": "A final verdict naming beachheads, lateral targets, and users involved."
      },
      "parents": [
        {
          "id": "winrm-lateral-movement",
          "kind": "merge"
        },
        {
          "id": "recon-and-rundll32",
          "kind": "merge"
        }
      ]
    },
    {
      "id": "route-response",
      "type": "checkpoint",
      "label": "Route based on breach scope",
      "config": {
        "fuzzy": true,
        "judge": "hunter",
        "question": "the triage-intrusion-scope verdict is malicious for at least one host, indicating confirmed lateral movement or AD discovery",
        "condition": "the triage-intrusion-scope verdict is malicious for at least one host, indicating confirmed lateral movement or AD discovery",
        "blind_spot": "no-network-telemetry",
        "confidence": "high",
        "description": "Direct response actions based on the confirmed scope of the lateral movement.",
        "checkpoint_type": "mandatory"
      },
      "parents": [
        {
          "id": "triage-intrusion-scope"
        }
      ]
    },
    {
      "id": "isolate-host",
      "type": "action",
      "label": "Isolate compromised host",
      "config": {
        "target": "endpoint",
        "description": "Sever the attacker's interactive session and stop further lateral movement.",
        "instructions": "Isolate the hosts identified as compromised beachheads. Revoke credentials for associated users and begin forensic collection of the LocalAppData artifacts.",
        "action_approval": "required"
      },
      "parents": [
        {
          "id": "route-response",
          "branch": "on_supports"
        }
      ]
    },
    {
      "id": "analyst-review",
      "type": "task",
      "label": "Analyze intrusion depth",
      "config": {
        "assignee": "analyst",
        "description": "Identify what the operator accessed after moving laterally.",
        "instructions": "Examine the targets of the WinRM connections for follow-on payloads. Review the Teams chat history of affected users to identify the attacker's ingress method and the external tenant involved."
      },
      "parents": [
        {
          "id": "route-response",
          "branch": "default"
        },
        {
          "id": "route-response",
          "branch": "on_unavailable"
        },
        {
          "id": "isolate-host"
        }
      ]
    },
    {
      "id": "close-out",
      "type": "task",
      "label": "Hunt close-out",
      "config": {
        "assignee": "analyst",
        "description": "Document findings and negative results.",
        "instructions": "Record that no evidence of the Node.js implant or associated WinRM pivoting was found. Archive the instances of legitimate Node.js usage observed in profile paths for future tuning."
      },
      "parents": [
        {
          "id": "route-response",
          "branch": "on_refutes"
        }
      ]
    }
  ]
}