{
  "hunt": {
    "meta": {
      "tlp": "clear",
      "hunt": {
        "handoff": "keep-as-periodic-hunt",
        "trigger": "intel-report",
        "methodology": "model-assisted",
        "applicability": "campaign-specific",
        "justification": "ClickFix is a high-volume initial access technique leading directly to long-term persistence via DLL sideloading and reverse tunnels. Detecting these footholds is essential to stopping lateral movement and data theft."
      },
      "name": "Persistence via Sideloading and Reverse Tunnels",
      "type": "investigation",
      "labels": [
        "hunt",
        "attack.t1547.001",
        "attack.t1053.005",
        "attack.t1574.002",
        "attack.t1572",
        "command and control",
        "defense evasion",
        "execution",
        "initial access",
        "persistence"
      ],
      "series": {
        "slug": "beyond-the-clipboard-the-evolving-tradecraft-of-clickfix",
        "index": 2,
        "title": "Beyond the clipboard: The evolving tradecraft of ClickFix",
        "total": 2
      },
      "related": [
        {
          "hunt": "initial-access-clickfix-clipboard",
          "reason": "This hunt focuses on the post-compromise persistence; a separate hunt is needed to target the initial clipboard-based social engineering.",
          "relation": "out-of-scope-alternative"
        },
        {
          "hunt": "clickfix-redirection-script-execution",
          "relation": "follows"
        }
      ],
      "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": "A simple detection rule may find a specific Run key name, but this hunt pivots between the persistence artifact, the prevalence of module loads (detecting sideloading behaviors), and network-level SSH tunnel infrastructure to identify compromised hosts even as IOCs rotate.",
      "coverage": [
        {
          "stage": "persistence-staging-scripts",
          "steps": [
            "run-key-persistence"
          ],
          "status": "covered"
        },
        {
          "stage": "evasion-dll-sideloading",
          "steps": [
            "rare-programdata-modules"
          ],
          "status": "covered"
        },
        {
          "stage": "c2-reverse-tunneling",
          "steps": [
            "c2-tunnel-ips"
          ],
          "status": "covered"
        },
        {
          "stage": "initial-access-clickfix-lure",
          "reason": "Belongs to another part of the 'Beyond the clipboard: The evolving tradecraft of ClickFix' series.",
          "status": "out_of_scope"
        },
        {
          "stage": "execution-clipboard-powershell",
          "reason": "Belongs to another part of the 'Beyond the clipboard: The evolving tradecraft of ClickFix' series.",
          "status": "out_of_scope"
        }
      ],
      "scenario": {
        "stages": [
          {
            "name": "ClickFix Web Redirection",
            "slug": "initial-access-clickfix-lure",
            "tactic": "initial-access",
            "techniques": [
              "T1566.002"
            ],
            "observables": [
              "vvestalw.ghost.io",
              "westlaw-signon.com",
              "apirequestaccess.com",
              "moziw.com",
              "http://apirequestaccess.com/cfirm.php?token="
            ]
          },
          {
            "name": "Clipboard-based PowerShell Execution",
            "slug": "execution-clipboard-powershell",
            "tactic": "execution",
            "techniques": [
              "T1059.001",
              "T1115"
            ],
            "observables": [
              "powershell.exe",
              "Get-Clipboard",
              "6341434163416441.txt",
              "cf_verify.zip"
            ]
          },
          {
            "name": "Persistence via Tasks and Run Keys",
            "slug": "persistence-staging-scripts",
            "tactic": "persistence",
            "techniques": [
              "T1053.005",
              "T1547.001"
            ],
            "observables": [
              "1.bat",
              "C:\\ProgramData\\f8f33b09aed97a47\\",
              "C:\\ProgramData\\7168f7f870a45fbb\\",
              "CertEnrollCtrl_Y0db6oZq9",
              "LockScreenContentServer_qQrRrJiHX",
              "DuskDesk",
              "SysyService"
            ]
          },
          {
            "name": "DLL Sideloading",
            "slug": "evasion-dll-sideloading",
            "tactic": "defence-evasion",
            "techniques": [
              "T1574.002"
            ],
            "observables": [
              "CertEnrollCtrl.exe",
              "CertEnroll.dll",
              "LockScreenContentServer.exe",
              "dui70.dll"
            ]
          },
          {
            "name": "Reverse Tunnel and C2",
            "slug": "c2-reverse-tunneling",
            "tactic": "command-and-control",
            "techniques": [
              "T1572"
            ],
            "observables": [
              "C:\\ProgramData\\ShService\\r.ps1",
              "23.227.199.41",
              "167.148.201.104",
              "node.exe",
              "LimeMint.js",
              "launch.js"
            ]
          }
        ],
        "summary": "Threat actors use SEO poisoning and malvertising to lure users to fake verification pages (ClickFix) that trick them into executing malicious PowerShell commands from their clipboard. These commands download multi-stage payloads that establish persistence through scheduled tasks and Run keys, eventually deploying DLL sideloading chains for reverse SSH tunnels or Node.js-based RATs."
      },
      "severity": "high",
      "rationale": "Look for endpoints with recent software installation errors or those reporting high PowerShell script block volume. Prioritize hosts where ProgramData contains new, single-character or random-character subdirectories.",
      "guardrails": {
        "claims": "no_unsupported",
        "evidence": "citation_required",
        "telemetry": "untrusted",
        "missing_data": "not_benign"
      },
      "hypothesis": "An attacker has established persistence using ClickFix-dropped batch scripts that install DLL sideloading implants and reverse SSH tunnels to maintain long-term access.",
      "parameters": {
        "c2_ips": {
          "from": {
            "ref": "huntress-clickfix-beyond-clipboard",
            "kind": "article",
            "observed": "2026-11-10"
          },
          "type": "list[ip]",
          "default": [
            "167.148.201.104",
            "23.227.199.41",
            "151.240.151.76"
          ],
          "description": "Known C2 or tunnel exit IPs from the research."
        },
        "lookback_days": {
          "type": "number",
          "default": "14",
          "description": "Days of history to examine."
        },
        "target_run_paths": {
          "from": {
            "ref": "huntress-clickfix-beyond-clipboard",
            "kind": "article",
            "observed": "2026-11-10"
          },
          "type": "list[string]",
          "default": [
            "CertEnrollCtrl_Y0db6oZq9",
            "LockScreenContentServer_qQrRrJiHX",
            "DuskDesk"
          ],
          "description": "Specific Run key value names observed in ClickFix campaigns."
        }
      },
      "provenance": {
        "authors": [
          {
            "org": "huntbase.io",
            "name": "Huntbase hunt generation"
          }
        ],
        "generated": {
          "by": "huntbase-hunt-generation",
          "from": "https://www.huntress.com/blog/the-evolving-tradecraft-of-clickfix",
          "gates": [
            "dry-run",
            "lint",
            "critic"
          ],
          "model": "hb_google/gemini-3-flash-preview"
        }
      },
      "references": [
        {
          "url": "https://www.huntress.com/blog/the-evolving-tradecraft-of-clickfix",
          "name": "The evolving tradecraft of ClickFix \u2014 Huntress"
        }
      ],
      "blind_spots": [
        {
          "id": "endpoint-visibility-gap",
          "risk": "A host without EDR or Sysmon will not report the registry or module load artifacts, even if it is participating in a reverse tunnel.",
          "question": "whether persistence was established on hosts without agent coverage",
          "requires": "hb_module_activity and hb_registry_activity coverage on all hosts"
        },
        {
          "id": "script-block-logging-disabled",
          "risk": "If script block logging is off, we cannot see the parameters of the reverse tunnel if the on-disk script is ephemeral.",
          "stage": "c2-reverse-tunneling",
          "question": "the content of r.ps1 if the file is deleted before collection",
          "requires": "hb_script_activity (PowerShell Script Block Logging)"
        }
      ]
    },
    "name": "Persistence via Sideloading and Reverse Tunnels",
    "description": "This hunt targets the persistent phase of ClickFix campaigns where initial script execution leads to established footholds. It focuses on non-standard Registry Run keys pointing to ProgramData staging paths, identifies rare module loads that indicate DLL sideloading, and corroborates these findings with network connections to known reverse-tunnel infrastructure. An agent weighs the persistence, module prevalence, and network telemetry to identify compromised hosts."
  },
  "nodes": [
    {
      "id": "hypothesis",
      "type": "hypothesis",
      "label": "Hypothesis",
      "config": {
        "tags": [],
        "series": {
          "slug": "beyond-the-clipboard-the-evolving-tradecraft-of-clickfix",
          "index": 2,
          "title": "Beyond the clipboard: The evolving tradecraft of ClickFix",
          "total": 2
        },
        "coverage": [
          {
            "stage": "persistence-staging-scripts",
            "steps": [
              "run-key-persistence"
            ],
            "status": "covered"
          },
          {
            "stage": "evasion-dll-sideloading",
            "steps": [
              "rare-programdata-modules"
            ],
            "status": "covered"
          },
          {
            "stage": "c2-reverse-tunneling",
            "steps": [
              "c2-tunnel-ips"
            ],
            "status": "covered"
          },
          {
            "stage": "initial-access-clickfix-lure",
            "reason": "Belongs to another part of the 'Beyond the clipboard: The evolving tradecraft of ClickFix' series.",
            "status": "out_of_scope"
          },
          {
            "stage": "execution-clipboard-powershell",
            "reason": "Belongs to another part of the 'Beyond the clipboard: The evolving tradecraft of ClickFix' series.",
            "status": "out_of_scope"
          }
        ],
        "rationale": "An attacker has established persistence using ClickFix-dropped batch scripts that install DLL sideloading implants and reverse SSH tunnels to maintain long-term access.",
        "blind_spots": [
          {
            "id": "endpoint-visibility-gap",
            "risk": "A host without EDR or Sysmon will not report the registry or module load artifacts, even if it is participating in a reverse tunnel.",
            "question": "whether persistence was established on hosts without agent coverage",
            "requires": "hb_module_activity and hb_registry_activity coverage on all hosts"
          },
          {
            "id": "script-block-logging-disabled",
            "risk": "If script block logging is off, we cannot see the parameters of the reverse tunnel if the on-disk script is ephemeral.",
            "stage": "c2-reverse-tunneling",
            "question": "the content of r.ps1 if the file is deleted before collection",
            "requires": "hb_script_activity (PowerShell Script Block Logging)"
          }
        ],
        "scoping_notes": "Look for endpoints with recent software installation errors or those reporting high PowerShell script block volume. Prioritize hosts where ProgramData contains new, single-character or random-character subdirectories.",
        "beyond_detection": "A simple detection rule may find a specific Run key name, but this hunt pivots between the persistence artifact, the prevalence of module loads (detecting sideloading behaviors), and network-level SSH tunnel infrastructure to identify compromised hosts even as IOCs rotate."
      }
    },
    {
      "id": "run-key-persistence",
      "type": "query",
      "label": "ProgramData Run key persistence",
      "config": {
        "dsl": "sqlite",
        "role": "detection-candidate",
        "source": "endpoint",
        "content": "SELECT device_hostname, reg_target, reg_value_data, reg_value_name, time FROM hb_registry_activity WHERE (LOWER(reg_target) LIKE '%\\currentversion\\run%' OR LOWER(reg_target) LIKE '%\\currentversion\\runonce%') AND (LOWER(reg_value_data) LIKE '%c:\\programdata\\%' OR instr(',' || '{{target_run_paths}}' || ',', ',' || reg_value_name || ',') > 0) AND time >= datetime('now', '-{{lookback_days}} days')",
        "surface": "hb_registry_activity",
        "description": "Find Run keys that point to scripts or binaries staged in ProgramData, matching specific campaign patterns.",
        "expected_signal": "A Run key pointing to a ProgramData path or using a known campaign value name. Silence means no such persistence was identified via Registry."
      },
      "parents": [
        {
          "id": "hypothesis"
        }
      ],
      "primitive_config": {
        "dsl": "sqlite",
        "role": "detection-candidate",
        "label": "ProgramData Run key persistence",
        "reads": [
          "device_hostname",
          "reg_target",
          "reg_value_data",
          "reg_value_name",
          "time"
        ],
        "source": "hb_registry_activity",
        "target": "endpoint",
        "content": "SELECT device_hostname, reg_target, reg_value_data, reg_value_name, time FROM hb_registry_activity WHERE (LOWER(reg_target) LIKE '%\\currentversion\\run%' OR LOWER(reg_target) LIKE '%\\currentversion\\runonce%') AND (LOWER(reg_value_data) LIKE '%c:\\programdata\\%' OR instr(',' || '{{target_run_paths}}' || ',', ',' || reg_value_name || ',') > 0) AND time >= datetime('now', '-{{lookback_days}} days')",
        "silence": "not_evidence_of_absence",
        "expected": "A Run key pointing to a ProgramData path or using a known campaign value name. Silence means no such persistence was identified via Registry.",
        "verified": "dry-run",
        "verified_at": "2026-11-12"
      }
    },
    {
      "id": "rare-programdata-modules",
      "type": "query",
      "label": "Rare modules loaded from ProgramData",
      "config": {
        "dsl": "sqlite",
        "role": "baseline",
        "source": "endpoint",
        "content": "SELECT module_name, module_path, COUNT(DISTINCT device_hostname) AS host_count, MIN(time) AS first_load FROM hb_module_activity WHERE LOWER(module_path) LIKE 'c:\\programdata\\%' AND time >= datetime('now', '-{{lookback_days}} days') GROUP BY module_name, module_path HAVING host_count <= 3 ORDER BY host_count ASC",
        "surface": "hb_module_activity",
        "description": "Stack-count module loads from ProgramData to identify rare DLLs that may be sideloaded.",
        "expected_signal": "A module load from a ProgramData subdirectory occurring on only a few hosts across the fleet."
      },
      "parents": [
        {
          "id": "run-key-persistence"
        }
      ],
      "primitive_config": {
        "dsl": "sqlite",
        "role": "baseline",
        "label": "Rare modules loaded from ProgramData",
        "reads": [
          "device_hostname",
          "module_name",
          "module_path",
          "time"
        ],
        "source": "hb_module_activity",
        "target": "endpoint",
        "content": "SELECT module_name, module_path, COUNT(DISTINCT device_hostname) AS host_count, MIN(time) AS first_load FROM hb_module_activity WHERE LOWER(module_path) LIKE 'c:\\programdata\\%' AND time >= datetime('now', '-{{lookback_days}} days') GROUP BY module_name, module_path HAVING host_count <= 3 ORDER BY host_count ASC",
        "silence": "not_evidence_of_absence",
        "baseline": {
          "window": "{{lookback_days}}d",
          "compare": "first_seen"
        },
        "expected": "A module load from a ProgramData subdirectory occurring on only a few hosts across the fleet.",
        "verified": "dry-run",
        "prevalence": {
          "by": "device_hostname",
          "key": [
            "module_name",
            "module_path"
          ],
          "rare_below": 3
        },
        "verified_at": "2026-11-12"
      }
    },
    {
      "id": "c2-tunnel-ips",
      "type": "query",
      "label": "Network connections to tunnel infrastructure",
      "config": {
        "dsl": "sqlite",
        "role": "enrichment",
        "source": "network",
        "content": "SELECT device_hostname, process_name, dst_endpoint_ip, dst_endpoint_port, time FROM hb_network_connection WHERE instr(',' || '{{c2_ips}}' || ',', ',' || dst_endpoint_ip || ',') > 0 AND time >= datetime('now', '-{{lookback_days}} days')",
        "surface": "hb_network_connection",
        "description": "Match network connections to known ClickFix and reverse SSH tunnel infrastructure.",
        "expected_signal": "A host connecting to a known tunnel IP, especially via processes like node.exe or powershell.exe."
      },
      "parents": [
        {
          "id": "run-key-persistence"
        }
      ],
      "primitive_config": {
        "dsl": "sqlite",
        "role": "enrichment",
        "label": "Network connections to tunnel infrastructure",
        "reads": [
          "device_hostname",
          "dst_endpoint_ip",
          "dst_endpoint_port",
          "process_name",
          "time"
        ],
        "source": "hb_network_connection",
        "target": "network",
        "content": "SELECT device_hostname, process_name, dst_endpoint_ip, dst_endpoint_port, time FROM hb_network_connection WHERE instr(',' || '{{c2_ips}}' || ',', ',' || dst_endpoint_ip || ',') > 0 AND time >= datetime('now', '-{{lookback_days}} days')",
        "silence": "not_evidence_of_absence",
        "expected": "A host connecting to a known tunnel IP, especially via processes like node.exe or powershell.exe.",
        "verified": "dry-run",
        "verified_at": "2026-11-12"
      }
    },
    {
      "id": "triage-implants",
      "type": "analytic",
      "label": "Triage implants and tunnels",
      "config": {
        "cite": "required",
        "tools": [
          "endpoint",
          "network"
        ],
        "context": [
          "run-key-persistence",
          "rare-programdata-modules",
          "c2-tunnel-ips"
        ],
        "objective": "Determine if a host has been successfully compromised with a persistent ClickFix implant. Correlate the Run key entry with rare DLL loads from the same staging path and any network connections to known tunnel IPs.",
        "description": "Evaluate whether the persistence mechanisms, rare module loads, and network activity together indicate a successful ClickFix implant.",
        "max_iterations": 3,
        "expected_signal": "A per-host verdict of malicious | suspicious | benign citing specific rows from the registry, module, and network steps.",
        "success_criteria": "A clear verdict per host citing the intersection of persistence and behavior."
      },
      "parents": [
        {
          "id": "rare-programdata-modules",
          "kind": "merge"
        },
        {
          "id": "c2-tunnel-ips",
          "kind": "merge"
        }
      ]
    },
    {
      "id": "route-verdict",
      "type": "checkpoint",
      "label": "Route on verdict",
      "config": {
        "fuzzy": true,
        "judge": "hunter",
        "question": "the triage verdict is malicious for at least one host",
        "condition": "the triage verdict is malicious for at least one host",
        "blind_spot": "endpoint-visibility-gap",
        "confidence": "high",
        "description": "Take containment action on malicious hosts or route to manual review.",
        "checkpoint_type": "mandatory"
      },
      "parents": [
        {
          "id": "triage-implants"
        }
      ]
    },
    {
      "id": "isolate-host",
      "type": "action",
      "label": "Isolate compromised host",
      "config": {
        "target": "endpoint",
        "description": "Halt C2 communication and prevent lateral movement.",
        "instructions": "Isolate the host using the endpoint agent. Revoke any active sessions for the user logged into the host.",
        "action_approval": "required"
      },
      "parents": [
        {
          "id": "route-verdict",
          "branch": "on_supports"
        }
      ]
    },
    {
      "id": "analyst-forensic-review",
      "type": "task",
      "label": "Analyst forensic review",
      "config": {
        "assignee": "analyst",
        "description": "Verify the findings and collect evidence from the ProgramData staging path.",
        "instructions": "Examine the registry values and module paths cited by the agent. Collect any scripts or DLLs found in the C:\\ProgramData subfolders for reverse engineering. Check for reverse SSH tunnel processes (e.g., node.exe or powershell.exe) and their command lines."
      },
      "parents": [
        {
          "id": "route-verdict",
          "branch": "default"
        },
        {
          "id": "route-verdict",
          "branch": "on_unavailable"
        },
        {
          "id": "isolate-host"
        }
      ]
    },
    {
      "id": "close-out",
      "type": "task",
      "label": "Hunt close-out",
      "config": {
        "assignee": "analyst",
        "description": "Document results and findings.",
        "instructions": "Record the hunt results. If any new IOCs were found in the forensic review (new IPs or DLL names), update the global watchlist and the parameters of this hunt."
      },
      "parents": [
        {
          "id": "route-verdict",
          "branch": "on_refutes"
        },
        {
          "id": "analyst-forensic-review"
        }
      ]
    }
  ]
}