{
  "hunt": {
    "meta": {
      "tlp": "clear",
      "hunt": {
        "handoff": "keep-as-periodic-hunt",
        "trigger": "intel-report",
        "methodology": "model-assisted",
        "applicability": "campaign-specific",
        "justification": "Internal movement via SMB and WinRM is a critical phase of framework-driven intrusions; a negative result over these protocols confirms the integrity of the internal network."
      },
      "name": "Metasploit Lateral Movement and Native Persistence",
      "type": "investigation",
      "labels": [
        "hunt",
        "attack.t1021.002",
        "attack.t1059.001"
      ],
      "series": {
        "slug": "metasploit-wrap-up-payloads-and-exploits-and-scanners-oh-my",
        "index": 2,
        "title": "Metasploit Wrap Up: Payloads and Exploits, and Scanners, Oh my!",
        "total": 2
      },
      "related": [
        {
          "hunt": "metasploit-external-exploit-hunting",
          "reason": "External scanning and application exploitation are handled by a sibling hunt focusing on the perimeter.",
          "relation": "out-of-scope-alternative"
        },
        {
          "hunt": "metasploit-2026-recon-web-exploitation",
          "relation": "follows"
        }
      ],
      "targets": {
        "hunter": {
          "name": "Hunt agent",
          "agent": true
        },
        "analyst": {
          "name": "Tier-2 analyst",
          "role": "analyst"
        },
        "endpoint": {
          "name": "Endpoint telemetry (hb_ surfaces)",
          "category": "endpoint",
          "telemetry": [
            "endpoint"
          ]
        },
        "identity": {
          "name": "Identity / sign-in telemetry",
          "category": "identity",
          "telemetry": [
            "identity"
          ]
        }
      },
      "analysis": "A standard detection rule alerts on the PsExec service. This hunt correlates successful authentication with stack-counted process trees across the fleet to reconstruct the entire movement chain.",
      "coverage": [
        {
          "stage": "remote-command-execution-and-payloads",
          "steps": [
            "winrm-authentication-lead",
            "native-process-persistence"
          ],
          "status": "covered"
        },
        {
          "stage": "lateral-movement-smb-winrm",
          "steps": [
            "smb-movement-check"
          ],
          "status": "covered"
        },
        {
          "stage": "persistence-via-process-creation",
          "steps": [
            "native-process-persistence"
          ],
          "status": "covered"
        },
        {
          "stage": "vulnerability-scanning-and-reconnaissance",
          "reason": "Belongs to another part of the 'Metasploit Wrap Up: Payloads and Exploits, and Scanners, Oh my!' series.",
          "status": "out_of_scope"
        },
        {
          "stage": "exploit-public-facing-web-applications",
          "reason": "Belongs to another part of the 'Metasploit Wrap Up: Payloads and Exploits, and Scanners, Oh my!' series.",
          "status": "out_of_scope"
        }
      ],
      "scenario": {
        "stages": [
          {
            "name": "Protocol and Application Fingerprinting",
            "slug": "vulnerability-scanning-and-reconnaissance",
            "tactic": "initial-access",
            "techniques": [
              "T1190"
            ],
            "observables": [
              "opc.tcp://",
              "/ccm/system/dialogs/file/usage/",
              "CVE-2026-0265",
              "CVE-2026-16232",
              "CVE-2026-6826"
            ]
          },
          {
            "name": "Exploitation of Web Vulnerabilities",
            "slug": "exploit-public-facing-web-applications",
            "tactic": "initial-access",
            "techniques": [
              "T1190"
            ],
            "observables": [
              "ulap.php",
              "file://localhost/etc/passwd",
              "X-Spip-Filtre",
              "CVE-2026-3576",
              "CVE-2026-59774",
              "CVE-2026-9082",
              "CVE-2026-66066"
            ]
          },
          {
            "name": "Authenticated Execution and Payloads",
            "slug": "remote-command-execution-and-payloads",
            "tactic": "execution",
            "techniques": [
              "T1059.001"
            ],
            "observables": [
              "PSRP-backed PowerShell session",
              "MIPS64 exec payload",
              "CVE-2026-19681",
              "CVE-2026-21820",
              "CVE-2026-56274"
            ]
          },
          {
            "name": "Lateral Movement via SMB and WinRM",
            "slug": "lateral-movement-smb-winrm",
            "tactic": "lateral-movement",
            "techniques": [
              "T1021.002"
            ],
            "observables": [
              "windows/smb/psexec aarch64",
              "winrm_login with SessionType PSRP"
            ]
          },
          {
            "name": "Persistence via CreateProcess",
            "slug": "persistence-via-process-creation",
            "tactic": "persistence",
            "techniques": [
              "T1059.001"
            ],
            "observables": [
              "Metasploit persistence modules using create_process instead of cmd_exec"
            ]
          }
        ],
        "summary": "This Metasploit update details a range of exploit and scanner modules targeting vulnerabilities in web platforms (Forgejo, WordPress, Drupal, SPIP), networking hardware (PAN-OS, Check Point), and SCADA protocols. The framework has been enhanced to support remote execution via PSRP-backed PowerShell sessions, cross-platform SMB movement on aarch64, and improved persistence through native process creation."
      },
      "severity": "high",
      "rationale": "The lead query focuses on servers where management protocols are typical. The gated logic ensures expensive process and share queries only run if a potential authenticated entry point is found.",
      "guardrails": {
        "claims": "no_unsupported",
        "evidence": "citation_required",
        "telemetry": "untrusted",
        "missing_data": "not_benign"
      },
      "hypothesis": "An intruder uses Metasploit to move laterally via WinRM and SMB and maintains persistence through direct process creation from user-writable paths to evade shell-based detection.",
      "parameters": {
        "scope_hosts": {
          "from": {
            "ref": "analyst-scoping",
            "kind": "manual",
            "observed": "2026-08-28"
          },
          "type": "list[host]",
          "default": [],
          "description": "Optional list of hosts to focus the fan-out queries; leave empty to hunt across the entire estate."
        },
        "admin_shares": {
          "from": {
            "ref": "rapid7-wrap-up",
            "kind": "article",
            "observed": "2026-08-28"
          },
          "type": "list[string]",
          "default": [
            "\\\\*\\ADMIN$",
            "\\\\*\\C$",
            "\\\\*\\IPC$"
          ],
          "description": "Standard administrative shares used by Metasploit psexec modules."
        },
        "lookback_days": {
          "from": {
            "ref": "hunt-standard",
            "kind": "manual",
            "observed": "2026-08-28"
          },
          "type": "number",
          "default": "14",
          "description": "Days of history to examine for authentication and telemetry."
        },
        "standard_parent_paths": {
          "from": {
            "ref": "baseline-standard",
            "kind": "manual",
            "observed": "2026-08-28"
          },
          "type": "list[path]",
          "default": [
            "C:\\Windows\\System32\\services.exe",
            "C:\\Windows\\explorer.exe",
            "C:\\Windows\\System32\\cmd.exe",
            "C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe"
          ],
          "description": "Expected parent process paths to filter out during persistence hunting."
        }
      },
      "provenance": {
        "authors": [
          {
            "org": "huntbase.io",
            "name": "Huntbase hunt generation"
          }
        ],
        "generated": {
          "by": "huntbase-hunt-generation",
          "from": "https://www.rapid7.com/blog/post/pt-metasploit-wrap-up-payloads-exploits-scanners",
          "gates": [
            "dry-run",
            "lint",
            "critic"
          ],
          "model": "hb_google/gemini-3-flash-preview"
        }
      },
      "references": [
        {
          "url": "https://www.rapid7.com/blog/post/pt-metasploit-wrap-up-payloads-exploits-scanners",
          "name": "Metasploit Wrap Up: Payloads and Exploits, and Scanners, Oh my!"
        }
      ],
      "blind_spots": [
        {
          "id": "no-remoting-telemetry",
          "risk": "The adversary can bypass the lead entirely if their beachhead is on infrastructure not reporting to the auth surface.",
          "stage": "remote-command-execution-and-payloads",
          "question": "whether the initial WinRM session occurred on an unmonitored host",
          "requires": "hb_auth_signin coverage for all internal endpoints"
        },
        {
          "id": "missing-process-context",
          "risk": "Without historical command lines, the triage agent may fail to distinguish between legitimate management tools and persistence.",
          "stage": "persistence-via-process-creation",
          "question": "the exact arguments passed to the persistent binary",
          "requires": "hb_process_activity with command line history"
        }
      ]
    },
    "name": "Metasploit Lateral Movement and Native Persistence",
    "description": "The adversary moves through the internal network using authenticated remoting and installs persistence by creating processes from user-controlled directories. This hunt identifying successful WinRM and PSRP logons as an initial lead. If the hunt finds anomalous remoting activity, it fans out to examine two surfaces: administrative share access for movement and rare parent-child process relationships where binaries in writable directories run from non-standard parents. Finally, an agent correlates the findings to identify compromised hosts and the analyst suggests containment actions."
  },
  "nodes": [
    {
      "id": "hypothesis",
      "type": "hypothesis",
      "label": "Hypothesis",
      "config": {
        "tags": [],
        "series": {
          "slug": "metasploit-wrap-up-payloads-and-exploits-and-scanners-oh-my",
          "index": 2,
          "title": "Metasploit Wrap Up: Payloads and Exploits, and Scanners, Oh my!",
          "total": 2
        },
        "coverage": [
          {
            "stage": "remote-command-execution-and-payloads",
            "steps": [
              "winrm-authentication-lead",
              "native-process-persistence"
            ],
            "status": "covered"
          },
          {
            "stage": "lateral-movement-smb-winrm",
            "steps": [
              "smb-movement-check"
            ],
            "status": "covered"
          },
          {
            "stage": "persistence-via-process-creation",
            "steps": [
              "native-process-persistence"
            ],
            "status": "covered"
          },
          {
            "stage": "vulnerability-scanning-and-reconnaissance",
            "reason": "Belongs to another part of the 'Metasploit Wrap Up: Payloads and Exploits, and Scanners, Oh my!' series.",
            "status": "out_of_scope"
          },
          {
            "stage": "exploit-public-facing-web-applications",
            "reason": "Belongs to another part of the 'Metasploit Wrap Up: Payloads and Exploits, and Scanners, Oh my!' series.",
            "status": "out_of_scope"
          }
        ],
        "rationale": "An intruder uses Metasploit to move laterally via WinRM and SMB and maintains persistence through direct process creation from user-writable paths to evade shell-based detection.",
        "blind_spots": [
          {
            "id": "no-remoting-telemetry",
            "risk": "The adversary can bypass the lead entirely if their beachhead is on infrastructure not reporting to the auth surface.",
            "stage": "remote-command-execution-and-payloads",
            "question": "whether the initial WinRM session occurred on an unmonitored host",
            "requires": "hb_auth_signin coverage for all internal endpoints"
          },
          {
            "id": "missing-process-context",
            "risk": "Without historical command lines, the triage agent may fail to distinguish between legitimate management tools and persistence.",
            "stage": "persistence-via-process-creation",
            "question": "the exact arguments passed to the persistent binary",
            "requires": "hb_process_activity with command line history"
          }
        ],
        "scoping_notes": "The lead query focuses on servers where management protocols are typical. The gated logic ensures expensive process and share queries only run if a potential authenticated entry point is found.",
        "beyond_detection": "A standard detection rule alerts on the PsExec service. This hunt correlates successful authentication with stack-counted process trees across the fleet to reconstruct the entire movement chain."
      }
    },
    {
      "id": "winrm-authentication-lead",
      "type": "query",
      "label": "WinRM and PSRP Authentication Lead",
      "config": {
        "dsl": "sqlite",
        "role": "scoping",
        "source": "identity",
        "content": "SELECT actor_user_name, src_endpoint_ip, dst_endpoint_name, auth_protocol, time FROM hb_auth_signin WHERE (LOWER(dst_endpoint_name) LIKE '%winrm%' OR LOWER(dst_endpoint_name) LIKE '%powershell%') AND status_id = 1 AND time >= datetime('now', '-{{lookback_days}} days')",
        "surface": "hb_auth_signin",
        "description": "Identify successful WinRM or PowerShell Remoting logons that may indicate a beachhead moving laterally.",
        "expected_signal": "Rows show users connecting to remoting services. Zero rows mean no recent remoting sessions were logged."
      },
      "parents": [
        {
          "id": "hypothesis"
        }
      ],
      "primitive_config": {
        "dsl": "sqlite",
        "role": "scoping",
        "label": "WinRM and PSRP Authentication Lead",
        "reads": [
          "actor_user_name",
          "auth_protocol",
          "dst_endpoint_name",
          "src_endpoint_ip",
          "status_id",
          "time"
        ],
        "source": "hb_auth_signin",
        "target": "identity",
        "content": "SELECT actor_user_name, src_endpoint_ip, dst_endpoint_name, auth_protocol, time FROM hb_auth_signin WHERE (LOWER(dst_endpoint_name) LIKE '%winrm%' OR LOWER(dst_endpoint_name) LIKE '%powershell%') AND status_id = 1 AND time >= datetime('now', '-{{lookback_days}} days')",
        "silence": "not_evidence_of_absence",
        "expected": "Rows show users connecting to remoting services. Zero rows mean no recent remoting sessions were logged.",
        "verified": "dry-run",
        "verified_at": "2026-09-28"
      }
    },
    {
      "id": "evaluate-lead-logons",
      "type": "analytic",
      "label": "Evaluate Lead Logons",
      "config": {
        "cite": "required",
        "tools": [
          "endpoint",
          "identity"
        ],
        "context": [
          "winrm-authentication-lead"
        ],
        "objective": "Determine if the WinRM/PSRP logons in winrm-authentication-lead warrant a detailed movement investigation by checking for anomalous source IPs or usernames.",
        "description": "Assess whether the remoting logons in the lead step appear suspicious or anomalous.",
        "max_iterations": 3,
        "expected_signal": "A recommendation to proceed or stop.",
        "success_criteria": "A clear decision on proceeding to fan-out queries."
      },
      "parents": [
        {
          "id": "winrm-authentication-lead"
        }
      ]
    },
    {
      "id": "gate-check",
      "type": "checkpoint",
      "label": "Gate Check",
      "config": {
        "fuzzy": true,
        "judge": "hunter",
        "question": "the evaluate-lead-logons agent identifies at least one logon as suspicious or requiring further investigation",
        "condition": "the evaluate-lead-logons agent identifies at least one logon as suspicious or requiring further investigation",
        "blind_spot": "no-remoting-telemetry",
        "confidence": "high",
        "description": "Route the hunt based on the agent's evaluation of the logon lead.",
        "checkpoint_type": "mandatory"
      },
      "parents": [
        {
          "id": "evaluate-lead-logons"
        }
      ]
    },
    {
      "id": "smb-movement-check",
      "type": "query",
      "label": "SMB Administrative Share Movement",
      "config": {
        "dsl": "sqlite",
        "role": "triage",
        "source": "endpoint",
        "content": "SELECT device_hostname, actor_user_name, share_name, src_endpoint_ip, time FROM hb_smb_activity WHERE instr(',' || '{{admin_shares}}' || ',', ',' || share_name || ',') > 0 AND ('{{scope_hosts}}' = '' OR instr(',' || '{{scope_hosts}}' || ',', ',' || device_hostname || ',') > 0) AND time >= datetime('now', '-{{lookback_days}} days')",
        "surface": "hb_smb_activity",
        "description": "Detect SMB lateral movement through administrative shares, focusing on the scoped hosts.",
        "expected_signal": "Access to hidden shares like ADMIN$ or C$. Presence of these rows on hosts that also had WinRM logons confirms movement."
      },
      "parents": [
        {
          "id": "gate-check",
          "branch": "on_supports"
        }
      ],
      "primitive_config": {
        "dsl": "sqlite",
        "role": "triage",
        "label": "SMB Administrative Share Movement",
        "reads": [
          "actor_user_name",
          "device_hostname",
          "share_name",
          "src_endpoint_ip",
          "time"
        ],
        "source": "hb_smb_activity",
        "target": "endpoint",
        "content": "SELECT device_hostname, actor_user_name, share_name, src_endpoint_ip, time FROM hb_smb_activity WHERE instr(',' || '{{admin_shares}}' || ',', ',' || share_name || ',') > 0 AND ('{{scope_hosts}}' = '' OR instr(',' || '{{scope_hosts}}' || ',', ',' || device_hostname || ',') > 0) AND time >= datetime('now', '-{{lookback_days}} days')",
        "silence": "not_evidence_of_absence",
        "expected": "Access to hidden shares like ADMIN$ or C$. Presence of these rows on hosts that also had WinRM logons confirms movement.",
        "verified": "dry-run",
        "verified_at": "2026-09-28"
      }
    },
    {
      "id": "native-process-persistence",
      "type": "query",
      "label": "Native Process Creation Persistence",
      "config": {
        "dsl": "sqlite",
        "role": "baseline",
        "source": "endpoint",
        "content": "SELECT device_hostname, process_name, parent_process_name, process_cmd_line, COUNT(DISTINCT device_hostname) AS host_count FROM hb_process_activity WHERE (LOWER(process_path) LIKE '%\\appdata\\%' OR LOWER(process_path) LIKE '%\\users\\public\\%' OR LOWER(process_path) LIKE '%/tmp/%') AND NOT instr(',' || '{{standard_parent_paths}}' || ',', ',' || LOWER(parent_process_name) || ',') > 0 AND ('{{scope_hosts}}' = '' OR instr(',' || '{{scope_hosts}}' || ',', ',' || device_hostname || ',') > 0) AND time >= datetime('now', '-{{lookback_days}} days') GROUP BY process_name, parent_process_name HAVING host_count <= 3",
        "surface": "hb_process_activity",
        "description": "Identify processes in writable directories with non-standard parent hierarchies using stack-counting.",
        "expected_signal": "Unique parent-child pairs where the binary lives in a profile path. Rare hits in a large fleet indicate potential persistence."
      },
      "parents": [
        {
          "id": "gate-check",
          "branch": "on_supports"
        }
      ],
      "primitive_config": {
        "dsl": "sqlite",
        "role": "baseline",
        "label": "Native Process Creation Persistence",
        "reads": [
          "device_hostname",
          "parent_process_name",
          "process_cmd_line",
          "process_name",
          "process_path",
          "time"
        ],
        "source": "hb_process_activity",
        "target": "endpoint",
        "content": "SELECT device_hostname, process_name, parent_process_name, process_cmd_line, COUNT(DISTINCT device_hostname) AS host_count FROM hb_process_activity WHERE (LOWER(process_path) LIKE '%\\appdata\\%' OR LOWER(process_path) LIKE '%\\users\\public\\%' OR LOWER(process_path) LIKE '%/tmp/%') AND NOT instr(',' || '{{standard_parent_paths}}' || ',', ',' || LOWER(parent_process_name) || ',') > 0 AND ('{{scope_hosts}}' = '' OR instr(',' || '{{scope_hosts}}' || ',', ',' || device_hostname || ',') > 0) AND time >= datetime('now', '-{{lookback_days}} days') GROUP BY process_name, parent_process_name HAVING host_count <= 3",
        "silence": "not_evidence_of_absence",
        "baseline": {
          "window": "{{lookback_days}}d",
          "compare": "first_seen"
        },
        "expected": "Unique parent-child pairs where the binary lives in a profile path. Rare hits in a large fleet indicate potential persistence.",
        "verified": "dry-run",
        "prevalence": {
          "by": "device_hostname",
          "key": [
            "process_name",
            "parent_process_name"
          ],
          "rare_below": 3
        },
        "verified_at": "2026-09-28"
      }
    },
    {
      "id": "movement-triage",
      "type": "analytic",
      "label": "Movement Triage",
      "config": {
        "cite": "required",
        "tools": [
          "endpoint",
          "identity"
        ],
        "context": [
          "evaluate-lead-logons",
          "smb-movement-check",
          "native-process-persistence"
        ],
        "objective": "Weigh the initial logon lead together with SMB share activity and rare process hierarchies to determine if a host is compromised by Metasploit movement or persistence.",
        "description": "Correlate the WinRM logons with the detailed telemetry to confirm an intrusion.",
        "max_iterations": 6,
        "expected_signal": "A detailed per-host verdict.",
        "success_criteria": "A verdict of malicious | suspicious | benign per host, citing relevant rows from the queries."
      },
      "parents": [
        {
          "id": "smb-movement-check",
          "kind": "merge"
        },
        {
          "id": "native-process-persistence",
          "kind": "merge"
        }
      ]
    },
    {
      "id": "route-on-verdict",
      "type": "checkpoint",
      "label": "Route on Verdict",
      "config": {
        "fuzzy": true,
        "judge": "hunter",
        "question": "the movement-triage verdict identifies at least one host as malicious or suspicious",
        "condition": "the movement-triage verdict identifies at least one host as malicious or suspicious",
        "blind_spot": "missing-process-context",
        "confidence": "high",
        "description": "Direct the hunt to containment or closure.",
        "checkpoint_type": "mandatory"
      },
      "parents": [
        {
          "id": "movement-triage"
        }
      ]
    },
    {
      "id": "isolate-host",
      "type": "action",
      "label": "Isolate Compromised Host",
      "config": {
        "target": "endpoint",
        "description": "Contain the movement by isolating the endpoint and revoking credentials.",
        "instructions": "Isolate the hosts identified as malicious and revoke the credentials used for the suspicious remoting sessions.",
        "action_approval": "required"
      },
      "parents": [
        {
          "id": "route-on-verdict",
          "branch": "on_supports"
        }
      ]
    },
    {
      "id": "analyst-review",
      "type": "task",
      "label": "Analyst Review",
      "config": {
        "assignee": "analyst",
        "description": "Perform manual validation and record findings for future tuning.",
        "instructions": "Review the cited telemetry; confirm if the persistence mechanisms match expected administrative behavior and provide tuning feedback for the standard_parent_paths parameter."
      },
      "parents": [
        {
          "id": "gate-check",
          "branch": "default"
        },
        {
          "id": "gate-check",
          "branch": "on_unavailable"
        },
        {
          "id": "route-on-verdict",
          "branch": "default"
        },
        {
          "id": "route-on-verdict",
          "branch": "on_unavailable"
        },
        {
          "id": "isolate-host"
        }
      ]
    },
    {
      "id": "close-out",
      "type": "task",
      "label": "Close Out",
      "config": {
        "assignee": "analyst",
        "description": "Document the final state and whether any gaps were identified.",
        "instructions": "Summarize the hosts examined and any evidence of absence for the lateral movement phase. Record any visibility gaps encountered."
      },
      "parents": [
        {
          "id": "gate-check",
          "branch": "on_refutes"
        },
        {
          "id": "route-on-verdict",
          "branch": "on_refutes"
        },
        {
          "id": "analyst-review"
        }
      ]
    }
  ]
}