该漏洞影响版本在6.2.6,7.1.6,8.0.6 [1] 之前的Apple Safari浏览器,攻击者可以通过精心构造的网址,绕过同源策略任意读取文件。
在Safari浏览器中输入类似http://localhost:12345(该端口应该是没有开放的)的地址,会出现出错页面。在console下输入 window.location.href会显示:
> window.location.href < "file:///Applications/Safari.app/Contents/Resources/"
因此错误页面是通过file URL来呈现的。这本身并没有问题。但是,它允许任意的网页能获得file:// 的窗口的引用。虽然并不能在嵌入的iframe中显示该错误页,但是可以打开一个新的窗口(从而能出现该错误页,当然就需要诱导用户进行点击操作-自动弹出的窗口通常会被拦截),如:
window.onclick = function() { var fileWin = window.open('http://localhost:12345', '_blank'); }
此时变量fileWin就是file://url对应窗口的一个引用。通常情况下,由于同源策略的影响,我们并不能直接向该跨域窗体中注入脚本。而Safari中,一个窗体能访问到跨域窗体的一些受限的属性,包括location,postMessage,和history.如:
> console.log(fileWin.history) < [Object object] > fileWin.history.replaceState({},{},'/'); SecurityError
虽然能够访问到history对象,但我们并不能访问history对象的pushState和replaceState属性,那么使用当前history对象的replaceState并作用于跨域的history对象,会怎样了?
history.replaceState.call(fileWin.history, {}, {}, 'file:///');
因为仅仅是状态改变了,并没有发送新的页面请求,因此并没有显示的变化。重新加载如下:
history.replaceState.call(fileWin.history, {}, {}, 'file:///'); fileWin.location.reload();
重现加载后safari崩溃。崩溃的原因是,Safari在访问文档时会导航到file://URL.Safari对于可以直接使用file://URL进行浏览的file://URL有一个白名单。如果该URL没有在该白名单上,或者不是允许的URL的子目录,浏览器就会崩溃(If the desired URL is not on the list, or is not in a subdirectory of a URL on the list, the browser crashes on an assertion.)
浏览器中通过后退(history.back())操作访问的页面允许是file://url型地址.该特性用于浏览器崩溃后或退出后的修复(修复时这些窗口的history state也会修复)因此可以利用该特性访问用户会话结束前访问过的file://URL页面。
history.replaceState.call(fileWin.history, {}, {}, 'file:///'); fileWin.location = 'about:blank'; fileWin.history.back();
上面的代码会打开一个指向“/”的Finder窗口.由于根目录file:///存在于history中,攻击者可以应用它访问任意有效的file URL。
file://URL下的html文档可以读取文件系统中的任意文件,并可以注入javascript脚本到任意的domains.然而,有一个限制是如果html文件有Apple的Quarantine属性(下载的文件,挂载的文件系统都会自动设置上该属性),该html将允许在沙盒环境下。此时可以利用.webarchive文件 [2] 。
【1】https://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2015-1155
【2】 http://joevennix.com/2013/04/25/Abusing-Safaris-webarchive-file-format.html
【3】http://joevennix.com/2015/06/24/Adventures-in-Browser-Exploitation-Part-II–Safari-8-UXSS.html(翻译文章来源)