{
  "hunt": {
    "meta": {
      "tlp": "clear",
      "hunt": {
        "handoff": "promote-to-detection",
        "trigger": "intel-report",
        "methodology": "model-assisted",
        "applicability": "campaign-specific",
        "justification": "FamousSparrow is an active APT targeting governmental assets. SparroWocky is their latest implant designed to evade standard detections through DLL side-loading and memory-only execution; a negative result provides assurance against this specific regional threat."
      },
      "name": "SparroWocky Backdoor and FamousSparrow APT Activity",
      "type": "investigation",
      "labels": [
        "hunt",
        "attack.t1190",
        "attack.t1574.002",
        "attack.t1547.001",
        "attack.t1041"
      ],
      "related": [
        {
          "hunt": "sparrowdoor-persistence-detection",
          "reason": "SparroWocky has replaced SparrowDoor as the group's primary implant.",
          "relation": "supersedes"
        }
      ],
      "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"
          ]
        }
      },
      "analysis": "This hunt correlates evidence across four surfaces\u2014processes, modules, files, and network activity\u2014to detect a phased infection that a single registry or network rule would likely miss due to the modularity of the backdoor.",
      "coverage": [
        {
          "stage": "initial-access-exploit-public-app",
          "steps": [
            "scoping-web-servers"
          ],
          "status": "covered"
        },
        {
          "stage": "execution-trident-side-loading",
          "steps": [
            "rare-unsigned-modules",
            "suspicious-dat-files"
          ],
          "status": "covered"
        },
        {
          "stage": "persistence-service-registry",
          "steps": [
            "persistence-check"
          ],
          "status": "covered"
        },
        {
          "stage": "c2-exfiltration-tls",
          "steps": [
            "c2-network-activity"
          ],
          "status": "covered"
        }
      ],
      "scenario": {
        "stages": [
          {
            "name": "Exploitation of Public-Facing Applications",
            "slug": "initial-access-exploit-public-app",
            "tactic": "initial-access",
            "techniques": [
              "T1190"
            ],
            "observables": [
              "Vulnerable governmental web servers",
              "ProxyLogon (historical context)"
            ]
          },
          {
            "name": "Trident Loader DLL Side-loading",
            "slug": "execution-trident-side-loading",
            "tactic": "execution",
            "techniques": [
              "T1574.002"
            ],
            "observables": [
              "Legitimate executable loading patched DLL",
              "Payload file with .dat extension",
              "Encrypted file header magic value 0x11328712",
              "Malicious code in patched .text section of legitimate DLLs",
              "Reflective PE loading with stripped MZ/PE magic values"
            ]
          },
          {
            "name": "Persistence via Service or Registry",
            "slug": "persistence-service-registry",
            "tactic": "persistence",
            "techniques": [
              "T1547.001"
            ],
            "observables": [
              "Service name ProcAuditManager",
              "Registry Run keys for persistence",
              "Configuration field Persistence method set to 1 (Service) or 2 (Registry)"
            ]
          },
          {
            "name": "Exfiltration over TLS C2 Channel",
            "slug": "c2-exfiltration-tls",
            "tactic": "exfiltration",
            "techniques": [
              "T1041"
            ],
            "observables": [
              "C2 IP 216.238.110.120",
              "C2 Port 443",
              "TLS protocol used for secure channel",
              "RC4 encrypted exfiltration data",
              "Periodic screenshots",
              "TCP proxy activity"
            ]
          }
        ],
        "summary": "The China-aligned FamousSparrow APT group is targeting Latin American governmental organizations using the modular SparroWocky backdoor. The campaign uses a trident loader scheme involving DLL side-loading and a custom encrypted payload to establish persistence via services or registry keys and communicate with a hardcoded C2 infrastructure."
      },
      "severity": "high",
      "rationale": "Target hosts running critical web-facing services (IIS, Apache, Exchange) particularly in Latin American regional subnets.",
      "guardrails": {
        "claims": "no_unsupported",
        "evidence": "citation_required",
        "telemetry": "untrusted",
        "missing_data": "not_benign"
      },
      "hypothesis": "An adversary has established a beachhead on a web-facing server using a trident loader scheme and is communicating with SparroWocky C2 infrastructure.",
      "parameters": {
        "c2_ips": {
          "from": {
            "ref": "eset-sparrowocky",
            "kind": "article",
            "observed": "2026-09-17"
          },
          "type": "list[ip]",
          "default": [
            "216.238.110.120"
          ],
          "description": "Known SparroWocky C2 IP addresses."
        },
        "scope_hosts": {
          "from": {
            "ref": "analyst-defined",
            "kind": "manual",
            "observed": "2026-09-17"
          },
          "type": "list[host]",
          "default": [],
          "description": "Optional list of hostnames to narrow the hunt."
        },
        "lookback_days": {
          "from": {
            "ref": "hunt-standard",
            "kind": "manual",
            "observed": "2026-09-17"
          },
          "type": "number",
          "default": "14",
          "description": "Days of history to examine."
        },
        "web_server_processes": {
          "from": {
            "ref": "standard-web-processes",
            "kind": "manual",
            "observed": "2026-09-17"
          },
          "type": "list[string]",
          "default": [
            "w3wp.exe",
            "httpd.exe",
            "nginx.exe",
            "exchange.exe",
            "tomcat.exe"
          ],
          "description": "Process names for common web servers to scope initial access."
        }
      },
      "provenance": {
        "authors": [
          {
            "org": "huntbase.io",
            "name": "Huntbase hunt generation"
          }
        ],
        "generated": {
          "by": "huntbase-hunt-generation",
          "from": "https://www.welivesecurity.com/en/eset-research/beware-sparrowock-backdoor-bites-commands-catch/",
          "gates": [
            "dry-run",
            "lint"
          ],
          "model": "hb_google/gemini-3-flash-preview"
        }
      },
      "references": [
        {
          "url": "https://www.welivesecurity.com/en/eset-research/beware-sparrowock-backdoor-bites-commands-catch/",
          "name": "ESET Research \u2014 Beware the SparroWock: The backdoor that bites, the commands that catch"
        }
      ],
      "blind_spots": [
        {
          "id": "no-reflective-mapping-telemetry",
          "risk": "SparroWocky strips PE magic values to evade memory scanners; standard process activity may miss the reflective load event.",
          "owner": "Detection Engineering",
          "stage": "execution-trident-side-loading",
          "question": "whether the backdoor was reflectively loaded directly into memory",
          "requires": "hb_process_activity with on_disk = 0 context",
          "remediation": "Enable memory-mapping event logging for web server processes."
        }
      ]
    },
    "name": "SparroWocky Backdoor and FamousSparrow APT Activity",
    "description": "This hunt targets the China-aligned FamousSparrow APT group and its SparroWocky backdoor. The attack chain begins with the exploitation of web-facing applications, followed by the deployment of a trident loader that uses DLL side-loading to reflectively load the backdoor from an encrypted .dat payload. The hunt uses a phased approach: it first scopes the web-facing estate and searches for the loader's side-loaded modules and companion data files, then follows on to hunt for service-based persistence and confirmed C2 traffic. An agent synthesizes the evidence across process, module, file, and network telemetry to reach a verdict."
  },
  "nodes": [
    {
      "id": "hypothesis",
      "type": "hypothesis",
      "label": "Hypothesis",
      "config": {
        "tags": [],
        "coverage": [
          {
            "stage": "initial-access-exploit-public-app",
            "steps": [
              "scoping-web-servers"
            ],
            "status": "covered"
          },
          {
            "stage": "execution-trident-side-loading",
            "steps": [
              "rare-unsigned-modules",
              "suspicious-dat-files"
            ],
            "status": "covered"
          },
          {
            "stage": "persistence-service-registry",
            "steps": [
              "persistence-check"
            ],
            "status": "covered"
          },
          {
            "stage": "c2-exfiltration-tls",
            "steps": [
              "c2-network-activity"
            ],
            "status": "covered"
          }
        ],
        "rationale": "An adversary has established a beachhead on a web-facing server using a trident loader scheme and is communicating with SparroWocky C2 infrastructure.",
        "blind_spots": [
          {
            "id": "no-reflective-mapping-telemetry",
            "risk": "SparroWocky strips PE magic values to evade memory scanners; standard process activity may miss the reflective load event.",
            "owner": "Detection Engineering",
            "stage": "execution-trident-side-loading",
            "question": "whether the backdoor was reflectively loaded directly into memory",
            "requires": "hb_process_activity with on_disk = 0 context",
            "remediation": "Enable memory-mapping event logging for web server processes."
          }
        ],
        "scoping_notes": "Target hosts running critical web-facing services (IIS, Apache, Exchange) particularly in Latin American regional subnets.",
        "beyond_detection": "This hunt correlates evidence across four surfaces\u2014processes, modules, files, and network activity\u2014to detect a phased infection that a single registry or network rule would likely miss due to the modularity of the backdoor."
      }
    },
    {
      "id": "scoping-web-servers",
      "type": "query",
      "label": "Scope potential beachheads",
      "config": {
        "dsl": "sqlite",
        "role": "scoping",
        "source": "endpoint",
        "content": "SELECT DISTINCT device_hostname FROM hb_process_activity WHERE instr(',' || '{{web_server_processes}}' || ',', ',' || LOWER(process_name) || ',') > 0 AND ('{{scope_hosts}}' = '' OR instr(',' || '{{scope_hosts}}' || ',', ',' || device_hostname || ',') > 0) AND time >= datetime('now', '-{{lookback_days}} days')",
        "surface": "hb_process_activity",
        "description": "Identify hosts running web server processes, which are the primary initial access targets.",
        "expected_signal": "A list of hostnames representing the web-facing attack surface. Silence means no web server processes were active."
      },
      "parents": [
        {
          "id": "hypothesis"
        }
      ],
      "primitive_config": {
        "dsl": "sqlite",
        "role": "scoping",
        "label": "Scope potential beachheads",
        "reads": [
          "device_hostname",
          "process_name",
          "time"
        ],
        "source": "hb_process_activity",
        "target": "endpoint",
        "content": "SELECT DISTINCT device_hostname FROM hb_process_activity WHERE instr(',' || '{{web_server_processes}}' || ',', ',' || LOWER(process_name) || ',') > 0 AND ('{{scope_hosts}}' = '' OR instr(',' || '{{scope_hosts}}' || ',', ',' || device_hostname || ',') > 0) AND time >= datetime('now', '-{{lookback_days}} days')",
        "silence": "not_evidence_of_absence",
        "expected": "A list of hostnames representing the web-facing attack surface. Silence means no web server processes were active.",
        "verified": "dry-run",
        "verified_at": "2026-09-28"
      }
    },
    {
      "id": "rare-unsigned-modules",
      "type": "query",
      "label": "Rare unsigned module loads",
      "config": {
        "dsl": "sqlite",
        "role": "baseline",
        "source": "endpoint",
        "content": "SELECT device_hostname, module_path, process_name, COUNT(*) AS load_count, MIN(time) AS first_seen FROM hb_module_activity WHERE module_signed = 'false' AND LOWER(module_path) NOT LIKE 'c:\\windows\\%' AND ('{{scope_hosts}}' = '' OR instr(',' || '{{scope_hosts}}' || ',', ',' || device_hostname || ',') > 0) AND time >= datetime('now', '-{{lookback_days}} days') GROUP BY device_hostname, module_path, process_name HAVING COUNT(DISTINCT device_hostname) <= 3 ORDER BY load_count ASC",
        "surface": "hb_module_activity",
        "description": "Identify potential DLL side-loading by finding rare, unsigned modules loaded from non-system directories.",
        "expected_signal": "Unsigned modules appearing on a small number of hosts in application-specific paths."
      },
      "parents": [
        {
          "id": "scoping-web-servers"
        }
      ],
      "primitive_config": {
        "dsl": "sqlite",
        "role": "baseline",
        "label": "Rare unsigned module loads",
        "reads": [
          "device_hostname",
          "module_path",
          "module_signed",
          "time",
          "process_name"
        ],
        "source": "hb_module_activity",
        "target": "endpoint",
        "content": "SELECT device_hostname, module_path, process_name, COUNT(*) AS load_count, MIN(time) AS first_seen FROM hb_module_activity WHERE module_signed = 'false' AND LOWER(module_path) NOT LIKE 'c:\\windows\\%' AND ('{{scope_hosts}}' = '' OR instr(',' || '{{scope_hosts}}' || ',', ',' || device_hostname || ',') > 0) AND time >= datetime('now', '-{{lookback_days}} days') GROUP BY device_hostname, module_path, process_name HAVING COUNT(DISTINCT device_hostname) <= 3 ORDER BY load_count ASC",
        "silence": "evidence_of_absence",
        "baseline": {
          "window": "{{lookback_days}}d",
          "compare": "first_seen"
        },
        "expected": "Unsigned modules appearing on a small number of hosts in application-specific paths.",
        "verified": "dry-run",
        "prevalence": {
          "by": "device_hostname",
          "key": [
            "module_path"
          ],
          "rare_below": 3
        },
        "verified_at": "2026-09-28"
      }
    },
    {
      "id": "suspicious-dat-files",
      "type": "query",
      "label": "Suspicious payload file activity",
      "config": {
        "dsl": "sqlite",
        "role": "enrichment",
        "source": "endpoint",
        "content": "SELECT device_hostname, file_path, process_name, time FROM hb_file_activity WHERE LOWER(file_name) LIKE '%.dat' AND LOWER(file_path) NOT LIKE 'c:\\windows\\%' AND ('{{scope_hosts}}' = '' OR instr(',' || '{{scope_hosts}}' || ',', ',' || device_hostname || ',') > 0) AND time >= datetime('now', '-{{lookback_days}} days')",
        "surface": "hb_file_activity",
        "description": "Detect the .dat payload files typically associated with the SparroWocky loader.",
        "expected_signal": "Process activity touching .dat files in non-standard directories. Silence proves no such files were touched."
      },
      "parents": [
        {
          "id": "scoping-web-servers"
        }
      ],
      "primitive_config": {
        "dsl": "sqlite",
        "role": "enrichment",
        "label": "Suspicious payload file activity",
        "reads": [
          "device_hostname",
          "file_name",
          "file_path",
          "process_name",
          "time"
        ],
        "source": "hb_file_activity",
        "target": "endpoint",
        "content": "SELECT device_hostname, file_path, process_name, time FROM hb_file_activity WHERE LOWER(file_name) LIKE '%.dat' AND LOWER(file_path) NOT LIKE 'c:\\windows\\%' AND ('{{scope_hosts}}' = '' OR instr(',' || '{{scope_hosts}}' || ',', ',' || device_hostname || ',') > 0) AND time >= datetime('now', '-{{lookback_days}} days')",
        "silence": "evidence_of_absence",
        "expected": "Process activity touching .dat files in non-standard directories. Silence proves no such files were touched.",
        "verified": "dry-run",
        "verified_at": "2026-09-28"
      }
    },
    {
      "id": "loader-early-agent",
      "type": "analytic",
      "label": "Evaluate loader beachhead",
      "config": {
        "cite": "required",
        "tools": [
          "endpoint",
          "network"
        ],
        "context": [
          "scoping-web-servers",
          "rare-unsigned-modules",
          "suspicious-dat-files"
        ],
        "objective": "Identify hosts where rare unsigned modules and suspicious .dat files exist on web-facing infrastructure.",
        "description": "Analyze early-stage findings to determine if the combined evidence indicates a SparroWocky infection.",
        "max_iterations": 3,
        "expected_signal": "A per-host triage identifying high-confidence beachhead hosts.",
        "success_criteria": "A list of suspicious hosts with cited evidence of the trident loader scheme."
      },
      "parents": [
        {
          "id": "rare-unsigned-modules",
          "kind": "merge"
        },
        {
          "id": "suspicious-dat-files",
          "kind": "merge"
        }
      ]
    },
    {
      "id": "persistence-check",
      "type": "query",
      "label": "Identify SparroWocky persistence",
      "config": {
        "dsl": "sqlite",
        "role": "triage",
        "source": "endpoint",
        "content": "SELECT device_hostname, reg_target, reg_value_data, time FROM hb_registry_activity WHERE (LOWER(reg_target) LIKE '%procauditmanager%' OR LOWER(reg_target) LIKE '%\\currentversion\\run%') AND ('{{scope_hosts}}' = '' OR instr(',' || '{{scope_hosts}}' || ',', ',' || device_hostname || ',') > 0) AND time >= datetime('now', '-{{lookback_days}} days')",
        "surface": "hb_registry_activity",
        "description": "Search for the specific service name or Run key entries used by SparroWocky.",
        "expected_signal": "Registry writes associated with service creation or run-key persistence. Silence means no such activity was recorded."
      },
      "parents": [
        {
          "id": "loader-early-agent"
        }
      ],
      "primitive_config": {
        "dsl": "sqlite",
        "role": "triage",
        "label": "Identify SparroWocky persistence",
        "reads": [
          "device_hostname",
          "reg_target",
          "reg_value_data",
          "time"
        ],
        "source": "hb_registry_activity",
        "target": "endpoint",
        "content": "SELECT device_hostname, reg_target, reg_value_data, time FROM hb_registry_activity WHERE (LOWER(reg_target) LIKE '%procauditmanager%' OR LOWER(reg_target) LIKE '%\\currentversion\\run%') AND ('{{scope_hosts}}' = '' OR instr(',' || '{{scope_hosts}}' || ',', ',' || device_hostname || ',') > 0) AND time >= datetime('now', '-{{lookback_days}} days')",
        "silence": "not_evidence_of_absence",
        "expected": "Registry writes associated with service creation or run-key persistence. Silence means no such activity was recorded.",
        "verified": "dry-run",
        "verified_at": "2026-09-28"
      }
    },
    {
      "id": "c2-network-activity",
      "type": "query",
      "label": "Confirmed C2 network traffic",
      "config": {
        "dsl": "sqlite",
        "role": "detection-candidate",
        "source": "network",
        "content": "SELECT device_hostname, dst_endpoint_ip, dst_endpoint_port, process_name, time FROM hb_network_connection WHERE instr(',' || '{{c2_ips}}' || ',', ',' || dst_endpoint_ip || ',') > 0 AND ('{{scope_hosts}}' = '' OR instr(',' || '{{scope_hosts}}' || ',', ',' || device_hostname || ',') > 0) AND time >= datetime('now', '-{{lookback_days}} days')",
        "surface": "hb_network_connection",
        "description": "Identify active network connections to the known SparroWocky C2 infrastructure.",
        "expected_signal": "Connections to 216.238.110.120. Silence proves no communication with this IP occurred."
      },
      "parents": [
        {
          "id": "loader-early-agent"
        }
      ],
      "primitive_config": {
        "dsl": "sqlite",
        "role": "detection-candidate",
        "label": "Confirmed C2 network traffic",
        "reads": [
          "device_hostname",
          "dst_endpoint_ip",
          "dst_endpoint_port",
          "process_name",
          "time"
        ],
        "source": "hb_network_connection",
        "target": "network",
        "content": "SELECT device_hostname, dst_endpoint_ip, dst_endpoint_port, process_name, time FROM hb_network_connection WHERE instr(',' || '{{c2_ips}}' || ',', ',' || dst_endpoint_ip || ',') > 0 AND ('{{scope_hosts}}' = '' OR instr(',' || '{{scope_hosts}}' || ',', ',' || device_hostname || ',') > 0) AND time >= datetime('now', '-{{lookback_days}} days')",
        "silence": "evidence_of_absence",
        "expected": "Connections to 216.238.110.120. Silence proves no communication with this IP occurred.",
        "verified": "dry-run",
        "verified_at": "2026-09-28"
      }
    },
    {
      "id": "backdoor-final-agent",
      "type": "analytic",
      "label": "Final infection assessment",
      "config": {
        "cite": "required",
        "tools": [
          "endpoint",
          "network"
        ],
        "context": [
          "loader-early-agent",
          "persistence-check",
          "c2-network-activity"
        ],
        "objective": "Reach a final verdict by correlating early loader artifacts with confirmed persistence and C2 traffic.",
        "description": "Synthesize the loader triage with follow-on persistence and C2 traffic to reach a definitive verdict.",
        "max_iterations": 4,
        "expected_signal": "A final verdict of malicious for hosts exhibiting both loader artifacts and follow-on activity.",
        "success_criteria": "A per-host verdict of malicious, suspicious, or benign citing all relevant rows."
      },
      "parents": [
        {
          "id": "persistence-check",
          "kind": "merge"
        },
        {
          "id": "c2-network-activity",
          "kind": "merge"
        }
      ]
    },
    {
      "id": "route-on-verdict",
      "type": "checkpoint",
      "label": "Route based on verdict",
      "config": {
        "fuzzy": true,
        "judge": "hunter",
        "question": "the final assessment verdict is malicious for at least one host",
        "condition": "the final assessment verdict is malicious for at least one host",
        "blind_spot": "no-reflective-mapping-telemetry",
        "confidence": "high",
        "description": "Direct the workflow based on the final infection assessment.",
        "checkpoint_type": "mandatory"
      },
      "parents": [
        {
          "id": "backdoor-final-agent"
        }
      ]
    },
    {
      "id": "isolate-host",
      "type": "action",
      "label": "Isolate compromised host",
      "config": {
        "target": "endpoint",
        "description": "Prevent further exfiltration and lateral movement by isolating the host.",
        "instructions": "Isolate the host immediately via EDR containment. Collect the suspicious .dat and DLL files for forensic analysis.",
        "action_approval": "required"
      },
      "parents": [
        {
          "id": "route-on-verdict",
          "branch": "on_supports"
        }
      ]
    },
    {
      "id": "analyst-review",
      "type": "task",
      "label": "Analyst review",
      "config": {
        "assignee": "analyst",
        "description": "Validate the agent's findings and identify additional persistence mechanisms.",
        "instructions": "Review the cited rows. Confirm the existence of the 'ProcAuditManager' service. Verify if any other hosts contacted 216.238.110.120."
      },
      "parents": [
        {
          "id": "route-on-verdict",
          "branch": "default"
        },
        {
          "id": "route-on-verdict",
          "branch": "on_unavailable"
        },
        {
          "id": "route-on-verdict",
          "branch": "on_refutes"
        },
        {
          "id": "isolate-host"
        }
      ]
    },
    {
      "id": "close-out",
      "type": "task",
      "label": "Close out",
      "config": {
        "assignee": "analyst",
        "description": "Record findings and propose standing detections.",
        "instructions": "Document the compromised hosts and the identified loader artifacts. Propose a standing rule for connections to the C2 IP."
      },
      "parents": [
        {
          "id": "analyst-review"
        }
      ]
    }
  ]
}