原文:https://labs.detectify.com/2018/10/19/xss-using-a-bug-in-safari-and-why-blacklists-are-stupid/
简介
人们在Safari中发现了一个漏洞,攻击者可以利用该漏洞来绕过过滤器,从而发动相应的XSS攻击。
大约一年前,我开始研究某公司名下的资产,因为他们正在开展一项公开的漏洞赏金计划。其中,接近目标的一种方法是查找托管在网站上的纯HTML文件,当然,这些网站未必是利用这种形式搭建的。之所以这么做,是因为这种文件通常会含有DOM-XSS漏洞(相关资料,读者可以访问https://blog.detectify.com/2018/10/04/iframe-busters-lead-to-xss/)。
下面是我无意中找到一个文件(当然,为了简洁起见,这里删除了不必要的代码):
<script type="text/javascript">
var parseQueryString = function parse(queryString) {
*/
parsing
/*
return params;
}
var search = window.location.search;
var query = parseQueryString(search);
var redirect = query.redirect;
redirect = decodeURIComponent(redirect);
var parser = document.createElement('a');
parser.href = redirect;
var protocol = parser.protocol.toLowerCase();
if (['javascript:', 'vbscript:', 'http:', 'https:', 'data:'].indexOf(protocol) < 0) {
window.top.location = redirect;
}
</script>
该页面的作用貌似将访问者重定向到移动应用程序。这里,它会利用redirect参数,来检查相应的协议是否位于黑名单中,如果没有的话,就将访问者重定向到移动应用上面。
为了利用这个漏洞,我们需要创建这样一种连接:它将作为Javascript执行,而它的协议却不是“javascript”。据我所知,根据浏览器的规范,这是不可能的。但是,与所有软件一样,浏览器也并不总是严格遵守规范的。
由于我认为过滤器部分没有什么问题,所以,我就把精力都放到了重定向部分。我们发现,这里用到了.toLowerCase()函数,那么,是否可以找到一些unicode字符,使其转换为小写时,会变成另一个字符呢?如果我们使用换行符对协议进行分隔的话,它可以正常工作吗?
当然,这些尝试都没有成功,此外,我还进行了一些其他方面的尝试,不过也都以失败告终了。但是,所有这些尝试,我都完整地记录到了一个文本文件中,以备将来之用。
将焦点转移到重定向部分
大约半年后,我又一次回顾了这个问题。经过一番思考之后,我决定并重点放到重定向部分,而不是原来关注的过滤器部分。
根据自己的直觉,这次开始鼓捣Safari浏览器。玩过一段时间之后,我发现它对于域和URL的处理方式比较怪异。我觉得,如果有用的漏洞的话,那么,这里就是最有可能找到它们的地方。
我打开控制台,编写了一个简单的函数来模拟各种绕过方法,然后,开始各种尝试。但是,这能行得通吗?
//
是Javaccript中的单行注释符,%0a
是一个URL编码形式的换行符,用于对注释符进行转义处理。从上图可以看出,这里好像没有什么问题。但是,之后……
令我惊讶的是,这次竟然奏效了。当然,这次可能主要归功于我们的运气,但无论如何,这种方法的确奏效!由于黑名单中未指定空协议,因此,它才能绕过过滤器。
最终的有效载荷将是?redirect=javascript://%0aalert(document.domain)
。
我将这个安全问题报告给了使用这个SaaS供应商的一些大型网站。其实,通过将其中一个子域指向该服务的话,它们自身也会受到影响。其中一个受影响的站点联系了该SaaS供应商,该漏洞很快就被上游厂商修复了。同时,Apple公式也收到了该漏洞的相关报告。通常情况下,一切都将结束并被遗忘才对,但这次不是。
引入新漏洞的补丁
这个漏洞很快就被SaaS供应商修复了,这意味着,所有受影响的站点都恢复了安全。但是,该漏洞的补丁似乎破坏了页面的某些功能,这让我觉得,它是一个临时修复方案。之后,我会时不时地浏览这个页面,以期遇到一个永久性的解决方案,但过了一段时间,我就忘记了一切。
几个月后,我收到了一个链接到vpnMentor的文章,文章表明临时修复已被更永久性修复所取代。然而,谁能想到这次又引入了新的XSS漏洞,不过,这个漏洞是由vpnMentor发现的。
漏洞再次回归
最让人感兴趣的是,即使在vpnMentor发现的漏洞得到修复之后,最初的有效载荷仍然有效。我收到了相关文章的链接,因为发件人认为我第一次忘记了提交报告。第二个漏洞修复后,它仍然面临第三个漏洞的威胁,因为我们可使用与第一个报告中相同的有效载荷来发动攻击。
但是,这次不再是纯粹的DOM-XSS漏洞。因为现在Javascript已经不再读取URL参数,而是使用服务器端返回的数据。但是,除此之外,它或多或少仍然以同样的方式工作。
我想强调的是,即使现在存在一些漏洞,受影响的SaaS供应商的响应时间也一直很短并且处理得很好。所有软件都免不了有漏洞。
最新的解决方案
当前,修复第三个漏洞的解决方案是将''和':'添加到黑名单中。当目前为止,我还没有想出绕过它的方法,但这并不代表没有绕过它的方法。
// App redirects only.
if ([ 'javascript:', 'vbscript:', 'http:', 'https:', 'data:', 'ftp:', ':', ' ' ].indexOf(protocol) < 0) {
window.top.location = validate("[injection]");
}
这个函数很可能需要支持许多不同的自定义应用程序协议,这会使得使用白名单(而非黑名单)是不可能的,否则的话,我们强烈建议采用这种方法。
小贴士
当协议漏洞在半年前首次被发现时,苹果公司就接到了相关的通知。但是,在Mac和移动设备上最新版本的Safari浏览器中,该漏洞仍然存在。