SVG在Web攻击中的应用( 二 )


这种方式可以运行任意HTML代码 , 意味着我们可以简单从SVG图像中发起类似钓鱼、绕过同源策略、CSRF之类的攻击 。
XML实体:Billion Laughs Attack
由于SVG是基于XML的矢量图 , 因此可以支持Entity(实体)功能 。Entity可以用来定义特殊字符的快捷方式 , 也可以声明成内部或外部实体 。
我们可以通过如下方式声明内部Entity:
<!ENTITY entity-name "entity-value">通过如下方式声明外部Entity:
<!ENTITY entity-name SYSTEM "URI/URL">如果解析文件的XML解析器存在脆弱性 , 那么我们就可以滥用外部Entity功能来泄露内部数据 。由于现在大家主要使用的都是现代浏览器 , 因此我们假设可用的解析器都经过fuzzer的严格测试 , 因此没那么容易被攻击 。在这个前提下 , 这里我们主要讨论如何滥用内部Entity 。
entity.svg的内部实现如下所示:

SVG在Web攻击中的应用

文章插图
 
图8. entity.svg代码片段
如上图所示 , 我们在第2行定义lab这个Entity , 然后在SVG元素中调用该实体 。结果如图9所示:
SVG在Web攻击中的应用

文章插图
 
图9. lab实体被加载到页面
一切非常顺利 , 来尝试另一个例子:entity_2.svg , 如下图所示:
SVG在Web攻击中的应用

文章插图
 
图10. entity_2.svg代码片段
结果如下:
SVG在Web攻击中的应用

文章插图
 
图11. lab2实体被加载到页面
如上图所示 , 这里的文本内容被重复渲染 , 这表明我们可以使用Entity标签发起“ Billion Laughs ”攻击 。
“ Billion Laughs ”攻击是一种DoS(拒绝服务)攻击 , 目标是XML文档解析器 。这种攻击也被称之为XML炸弹或者指数实体攻击 。
SVG在Web攻击中的应用

文章插图
 
图12. billion_laughs.svg代码片段
我们的浏览器在解析这个 billion_laughs.svg数据时 , 只花了4~5秒就能正常响应 。这是因为大多数现代浏览器已经能够能应付这种攻击 , 可以在渲染过程中解决该问题 , 因此不会造成安全风险 。
拒绝服务:新型SVG “Billion Laughs”攻击
在上一节中 , 我们发现“ Billion Laughs ”攻击可以延缓浏览器的处理速度 , 浏览器需要4~5秒才能应付该攻击 。不幸的是 , 攻击者还可以通过SVG图像 , 发起另一种“ Billion Laughs ”攻击 , 绕过这些防御措施 。
这一次我们使用xlink:href来代替XML Entity 。来看一下 xlink_laughs.svg所使用的payload:
SVG在Web攻击中的应用

文章插图
 
图13. xlink_laughs.svg代码片段
xlink:href属性以IRI(国际资源标识)方式定义了对某个资源的引用 , 该链接的具体含义需根据使用该链接的每个元素的上下文来决定 。
<use>元素从SVG文档中获取节点 , 然后将其复制到其他位置 。
我们现在a0中定义circle元素 , 然后在a1、a2、a3……中通过xlink:href属性调用<use>元素 , 通过这种方式反复克隆circle 。结果如下图所示:
SVG在Web攻击中的应用

文章插图
 
图14. 在解析恶意SVG时 , 通过xlink:href发起“ Billion Laugh”攻击
需要注意的是 , 在最坏的情况下 , 大多数现代浏览器在尝试解析网站上的这张SVG图像时可能会发生崩溃 , 或者至少会出现无响应情况 。
有趣的是 , 我们在测试某些开源SVG/XML过滤器时 , 发现这些过滤器并不能正确捕捉到图13所示的SVG图像 。因此 , 这种错误格式的SVG图像也可能造成DoS效果 。
0x03 总结
SVG图像更像HTML , 而不单单是一张简单的图像 。因此 , 我们建议web开发者尽可能不要以对象或者iframe形式加载任何SVG 。Web管理员同样应当限制可以上传到站点的文件类型 。
此外 , 任何不可信的SVG图像在被上传到服务端前都必须经过过滤处理 , 可以采取如下操作:


推荐阅读