{
  "hunt": {
    "meta": {
      "tlp": "clear",
      "hunt": {
        "handoff": "keep-as-periodic-hunt",
        "trigger": "intel-report",
        "methodology": "model-assisted",
        "applicability": "campaign-specific",
        "justification": "APT29's use of mobile exploit kits via high-profile watering holes targets high-value credentials and sensitive data (Wi-Fi passwords, cookies); a negative result confirms lack of exposure to this infrastructure."
      },
      "name": "Mobile Device Watering Hole and Exploitation",
      "type": "investigation",
      "labels": [
        "hunt",
        "attack.t1190",
        "attack.t1195",
        "attack.t1566",
        "attack.t1041",
        "execution",
        "exfiltration",
        "initial access"
      ],
      "related": [
        {
          "hunt": "mobile-mdm-vulnerability-audit",
          "reason": "This hunt looks for active exploitation; a posture audit would proactively find every vulnerable mobile device.",
          "relation": "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 static rule would only fire on known domains. This hunt uses a behavioral baseline for analytics script loading and correlates redirection with vulnerability findings to confirm actual exploitation risk.",
      "coverage": [
        {
          "stage": "watering-hole-redirection",
          "steps": [
            "redirection-and-script-lead"
          ],
          "status": "covered"
        },
        {
          "stage": "client-side-profiling-and-exploitation",
          "steps": [
            "vulnerability-check",
            "http-deep-dive"
          ],
          "status": "covered"
        },
        {
          "stage": "mobile-data-exfiltration",
          "steps": [
            "http-deep-dive"
          ],
          "status": "covered"
        }
      ],
      "scenario": {
        "stages": [
          {
            "name": "Watering Hole and Supply Chain Redirection",
            "slug": "watering-hole-redirection",
            "tactic": "initial-access",
            "techniques": [
              "T1190",
              "T1195",
              "T1566"
            ],
            "observables": [
              "a.plerdy.com",
              "america250.holiday",
              "theowo.club",
              "america250.org",
              "ads-it-assets.com",
              "cdn.adv-static.com",
              "window.onload",
              "document.createElement('script')",
              "script.src"
            ]
          },
          {
            "name": "Client-Side Profiling and Exploitation",
            "slug": "client-side-profiling-and-exploitation",
            "tactic": "execution",
            "observables": [
              "static.flux-telemetry.com",
              "edge-ord.clouds-stacks.com",
              "module/5b4c8fea5cbcee273e8d830f52-temfp.js",
              "UltimateFingerprinter",
              "DarkSword",
              "CVE-2024-27808",
              "CVE-2024-27833",
              "CVE-2024-27834",
              "CVE-2025-14174",
              "CVE-2025-24201"
            ]
          },
          {
            "name": "Mobile Data and Cookie Exfiltration",
            "slug": "mobile-data-exfiltration",
            "tactic": "exfiltration",
            "techniques": [
              "T1041"
            ],
            "observables": [
              "exfiltration of cookies",
              "exfiltration of Wi-Fi passwords",
              "exfiltration of Chrome data",
              "109.104.106.107"
            ]
          }
        ],
        "summary": "APT29 conducted a large-scale watering hole campaign targeting iOS and Android devices through compromised legitimate websites, AiTM proxy domains, and a supply chain compromise of the Plerdy analytics service. The campaign used an 'UltimateFingerprinter' script to profile victims and serve tailored n-day exploit chains (including the DarkSword iOS kit) to exfiltrate cookies, Chrome data, and Wi-Fi passwords without establishing persistence."
      },
      "severity": "high",
      "rationale": "Start with corporate endpoints that frequently access international news or government services. Focus on mobile devices enrolled in MDM first.",
      "guardrails": {
        "claims": "no_unsupported",
        "evidence": "citation_required",
        "telemetry": "untrusted",
        "missing_data": "not_benign"
      },
      "hypothesis": "An adversary has redirected users to a watering hole or compromised supply chain to profile mobile devices and deliver n-day exploits based on browser versions.",
      "parameters": {
        "c2_ips": {
          "from": {
            "ref": "https://www.sekoia.com/blog/poisoned-source-apt29-watering-holes-targets-mobile-devices-with-n-day-exploits",
            "kind": "article",
            "observed": "2026-10-29"
          },
          "type": "list[ip]",
          "default": [
            "109.104.106.107"
          ],
          "description": "Infrastructure IPs for delivery and exfiltration."
        },
        "target_cves": {
          "from": {
            "ref": "https://www.sekoia.com/blog/poisoned-source-apt29-watering-holes-targets-mobile-devices-with-n-day-exploits",
            "kind": "article",
            "observed": "2026-10-29"
          },
          "type": "list[string]",
          "default": [
            "CVE-2024-27808",
            "CVE-2024-27833",
            "CVE-2024-27834",
            "CVE-2025-14174",
            "CVE-2025-24201",
            "CVE-2025-27038",
            "CVE-2025-31277",
            "CVE-2025-43510",
            "CVE-2025-43520",
            "CVE-2025-43529",
            "CVE-2026-20700",
            "CVE-2026-3910"
          ],
          "description": "Mobile and browser CVEs exploited in the campaign."
        },
        "lookback_days": {
          "type": "number",
          "default": "14",
          "description": "Days of history to examine."
        },
        "malicious_domains": {
          "from": {
            "ref": "https://www.sekoia.com/blog/poisoned-source-apt29-watering-holes-targets-mobile-devices-with-n-day-exploits",
            "kind": "article",
            "observed": "2026-10-29"
          },
          "type": "list[domain]",
          "default": [
            "static.flux-telemetry.com",
            "america250.holiday",
            "america250.org",
            "theowo.club",
            "a.plerdy.com",
            "edge-ord.clouds-stacks.com",
            "ads-it-assets.com",
            "cdn.adv-static.com"
          ],
          "description": "Redirection and profiling domains named in the report."
        }
      },
      "provenance": {
        "authors": [
          {
            "org": "huntbase.io",
            "name": "Huntbase hunt generation"
          }
        ],
        "generated": {
          "by": "huntbase-hunt-generation",
          "from": "https://www.sekoia.com/blog/poisoned-source-apt29-watering-holes-targets-mobile-devices-with-n-day-exploits",
          "gates": [
            "dry-run",
            "lint"
          ],
          "model": "hb_google/gemini-3-flash-preview"
        }
      },
      "references": [
        {
          "url": "https://www.sekoia.com/blog/poisoned-source-apt29-watering-holes-targets-mobile-devices-with-n-day-exploits",
          "name": "Sekoia \u2014 Poisoned Source: APT29 Watering Holes Targets Mobile Devices"
        }
      ],
      "blind_spots": [
        {
          "id": "encrypted-traffic-blindness",
          "risk": "Without TLS inspection, the specific script paths like 'temfp.js' are invisible to hb_http_activity, leaving only domain-level visibility.",
          "stage": "watering-hole-redirection",
          "question": "The specific path and contents of the profiling script delivered over HTTPS",
          "requires": "TLS inspection or transparent proxy logs"
        },
        {
          "id": "mobile-os-telemetry-gap",
          "risk": "Exploitation of personally-owned or unmanaged mobile devices using corporate credentials will not be visible in endpoint-level surfaces.",
          "stage": "client-side-profiling-and-exploitation",
          "question": "Whether a non-enrolled mobile device was compromised while off the corporate VPN",
          "requires": "Mobile EDR or specialized mobile telemetry"
        }
      ]
    },
    "name": "Mobile Device Watering Hole and Exploitation",
    "description": "This hunt identifies a sophisticated watering hole campaign attributed to APT29 that targets mobile devices through compromised web analytics and reverse proxies. The campaign uses several infection vectors, including a supply-chain compromise of the Plerdy analytics service, to deliver profiling scripts and n-day exploit chains like DarkSword. The hunt begins with a behavioral lead query that baselines script inclusions from analytics providers and checks for known redirection domains. If suspicious traffic is confirmed, it fans out to correlate the exposure of browser and mobile CVEs on affected hosts with detailed HTTP telemetry for specific profiling script paths and exfiltration patterns. An agent weighs the intersection of these findings to identify successful exploitation."
  },
  "nodes": [
    {
      "id": "hypothesis",
      "type": "hypothesis",
      "label": "Hypothesis",
      "config": {
        "tags": [],
        "coverage": [
          {
            "stage": "watering-hole-redirection",
            "steps": [
              "redirection-and-script-lead"
            ],
            "status": "covered"
          },
          {
            "stage": "client-side-profiling-and-exploitation",
            "steps": [
              "vulnerability-check",
              "http-deep-dive"
            ],
            "status": "covered"
          },
          {
            "stage": "mobile-data-exfiltration",
            "steps": [
              "http-deep-dive"
            ],
            "status": "covered"
          }
        ],
        "rationale": "An adversary has redirected users to a watering hole or compromised supply chain to profile mobile devices and deliver n-day exploits based on browser versions.",
        "blind_spots": [
          {
            "id": "encrypted-traffic-blindness",
            "risk": "Without TLS inspection, the specific script paths like 'temfp.js' are invisible to hb_http_activity, leaving only domain-level visibility.",
            "stage": "watering-hole-redirection",
            "question": "The specific path and contents of the profiling script delivered over HTTPS",
            "requires": "TLS inspection or transparent proxy logs"
          },
          {
            "id": "mobile-os-telemetry-gap",
            "risk": "Exploitation of personally-owned or unmanaged mobile devices using corporate credentials will not be visible in endpoint-level surfaces.",
            "stage": "client-side-profiling-and-exploitation",
            "question": "Whether a non-enrolled mobile device was compromised while off the corporate VPN",
            "requires": "Mobile EDR or specialized mobile telemetry"
          }
        ],
        "scoping_notes": "Start with corporate endpoints that frequently access international news or government services. Focus on mobile devices enrolled in MDM first.",
        "beyond_detection": "A static rule would only fire on known domains. This hunt uses a behavioral baseline for analytics script loading and correlates redirection with vulnerability findings to confirm actual exploitation risk."
      }
    },
    {
      "id": "redirection-and-script-lead",
      "type": "query",
      "label": "Redirection traffic and unusual analytics scripts",
      "config": {
        "dsl": "sqlite",
        "role": "detection-candidate",
        "source": "web",
        "content": "SELECT device_hostname, url_hostname, url_path, COUNT(*) AS requests, MIN(time) AS first_seen FROM hb_http_activity WHERE (instr(',' || '{{malicious_domains}}' || ',', ',' || LOWER(url_hostname) || ',') > 0 OR (LOWER(url_hostname) = 'a.plerdy.com' AND LOWER(url_path) LIKE '%.js')) AND time >= datetime('now', '-{{lookback_days}} days') GROUP BY device_hostname, url_hostname, url_path",
        "surface": "hb_http_activity",
        "description": "Find known redirection indicators and baseline JS script loads from analytics providers like Plerdy.",
        "expected_signal": "A row indicates interaction with malicious infrastructure or a script load from Plerdy. Unusual script paths should stand out from baseline patterns."
      },
      "parents": [
        {
          "id": "hypothesis"
        }
      ],
      "primitive_config": {
        "dsl": "sqlite",
        "role": "detection-candidate",
        "label": "Redirection traffic and unusual analytics scripts",
        "reads": [
          "device_hostname",
          "url_hostname",
          "url_path",
          "time"
        ],
        "source": "hb_http_activity",
        "target": "web",
        "content": "SELECT device_hostname, url_hostname, url_path, COUNT(*) AS requests, MIN(time) AS first_seen FROM hb_http_activity WHERE (instr(',' || '{{malicious_domains}}' || ',', ',' || LOWER(url_hostname) || ',') > 0 OR (LOWER(url_hostname) = 'a.plerdy.com' AND LOWER(url_path) LIKE '%.js')) AND time >= datetime('now', '-{{lookback_days}} days') GROUP BY device_hostname, url_hostname, url_path",
        "silence": "not_evidence_of_absence",
        "baseline": {
          "window": "{{lookback_days}}d",
          "compare": "new_this_window"
        },
        "expected": "A row indicates interaction with malicious infrastructure or a script load from Plerdy. Unusual script paths should stand out from baseline patterns.",
        "verified": "dry-run",
        "prevalence": {
          "by": "device_hostname",
          "key": [
            "url_hostname",
            "url_path"
          ],
          "rare_below": 5
        },
        "verified_at": "2026-11-05"
      }
    },
    {
      "id": "lead-agent",
      "type": "analytic",
      "label": "Evaluate lead activity",
      "config": {
        "cite": "required",
        "tools": [
          "endpoint",
          "web"
        ],
        "context": [
          "redirection-and-script-lead"
        ],
        "objective": "Determine if any host shows interaction with malicious domains or unexpected script inclusions from the Plerdy supply chain.",
        "description": "Review the lead results to decide if a deeper forensic investigation is required.",
        "max_iterations": 3,
        "expected_signal": "A per-host assessment of the redirection and script traffic.",
        "success_criteria": "A verdict citing specific hosts and malicious/behavioral indicators."
      },
      "parents": [
        {
          "id": "redirection-and-script-lead"
        }
      ]
    },
    {
      "id": "gate",
      "type": "checkpoint",
      "label": "Gate: Malicious traffic confirmed",
      "config": {
        "fuzzy": true,
        "judge": "hunter",
        "question": "the lead-agent verdict confirms at least one host queried a malicious domain or loaded an unusual script from a.plerdy.com",
        "condition": "the lead-agent verdict confirms at least one host queried a malicious domain or loaded an unusual script from a.plerdy.com",
        "blind_spot": "encrypted-traffic-blindness",
        "confidence": "high",
        "description": "Restrict the hunt to forensic queries only when the lead indicates a potential intrusion.",
        "checkpoint_type": "mandatory"
      },
      "parents": [
        {
          "id": "lead-agent"
        }
      ]
    },
    {
      "id": "vulnerability-check",
      "type": "query",
      "label": "Host vulnerability for targeted CVEs",
      "config": {
        "dsl": "sqlite",
        "role": "enrichment",
        "source": "endpoint",
        "content": "SELECT d.hostname AS device_hostname, vf.cve_uid, vf.severity, vf.resource_uid FROM hb_vulnerability_finding AS vf JOIN hb_devices AS d ON vf.device_uid = d.device_uid AND vf.provider = d.provider WHERE instr(',' || '{{target_cves}}' || ',', ',' || vf.cve_uid || ',') > 0",
        "surface": "hb_vulnerability_finding",
        "description": "Identify hosts in the estate that are vulnerable to the specific n-day exploits used by the campaign.",
        "expected_signal": "A list of hostnames matching the campaign's target browser or mobile vulnerabilities."
      },
      "parents": [
        {
          "id": "gate",
          "branch": "on_supports"
        }
      ],
      "primitive_config": {
        "dsl": "sqlite",
        "role": "enrichment",
        "label": "Host vulnerability for targeted CVEs",
        "reads": [
          "device_uid",
          "cve_uid",
          "severity",
          "resource_uid"
        ],
        "source": "hb_vulnerability_finding",
        "target": "endpoint",
        "content": "SELECT d.hostname AS device_hostname, vf.cve_uid, vf.severity, vf.resource_uid FROM hb_vulnerability_finding AS vf JOIN hb_devices AS d ON vf.device_uid = d.device_uid AND vf.provider = d.provider WHERE instr(',' || '{{target_cves}}' || ',', ',' || vf.cve_uid || ',') > 0",
        "silence": "not_evidence_of_absence",
        "expected": "A list of hostnames matching the campaign's target browser or mobile vulnerabilities.",
        "verified": "dry-run",
        "verified_at": "2026-11-05"
      }
    },
    {
      "id": "http-deep-dive",
      "type": "query",
      "label": "Profiling script delivery and C2 traffic",
      "config": {
        "dsl": "sqlite",
        "role": "baseline",
        "source": "web",
        "content": "SELECT device_hostname, url_hostname, url_path, dst_endpoint_ip, COUNT(*) AS count, MIN(time) AS first_seen FROM hb_http_activity WHERE (LOWER(url_path) LIKE '%temfp.js%' OR instr(',' || '{{c2_ips}}' || ',', ',' || dst_endpoint_ip || ',') > 0) AND time >= datetime('now', '-{{lookback_days}} days') GROUP BY device_hostname, url_hostname, url_path, dst_endpoint_ip",
        "surface": "hb_http_activity",
        "description": "Detect the profiling script 'temfp.js' and potential exfiltration to known campaign IPs.",
        "expected_signal": "Hits on the profiling script path or specific C2 IPs (109.104.106.107). Rare hits are suspicious."
      },
      "parents": [
        {
          "id": "gate",
          "branch": "on_supports"
        }
      ],
      "primitive_config": {
        "dsl": "sqlite",
        "role": "baseline",
        "label": "Profiling script delivery and C2 traffic",
        "reads": [
          "device_hostname",
          "url_hostname",
          "url_path",
          "dst_endpoint_ip",
          "time"
        ],
        "source": "hb_http_activity",
        "target": "web",
        "content": "SELECT device_hostname, url_hostname, url_path, dst_endpoint_ip, COUNT(*) AS count, MIN(time) AS first_seen FROM hb_http_activity WHERE (LOWER(url_path) LIKE '%temfp.js%' OR instr(',' || '{{c2_ips}}' || ',', ',' || dst_endpoint_ip || ',') > 0) AND time >= datetime('now', '-{{lookback_days}} days') GROUP BY device_hostname, url_hostname, url_path, dst_endpoint_ip",
        "silence": "not_evidence_of_absence",
        "baseline": {
          "window": "{{lookback_days}}d",
          "compare": "new_this_window"
        },
        "expected": "Hits on the profiling script path or specific C2 IPs (109.104.106.107). Rare hits are suspicious.",
        "verified": "dry-run",
        "prevalence": {
          "by": "device_hostname",
          "key": [
            "url_path",
            "dst_endpoint_ip"
          ],
          "rare_below": 3
        },
        "verified_at": "2026-11-05"
      }
    },
    {
      "id": "triage",
      "type": "analytic",
      "label": "Correlate exploitation evidence",
      "config": {
        "cite": "required",
        "tools": [
          "endpoint",
          "web"
        ],
        "context": [
          "lead-agent",
          "vulnerability-check",
          "http-deep-dive"
        ],
        "objective": "Identify the intersection of hosts that both visited the redirection infrastructure and possess the relevant browser or mobile CVEs to prioritize confirmed compromises.",
        "description": "Identify hosts where the intersection of vulnerability and malicious traffic suggests successful exploitation.",
        "max_iterations": 5,
        "expected_signal": "A list of compromised hosts with cited evidence from both vulnerability and traffic surfaces.",
        "success_criteria": "A verdict of malicious | suspicious | benign per host, prioritizing those where vulnerability findings overlap with malicious HTTP traffic."
      },
      "parents": [
        {
          "id": "vulnerability-check",
          "kind": "merge"
        },
        {
          "id": "http-deep-dive",
          "kind": "merge"
        }
      ]
    },
    {
      "id": "route",
      "type": "checkpoint",
      "label": "Route on triage verdict",
      "config": {
        "fuzzy": true,
        "judge": "hunter",
        "question": "the triage verdict is malicious for at least one host showing the intersection of vulnerability and traffic",
        "condition": "the triage verdict is malicious for at least one host showing the intersection of vulnerability and traffic",
        "blind_spot": "mobile-os-telemetry-gap",
        "confidence": "high",
        "description": "Isolate confirmed breaches and send suspicious activity to manual review.",
        "checkpoint_type": "mandatory"
      },
      "parents": [
        {
          "id": "triage"
        }
      ]
    },
    {
      "id": "isolate",
      "type": "action",
      "label": "Isolate host",
      "config": {
        "target": "endpoint",
        "description": "Prevent further exfiltration from a compromised device.",
        "instructions": "Isolate the host and revoke its cloud sessions while forensics proceed.",
        "action_approval": "required"
      },
      "parents": [
        {
          "id": "route",
          "branch": "on_supports"
        }
      ]
    },
    {
      "id": "analyst-review",
      "type": "task",
      "label": "Analyst forensic review",
      "config": {
        "assignee": "analyst",
        "description": "Perform deep manual analysis of the HTTP exfiltration patterns and vulnerability context.",
        "instructions": "Review cited rows from http-deep-dive; look for POST requests to 109.104.106.107 suggesting cookie or password exfiltration. Verify the mobile OS version via hb_devices."
      },
      "parents": [
        {
          "id": "gate",
          "branch": "default"
        },
        {
          "id": "gate",
          "branch": "on_unavailable"
        },
        {
          "id": "route",
          "branch": "default"
        },
        {
          "id": "route",
          "branch": "on_unavailable"
        },
        {
          "id": "route",
          "branch": "on_refutes"
        },
        {
          "id": "isolate"
        }
      ]
    },
    {
      "id": "close-out",
      "type": "task",
      "label": "Close out",
      "config": {
        "assignee": "analyst",
        "description": "Document findings and negative results.",
        "instructions": "Record the negative results; if redirection was seen but no vulnerability exists, note for future patching priority."
      },
      "parents": [
        {
          "id": "gate",
          "branch": "on_refutes"
        }
      ]
    }
  ]
}