{
  "hunt": {
    "meta": {
      "tlp": "clear",
      "hunt": {
        "handoff": "keep-as-periodic-hunt",
        "trigger": "intel-report",
        "methodology": "model-assisted",
        "applicability": "campaign-specific",
        "justification": "Turla's CerealNeuron uses a passive listening mechanism that bypasses traditional outbound beaconing detection. Negative results across the Exchange estate are required to ensure espionage tools are not co-opting the organization's infrastructure."
      },
      "name": "Turla CerealNeuron Passive Exchange Backdoor",
      "type": "investigation",
      "labels": [
        "hunt",
        "attack.t1071.001",
        "attack.t1572",
        "collection",
        "command and control",
        "execution",
        "persistence"
      ],
      "series": {
        "slug": "exchange-for-breakfast-turla-s-cereal-tricks-are-not-for-kids",
        "index": 2,
        "title": "Exchange for breakfast: Turla\u2019s Cereal tricks are not for kids",
        "total": 2
      },
      "related": [
        {
          "hunt": "cereal-dotnet-stealth-execution",
          "reason": "This hunt identifies the C2 ingress; a separate hunt addresses the sophisticated .NET execution techniques used once commands are received.",
          "relation": "out-of-scope-alternative"
        },
        {
          "hunt": "turla-cereal-exchange-transport-hijack",
          "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": "Simple URI matching is brittle and easily bypassed by path rotation. This hunt combines indicator matching with a behavioral baseline of source IPs accessing Exchange namespaces, requiring an analyst to weigh source rarity against requested paths.",
      "coverage": [
        {
          "stage": "passive-web-backdoor",
          "steps": [
            "check-cereal-uris",
            "baseline-source-ips",
            "triage-web-evidence"
          ],
          "status": "covered"
        },
        {
          "stage": "dotnet-stealth-execution",
          "reason": "Handled by the execution-focused hunt in this series.",
          "status": "out_of_scope"
        },
        {
          "stage": "offline-command-processing",
          "reason": "Belongs to another part of the 'Exchange for breakfast: Turla\u2019s Cereal tricks are not for kids' series.",
          "status": "out_of_scope"
        },
        {
          "stage": "mail-pipeline-hijacking",
          "reason": "Belongs to another part of the 'Exchange for breakfast: Turla\u2019s Cereal tricks are not for kids' series.",
          "status": "out_of_scope"
        },
        {
          "stage": "espionage-data-staging",
          "reason": "Belongs to another part of the 'Exchange for breakfast: Turla\u2019s Cereal tricks are not for kids' series.",
          "status": "out_of_scope"
        }
      ],
      "scenario": {
        "stages": [
          {
            "name": "Sophisticated .NET Execution",
            "slug": "dotnet-stealth-execution",
            "tactic": "execution",
            "techniques": [
              "T1047"
            ],
            "observables": [
              "unmanaged entry points",
              "native image cache abuse",
              "nested .NET assemblies",
              "suspicious DLLs loaded by legitimate Windows processes"
            ]
          },
          {
            "name": "Passive Web Service Backdoor",
            "slug": "passive-web-backdoor",
            "tactic": "command-and-control",
            "techniques": [
              "T1071",
              "T1572"
            ],
            "observables": [
              "https://*:443/owa/sdds/",
              "HTTPS://*:443/AUTODISCOVER/PROXYSERVICE/",
              "HTTPS://*:443/MICROSOFT-SERVER-ACTIVESYNC/INTEGRATED/API/",
              "CerealNeuron"
            ]
          },
          {
            "name": "File-based Command Interface",
            "slug": "offline-command-processing",
            "tactic": "command-and-control",
            "techniques": [
              "T1071"
            ],
            "observables": [
              "encrypted command files on disk",
              "CerealHermit"
            ]
          },
          {
            "name": "Exchange Transport Hijack",
            "slug": "mail-pipeline-hijacking",
            "tactic": "persistence",
            "techniques": [
              "T1574"
            ],
            "observables": [
              "EdgeTransport.exe",
              "injection into EdgeTransport.exe",
              "memory hijacking of transport agents",
              "VTable Fixups",
              "CerealBox"
            ]
          },
          {
            "name": "Email Collection and Staging",
            "slug": "espionage-data-staging",
            "tactic": "collection",
            "techniques": [
              "T1041"
            ],
            "observables": [
              "compressed and encrypted files on disk",
              ".doc attachments",
              ".docx attachments",
              ".pdf attachments"
            ]
          }
        ],
        "summary": "The Turla-linked Cereal campaign targets government Exchange servers, utilizing a modular .NET toolset that operates without external C&C infrastructure by co-opting the victim server as a passive listener. The toolset intercepts mail by injecting into the EdgeTransport.exe process to hijack transport agents and uses specialized .NET tradecraft, such as native image cache abuse, to maintain stealthy execution."
      },
      "severity": "critical",
      "rationale": "Focus on Internet-facing Microsoft Exchange servers. Use the scoping query to narrow the estate, then refine with the scope_hosts parameter if specific servers are suspected.",
      "guardrails": {
        "claims": "no_unsupported",
        "evidence": "citation_required",
        "telemetry": "untrusted",
        "missing_data": "not_benign"
      },
      "hypothesis": "An adversary has installed a passive .NET backdoor on a Microsoft Exchange server that intercepts commands via specific URI paths within standard Exchange web services.",
      "parameters": {
        "scope_hosts": {
          "type": "list[host]",
          "default": [],
          "description": "Hosts identified as Exchange servers from the scoping step; leave empty to scan the entire estate."
        },
        "cereal_paths": {
          "from": {
            "ref": "https://www.welivesecurity.com/en/eset-research/exchange-for-breakfast-turlas-cereal-tricks-are-not-for-kids/",
            "kind": "article",
            "observed": "2026-11-10"
          },
          "type": "list[string]",
          "default": [
            "/owa/sdds/",
            "/autodiscover/proxyservice/",
            "/microsoft-server-activesync/integrated/api/"
          ],
          "description": "Legitimate-looking URIs reported for passive command reception."
        },
        "lookback_days": {
          "type": "number",
          "default": "14",
          "description": "Days of history to examine for web requests."
        }
      },
      "provenance": {
        "authors": [
          {
            "org": "huntbase.io",
            "name": "Huntbase hunt generation"
          }
        ],
        "generated": {
          "by": "huntbase-hunt-generation",
          "from": "https://www.welivesecurity.com/en/eset-research/exchange-for-breakfast-turlas-cereal-tricks-are-not-for-kids/",
          "gates": [
            "dry-run",
            "lint",
            "critic"
          ],
          "model": "hb_google/gemini-3-flash-preview"
        }
      },
      "references": [
        {
          "url": "https://www.welivesecurity.com/en/eset-research/exchange-for-breakfast-turlas-cereal-tricks-are-not-for-kids/",
          "name": "ESET Research \u2014 Exchange for breakfast: Turla\u2019s Cereal tricks are not for kids"
        }
      ],
      "blind_spots": [
        {
          "id": "visibility-gap-encrypted-http",
          "risk": "If the environment only provides network flow logs, the hunt cannot identify specific URI paths and must rely solely on source IP outliers.",
          "stage": "passive-web-backdoor",
          "question": "Can we see the URI path if the traffic is encrypted and the EDR does not hook the web server process?",
          "requires": "Endpoint-level HTTP inspection or SSL termination logs"
        },
        {
          "id": "uri-rotation",
          "risk": "Exact URI matching will fail, leaving the prevalence baseline as the only signal for identifying the intrusion.",
          "stage": "passive-web-backdoor",
          "question": "What if the adversary changes the hardcoded URI paths to different legitimate-looking endpoints?",
          "requires": "Threat research updates"
        }
      ]
    },
    "name": "Turla CerealNeuron Passive Exchange Backdoor",
    "description": "This hunt targets CerealNeuron, a component of Turla's Cereal toolset. Unlike traditional implants that beacon out, CerealNeuron acts as a passive listener within IIS on a compromised Exchange server. It monitors incoming web requests for specific encrypted payloads directed at sub-paths in /owa/, /autodiscover/, or /activesync/ namespaces. The hunt identifies Exchange assets, searches for hits against known malicious URIs, and baselines external source traffic to find anomalous access patterns that may indicate rotated command paths where standard indicators have changed."
  },
  "nodes": [
    {
      "id": "hypothesis",
      "type": "hypothesis",
      "label": "Hypothesis",
      "config": {
        "tags": [],
        "series": {
          "slug": "exchange-for-breakfast-turla-s-cereal-tricks-are-not-for-kids",
          "index": 2,
          "title": "Exchange for breakfast: Turla\u2019s Cereal tricks are not for kids",
          "total": 2
        },
        "coverage": [
          {
            "stage": "passive-web-backdoor",
            "steps": [
              "check-cereal-uris",
              "baseline-source-ips",
              "triage-web-evidence"
            ],
            "status": "covered"
          },
          {
            "stage": "dotnet-stealth-execution",
            "reason": "Handled by the execution-focused hunt in this series.",
            "status": "out_of_scope"
          },
          {
            "stage": "offline-command-processing",
            "reason": "Belongs to another part of the 'Exchange for breakfast: Turla\u2019s Cereal tricks are not for kids' series.",
            "status": "out_of_scope"
          },
          {
            "stage": "mail-pipeline-hijacking",
            "reason": "Belongs to another part of the 'Exchange for breakfast: Turla\u2019s Cereal tricks are not for kids' series.",
            "status": "out_of_scope"
          },
          {
            "stage": "espionage-data-staging",
            "reason": "Belongs to another part of the 'Exchange for breakfast: Turla\u2019s Cereal tricks are not for kids' series.",
            "status": "out_of_scope"
          }
        ],
        "rationale": "An adversary has installed a passive .NET backdoor on a Microsoft Exchange server that intercepts commands via specific URI paths within standard Exchange web services.",
        "blind_spots": [
          {
            "id": "visibility-gap-encrypted-http",
            "risk": "If the environment only provides network flow logs, the hunt cannot identify specific URI paths and must rely solely on source IP outliers.",
            "stage": "passive-web-backdoor",
            "question": "Can we see the URI path if the traffic is encrypted and the EDR does not hook the web server process?",
            "requires": "Endpoint-level HTTP inspection or SSL termination logs"
          },
          {
            "id": "uri-rotation",
            "risk": "Exact URI matching will fail, leaving the prevalence baseline as the only signal for identifying the intrusion.",
            "stage": "passive-web-backdoor",
            "question": "What if the adversary changes the hardcoded URI paths to different legitimate-looking endpoints?",
            "requires": "Threat research updates"
          }
        ],
        "scoping_notes": "Focus on Internet-facing Microsoft Exchange servers. Use the scoping query to narrow the estate, then refine with the scope_hosts parameter if specific servers are suspected.",
        "beyond_detection": "Simple URI matching is brittle and easily bypassed by path rotation. This hunt combines indicator matching with a behavioral baseline of source IPs accessing Exchange namespaces, requiring an analyst to weigh source rarity against requested paths."
      }
    },
    {
      "id": "identify-exchange-hosts",
      "type": "query",
      "label": "Identify Exchange Server Assets",
      "config": {
        "dsl": "sqlite",
        "role": "scoping",
        "source": "endpoint",
        "content": "SELECT DISTINCT device_hostname, package_name, package_version FROM hb_software_inventory WHERE LOWER(package_name) LIKE '%exchange server%'",
        "surface": "hb_software_inventory",
        "description": "Identify the hosts running Microsoft Exchange Server to provide a narrow scope for application-layer traffic analysis.",
        "expected_signal": "A list of hostnames hosting Exchange services. Silence means no managed hosts are running Exchange Server according to inventory."
      },
      "parents": [
        {
          "id": "hypothesis"
        }
      ],
      "primitive_config": {
        "dsl": "sqlite",
        "role": "scoping",
        "label": "Identify Exchange Server Assets",
        "reads": [
          "device_hostname",
          "package_name",
          "package_version"
        ],
        "source": "hb_software_inventory",
        "target": "endpoint",
        "content": "SELECT DISTINCT device_hostname, package_name, package_version FROM hb_software_inventory WHERE LOWER(package_name) LIKE '%exchange server%'",
        "silence": "not_evidence_of_absence",
        "expected": "A list of hostnames hosting Exchange services. Silence means no managed hosts are running Exchange Server according to inventory.",
        "verified": "dry-run",
        "verified_at": "2026-11-12"
      }
    },
    {
      "id": "check-cereal-uris",
      "type": "query",
      "label": "Match Known CerealNeuron Paths",
      "config": {
        "dsl": "sqlite",
        "role": "detection-candidate",
        "source": "web",
        "content": "SELECT device_hostname, url_path, src_endpoint_ip, user_agent, status_code, time FROM hb_http_activity WHERE ('{{scope_hosts}}' = '' OR instr(',' || '{{scope_hosts}}' || ',', ',' || device_hostname || ',') > 0) AND (instr(',' || '{{cereal_paths}}' || ',', ',' || LOWER(url_path) || ',') > 0) AND time >= datetime('now', '-{{lookback_days}} days')",
        "surface": "hb_http_activity",
        "description": "Match URI paths reported as C2 endpoints for the passive backdoor exactly.",
        "expected_signal": "Direct matches indicate an external entity requested a path used for C2. Silence confirms these specific paths were not observed."
      },
      "parents": [
        {
          "id": "identify-exchange-hosts"
        }
      ],
      "primitive_config": {
        "dsl": "sqlite",
        "role": "detection-candidate",
        "label": "Match Known CerealNeuron Paths",
        "reads": [
          "device_hostname",
          "url_path",
          "src_endpoint_ip",
          "user_agent",
          "status_code",
          "time"
        ],
        "source": "hb_http_activity",
        "target": "web",
        "content": "SELECT device_hostname, url_path, src_endpoint_ip, user_agent, status_code, time FROM hb_http_activity WHERE ('{{scope_hosts}}' = '' OR instr(',' || '{{scope_hosts}}' || ',', ',' || device_hostname || ',') > 0) AND (instr(',' || '{{cereal_paths}}' || ',', ',' || LOWER(url_path) || ',') > 0) AND time >= datetime('now', '-{{lookback_days}} days')",
        "silence": "evidence_of_absence",
        "expected": "Direct matches indicate an external entity requested a path used for C2. Silence confirms these specific paths were not observed.",
        "verified": "dry-run",
        "verified_at": "2026-11-12"
      }
    },
    {
      "id": "baseline-source-ips",
      "type": "query",
      "label": "Baseline Rare Source Access",
      "config": {
        "dsl": "sqlite",
        "role": "baseline",
        "source": "web",
        "content": "SELECT src_endpoint_ip, user_agent, url_path, COUNT(*) AS req_count, COUNT(DISTINCT device_hostname) AS host_count, MIN(time) AS first_seen FROM hb_http_activity WHERE ('{{scope_hosts}}' = '' OR instr(',' || '{{scope_hosts}}' || ',', ',' || device_hostname || ',') > 0) AND (LOWER(url_path) LIKE '/owa/%' OR LOWER(url_path) LIKE '/autodiscover/%' OR LOWER(url_path) LIKE '/microsoft-server-activesync/%') AND time >= datetime('now', '-{{lookback_days}} days') GROUP BY src_endpoint_ip, user_agent, url_path HAVING host_count <= 2 ORDER BY host_count ASC, req_count DESC",
        "surface": "hb_http_activity",
        "description": "Stack-count source IPs accessing Exchange namespaces to find operators maintaining a consistent source profile on non-standard paths.",
        "expected_signal": "Outlier IPs or User Agents targeting only one or two servers. Legitimate remote access typically spans a broader set of hosts or correlates with known user populations."
      },
      "parents": [
        {
          "id": "identify-exchange-hosts"
        }
      ],
      "primitive_config": {
        "dsl": "sqlite",
        "role": "baseline",
        "label": "Baseline Rare Source Access",
        "reads": [
          "src_endpoint_ip",
          "user_agent",
          "url_path",
          "device_hostname",
          "time"
        ],
        "source": "hb_http_activity",
        "target": "web",
        "content": "SELECT src_endpoint_ip, user_agent, url_path, COUNT(*) AS req_count, COUNT(DISTINCT device_hostname) AS host_count, MIN(time) AS first_seen FROM hb_http_activity WHERE ('{{scope_hosts}}' = '' OR instr(',' || '{{scope_hosts}}' || ',', ',' || device_hostname || ',') > 0) AND (LOWER(url_path) LIKE '/owa/%' OR LOWER(url_path) LIKE '/autodiscover/%' OR LOWER(url_path) LIKE '/microsoft-server-activesync/%') AND time >= datetime('now', '-{{lookback_days}} days') GROUP BY src_endpoint_ip, user_agent, url_path HAVING host_count <= 2 ORDER BY host_count ASC, req_count DESC",
        "silence": "not_evidence_of_absence",
        "baseline": {
          "window": "{{lookback_days}}d",
          "compare": "first_seen"
        },
        "expected": "Outlier IPs or User Agents targeting only one or two servers. Legitimate remote access typically spans a broader set of hosts or correlates with known user populations.",
        "verified": "dry-run",
        "prevalence": {
          "by": "device_hostname",
          "key": [
            "src_endpoint_ip",
            "user_agent"
          ],
          "rare_below": 3
        },
        "verified_at": "2026-11-12"
      }
    },
    {
      "id": "triage-web-evidence",
      "type": "analytic",
      "label": "Triage Web Traffic Evidence",
      "config": {
        "cite": "required",
        "tools": [
          "endpoint",
          "web"
        ],
        "context": [
          "check-cereal-uris",
          "baseline-source-ips"
        ],
        "objective": "Determine if any Exchange server shows patterns of passive command reception, specifically hits on known Turla URIs or rare, single-host access to sensitive namespaces.",
        "description": "Analyze the results from URI matching and prevalence analysis to determine if an Exchange server is co-opted as a C2 listener.",
        "max_iterations": 4,
        "expected_signal": "A host-by-host verdict classifying the activity as malicious, suspicious, or benign.",
        "success_criteria": "A per-host verdict citing specific rows, source IPs, and requested URIs."
      },
      "parents": [
        {
          "id": "check-cereal-uris",
          "kind": "merge"
        },
        {
          "id": "baseline-source-ips",
          "kind": "merge"
        }
      ]
    },
    {
      "id": "route-on-verdict",
      "type": "checkpoint",
      "label": "Route on Verdict",
      "config": {
        "fuzzy": true,
        "judge": "hunter",
        "question": "the triage-web-evidence verdict is malicious for at least one host",
        "condition": "the triage-web-evidence verdict is malicious for at least one host",
        "blind_spot": "visibility-gap-encrypted-http",
        "confidence": "high",
        "description": "Direct the workflow to containment or manual review based on the triage verdict.",
        "checkpoint_type": "mandatory"
      },
      "parents": [
        {
          "id": "triage-web-evidence"
        }
      ]
    },
    {
      "id": "isolate-server",
      "type": "action",
      "label": "Isolate Compromised Exchange Server",
      "config": {
        "target": "endpoint",
        "description": "Sever the command channel and prevent lateral movement from the confirmed beachhead.",
        "instructions": "Isolate the compromised Exchange server from the network. Do not reboot the server before capturing a memory dump, as the backdoor runs in volatile memory.",
        "action_approval": "required"
      },
      "parents": [
        {
          "id": "route-on-verdict",
          "branch": "on_supports"
        }
      ]
    },
    {
      "id": "forensic-verification",
      "type": "task",
      "label": "Forensic Verification",
      "config": {
        "assignee": "analyst",
        "description": "Verify the presence of malicious components in IIS processes and identify any staged data.",
        "instructions": "Acquire a memory dump of w3wp.exe. Search for suspicious .NET assemblies with unmanaged entry points. Inspect the file system for encrypted files under the Exchange installation directory that may indicate the presence of CerealHermit."
      },
      "parents": [
        {
          "id": "route-on-verdict",
          "branch": "default"
        },
        {
          "id": "route-on-verdict",
          "branch": "on_unavailable"
        },
        {
          "id": "isolate-server"
        }
      ]
    },
    {
      "id": "close-hunt",
      "type": "task",
      "label": "Hunt Close-out",
      "config": {
        "assignee": "analyst",
        "description": "Document findings and update baseline data for future runs.",
        "instructions": "Record all suspicious source IPs and URIs. Update the organization's baseline for remote access to Exchange services. If hits were found, escalate to full incident response."
      },
      "parents": [
        {
          "id": "route-on-verdict",
          "branch": "on_refutes"
        },
        {
          "id": "forensic-verification"
        }
      ]
    }
  ]
}