{
  "hunt": {
    "meta": {
      "tlp": "clear",
      "hunt": {
        "handoff": "keep-as-periodic-hunt",
        "trigger": "intel-report",
        "methodology": "model-assisted",
        "applicability": "campaign-specific",
        "justification": "Recent attacks on Danfoss controllers have led to significant financial losses due to food spoilage and safety risks. Confirming the absence of exploit synchronization activity is critical for refrigeration integrity."
      },
      "name": "Exposed Danfoss Controller Reconnaissance and Exploitation",
      "type": "investigation",
      "labels": [
        "hunt",
        "attack.t1190",
        "attack.t1041",
        "credential access",
        "impact",
        "initial access"
      ],
      "series": {
        "slug": "the-cold-chain-on-fire-unpatched-danfoss-controllers-exploited",
        "index": 1,
        "title": "The Cold Chain on Fire : Unpatched Danfoss controllers exploited",
        "total": 2
      },
      "related": [
        {
          "hunt": "ics-default-credential-spraying",
          "reason": "This hunt focuses on the xml.cgi vulnerability chain; general password spraying against default credentials is covered by a separate sibling hunt.",
          "relation": "out-of-scope-alternative"
        }
      ],
      "targets": {
        "web": {
          "name": "Web server / proxy logs",
          "category": "siem",
          "telemetry": [
            "network"
          ]
        },
        "hunter": {
          "name": "Hunt agent",
          "agent": true
        },
        "analyst": {
          "name": "Tier-2 analyst",
          "role": "analyst"
        },
        "endpoint": {
          "name": "Endpoint telemetry (hb_ surfaces)",
          "category": "endpoint",
          "telemetry": [
            "endpoint"
          ]
        }
      },
      "analysis": "A standing detection rule might flag known IPs, but this hunt baselines external IP behavior to Danfoss endpoints and pivots to inventory and public exposure data to identify targeted synchronization attempts that might rotate IPs.",
      "coverage": [
        {
          "stage": "recon-and-info-theft",
          "steps": [
            "http-recon-sync-activity",
            "external-ip-prevalence",
            "exposed-asset-check"
          ],
          "status": "covered"
        },
        {
          "stage": "exploit-synchronization",
          "steps": [
            "http-recon-sync-activity"
          ],
          "status": "covered"
        },
        {
          "stage": "brute-force-spraying",
          "reason": "Belongs to another part of the 'The Cold Chain on Fire : Unpatched Danfoss controllers exploited' series.",
          "status": "out_of_scope"
        },
        {
          "stage": "unauthenticated-account-takeover",
          "reason": "Belongs to another part of the 'The Cold Chain on Fire : Unpatched Danfoss controllers exploited' series.",
          "status": "out_of_scope"
        },
        {
          "stage": "parameter-sabotage",
          "reason": "Belongs to another part of the 'The Cold Chain on Fire : Unpatched Danfoss controllers exploited' series.",
          "status": "out_of_scope"
        }
      ],
      "scenario": {
        "stages": [
          {
            "name": "Controller Enumeration and Information Theft",
            "slug": "recon-and-info-theft",
            "tactic": "initial-access",
            "techniques": [
              "T1190",
              "T1041"
            ],
            "observables": [
              "xml.cgi",
              "read_units action",
              "retrieval of store identity and location from controller configuration"
            ]
          },
          {
            "name": "Bypass Synchronization via Time Check",
            "slug": "exploit-synchronization",
            "tactic": "initial-access",
            "techniques": [
              "T1190"
            ],
            "observables": [
              "read_date_time action",
              "xml.cgi",
              "CVE-2025-41450"
            ]
          },
          {
            "name": "Credential Spraying of Default Accounts",
            "slug": "brute-force-spraying",
            "tactic": "credential-access",
            "techniques": [
              "T1555"
            ],
            "observables": [
              "Supervisor account",
              "admin account",
              "password \"12345\"",
              "xml.cgi"
            ]
          },
          {
            "name": "Unauthorized User Account Takeover",
            "slug": "unauthenticated-account-takeover",
            "tactic": "credential-access",
            "techniques": [
              "T1555"
            ],
            "observables": [
              "unauthenticated renaming of user ID 1",
              "unauthenticated password reset requests",
              "IP 178.83.226.215",
              "IP 37.16.75.128"
            ]
          },
          {
            "name": "Malicious Modification of Control Parameters",
            "slug": "parameter-sabotage",
            "tactic": "impact",
            "techniques": [
              "T1190"
            ],
            "observables": [
              "temperature modification from 50 to 80C",
              "temperature reprogrammed to 110C",
              "modified defrost cycles",
              "modified alarm thresholds"
            ]
          }
        ],
        "summary": "Threat actors exploited unpatched, internet-exposed Danfoss refrigeration controllers to sabotage temperature and defrost settings, causing significant operational disruption and food spoilage across European supermarket chains. The campaign utilized unauthenticated vulnerabilities, such as CVE-2025-41450 and an account-renaming exploit, to bypass authentication and gain administrative control over the controllers."
      },
      "severity": "high",
      "rationale": "Initial focus is on all devices identified as Danfoss controllers in the software inventory. This includes systems likely residing on OT or building management subnets.",
      "guardrails": {
        "claims": "no_unsupported",
        "evidence": "citation_required",
        "telemetry": "untrusted",
        "missing_data": "not_benign"
      },
      "hypothesis": "An attacker is enumerating internet-exposed Danfoss controllers and synchronizing system time to bypass authentication via the CVE-2025-41450 vulnerability.",
      "parameters": {
        "scope_hosts": {
          "type": "list[host]",
          "default": [],
          "description": "Optional list of specific Danfoss hostnames to focus the search."
        },
        "attacker_ips": {
          "from": {
            "ref": "sekoia",
            "kind": "article",
            "observed": "2026-11-09"
          },
          "type": "list[ip]",
          "default": [
            "178.83.226.215",
            "37.16.75.128"
          ],
          "description": "Observed attacker IP addresses from recent campaigns."
        },
        "lookback_days": {
          "type": "number",
          "default": "14",
          "description": "Days of history to examine."
        },
        "target_endpoint": {
          "type": "string",
          "default": "/xml.cgi",
          "description": "The specific CGI endpoint targeted by the reconnaissance and exploit chain."
        }
      },
      "provenance": {
        "authors": [
          {
            "org": "huntbase.io",
            "name": "Huntbase hunt generation"
          }
        ],
        "generated": {
          "by": "huntbase-hunt-generation",
          "from": "https://www.sekoia.com/blog/the-cold-chain-on-fire-unpatched-danfoss-controllers-exploited",
          "gates": [
            "dry-run",
            "lint",
            "critic"
          ],
          "model": "hb_google/gemini-3-flash-preview"
        }
      },
      "references": [
        {
          "url": "https://www.sekoia.com/blog/the-cold-chain-on-fire-unpatched-danfoss-controllers-exploited",
          "name": "Sekoia \u2014 The Cold Chain on Fire: Unpatched Danfoss controllers exploited"
        }
      ],
      "blind_spots": [
        {
          "id": "limited-visibility-into-unmanaged-networks",
          "risk": "Unmanaged or shadow OT assets will not be scoped, leaving them vulnerable to undetected exploitation.",
          "question": "whether all Danfoss controllers in the estate are reporting inventory",
          "requires": "hb_software_inventory coverage for all OT segments"
        },
        {
          "id": "missing-http-post-bodies",
          "risk": "The hunt primarily analyzes URL paths and queries; if parameters like read_units are in the body, the activity will be missed.",
          "stage": "recon-and-info-theft",
          "question": "whether reconnaissance parameters were passed in the HTTP POST body",
          "requires": "hb_http_activity with request body capture"
        }
      ]
    },
    "name": "Exposed Danfoss Controller Reconnaissance and Exploitation",
    "description": "This hunt identifies Danfoss refrigeration controllers in the environment and monitors for unauthenticated HTTP requests targeting the xml.cgi endpoint. It specifically searches for 'read_units' actions used for reconnaissance and 'read_date_time' actions required to synchronize an exploit with the controller's internal clock for authentication bypass. An agent correlates these suspicious traffic patterns with known attacker infrastructure and external exposure data to identify targeted exploitation attempts."
  },
  "nodes": [
    {
      "id": "hypothesis",
      "type": "hypothesis",
      "label": "Hypothesis",
      "config": {
        "tags": [],
        "series": {
          "slug": "the-cold-chain-on-fire-unpatched-danfoss-controllers-exploited",
          "index": 1,
          "title": "The Cold Chain on Fire : Unpatched Danfoss controllers exploited",
          "total": 2
        },
        "coverage": [
          {
            "stage": "recon-and-info-theft",
            "steps": [
              "http-recon-sync-activity",
              "external-ip-prevalence",
              "exposed-asset-check"
            ],
            "status": "covered"
          },
          {
            "stage": "exploit-synchronization",
            "steps": [
              "http-recon-sync-activity"
            ],
            "status": "covered"
          },
          {
            "stage": "brute-force-spraying",
            "reason": "Belongs to another part of the 'The Cold Chain on Fire : Unpatched Danfoss controllers exploited' series.",
            "status": "out_of_scope"
          },
          {
            "stage": "unauthenticated-account-takeover",
            "reason": "Belongs to another part of the 'The Cold Chain on Fire : Unpatched Danfoss controllers exploited' series.",
            "status": "out_of_scope"
          },
          {
            "stage": "parameter-sabotage",
            "reason": "Belongs to another part of the 'The Cold Chain on Fire : Unpatched Danfoss controllers exploited' series.",
            "status": "out_of_scope"
          }
        ],
        "rationale": "An attacker is enumerating internet-exposed Danfoss controllers and synchronizing system time to bypass authentication via the CVE-2025-41450 vulnerability.",
        "blind_spots": [
          {
            "id": "limited-visibility-into-unmanaged-networks",
            "risk": "Unmanaged or shadow OT assets will not be scoped, leaving them vulnerable to undetected exploitation.",
            "question": "whether all Danfoss controllers in the estate are reporting inventory",
            "requires": "hb_software_inventory coverage for all OT segments"
          },
          {
            "id": "missing-http-post-bodies",
            "risk": "The hunt primarily analyzes URL paths and queries; if parameters like read_units are in the body, the activity will be missed.",
            "stage": "recon-and-info-theft",
            "question": "whether reconnaissance parameters were passed in the HTTP POST body",
            "requires": "hb_http_activity with request body capture"
          }
        ],
        "scoping_notes": "Initial focus is on all devices identified as Danfoss controllers in the software inventory. This includes systems likely residing on OT or building management subnets.",
        "beyond_detection": "A standing detection rule might flag known IPs, but this hunt baselines external IP behavior to Danfoss endpoints and pivots to inventory and public exposure data to identify targeted synchronization attempts that might rotate IPs."
      }
    },
    {
      "id": "scoping-danfoss-inventory",
      "type": "query",
      "label": "Identify Danfoss Controllers in Inventory",
      "config": {
        "dsl": "sqlite",
        "role": "scoping",
        "source": "endpoint",
        "content": "SELECT device_hostname, package_name, package_version, vendor_name FROM hb_software_inventory WHERE LOWER(package_name) LIKE '%danfoss%' OR LOWER(vendor_name) LIKE '%danfoss%'",
        "surface": "hb_software_inventory",
        "description": "Find every device reporting Danfoss software or firmware to narrow the hunt's focus.",
        "expected_signal": "A list of hosts likely representing Danfoss controller hardware. Silence indicates no Danfoss assets are managed or inventoried."
      },
      "parents": [
        {
          "id": "hypothesis"
        }
      ],
      "primitive_config": {
        "dsl": "sqlite",
        "role": "scoping",
        "label": "Identify Danfoss Controllers in Inventory",
        "reads": [
          "device_hostname",
          "package_name",
          "package_version",
          "vendor_name"
        ],
        "source": "hb_software_inventory",
        "target": "endpoint",
        "content": "SELECT device_hostname, package_name, package_version, vendor_name FROM hb_software_inventory WHERE LOWER(package_name) LIKE '%danfoss%' OR LOWER(vendor_name) LIKE '%danfoss%'",
        "silence": "not_evidence_of_absence",
        "expected": "A list of hosts likely representing Danfoss controller hardware. Silence indicates no Danfoss assets are managed or inventoried.",
        "verified": "dry-run",
        "verified_at": "2026-11-10"
      }
    },
    {
      "id": "http-recon-sync-activity",
      "type": "query",
      "label": "Detect Recon and Synchronization HTTP Requests",
      "config": {
        "dsl": "sqlite",
        "role": "detection-candidate",
        "source": "web",
        "content": "SELECT device_hostname, src_endpoint_ip, url_path, url_query, user_agent, status_code, time FROM hb_http_activity WHERE ('{{scope_hosts}}' = '' OR instr(',' || '{{scope_hosts}}' || ',', ',' || device_hostname || ',') > 0) AND (LOWER(url_path) = LOWER('{{target_endpoint}}') OR LOWER(url_full) LIKE '%' || LOWER('{{target_endpoint}}') || '%') AND (LOWER(url_query) LIKE '%read_units%' OR LOWER(url_query) LIKE '%read_date_time%' OR instr(',' || '{{attacker_ips}}' || ',', ',' || src_endpoint_ip || ',') > 0) AND time >= datetime('now', '-{{lookback_days}} days')",
        "surface": "hb_http_activity",
        "description": "Match specific actions used to enumerate units or read system time for exploit synchronization.",
        "expected_signal": "Requests from external IPs attempting to retrieve controller details or synchronization time. Hits from attacker IPs are high-confidence leads."
      },
      "parents": [
        {
          "id": "scoping-danfoss-inventory"
        }
      ],
      "primitive_config": {
        "dsl": "sqlite",
        "role": "detection-candidate",
        "label": "Detect Recon and Synchronization HTTP Requests",
        "reads": [
          "device_hostname",
          "src_endpoint_ip",
          "status_code",
          "time",
          "url_full",
          "url_path",
          "url_query",
          "user_agent"
        ],
        "source": "hb_http_activity",
        "target": "web",
        "content": "SELECT device_hostname, src_endpoint_ip, url_path, url_query, user_agent, status_code, time FROM hb_http_activity WHERE ('{{scope_hosts}}' = '' OR instr(',' || '{{scope_hosts}}' || ',', ',' || device_hostname || ',') > 0) AND (LOWER(url_path) = LOWER('{{target_endpoint}}') OR LOWER(url_full) LIKE '%' || LOWER('{{target_endpoint}}') || '%') AND (LOWER(url_query) LIKE '%read_units%' OR LOWER(url_query) LIKE '%read_date_time%' OR instr(',' || '{{attacker_ips}}' || ',', ',' || src_endpoint_ip || ',') > 0) AND time >= datetime('now', '-{{lookback_days}} days')",
        "silence": "not_evidence_of_absence",
        "expected": "Requests from external IPs attempting to retrieve controller details or synchronization time. Hits from attacker IPs are high-confidence leads.",
        "verified": "dry-run",
        "verified_at": "2026-11-10"
      }
    },
    {
      "id": "external-ip-prevalence",
      "type": "query",
      "label": "Baseline External IP Activity to Danfoss Endpoints",
      "config": {
        "dsl": "sqlite",
        "role": "baseline",
        "source": "web",
        "content": "SELECT src_endpoint_ip, COUNT(DISTINCT device_hostname) AS host_count, MIN(time) AS first_seen, MAX(time) AS last_seen FROM hb_http_activity WHERE (LOWER(url_path) = LOWER('{{target_endpoint}}') OR LOWER(url_full) LIKE '%' || LOWER('{{target_endpoint}}') || '%') AND time >= datetime('now', '-{{lookback_days}} days') GROUP BY src_endpoint_ip ORDER BY host_count ASC",
        "surface": "hb_http_activity",
        "description": "Stack-count external IPs hitting the targeted endpoint to distinguish broad scanners from targeted exploiters.",
        "expected_signal": "An IP hitting a large number of hosts suggests a wide scanner; an IP hitting only one or two controllers may indicate a targeted exploit attempt."
      },
      "parents": [
        {
          "id": "scoping-danfoss-inventory"
        }
      ],
      "primitive_config": {
        "dsl": "sqlite",
        "role": "baseline",
        "label": "Baseline External IP Activity to Danfoss Endpoints",
        "reads": [
          "device_hostname",
          "src_endpoint_ip",
          "time",
          "url_full",
          "url_path"
        ],
        "source": "hb_http_activity",
        "target": "web",
        "content": "SELECT src_endpoint_ip, COUNT(DISTINCT device_hostname) AS host_count, MIN(time) AS first_seen, MAX(time) AS last_seen FROM hb_http_activity WHERE (LOWER(url_path) = LOWER('{{target_endpoint}}') OR LOWER(url_full) LIKE '%' || LOWER('{{target_endpoint}}') || '%') AND time >= datetime('now', '-{{lookback_days}} days') GROUP BY src_endpoint_ip ORDER BY host_count ASC",
        "silence": "not_evidence_of_absence",
        "baseline": {
          "window": "{{lookback_days}}d",
          "compare": "first_seen"
        },
        "expected": "An IP hitting a large number of hosts suggests a wide scanner; an IP hitting only one or two controllers may indicate a targeted exploit attempt.",
        "verified": "dry-run",
        "prevalence": {
          "by": "device_hostname",
          "key": [
            "src_endpoint_ip"
          ],
          "rare_below": 2
        },
        "verified_at": "2026-11-10"
      }
    },
    {
      "id": "exposed-asset-check",
      "type": "query",
      "label": "Verify Asset Exposure via Public Scanning Data",
      "config": {
        "dsl": "sqlite",
        "role": "enrichment",
        "source": "endpoint",
        "content": "SELECT domain_or_ip, port, product, version, discovered_at FROM hb_exposed_assets WHERE LOWER(product) LIKE '%danfoss%' OR LOWER(source_product) LIKE '%danfoss%'",
        "surface": "hb_exposed_assets",
        "description": "Cross-reference internal Danfoss assets with known public exposures.",
        "expected_signal": "Matches confirm that specific controllers are publicly reachable and known to scanners like Shodan or Censys."
      },
      "parents": [
        {
          "id": "scoping-danfoss-inventory"
        }
      ],
      "primitive_config": {
        "dsl": "sqlite",
        "role": "enrichment",
        "label": "Verify Asset Exposure via Public Scanning Data",
        "reads": [
          "discovered_at",
          "domain_or_ip",
          "port",
          "product",
          "source_product",
          "version"
        ],
        "source": "hb_exposed_assets",
        "target": "endpoint",
        "content": "SELECT domain_or_ip, port, product, version, discovered_at FROM hb_exposed_assets WHERE LOWER(product) LIKE '%danfoss%' OR LOWER(source_product) LIKE '%danfoss%'",
        "silence": "not_evidence_of_absence",
        "expected": "Matches confirm that specific controllers are publicly reachable and known to scanners like Shodan or Censys.",
        "verified": "dry-run",
        "verified_at": "2026-11-10"
      }
    },
    {
      "id": "triage-agent",
      "type": "analytic",
      "label": "Triage Reconnaissance and Sync Evidence",
      "config": {
        "cite": "required",
        "tools": [
          "endpoint",
          "web"
        ],
        "context": [
          "scoping-danfoss-inventory",
          "http-recon-sync-activity",
          "external-ip-prevalence",
          "exposed-asset-check"
        ],
        "objective": "Evaluate the rows from inventory, HTTP activity, and exposure logs to determine if any host has been targeted for exploit synchronization or reconnaissance. Focus on external IPs hitting only few hosts with read_units or read_date_time actions.",
        "description": "Correlate inventory data, suspicious HTTP actions, IP prevalence, and exposure status to reach a verdict.",
        "max_iterations": 5,
        "expected_signal": "A per-host verdict.",
        "success_criteria": "A verdict of malicious (exploit sync detected), suspicious (recon detected), or benign per host."
      },
      "parents": [
        {
          "id": "http-recon-sync-activity",
          "kind": "merge"
        },
        {
          "id": "external-ip-prevalence",
          "kind": "merge"
        },
        {
          "id": "exposed-asset-check",
          "kind": "merge"
        }
      ]
    },
    {
      "id": "route-verdict",
      "type": "checkpoint",
      "label": "Route on Verdict",
      "config": {
        "fuzzy": true,
        "judge": "hunter",
        "question": "the triage verdict is malicious for at least one host",
        "condition": "the triage verdict is malicious for at least one host",
        "blind_spot": "limited-visibility-into-unmanaged-networks",
        "confidence": "high",
        "description": "Direct the hunt to containment or further analyst review.",
        "checkpoint_type": "mandatory"
      },
      "parents": [
        {
          "id": "triage-agent"
        }
      ]
    },
    {
      "id": "isolate-host",
      "type": "action",
      "label": "Isolate Affected Controller",
      "config": {
        "target": "endpoint",
        "description": "Immediately disconnect targeted controllers from the public internet.",
        "instructions": "Remove the affected Danfoss controller from any direct internet-facing exposure. Place it behind a VPN or firewall with strict access controls. Collect logs from the device for further analysis.",
        "action_approval": "required"
      },
      "parents": [
        {
          "id": "route-verdict",
          "branch": "on_supports"
        }
      ]
    },
    {
      "id": "analyst-review-task",
      "type": "task",
      "label": "Analyst Verification and Remediation",
      "config": {
        "assignee": "analyst",
        "description": "Confirm findings and ensure all Danfoss controllers are patched.",
        "instructions": "Review the cited HTTP activity for any confirmed exploit synchronization. Identify all controllers running firmware versions older than 4.2. Work with site administrators to apply Danfoss security updates and change default administrative passwords."
      },
      "parents": [
        {
          "id": "route-verdict",
          "branch": "default"
        },
        {
          "id": "route-verdict",
          "branch": "on_unavailable"
        },
        {
          "id": "route-verdict",
          "branch": "on_refutes"
        },
        {
          "id": "isolate-host"
        }
      ]
    },
    {
      "id": "close-out-task",
      "type": "task",
      "label": "Close Out and Record Findings",
      "config": {
        "assignee": "analyst",
        "description": "Finalize the hunt and record any gaps in visibility.",
        "instructions": "Document the number of controllers affected and the volume of suspicious reconnaissance traffic observed. Note any controllers that were discovered through the hunt but were missing from official inventory."
      },
      "parents": [
        {
          "id": "analyst-review-task"
        }
      ]
    }
  ]
}