☰
SVG钓鱼攻击:图片伪装下的恶意脚本与防御指南
2026/10/22 11:34:04 网站建设 项目流程

我看到这个标题时,第一反应是“这种玩法怎么还能一直有效”。SVG 钓鱼并不是什么刚出现的新招,但在最近几个月的应急响应里,我明显感觉到它的出现频率在上升。原因很简单:传统钓鱼附件还有各类伪装,但 SVG 这种“看起来是人畜无害的图片”走的完全是另一条路线——它不属于可执行文件,却能在打开时执行脚本,天然避开了大量安全设备的注意力。

SVG 的全称是可缩放矢量图形,本质上是基于 XML 的文本格式。这意味着它跟普通图片有本质区别:PNG、JPG 被浏览器渲染成位图后,就是一堆像素;而 SVG 在渲染前,先会被解析成一份带结构的文档。攻击者就是看中这一点,把恶意代码直接写进 SVG 的脚本节点里。用户双击文件,浏览器打开它,代码就跑了。

更麻烦的地方在于,这类攻击在早期很难被一锤子打死。单看 SVG 这个文件,它可能只是一段无害的加载逻辑,真正干坏事的内容在后续下载的载荷里。这就是我一直说的“前段轻、后段重”的攻击模式——入口文件干净,恶意内容动态落地。接下来我把整个攻击链路、样本特征、防御落地和应急排查完完整整拆一遍。

1. 一张“图片”为什么会成为攻击入口

1.1 SVG 不是普通图片:它在浏览器里其实是一段“文档”

先补一个基础认知。位图和矢量图的差别,大家平时不太注意,但在安全视角里这是天壤之别。

位图比如 JPG、PNG,打开之后就是一个静态的、按像素点排列的数据块。浏览器要做的只是解码、显示,没有任何“语义”层面的解析。攻击者在位图里塞东西,最多就是隐写术——把数据藏在像素通道或文件尾,但想让它自动执行,还需要额外找一个解释器去提取。

SVG 不一样。SVG 文件用尖括号组织的 XML 结构,浏览器会先把它当文档解析,再根据其中的标签去渲染图形。在这个过程中,SVG 支持内嵌脚本,也支持 onload、onclick 这类事件处理器。攻击者只需要一句话:

一个被浏览器打开的 SVG,可以自动执行 JavaScript,并且这段 JavaScript 能访问当前页面的 DOM,能发起网络请求,能调用浏览器暴露出来的各种接口。对攻击者来说,这不是“图片”,这是一张可以远程控制的木马入场券。

我在分析样本时见过的最典型写法是:SVG 文件开头是一个看起来完全正常的矢量图形,图形中间或尾部嵌入脚本节点,然后用 onload 事件触发。整份文件在文本编辑器里看,前半段是正常的形状绘制,后半段才是真正的恶意逻辑。很多只看文件头的工具,根本不会发现异常。

1.2 攻击者盯上 SVG 的三个现实理由

第一,视觉伪装太成功。默认情况下,桌面系统的文件夹里 SVG 会显示为图片图标,双击后如果默认打开程序是浏览器,或者某些支持 SVG 的看图软件,用户会觉得“这就是张图”。即便邮件网关或安全软件弹了提醒,用户也容易被“一张图而已”的心理预期带偏。标题里说的“特洛伊木马”,骗的就是这个信任感。

第二,检测盲区太明显。大部分传统邮件网关对附件的处理逻辑,是看文件扩展名、MIME 类型和特征码。exe、cmd、脚本文件都在重点监控名单里,但 SVG 常年不在。发一个 .svg 附件,很多网关甚至连“图片类附件白名单”都懒得设。它既不在高危名单里,也没有人专门对它做行为分析,等于在门口保安的眼皮底下溜进去。

第三,执行条件太好满足。SVG 打开即执行,不需要用户手动启用宏,不需要右键管理员运行,不需要像某些漏洞利用那样精打细算打补丁。用户只需要按照邮件正文里的提示“双击打开附件”,攻击就往前走了一大步。这种一点即中、零交互的执行条件,是它比 Office 宏文档更受攻击者欢迎的原因。

2. 攻击链路拆解:从钓鱼邮件到窃密与挖矿的完整动作

2.1 第一阶段:伪装与投递

攻击者的投递主题,几乎都是照着企业真实业务场景抄的。发票确认、物流异常、银行对账单、项目合同回执,哪个场景最让员工习惯性点开,他们就抄哪个。邮件正文通常写得非常简洁,比如“附件是您的最新发票,请查收”或“请查看附件中更新后的收货信息”,目的就是让收件人没有犹豫地点击。

附件后缀是 .svg,文件名往往是 invoice.svg、report.svg、shipment.svg 之类。有些攻击者还会在文件名上加两段后缀,比如 “invoice.pdf.svg”,因为很多系统在显示文件名时只显示最后一部分,或者用户默认只注意到前几段,根本不会点开属性看完整扩展名。

这里有个特别容易骗过老员工的因素:企业邮箱如果部署了收发件归档,历史邮件里经常有包含 pdf.svg 这类附件的样例,邮件系统自己从不拦。时间一长,员工就形成路径依赖——“这种附件以前也收过,没事”。

2.2 第二阶段:脚本触发与载荷落地

用户双击 SVG,桌面系统如果配置的是默认浏览器打开,浏览器就会加载整个 SVG 文档。渲染前,文档里任何带 onload 的全局事件都会自动触发。

恶意代码的第一层,通常是少量且故意写得含糊的 JavaScript,例如字符串拼接、Base64 解码、字符反转。原因是:如果 SVG 里直接放完整攻击代码,文件体积会很大,也容易被安全沙箱的静态扫描识别。所以攻击者习惯只放一个“下载器”,把真正的载荷放在远程服务器上。

下载器拿到远程地址后,会尝试用 fetch、XMLHttpRequest 或者动态插入 img 标签请求等方式,把第二段载荷拉下来。为了躲过代理审计,这段远程地址往往不是直接写死的明文,而是拆成几个片段,在脚本运行到某一步才拼接出来。我在某次事件里看到过地址被倒序处理,脚本执行时再逐段 reverse,就是为了绕开只看字符特征的安全策略。

第二段载荷的落地方式也很有讲究。有的直接是 exe,有的先落一个 zip 压缩包,再用系统自带的解压命令解出来,还有的把载荷伪装成图片文件,实际上是一段可执行代码。落地之后,攻击者会在脚本里调用系统自带的脚本运行器或命令行工具,把这个载荷拉起来。这一步如果成功,恶意程序就以完整权限运行起来了。

2.3 第三阶段:窃密与挖矿组合拳

载荷运行起来之后,攻击者经常同时部署两条收益线。

窃密模块的主要动作,是搜集浏览器保存的账号密码、cookie、本地存储数据,邮件客户端的通讯录和邮件缓存,以及桌面和下载目录里跟财务、合同、账号有关的文档。它还会主动截取屏幕、记录键盘输入,在某些环境下会尝试读取聊天工具的本地数据库。数据会被压缩后发送到攻击者控制的服务器,整个操作通常会在几分钟内完成,因为攻击者清楚,传播时间越短,被发现和阻断的概率越低。

挖矿模块则是长期驻留型。它根据指挥服务器下发的配置,在系统空闲或低负载时段启用 CPU 计算,把算力用来挖加密货币。这样做的好处是,机器平时用起来感觉不到明显卡顿,在任务管理器里也不容易看出异常,顶多就是 CPU 偶尔占用偏高。攻击者把数据窃取和算力榨取放在一个攻击动作里,等于一条攻击链路带来两份收益。

这两个模块还经常互相掩护:窃密模块负责制造流量和网络连接的“噪音”,让安全团队把注意力集中在数据外传上;挖矿模块则通过进程伪装、计划任务注册等方式,在系统里长期存活。

3. 我在样本分析中看到的典型特征

3.1 恶意代码的混淆痕迹

我分析恶意 SVG 样本时,视线第一时间会落在 script 标签的位置和内容上。

最常见的特征,是 script 标签出现在文件中间偏后的位置,而不是视觉图形部分。整份文件在文本编辑器里打开,前面的路径命令都是正常的M、L、C这类矢量绘制指令,突然出现一段与图形无关的 JavaScript,这就是强信号。

另一个特征是代码几乎都经过混淆。我见过用 Base64 套一层、再把字符串倒序的,也见过用字符串数组加索引取值来躲避特征匹配的。还有一类样本会在脚本里反复调用 unescape 或 fromCharCode,把十六进制编码还原成可读代码。这类混淆本身没有太高难度,但对付只看裸字符特征的传统杀毒引擎绰绰有余。

3.2 容易被忽略的“图片加载”细节

有一类 SVG 样本,攻击者给它包了一个看起来完全正常的图形外壳。外壳里的内容经常是公司 logo、快递单样式,或者某个网站的登录界面截图。这份“图片”之所以叫图片,就是因为这部分绘制逻辑写得挺认真。

但外壳底下还藏着别的。比如某些 SVG 会嵌入外部实体引用,也就是 XML 的实体扩展功能。攻击者可以利用这个读取本地文件,比如在浏览器解析时把系统里的某个敏感文本文件内容拼进图片属性里再回传。这就是典型的 XXE 攻击思路。

再比如有些 SVG 用onerror或onload触发脚本后,脚本第一件事不是下载载荷,而是检测运行环境。它会检查当前是否有调试器、是否运行在无头浏览器里、网络请求是否超时。如果环境不对,脚本就直接做图片渲染,啥也不干。这种“环境感知”逻辑,让很多自动化沙箱拿不到后续载荷。

3.3 沙箱检测为何会漏

我见过不止一个安全产品给出的检测结论是“未发现恶意行为”。这不是产品能力不行,而是这类攻击天然挑环境中挑时机。

沙箱里打开 SVG,很常见的情况是沙箱直接拿图片解析库去读取文件,根本不触发浏览器渲染。即使触发了浏览器,如果沙箱不具备网络外联能力,或者攻击者用了“首次访问需要带特定 Cookie 或令牌”的逻辑,真实载荷根本不会响应。

更狡猾的手段是延迟请求。脚本在 SVG 打开后先等几分钟,等沙箱的静态扫描和动态分析基本结束后,才开始外连。有些沙箱的超时判断是 60 秒,攻击者把延迟改成 120 秒,就成功地躲了过去。

这也是我一直在强调的:只看单文件、单次行为,很难完整还原攻击。必须把邮件、文件、进程、网络请求串联起来看,才能发现真正的恶意链路。

4. 企业环境里的检测与防御落地

4.1 邮件网关与客户端的两道关口

把 SVG 附件直接禁止,是成本最低、效果最明显的入口管控方案。

邮件网关里,可以在附件类型策略里增加一条规则:所有 .svg、.svgz 后缀的附件一律拦截,或者在放行前强制转成安全格式。如果业务上确实有接收矢量图的需求,可以让用户通过公司内部的网盘或文档系统传输,不走邮件附件通道。

客户端侧,可以统一调整默认打开方式。SVG 文件的默认打开程序,从浏览器改成纯文本编辑器或一款不执行脚本的图片查看器。这样即便用户手动打开,看到的也是源代码而不是“可执行图片”。虽然这种做法会影响正常的图片预览体验,但对安全目标明确的团队来说,这点牺牲是值得的。

还有一道容易被忽略的关口,是即时通讯工具和内部文件共享。攻击者会通过邮件拿到第一个入口,但同样会用即时通讯把恶意 SVG 传给指定的人。这类通道往往没有邮件网关那么成熟,需要靠终端策略补上。

4.2 终端侧的行为监控策略

终端安全软件能不能拦住这类攻击,关键不在于有没有“查杀 SVG”的特征库,而在于行为监控做得到不到位。

我建议监控这些行为点:

  • 浏览器进程启动后 5 秒内,又拉起一个新的进程,而且这个新进程不是常见子进程,要重点记录。
  • 系统自带的脚本解释器在短时间内从浏览器进程的目录下执行文件,或者从临时目录执行东西,要触发告警。
  • 进程访问冷门域名或 IP,尤其是刚注册不久、无备案、不常见端口号的外联,要记录完整请求。
  • 计划任务新增、启动项写入、注册表自动运行键被改动,这些动作发生在非安装时间的也要关注。

把监控点定在这些行为上,恶意 SVG 的下载和执行链条就能被拆开。攻击者可以藏住文件特征,但藏不住行为特征——他要下载载荷,就要发起网络请求;要执行载荷,就要启动子进程;要持久化,就要写启动项。这三步只要有一步被监控到,就有机会把攻击按死在半路。

4.3 员工安全意识教育的具体切入口

很多安全团队在意识教育上只会说“不要点陌生邮件”“不要打开可疑附件”。这种话讲多了,员工就麻痹了。更有效的做法,是用实际攻击场景做案例复盘。

比如,你可以组织一次内部钓鱼演练,邮件主题就是“本月工资条调整通知”,附件就是一个 SVG 格式的“工资条”。员工点击后,页面跳到一个“密码已过期,请重新认证”的提示。后台记录下点击和输入行为,然后安全团队逐个部门公布结果。这种演练比十次幻灯片宣讲都管用。

在平时,培训里至少要让员工建立两个具体认知:第一,邮件附件如果不是日常固定接收的类型,一定要先看完整文件名,确认扩展名;第二,任何要求“双击打开”“启用内容”“重新认证”的附件,都要先咨询安全团队。把这些话放到具体场景里讲,员工才能真正记住。

5. 应急响应与排查思路

5.1 发现可疑文件后先做什么

如果安全团队收到员工上报,说“打开附件后电脑突然卡顿,风扇转得很快”,先不要急着清理文件,先把现场留好。

第一步,让员工断开网络连接,但不要关机。断网能切断恶意载荷继续下载或外传数据的通道,不关机是为了保留内存里的攻击痕迹。

第二步,把可疑 SVG 文件复制到一个单独的隔离目录,保留原件。随后用文本编辑器打开这个 SVG,重点搜几个关键词:onload、onerror、script、>

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询