除了HTML文档,浏览器还可以识别其他若干的文件格式,而这些文件格式,在大多数情况风险比较低,但是在某些时候,会冒出致命的危险,接下来会说的一个最近刚刚曝出的漏洞。
Content-Type: text/plain
除了IE,收到没有头域的HTTP/0.9 或者缺少Content-Type 的响应,默认是处理为纯文本文件,而IE会处理为HTML 文件。同时,大多数浏览器,对若干的MIME 类型,及其各种变种,text/CSS 都映射为纯文本文件,是为了方便开发人员,当然,JSON除外。
在缺少Content-Type 响应头的情况下,会有解析器去检测文档的头部信息,来判断类型。如果包含了Content-Type类型,那么先匹配到MIME 类型,如果无法解析,就会再检测文档头部信息,来确定类型。
而近期曝出的ImageMagick 的0day 漏洞,就是这样一个漏洞,漏洞发生在这款ImageMagick 的图像处理软件,它被广泛用来在网站上进行图像处理,其原理就是,用户上传图像,每个图像会有一个magic bytes,实际上就是文件头,用来表示图像类型,ImageMagick 的功能就是通过解析器,对文件头进行解析,然后进一步处理。
如果我们把一个含有恶意代码的文件保存为文件格式,交给ImageMagick 解析,正常是ImageMagick 无法解析的,当然漏洞就是不正常的时候了,参考如下代码:
|
|
将其保存为jpg 格式等,调用ImageMagick 去处理它,就会触发一个最常见的查看本地文件的漏洞,下面在说一下原因。
ImageMagick 在 MagickCore/constitute.c 的 ReadImage 函数中解析图片,如果图片地址是 https:// 开头的,即调用 InvokeDelegate。MagickCore/delegate.c 定义了委托。作为一个执行命令被引入的,但是,对参数的引入没有做好足够的过滤,造成了渗透的可能,比如一个默认命令是为了处理来自http 请求送来的:
|
|
此处的%M 是真实的输入参数,如果他的值是这样的:
|
|
很显然,由于引号的奇怪闭合方式,这一块恰好满足了bash 的语法,通过一个通道符,我们继续调用了ls -la ,显然,这就引起了注入
|
|
这是基本的原因,实际上的利用漏洞过程通过上传文件,构造exploit, 上文中已经构造了一个文件,他的格式是按照mvg 格式,对于ImageMigick 存在这种漏洞的有两个格式,mvg,和svg,mvg 相对好构造一点。
更进一步的,通过构造exploit ,我们可以删除服务器文件,移动服务器文件,或者是读取服务器文件,其结果,你懂得。
具体参见这个漏洞专门成立的网站Imagetragick, 如今在乌云上,借着这个漏洞,已经提交了无数个0day 漏洞了。
其细节内容,不做过多的深究,对于其安全隐患,也就是是否合理的消除类型错判带来的风险,和上边的图片处理有一点点相似。
另外,作者想了一个很有想象力的情况,如果
浏览器会根据收到的Content-Type 或一些其他线索,为集中特殊的XML 格式提供单一用途的XML 解析器。而绝大部分时候,和XHTML 同一个解析器。在XML 中,
如果没有能够识别的命名空间设定,那么浏览器会默认显示一种树状结构,如果有的话,就按照实际含义进行显示。
但由于这种需要显示未知用途和无法识别命名空间的XML 文档,会带来一定的容错,这种容错,可能导致XSS,比如代理未经过滤的RSS 订阅源,一般来说是有特定的解析器进行处理,但如果没有内置RSS 阅读功能的浏览器,可能会使用最常规的解析模式,而RSS 订阅源中可能存在有HTML 代码,造成XSS 漏洞。
这里所说的一般是SVG,在上一部分的那个例子里,已经探讨过SVG带来的灾难,一个常见的svg 表达方式如下:
|
|
目前该特性已被绝大多数浏览器支持,这里的svg是完成了一个划出圆圈,同时在圆圈中点击会显示提示信息。
对于svg来说,这种格式的图片可以直接放在独立的XML 文档中被访问到,同时也可以放在第三方页面上用< img>引用到,而使用img的话,svg的脚本部分会被完全禁止掉,但是虽然会被禁止,但是还是有危险的,他所在的内置脚本仍然有可能获得图片所在域名的上下文环境权限并且执行,所以如果引入外部来源的svg,就一定要做好非常严谨的语法过滤,上文提到的ImageMagick 漏洞,就是因为在处理图片头的时候,没有做好过滤造成的。
除此之外,还有一些其他类型的文档,比如数学标记语言, XML用户界面语言, 无线标记语言,RSS Atom订阅源 等等。
另外,还有一些不可显示的文件类型,如插件和扩展的安装清单列表,manifests,自动HTTP代理配置歘繁忙PAC,可安装的外观样式,整数撤销列表CRL,反恶意网站黑名单等等。
当需要处理的数据很可能被解析为XHTML 格式,或其他支持脚本的文档类型,不要只去根据Content-Type 响应头和最顶层的xmlns 指令来判断。同时不要再任意位置上允许出现可由用户控制的标记语言。
如果不需要直接访问该文件,可以在响应的响应头加上Content-Disposition:Attachment。
对于非HTML 类型文档,正确识别Content-Type响应头,同时正确设置字符集编码,也很重要。
浏览器插件林林总总,形态各异。简单来讲,一个常见的插件,是讲在浏览器中显示一种新型的文件格式,格式类似于HTML,浏览器得到后交给插件进行处理。
很容易可以想到,浏览器插件的安全漏洞,不仅多,而且千奇百怪,可以说针对Web 应用程序的攻击,与插件占有关系占了很大一部分。
对插件的调用通过几个显式的形式调用:
这里我们要强调的是,在对插件Content-Type 处理时是存在风险的,若干插件实际上有自己完整的代码执行环境,而且这些可执行的应用在于他们所在源站点进行交互时拥有一系列的特权,就很容易出现CSRF 的跨站漏洞。比如已经被启用的< applet>标签,可用于加载java 小程序。GIFAR 漏洞在2008年诞生,就是用一个applet 中加载的java程序,偷偷的隐藏在一个GIF 图片中。
插件的各种应用框架
这其中藏着无数的坑待挖掘,这里只是个小引子~
提供需要让插件处理的文件时:
对于需要嵌入由插件处理的文件,无外乎就是确保type 参数明确,如果无法被识别的话,一定要做出各种限制,任何非信任站点来的东西,都不要随便接收,做好对设置的核查。
开发ActiveX 组件?放弃吧!
由于对浏览器插件这一块不熟,而且感觉这里边有一些有趣的文章可以做,但作者又讲的很少,而且大多数是一些行将就木的过时插件的东西,所以这里我就简短的写了写。
至此,所有关于Web 的东西基本上结束了,回顾整个过程,我们会发现,在Web 中,存在的漏洞一方面是由于本身在协议阶段就存在不科学的地方,另一方面在浏览器等客户端在实现过程中,又由于各自为战,也存在有不统一和各自的缺陷存在,还有一个原因,就是开发者自己在开发中,并不懂自己写出来的代码会带来什么样的困扰,这大概是最可怕的,同时,由于客户端的真正操作者是对程序对代码一窍不通的人,在安全风险上,完全不能依赖他们去提供一点点的阻挡。
所以,一个真正想要构建安全环境的产品,是需要一个团队在整个流程里,能准确把握所有可能造成安全问题的隐患,用最稳妥的方式处理。渗透不可怕,可怕的是每次只有当渗透发生了之后,仅仅明白哪里出错,而不知道为什么会出错,为什么会被黑客抓住。
所以,真正的安全者,是对自己的产品每一块防护措施都了如指掌的人。