图片XSS小结
/最近做题遇到图片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 | <html> |
但是现在只剩gif可以执行XSS了,bmp不行:
SVG XSS
SVG是一种基于XML的图像文件格式。
use元素
SVG中的use元素用于重用其他元素,主要用于联接defs和alike,而我们却用它来引用外部SVG文件中的元素。
元素通过其id被引用,在use标签的xlink:href属性中以’#’井字符开头,外部元素的引用同样如此。
示例如下。
pic.html:
1 | <svg> |
exp.svg:
1 | <svg id="m7" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="100" height="100"> |
.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 | <svg> |
其中base64加密的内容为:
1 | <svg id="m7" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="100" height="100"> |
但只能在Firefox中测试可行,点击黑框后能够成功触发:
无需点击——foreignObject元素
如果在exp.svg中写script标签是不会被解析,但是SVG支持foreignObject元素。
通过阐述这个对象需要的扩展属性,有可能加载非SVG元素。这就意味着现在有可能是有iframe、embed及其他所有支持的HTML元素了,我们可以从一堆元素中进行选择执行Javascript,这里使用embed+JavascriptURL协议。
pic.html:
1 | <svg> |
其中base64加密内容为:
1 | <svg id="m7" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="100" height="100"> |
可以看到,在Firefox下,无需点击即可触发foreignObject标签内embed的JS伪协议执行JS代码从而弹框,同时没有弹框显示1说明了script标签不会被解析:
link XSS
前面利用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 | data:,<文本数据> |