{
  "hunt": {
    "meta": {
      "tlp": "clear",
      "hunt": {
        "handoff": "promote-to-detection",
        "trigger": "intel-report",
        "methodology": "model-assisted",
        "applicability": "campaign-specific",
        "justification": "The theft of central management configurations exposes the entire perimeter security architecture. Detecting the PEERSTITCH implant is required to prevent long-term credential interception across the managed estate."
      },
      "name": "Fortinet Management Plane Exploitation and PEERSTITCH Deployment",
      "type": "investigation",
      "labels": [
        "hunt",
        "attack.t1190",
        "attack.t1041",
        "attack.t1133",
        "attack.t1071",
        "defense evasion",
        "execution",
        "exfiltration",
        "initial access",
        "persistence"
      ],
      "related": [
        {
          "hunt": "fortios-configuration-integrity-monitor",
          "reason": "This hunt focuses on PEERSTITCH deployment; a separate hunt should monitor for unauthorized sniffer configuration changes.",
          "relation": "out-of-scope-alternative"
        }
      ],
      "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"
          ]
        },
        "identity": {
          "name": "Identity / sign-in telemetry",
          "category": "identity",
          "telemetry": [
            "identity"
          ]
        }
      },
      "analysis": "A single rule might find the rogue IPs, but this hunt connects the initial management-plane breach to a multi-stage persistence and deployment chain targeting specific ARM64 firewall daemons, requiring cross-surface correlation between vulnerability, network, and process activity.",
      "coverage": [
        {
          "stage": "initial-access-fortimanager-exploit",
          "steps": [
            "vulnerability-scoping",
            "rogue-fmg-access"
          ],
          "status": "covered"
        },
        {
          "stage": "exfiltration-configuration-archive",
          "steps": [
            "rare-config-archive-touches"
          ],
          "status": "covered"
        },
        {
          "stage": "persistence-unauthorized-vpn-access",
          "steps": [
            "unauthorized-vpn-logons"
          ],
          "status": "covered"
        },
        {
          "stage": "privilege-escalation-path-traversal",
          "steps": [
            "peerstitch-deployment"
          ],
          "status": "covered"
        },
        {
          "stage": "defense-evasion-memory-injection",
          "steps": [
            "peerstitch-deployment"
          ],
          "status": "covered"
        }
      ],
      "scenario": {
        "stages": [
          {
            "name": "FortiManager Exploitation and Rogue Registration",
            "slug": "initial-access-fortimanager-exploit",
            "tactic": "initial-access",
            "techniques": [
              "T1190"
            ],
            "observables": [
              "CVE-2024-47575",
              "TCP port 541 (FMG-Access)",
              "Rogue device serial: FMG-VMTM23017412",
              "Rogue device name: localhost",
              "Source IPs: 45.32.41.202, 198.199.122.22"
            ]
          },
          {
            "name": "Database and Configuration Exfiltration",
            "slug": "exfiltration-configuration-archive",
            "tactic": "exfiltration",
            "techniques": [
              "T1041"
            ],
            "observables": [
              "Archive file: .tm",
              "Database files: global.db, revinfo.db",
              "Configuration for over 500 managed FortiGate firewalls"
            ]
          },
          {
            "name": "Credential-based VPN Persistence",
            "slug": "persistence-unauthorized-vpn-access",
            "tactic": "persistence",
            "techniques": [
              "T1133"
            ],
            "observables": [
              "Source IPs: 23.240.77.233, 47.18.167.159",
              "SSL/VPN sessions to perimeter firewalls",
              "Usage of administrative credentials recovered from exfiltrated configs"
            ]
          },
          {
            "name": "FortiOS Path Traversal and PEERSTITCH Deployment",
            "slug": "privilege-escalation-path-traversal",
            "tactic": "execution",
            "techniques": [
              "T1190"
            ],
            "observables": [
              "CVE-2025-61624",
              "Object name: ../../../../setup",
              "auto-script engine exploitation",
              "Directory: /data2/template/",
              "Malware files: pM.js, index.js, index.wasm, ipssem.js, lldprx"
            ]
          },
          {
            "name": "PEERSTITCH Memory-Resident Injection",
            "slug": "defense-evasion-memory-injection",
            "tactic": "defense-evasion",
            "techniques": [
              "T1071"
            ],
            "observables": [
              "Process injection targets: /bin/miglogd, /bin/iked",
              "ptrace(PTRACE_SEIZE, pid) usage",
              "Writing to /proc/<pid>/mem",
              "Memory patches at static offsets: base + 0x106F7B8, base + 0x1072E20, base + 0x109A570",
              "20-byte trampoline at base + 0x135102C",
              "In-memory marker search for '8550' and '169.254.0.1'"
            ]
          }
        ],
        "summary": "Attackers exploited CVE-2024-47575 on FortiManager to register rogue appliances and exfiltrate configuration archives containing credentials for over 500 managed firewalls. They subsequently used these credentials to establish VPN sessions and exploit CVE-2025-61624 for privilege escalation, ultimately deploying PEERSTITCH, a memory-resident ARM64 implant that intercepts traffic and bypasses security validations via process injection."
      },
      "severity": "critical",
      "rationale": "Start with centralized FortiManager instances as identifying the breach here is the first link. Widen to perimeter firewalls using the hosts returned by the scoping step to identify subsequent implantation.",
      "guardrails": {
        "claims": "no_unsupported",
        "evidence": "citation_required",
        "telemetry": "untrusted",
        "missing_data": "not_benign"
      },
      "hypothesis": "An attacker has exploited a central management appliance to exfiltrate configurations and then used stolen credentials to deploy a memory-resident ARM64 implant on managed firewalls.",
      "parameters": {
        "scope_hosts": {
          "type": "list[host]",
          "default": [],
          "description": "Target hosts identified by the scoping step."
        },
        "lookback_days": {
          "type": "number",
          "default": "14",
          "description": "Days of history to examine."
        },
        "attacker_ips_vpn": {
          "from": {
            "ref": "unit42-peerstitch",
            "kind": "article",
            "observed": "2024-10-14"
          },
          "type": "list[ip]",
          "default": [
            "23.240.77.233",
            "47.18.167.159"
          ],
          "description": "IPs observed establishing unauthorized SSL/VPN sessions."
        },
        "vulnerability_ids": {
          "from": {
            "ref": "unit42-peerstitch",
            "kind": "article",
            "observed": "2024-10-14"
          },
          "type": "list[string]",
          "default": [
            "CVE-2024-47575",
            "CVE-2025-61624"
          ],
          "description": "CVEs for FortiManager auth bypass and FortiOS path traversal."
        },
        "attacker_ips_initial": {
          "from": {
            "ref": "unit42-peerstitch",
            "kind": "article",
            "observed": "2024-10-14"
          },
          "type": "list[ip]",
          "default": [
            "45.32.41.202",
            "198.199.122.22"
          ],
          "description": "IPs observed performing rogue FortiManager registration."
        }
      },
      "provenance": {
        "authors": [
          {
            "org": "huntbase.io",
            "name": "Huntbase hunt generation"
          }
        ],
        "generated": {
          "by": "huntbase-hunt-generation",
          "from": "https://unit42.paloaltonetworks.com/fortimanager-cve-2024-47575-peerstitch-malware/",
          "gates": [
            "dry-run",
            "lint"
          ],
          "model": "hb_google/gemini-3-flash-preview"
        }
      },
      "references": [
        {
          "url": "https://unit42.paloaltonetworks.com/fortimanager-cve-2024-47575-peerstitch-malware/",
          "name": "Unit 42 \u2014 Unit 42 Uncovers PEERSTITCH, a Stealthy FortiGate Implant"
        }
      ],
      "blind_spots": [
        {
          "id": "memory-hook-blind-spot",
          "risk": "The implant resides only in memory and uses existing processes for C2; if the initial injector process (lldprx) is not captured, the implant is invisible to standard process/file queries.",
          "stage": "defense-evasion-memory-injection",
          "question": "whether PEERSTITCH has successfully patched daemons in memory",
          "requires": "ptrace and memory allocation telemetry"
        },
        {
          "id": "fortios-auto-script-logging",
          "risk": "Management plane logs may record object creation but not the low-level path traversal that drops the malware payload if logging levels are default.",
          "stage": "privilege-escalation-path-traversal",
          "question": "whether the auto-script traversal succeeded in dropping files",
          "requires": "FortiOS auto-script execution logs"
        }
      ]
    },
    "name": "Fortinet Management Plane Exploitation and PEERSTITCH Deployment",
    "description": "This hunt targets the multi-stage exploitation of Fortinet infrastructure. It starts by identifying vulnerable appliances and rogue device registrations used for configuration exfiltration. It then pivots to find unauthorized VPN access from known actor infrastructure and the deployment of PEERSTITCH, a memory-resident injector that intercepts traffic by patching core daemons. The hunt correlates initial management-plane compromise with follow-on persistence on perimeter firewalls using a phased approach."
  },
  "nodes": [
    {
      "id": "hypothesis",
      "type": "hypothesis",
      "label": "Hypothesis",
      "config": {
        "tags": [],
        "coverage": [
          {
            "stage": "initial-access-fortimanager-exploit",
            "steps": [
              "vulnerability-scoping",
              "rogue-fmg-access"
            ],
            "status": "covered"
          },
          {
            "stage": "exfiltration-configuration-archive",
            "steps": [
              "rare-config-archive-touches"
            ],
            "status": "covered"
          },
          {
            "stage": "persistence-unauthorized-vpn-access",
            "steps": [
              "unauthorized-vpn-logons"
            ],
            "status": "covered"
          },
          {
            "stage": "privilege-escalation-path-traversal",
            "steps": [
              "peerstitch-deployment"
            ],
            "status": "covered"
          },
          {
            "stage": "defense-evasion-memory-injection",
            "steps": [
              "peerstitch-deployment"
            ],
            "status": "covered"
          }
        ],
        "rationale": "An attacker has exploited a central management appliance to exfiltrate configurations and then used stolen credentials to deploy a memory-resident ARM64 implant on managed firewalls.",
        "blind_spots": [
          {
            "id": "memory-hook-blind-spot",
            "risk": "The implant resides only in memory and uses existing processes for C2; if the initial injector process (lldprx) is not captured, the implant is invisible to standard process/file queries.",
            "stage": "defense-evasion-memory-injection",
            "question": "whether PEERSTITCH has successfully patched daemons in memory",
            "requires": "ptrace and memory allocation telemetry"
          },
          {
            "id": "fortios-auto-script-logging",
            "risk": "Management plane logs may record object creation but not the low-level path traversal that drops the malware payload if logging levels are default.",
            "stage": "privilege-escalation-path-traversal",
            "question": "whether the auto-script traversal succeeded in dropping files",
            "requires": "FortiOS auto-script execution logs"
          }
        ],
        "scoping_notes": "Start with centralized FortiManager instances as identifying the breach here is the first link. Widen to perimeter firewalls using the hosts returned by the scoping step to identify subsequent implantation.",
        "beyond_detection": "A single rule might find the rogue IPs, but this hunt connects the initial management-plane breach to a multi-stage persistence and deployment chain targeting specific ARM64 firewall daemons, requiring cross-surface correlation between vulnerability, network, and process activity."
      }
    },
    {
      "id": "vulnerability-scoping",
      "type": "query",
      "label": "Vulnerability identification",
      "config": {
        "dsl": "sqlite",
        "role": "scoping",
        "source": "endpoint",
        "content": "SELECT device_uid, resource_uid, cve_uid, severity_id, status FROM hb_vulnerability_finding WHERE instr(',' || '{{vulnerability_ids}}' || ',', ',' || cve_uid || ',') > 0",
        "surface": "hb_vulnerability_finding",
        "description": "Identify appliances currently reporting vulnerabilities used in the PEERSTITCH campaign.",
        "expected_signal": "A list of unique device IDs exposed to management plane or path traversal exploits. Silence indicates no reported findings."
      },
      "parents": [
        {
          "id": "hypothesis"
        }
      ],
      "primitive_config": {
        "dsl": "sqlite",
        "role": "scoping",
        "label": "Vulnerability identification",
        "reads": [
          "device_uid",
          "resource_uid",
          "cve_uid",
          "severity_id",
          "status"
        ],
        "source": "hb_vulnerability_finding",
        "target": "endpoint",
        "content": "SELECT device_uid, resource_uid, cve_uid, severity_id, status FROM hb_vulnerability_finding WHERE instr(',' || '{{vulnerability_ids}}' || ',', ',' || cve_uid || ',') > 0",
        "silence": "not_evidence_of_absence",
        "expected": "A list of unique device IDs exposed to management plane or path traversal exploits. Silence indicates no reported findings.",
        "verified": "dry-run",
        "verified_at": "2026-10-15"
      }
    },
    {
      "id": "rogue-fmg-access",
      "type": "query",
      "label": "Rogue FortiManager registration",
      "config": {
        "dsl": "sqlite",
        "role": "triage",
        "source": "network",
        "content": "SELECT device_hostname, src_endpoint_ip, dst_endpoint_port, direction, time FROM hb_network_connection WHERE dst_endpoint_port = 541 AND instr(',' || '{{attacker_ips_initial}}' || ',', ',' || src_endpoint_ip || ',') > 0 AND time >= datetime('now', '-{{lookback_days}} days')",
        "surface": "hb_network_connection",
        "description": "Detect inbound connections to the management channel from known attacker infrastructure.",
        "expected_signal": "Inbound connections from report IPs to port 541. This signifies a probable rogue registration attempt."
      },
      "parents": [
        {
          "id": "vulnerability-scoping"
        }
      ],
      "primitive_config": {
        "dsl": "sqlite",
        "role": "triage",
        "label": "Rogue FortiManager registration",
        "reads": [
          "device_hostname",
          "src_endpoint_ip",
          "dst_endpoint_port",
          "direction",
          "time"
        ],
        "source": "hb_network_connection",
        "target": "network",
        "content": "SELECT device_hostname, src_endpoint_ip, dst_endpoint_port, direction, time FROM hb_network_connection WHERE dst_endpoint_port = 541 AND instr(',' || '{{attacker_ips_initial}}' || ',', ',' || src_endpoint_ip || ',') > 0 AND time >= datetime('now', '-{{lookback_days}} days')",
        "silence": "not_evidence_of_absence",
        "expected": "Inbound connections from report IPs to port 541. This signifies a probable rogue registration attempt.",
        "verified": "dry-run",
        "verified_at": "2026-10-15"
      }
    },
    {
      "id": "rare-config-archive-touches",
      "type": "query",
      "label": "Rare configuration archive touches",
      "config": {
        "dsl": "sqlite",
        "role": "baseline",
        "source": "endpoint",
        "content": "SELECT file_name, activity_name, COUNT(DISTINCT device_hostname) AS hosts, MIN(time) AS first_seen FROM hb_file_activity WHERE (LOWER(file_name) IN ('.tm', 'global.db', 'revinfo.db')) AND time >= datetime('now', '-{{lookback_days}} days') GROUP BY file_name, activity_name HAVING hosts < 3",
        "surface": "hb_file_activity",
        "description": "Stack-count touches to database or archive files used by FortiManager to identify rare exfiltration events.",
        "expected_signal": "File touches on archive names restricted to very few hosts. Fleet-wide noise would imply standard backups."
      },
      "parents": [
        {
          "id": "vulnerability-scoping"
        }
      ],
      "primitive_config": {
        "dsl": "sqlite",
        "role": "baseline",
        "label": "Rare configuration archive touches",
        "reads": [
          "file_name",
          "activity_name",
          "device_hostname",
          "time"
        ],
        "source": "hb_file_activity",
        "target": "endpoint",
        "content": "SELECT file_name, activity_name, COUNT(DISTINCT device_hostname) AS hosts, MIN(time) AS first_seen FROM hb_file_activity WHERE (LOWER(file_name) IN ('.tm', 'global.db', 'revinfo.db')) AND time >= datetime('now', '-{{lookback_days}} days') GROUP BY file_name, activity_name HAVING hosts < 3",
        "silence": "not_evidence_of_absence",
        "baseline": {
          "window": "{{lookback_days}}d",
          "compare": "first_seen"
        },
        "expected": "File touches on archive names restricted to very few hosts. Fleet-wide noise would imply standard backups.",
        "verified": "dry-run",
        "prevalence": {
          "by": "device_hostname",
          "key": [
            "file_name"
          ],
          "rare_below": 3
        },
        "verified_at": "2026-10-15"
      }
    },
    {
      "id": "early-stage-read",
      "type": "analytic",
      "label": "Management plane compromise triage",
      "config": {
        "cite": "required",
        "tools": [
          "endpoint",
          "identity",
          "network"
        ],
        "context": [
          "vulnerability-scoping",
          "rogue-fmg-access",
          "rare-config-archive-touches"
        ],
        "objective": "Determine if any management hosts show signs of exploitation (CVE-2024-47575) and subsequent configuration theft.",
        "description": "Assess whether the appliance vulnerability, rogue network access, and rare file touches indicate a management-plane breach.",
        "max_iterations": 4,
        "expected_signal": "A verdict on whether the FortiManager appliance was compromised.",
        "success_criteria": "A per-host verdict of compromised | suspicious | clean, citing rows from network and file surfaces."
      },
      "parents": [
        {
          "id": "rogue-fmg-access",
          "kind": "merge"
        },
        {
          "id": "rare-config-archive-touches",
          "kind": "merge"
        }
      ]
    },
    {
      "id": "unauthorized-vpn-logons",
      "type": "query",
      "label": "Unauthorized VPN sign-ins",
      "config": {
        "dsl": "sqlite",
        "role": "enrichment",
        "source": "identity",
        "content": "SELECT device_hostname, src_endpoint_ip, actor_user_name, status, time FROM hb_auth_signin WHERE instr(',' || '{{attacker_ips_vpn}}' || ',', ',' || src_endpoint_ip || ',') > 0 AND ('{{scope_hosts}}' = '' OR instr(',' || '{{scope_hosts}}' || ',', ',' || device_hostname || ',') > 0) AND time >= datetime('now', '-{{lookback_days}} days')",
        "surface": "hb_auth_signin",
        "description": "Find sign-in events from the report's VPN IPs, filtered by the hosts identified in the scoping phase.",
        "expected_signal": "Authentication events from report-specified IPs to scoped firewalls. This confirms the attacker is using stolen credentials."
      },
      "parents": [
        {
          "id": "early-stage-read"
        }
      ],
      "primitive_config": {
        "dsl": "sqlite",
        "role": "enrichment",
        "label": "Unauthorized VPN sign-ins",
        "reads": [
          "device_hostname",
          "src_endpoint_ip",
          "actor_user_name",
          "status",
          "time"
        ],
        "source": "hb_auth_signin",
        "target": "identity",
        "content": "SELECT device_hostname, src_endpoint_ip, actor_user_name, status, time FROM hb_auth_signin WHERE instr(',' || '{{attacker_ips_vpn}}' || ',', ',' || src_endpoint_ip || ',') > 0 AND ('{{scope_hosts}}' = '' OR instr(',' || '{{scope_hosts}}' || ',', ',' || device_hostname || ',') > 0) AND time >= datetime('now', '-{{lookback_days}} days')",
        "silence": "not_evidence_of_absence",
        "expected": "Authentication events from report-specified IPs to scoped firewalls. This confirms the attacker is using stolen credentials.",
        "verified": "dry-run",
        "verified_at": "2026-10-15"
      }
    },
    {
      "id": "peerstitch-deployment",
      "type": "query",
      "label": "PEERSTITCH deployment artifacts",
      "config": {
        "dsl": "sqlite",
        "role": "detection-candidate",
        "source": "endpoint",
        "content": "SELECT device_hostname, process_name, process_cmd_line, time FROM hb_process_activity WHERE (LOWER(process_name) LIKE '%lldprx' OR (LOWER(process_cmd_line) LIKE '%setup%' AND LOWER(process_cmd_line) LIKE '%../../../../%')) AND time >= datetime('now', '-{{lookback_days}} days')",
        "surface": "hb_process_activity",
        "description": "Identify the PEERSTITCH native injector or path-traversal activity on firewall command lines.",
        "expected_signal": "Processes running the lldprx binary or command lines executing the setup script via traversal. Any such row is a high-fidelity indicator of implantation."
      },
      "parents": [
        {
          "id": "early-stage-read"
        }
      ],
      "primitive_config": {
        "dsl": "sqlite",
        "role": "detection-candidate",
        "label": "PEERSTITCH deployment artifacts",
        "reads": [
          "device_hostname",
          "process_name",
          "process_cmd_line",
          "time"
        ],
        "source": "hb_process_activity",
        "target": "endpoint",
        "content": "SELECT device_hostname, process_name, process_cmd_line, time FROM hb_process_activity WHERE (LOWER(process_name) LIKE '%lldprx' OR (LOWER(process_cmd_line) LIKE '%setup%' AND LOWER(process_cmd_line) LIKE '%../../../../%')) AND time >= datetime('now', '-{{lookback_days}} days')",
        "silence": "not_evidence_of_absence",
        "expected": "Processes running the lldprx binary or command lines executing the setup script via traversal. Any such row is a high-fidelity indicator of implantation.",
        "verified": "dry-run",
        "verified_at": "2026-10-15"
      }
    },
    {
      "id": "full-chain-read",
      "type": "analytic",
      "label": "Full chain intrusion triage",
      "config": {
        "cite": "required",
        "tools": [
          "endpoint",
          "identity",
          "network"
        ],
        "context": [
          "early-stage-read",
          "unauthorized-vpn-logons",
          "peerstitch-deployment"
        ],
        "objective": "Synthesize the results from early-stage management triage with follow-on VPN and deployment evidence to confirm if firewalls have been compromised and implanted.",
        "description": "Synthesize management plane evidence with follow-on persistence and deployment evidence to confirm the intrusion.",
        "max_iterations": 5,
        "expected_signal": "A comprehensive incident report across the intrusion path.",
        "success_criteria": "A forensic summary confirming credential theft, unauthorized access, and malware deployment per host."
      },
      "parents": [
        {
          "id": "unauthorized-vpn-logons",
          "kind": "merge"
        },
        {
          "id": "peerstitch-deployment",
          "kind": "merge"
        }
      ]
    },
    {
      "id": "route-on-verdict",
      "type": "checkpoint",
      "label": "Route on verdict",
      "config": {
        "fuzzy": true,
        "judge": "hunter",
        "question": "the forensic triage confirms a chain from management exfiltration to firewall implantation",
        "condition": "the forensic triage confirms a chain from management exfiltration to firewall implantation",
        "blind_spot": "memory-hook-blind-spot",
        "confidence": "high",
        "description": "Route the hunt based on the forensic triage of the PEERSTITCH intrusion chain.",
        "checkpoint_type": "mandatory"
      },
      "parents": [
        {
          "id": "full-chain-read"
        }
      ]
    },
    {
      "id": "contain-and-revoke",
      "type": "action",
      "label": "Isolate firewalls and rotate credentials",
      "config": {
        "target": "endpoint",
        "description": "Sever attacker persistence and prevent further use of stolen configurations.",
        "instructions": "Isolate the FortiManager and affected FortiGate appliances. Revoke all credentials contained in the exfiltrated archives (administrative, local, and SSL/VPN passwords).",
        "action_approval": "required"
      },
      "parents": [
        {
          "id": "route-on-verdict",
          "branch": "on_supports"
        }
      ]
    },
    {
      "id": "analyst-review",
      "type": "task",
      "label": "Verify implant presence",
      "config": {
        "assignee": "analyst",
        "description": "Verify the agent's synthesis and examine the extent of the traffic interception.",
        "instructions": "Review the full chain triage. Confirm the presence of the lldprx injector. Document which firewalls were touched by the attacker's VPN infrastructure. Document if ptrace or /proc/pid/mem activity was observed."
      },
      "parents": [
        {
          "id": "route-on-verdict",
          "branch": "default"
        },
        {
          "id": "route-on-verdict",
          "branch": "on_unavailable"
        },
        {
          "id": "contain-and-revoke"
        }
      ]
    },
    {
      "id": "close-out",
      "type": "task",
      "label": "Hunt closure",
      "config": {
        "assignee": "analyst",
        "description": "Finalize findings and coverage notes.",
        "instructions": "Note the blind spots related to in-memory passive traffic monitoring. Record whether any hosts in scope were missing vulnerability telemetry."
      },
      "parents": [
        {
          "id": "route-on-verdict",
          "branch": "on_refutes"
        },
        {
          "id": "analyst-review"
        }
      ]
    }
  ]
}