{
  "hunt": {
    "meta": {
      "tlp": "clear",
      "hunt": {
        "handoff": "keep-as-periodic-hunt",
        "trigger": "intel-report",
        "methodology": "model-assisted",
        "applicability": "campaign-specific",
        "justification": "Direct financial impact from mass food spoilage and physical damage to assets makes the verification of these internet-exposed controllers a critical priority."
      },
      "name": "Unauthorized Controller Takeover and Sabotage",
      "type": "investigation",
      "labels": [
        "hunt",
        "attack.t1190",
        "attack.t1555",
        "attack.t1041",
        "credential access",
        "impact",
        "initial access"
      ],
      "series": {
        "slug": "the-cold-chain-on-fire-unpatched-danfoss-controllers-exploited",
        "index": 2,
        "title": "The Cold Chain on Fire : Unpatched Danfoss controllers exploited",
        "total": 2
      },
      "related": [
        {
          "hunt": "ot-external-exposure-audit",
          "reason": "This hunt detects active takeover; a separate audit is needed to identify all exposed OT assets regardless of activity.",
          "relation": "out-of-scope-alternative"
        },
        {
          "hunt": "exposed-danfoss-recon-exploitation",
          "relation": "follows"
        }
      ],
      "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 static detection rule for specific IPs fails when the adversary rotates infrastructure. This hunt uses interaction prevalence to find rare external actors targeting the administrative CGI interface and correlates it with known OT-specific exploit strings.",
      "coverage": [
        {
          "stage": "brute-force-spraying",
          "steps": [
            "cgi-exploit-indicators",
            "management-ip-prevalence"
          ],
          "status": "covered"
        },
        {
          "stage": "unauthenticated-account-takeover",
          "steps": [
            "cgi-exploit-indicators",
            "triage-activity"
          ],
          "status": "covered"
        },
        {
          "stage": "parameter-sabotage",
          "steps": [
            "cgi-exploit-indicators",
            "triage-activity"
          ],
          "status": "covered"
        },
        {
          "stage": "recon-and-info-theft",
          "reason": "Belongs to another part of the 'The Cold Chain on Fire : Unpatched Danfoss controllers exploited' series.",
          "status": "out_of_scope"
        },
        {
          "stage": "exploit-synchronization",
          "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": "critical",
      "rationale": "Focus on subnets hosting refrigeration and building automation systems. Use hb_exposed_assets to identify controllers that may not be under standard endpoint management.",
      "guardrails": {
        "claims": "no_unsupported",
        "evidence": "citation_required",
        "telemetry": "untrusted",
        "missing_data": "not_benign"
      },
      "hypothesis": "An attacker is hijacking administrative accounts on refrigeration controllers via unauthenticated CGI endpoints to sabotage operational parameters like temperature and defrost cycles.",
      "parameters": {
        "scope_hosts": {
          "from": {
            "ref": "analyst-scoping",
            "kind": "manual",
            "observed": "2026-11-09"
          },
          "type": "list[host]",
          "default": [],
          "description": "Hostnames or IP addresses of identified controllers; leave empty to hunt across the entire estate."
        },
        "lookback_days": {
          "from": {
            "ref": "standard-retention",
            "kind": "manual",
            "observed": "2026-11-09"
          },
          "type": "number",
          "default": "14",
          "description": "Days of historical activity to examine."
        },
        "malicious_ips": {
          "from": {
            "ref": "sekoia-danfoss-report",
            "kind": "article",
            "observed": "2026-11-09"
          },
          "type": "list[ip]",
          "default": [
            "178.83.226.215",
            "37.16.75.128"
          ],
          "description": "IP addresses identified in the second wave of attacks."
        }
      },
      "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"
          ],
          "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": "encrypted-traffic-blindness",
          "risk": "If controllers are accessed via HTTPS without proxy decryption, hb_http_activity will not contain the URL paths, hiding exploit attempts.",
          "owner": "Network Security",
          "stage": "brute-force-spraying",
          "question": "whether attackers are using HTTPS to communicate with the xml.cgi endpoint",
          "requires": "TLS inspection",
          "remediation": "Enable TLS inspection for known ICS management endpoints."
        },
        {
          "id": "post-body-parameters",
          "risk": "The hb_http_activity surface only captures URL components. Commands sent in the POST body are invisible to this hunt.",
          "owner": "SOC Engineering",
          "stage": "parameter-sabotage",
          "question": "what parameters were modified if sent via POST rather than GET query strings",
          "requires": "HTTP POST body logging",
          "remediation": "Configure sensor to capture headers and body for administrative CGI paths."
        }
      ]
    },
    "name": "Unauthorized Controller Takeover and Sabotage",
    "description": "This hunt identifies exposed Danfoss refrigeration controllers and searches for evidence of administrative takeover. It focuses on the exploitation of xml.cgi, where unauthenticated requests can rename administrative accounts and reset passwords. The hunt uses HTTP activity to detect both known attacker IP addresses and anomalous access patterns to management interfaces, followed by an agent-led triage to verify if parameter sabotage has occurred."
  },
  "nodes": [
    {
      "id": "hypothesis",
      "type": "hypothesis",
      "label": "Hypothesis",
      "config": {
        "tags": [],
        "series": {
          "slug": "the-cold-chain-on-fire-unpatched-danfoss-controllers-exploited",
          "index": 2,
          "title": "The Cold Chain on Fire : Unpatched Danfoss controllers exploited",
          "total": 2
        },
        "coverage": [
          {
            "stage": "brute-force-spraying",
            "steps": [
              "cgi-exploit-indicators",
              "management-ip-prevalence"
            ],
            "status": "covered"
          },
          {
            "stage": "unauthenticated-account-takeover",
            "steps": [
              "cgi-exploit-indicators",
              "triage-activity"
            ],
            "status": "covered"
          },
          {
            "stage": "parameter-sabotage",
            "steps": [
              "cgi-exploit-indicators",
              "triage-activity"
            ],
            "status": "covered"
          },
          {
            "stage": "recon-and-info-theft",
            "reason": "Belongs to another part of the 'The Cold Chain on Fire : Unpatched Danfoss controllers exploited' series.",
            "status": "out_of_scope"
          },
          {
            "stage": "exploit-synchronization",
            "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 hijacking administrative accounts on refrigeration controllers via unauthenticated CGI endpoints to sabotage operational parameters like temperature and defrost cycles.",
        "blind_spots": [
          {
            "id": "encrypted-traffic-blindness",
            "risk": "If controllers are accessed via HTTPS without proxy decryption, hb_http_activity will not contain the URL paths, hiding exploit attempts.",
            "owner": "Network Security",
            "stage": "brute-force-spraying",
            "question": "whether attackers are using HTTPS to communicate with the xml.cgi endpoint",
            "requires": "TLS inspection",
            "remediation": "Enable TLS inspection for known ICS management endpoints."
          },
          {
            "id": "post-body-parameters",
            "risk": "The hb_http_activity surface only captures URL components. Commands sent in the POST body are invisible to this hunt.",
            "owner": "SOC Engineering",
            "stage": "parameter-sabotage",
            "question": "what parameters were modified if sent via POST rather than GET query strings",
            "requires": "HTTP POST body logging",
            "remediation": "Configure sensor to capture headers and body for administrative CGI paths."
          }
        ],
        "scoping_notes": "Focus on subnets hosting refrigeration and building automation systems. Use hb_exposed_assets to identify controllers that may not be under standard endpoint management.",
        "beyond_detection": "A static detection rule for specific IPs fails when the adversary rotates infrastructure. This hunt uses interaction prevalence to find rare external actors targeting the administrative CGI interface and correlates it with known OT-specific exploit strings."
      }
    },
    {
      "id": "find-danfoss-inventory",
      "type": "query",
      "label": "Identify Danfoss Controllers",
      "config": {
        "dsl": "sqlite",
        "role": "scoping",
        "source": "endpoint",
        "content": "SELECT DISTINCT domain_or_ip AS device_hostname FROM hb_exposed_assets WHERE LOWER(product) LIKE '%danfoss%' OR LOWER(source_product) LIKE '%danfoss%'",
        "surface": "hb_exposed_assets",
        "description": "Locate internet-exposed assets identified as Danfoss controllers via external scan data.",
        "expected_signal": "A list of hostnames or IPs corresponding to refrigeration controllers. Silence means no Danfoss devices were found in the exposure inventory."
      },
      "parents": [
        {
          "id": "hypothesis"
        }
      ],
      "primitive_config": {
        "dsl": "sqlite",
        "role": "scoping",
        "label": "Identify Danfoss Controllers",
        "reads": [
          "domain_or_ip",
          "product",
          "source_product"
        ],
        "source": "hb_exposed_assets",
        "target": "endpoint",
        "content": "SELECT DISTINCT domain_or_ip AS device_hostname FROM hb_exposed_assets WHERE LOWER(product) LIKE '%danfoss%' OR LOWER(source_product) LIKE '%danfoss%'",
        "silence": "not_evidence_of_absence",
        "expected": "A list of hostnames or IPs corresponding to refrigeration controllers. Silence means no Danfoss devices were found in the exposure inventory.",
        "verified": "dry-run",
        "verified_at": "2026-11-10"
      }
    },
    {
      "id": "cgi-exploit-indicators",
      "type": "query",
      "label": "CGI Exploit and Sabotage Primitives",
      "config": {
        "dsl": "sqlite",
        "role": "detection-candidate",
        "source": "web",
        "content": "SELECT device_hostname, src_endpoint_ip, url_path, url_query, status_code, time FROM hb_http_activity WHERE (LOWER(url_path) LIKE '%xml.cgi%' OR LOWER(url_query) LIKE '%xml.cgi%') AND status_code IN (200, 204) AND (instr(',' || '{{malicious_ips}}' || ',', ',' || src_endpoint_ip || ',') > 0 OR LOWER(url_query) LIKE '%rename%' OR LOWER(url_query) LIKE '%read_units%' OR LOWER(url_query) LIKE '%read_date_time%' OR LOWER(url_query) LIKE '%set_temp%' OR LOWER(url_query) LIKE '%defrost%') AND ('{{scope_hosts}}' = '' OR instr(',' || '{{scope_hosts}}' || ',', ',' || device_hostname || ',') > 0) AND time >= datetime('now', '-{{lookback_days}} days')",
        "surface": "hb_http_activity",
        "description": "Find successful HTTP requests to the xml.cgi endpoint associated with hijacking and parameter modification.",
        "expected_signal": "Requests showing successful interactions using OT-specific exploit strings. Silence means no known exploit patterns resulted in success."
      },
      "parents": [
        {
          "id": "find-danfoss-inventory"
        }
      ],
      "primitive_config": {
        "dsl": "sqlite",
        "role": "detection-candidate",
        "label": "CGI Exploit and Sabotage Primitives",
        "reads": [
          "device_hostname",
          "src_endpoint_ip",
          "url_path",
          "url_query",
          "status_code",
          "time"
        ],
        "source": "hb_http_activity",
        "target": "web",
        "content": "SELECT device_hostname, src_endpoint_ip, url_path, url_query, status_code, time FROM hb_http_activity WHERE (LOWER(url_path) LIKE '%xml.cgi%' OR LOWER(url_query) LIKE '%xml.cgi%') AND status_code IN (200, 204) AND (instr(',' || '{{malicious_ips}}' || ',', ',' || src_endpoint_ip || ',') > 0 OR LOWER(url_query) LIKE '%rename%' OR LOWER(url_query) LIKE '%read_units%' OR LOWER(url_query) LIKE '%read_date_time%' OR LOWER(url_query) LIKE '%set_temp%' OR LOWER(url_query) LIKE '%defrost%') AND ('{{scope_hosts}}' = '' OR instr(',' || '{{scope_hosts}}' || ',', ',' || device_hostname || ',') > 0) AND time >= datetime('now', '-{{lookback_days}} days')",
        "silence": "not_evidence_of_absence",
        "expected": "Requests showing successful interactions using OT-specific exploit strings. Silence means no known exploit patterns resulted in success.",
        "verified": "dry-run",
        "verified_at": "2026-11-10"
      }
    },
    {
      "id": "management-ip-prevalence",
      "type": "query",
      "label": "Rare Administrative Source IPs",
      "config": {
        "dsl": "sqlite",
        "role": "baseline",
        "source": "web",
        "content": "SELECT src_endpoint_ip, COUNT(DISTINCT device_hostname) AS affected_hosts, COUNT(*) AS request_count, MIN(time) AS first_seen FROM hb_http_activity WHERE (LOWER(url_path) LIKE '%xml.cgi%' OR LOWER(url_query) LIKE '%xml.cgi%') AND NOT (src_endpoint_ip LIKE '10.%' OR src_endpoint_ip LIKE '192.168.%' OR src_endpoint_ip LIKE '172.16.%' OR src_endpoint_ip LIKE '172.17.%' OR src_endpoint_ip LIKE '172.18.%' OR src_endpoint_ip LIKE '172.19.%' OR src_endpoint_ip LIKE '172.2%.%' OR src_endpoint_ip LIKE '172.30.%' OR src_endpoint_ip LIKE '172.31.%') AND ('{{scope_hosts}}' = '' OR instr(',' || '{{scope_hosts}}' || ',', ',' || device_hostname || ',') > 0) AND time >= datetime('now', '-{{lookback_days}} days') GROUP BY src_endpoint_ip HAVING affected_hosts <= 2 ORDER BY request_count DESC",
        "surface": "hb_http_activity",
        "description": "Identify rare external IP addresses interacting with the CGI interface, excluding internal management subnets.",
        "expected_signal": "Anomalous external IPs that talk to only one or two controllers. Silence suggests only internal or broad fleet-wide management is occurring."
      },
      "parents": [
        {
          "id": "find-danfoss-inventory"
        }
      ],
      "primitive_config": {
        "dsl": "sqlite",
        "role": "baseline",
        "label": "Rare Administrative Source IPs",
        "reads": [
          "src_endpoint_ip",
          "device_hostname",
          "time"
        ],
        "source": "hb_http_activity",
        "target": "web",
        "content": "SELECT src_endpoint_ip, COUNT(DISTINCT device_hostname) AS affected_hosts, COUNT(*) AS request_count, MIN(time) AS first_seen FROM hb_http_activity WHERE (LOWER(url_path) LIKE '%xml.cgi%' OR LOWER(url_query) LIKE '%xml.cgi%') AND NOT (src_endpoint_ip LIKE '10.%' OR src_endpoint_ip LIKE '192.168.%' OR src_endpoint_ip LIKE '172.16.%' OR src_endpoint_ip LIKE '172.17.%' OR src_endpoint_ip LIKE '172.18.%' OR src_endpoint_ip LIKE '172.19.%' OR src_endpoint_ip LIKE '172.2%.%' OR src_endpoint_ip LIKE '172.30.%' OR src_endpoint_ip LIKE '172.31.%') AND ('{{scope_hosts}}' = '' OR instr(',' || '{{scope_hosts}}' || ',', ',' || device_hostname || ',') > 0) AND time >= datetime('now', '-{{lookback_days}} days') GROUP BY src_endpoint_ip HAVING affected_hosts <= 2 ORDER BY request_count DESC",
        "silence": "not_evidence_of_absence",
        "baseline": {
          "window": "{{lookback_days}}d",
          "compare": "first_seen"
        },
        "expected": "Anomalous external IPs that talk to only one or two controllers. Silence suggests only internal or broad fleet-wide management is occurring.",
        "verified": "dry-run",
        "prevalence": {
          "by": "device_hostname",
          "key": [
            "src_endpoint_ip"
          ],
          "rare_below": 3
        },
        "verified_at": "2026-11-10"
      }
    },
    {
      "id": "triage-activity",
      "type": "analytic",
      "label": "Triage Controller Interaction",
      "config": {
        "cite": "required",
        "tools": [
          "endpoint",
          "web"
        ],
        "context": [
          "find-danfoss-inventory",
          "cgi-exploit-indicators",
          "management-ip-prevalence"
        ],
        "objective": "Determine if any Danfoss controller has been subjected to unauthorized account renaming or parameter sabotage by weighing the source IP rarity against the specific CGI query verbs used.",
        "description": "Evaluate whether the successful HTTP requests and source IP rarity indicate a true unauthorized takeover.",
        "max_iterations": 5,
        "expected_signal": "A per-host verdict citing specific evidence of account hijacking or sabotage.",
        "success_criteria": "A per-host verdict of malicious | suspicious | benign, citing specific URL query strings that indicate sabotage."
      },
      "parents": [
        {
          "id": "cgi-exploit-indicators",
          "kind": "merge"
        },
        {
          "id": "management-ip-prevalence",
          "kind": "merge"
        }
      ]
    },
    {
      "id": "route-on-verdict",
      "type": "checkpoint",
      "label": "Route on Triage Verdict",
      "config": {
        "fuzzy": true,
        "judge": "hunter",
        "question": "the triage-activity verdict is malicious for at least one host, indicating successful account renaming or parameter modification by an external actor",
        "condition": "the triage-activity verdict is malicious for at least one host, indicating successful account renaming or parameter modification by an external actor",
        "blind_spot": "encrypted-traffic-blindness",
        "confidence": "high",
        "description": "Direct the hunt toward immediate containment for confirmed sabotage or analyst review for suspicious signals.",
        "checkpoint_type": "mandatory"
      },
      "parents": [
        {
          "id": "triage-activity"
        }
      ]
    },
    {
      "id": "isolate-impacted-controller",
      "type": "action",
      "label": "Isolate Impacted Controller",
      "config": {
        "target": "endpoint",
        "description": "Halt the attack and prevent further temperature manipulation.",
        "instructions": "Isolate the controller at the network gateway or switch port. Block the identified attacker IP addresses at the perimeter. Notify on-site maintenance to manually verify and restore refrigeration settings.",
        "action_approval": "required"
      },
      "parents": [
        {
          "id": "route-on-verdict",
          "branch": "on_supports"
        }
      ]
    },
    {
      "id": "analyst-manual-review",
      "type": "task",
      "label": "Analyst Manual Review",
      "config": {
        "assignee": "analyst",
        "description": "Review suspicious CGI interactions and coordinate with maintenance teams.",
        "instructions": "Examine the url_query and url_path columns for the strings 'rename' or 'set_temp'. Verify if the source IP belongs to an authorized external maintenance provider. Check for unauthorized setting changes from the reported October or November timeframe."
      },
      "parents": [
        {
          "id": "route-on-verdict",
          "branch": "default"
        },
        {
          "id": "route-on-verdict",
          "branch": "on_unavailable"
        },
        {
          "id": "isolate-impacted-controller"
        }
      ]
    },
    {
      "id": "close-out-hunt",
      "type": "task",
      "label": "Close Out and Hygiene Review",
      "config": {
        "assignee": "analyst",
        "description": "Document the negative result and ensure patching is scheduled.",
        "instructions": "No active sabotage detected. Ensure that identified Danfoss controllers are prioritized for firmware updates to remediate unauthenticated account manipulation vulnerabilities."
      },
      "parents": [
        {
          "id": "route-on-verdict",
          "branch": "on_refutes"
        }
      ]
    }
  ]
}