【技术分享】利用多语种JPEGs文件绕过内容安全策略(CSP)
转载自:http://bobao.360.cn/learning/detail/3261.html
翻译:WisFree
预估稿费:140RMB(不服你也来投稿啊!)
投稿方式:发送邮件至linwei#360.cn,或登陆网页版在线投稿
前言
研究表明,如果某个网站使用同一域名下的主机来托管用户上传的图片文件,那么我们就可以通过构建多语言JavaScript/JPEG来绕过网站的内容安全策略(CSP)了。
技术实现-【PoC传送门】
首先,我们要分析一下JPEG的格式。前四个字节是一个有效的非ASCII JavaScript变量0xFF 0xD8 0xFF 0xE0。接下来的两个字节代表的是JPEG头的长度。我们可以从下面给出的信息中看到,JPEG头的长度为0x2F2A,如果我们可以把“0x2F2A”改成0x2F 0x2A的话,你可能会觉得此时我们便得到了一个非ASCII变量,之后的数据全部都变成了JavaScript的代码注释。接下来,用空值(00)填充JPEG头剩下的部分。
在JPEG文字注释中,我们可以闭合其中的JavaScript注释,然后为我们的非ASCII JavaScript变量赋值,即提供我们的Payload。然后在JPEG注释的底部再创建另外的多行注释。
0xFF 0xFE为注释头(comment header),0x00 0x1C代表注释的长度,剩下的数据即为我们的JavaScript Payload(*/=("Burp rocks.")/*)。
接下来,我们需要闭合JavaScript的注释,然后再对图片数据的最后四个字节进行编辑,其中的0xFF 0xD9是图像标记的结尾。文件结尾处的数据如下所示:
这就是我们的多语种JPEG了,虽然它也有一些不完善的地方。如果你没有指定字符集的话,它还是可以正常工作的。但是在火狐浏览器中,如果你指定要使用UTF-8字符集的话,那么浏览器在执行脚本代码的时候将会发生崩溃。所以,为了保证脚本能够正常运行,你需要在脚本标签中指定所用的字符集为ISO-8859-1。需要注意的是,我们的多语种JPEG可以在Safari、火狐浏览器、Edge、以及IE浏览器上运行,而谷歌的Chrome浏览器并不会将JPEG文件当作JavaScript脚本来运行。
点击【这里】获取这份多语种JPEG图片。
用于执行这个图片文件的JavaScript代码如下所示:
1
|
<script charset= "ISO-8859-1" src= "http://portswigger-labs.net/polyglot/jpeg/xss.jpg" ></script> |
文件大小限制
我曾尝试将这个图片文件作为phpBB账号的头像来上传,但是我发现这个论坛网站对上传的文件有限制:其支持的上传文件大小最大仅为6K,图片尺寸最大为90x90。所以我通过裁剪缩小了这个JPEG图片的尺寸,但是我要怎么才能减少这个JPEG文件中的数据量呢?我发现在JPEG头中,我使用了“/*”,其十六进制为0x2F和0x2A,合起来就是0x2F2A,其代表的长度为12074。这样一来,这部分数据就占用太多空间了,导致我们的JPEG图片大小超过了网站的上传限制。所以我打算查找一下ACSII码表,看看能否找到一些可用的字符组合来减少不必要的数据,并且保持JPEG稳健的有效性。
我所能找到的最小的值为0x9(制表符)和0x3A(冒号),合起来的十六进制值为0x093A(2362),这样就可以大大降低了我们这份文件所占的大小。接下来,创建一个有效的非ASCII JavaScript标签,然后使用JFIF标识符来声明一个变量。最后,我在JFIF标识符的结尾处填充了一个正斜杠“/”(0x2F),并用它来代替原来的空字符(NULL),然后用一个星号来作为版本号。结果如下图所示:
接下来,将我们JPEG头的数据补充完整,然后填充空值(NULL),最后注入我们的JavaScript Payload。结果如下图所示:
点击【这里】获取这个小尺寸的多语种JPEG图片。
影响
如果你允许用户上传JPEG格式的文件,而这些上传的文件保存在与你Web应用相同的域名主机之下,那么任何人都可以使用一个多语种JPEG文件(其中注入有恶意的JavaScript脚本代码)来绕过你的内容安全策略(CSP),并实施攻击。
总结
总的来说,如果你允许用户向你的网站上传JPEG文件(或者任意类型的文件),那么你最好将这些文件保存在其他域名的主机之中。在验证JPEG文件时,你应该重写其JPEG头,然后移除其中所有的JPEG注释,以此来保证其中没有参杂恶意代码。很明显,你还要重新审查一下你所部属的内容安全策略,确保用于保存这些上传文件的域名不允许执行JavaScript脚本。
如果没有Ange Albertini的帮助,我也不可能完成这篇文章,因为我在创建这个多语种JPEG的时候,一直在参考他的这个JPEG格式结构介绍图【传送门】。除此之外,我也参考了Jasvir Nagra那篇关于多语种GIF的博客文章【传送门】。
更新
Mozilla已经在火狐浏览器v51版本中修复了这个问题。
本文由 安全客 翻译,转载请注明“转自安全客”,并附上链接。
原文链接:http://blog.portswigger.net/2016/12/bypassing-csp-using-polyglot-jpegs.html
作者:ssooking 联系邮箱:c3Nvb2tpbmdAeWVhaC5uZXQ=
若无特殊说明,所发博文皆为原创,转载请务必注明出处、保留原文地址。欢迎交流分享!如果您有任何问题,请联系我!