技术讨论 | 如何利用Microsoft Edge漏洞获取本地文件?
作者:admin | 时间:2018-9-11 02:22:12 | 分类:黑客技术 隐藏侧边栏展开侧边栏
在2015年,微软发布了Edge浏览器。当它最初被开发时,它被命名为Project Spartan。
与Internet Explorer不同,Edge支持更为广泛的现代安全措施,如内容安全策略(CSP),以及现代JavaScript和CSS特性。放弃InternetExplorer,转而开发诸如Edge之类的现代浏览器,这带来了浏览器安全性的增强,但也带来了一些潜在的问题。
在类似的新项目开发中,有一件事经常被忽视,那就是从多年来对原有产品的安全修复中吸取经验。有相关工作经验的人应该都会知道,在开发新浏览器的过程中,你的团队最初可能会经历更多的错误。
原因在于,随着新型攻击技术的出现,浏览器的安全性也是一个需要被不断重新开发的过程,因为浏览器被黑客和安全专业人士视为潜在攻击面最为丰富的来源之一。在过去的几年里,一些能够导致浏览器中用户数据遭泄露的安全漏洞已经被修复,开发人员完全可以从中吸取经验,但事实证明,这些经验并没有在新浏览器的开发过程中被运用。
这或许正好可以解释为什么Microsoft Edge是我发现的唯一一个易受此漏洞影响的浏览器。
当然,这里需要提一下,此漏洞目前已经被微软修复。
那些版本受漏洞影响?
我已经在Microsoft Edge 40.15063.0.0上测试了这个漏洞,并取得了成功。
如何窃取本地文件?
首先,我们需要了解,是什么导致我无法窃取到你的本地文件?
我很肯定的告诉你,这是由于浏览器采用了同源策略(SOP)。举个例子来说明一下,同源策略(SOP)会阻止https://attacker.com读取file://C:/your/stuff.txt中的内容,这是因为它们不同源。如果要使用javascript请求读取数据,那么对应的协议、主机名(hostname)和端口都需要匹配。但文件URL有点特殊,file:// protocol和https:// protocol是明显不同的,这也就是为什么攻击者的域名不能读取你的本地文件的原因。
那么,如果我们处理的两个file URL既没有主机名也没有端口(即只有文件协议和路径),结果会是怎样的呢?答案很肯定,两个file URL将被默认来自相同源,因为:
端口匹配:因为没有端口;
主机名匹配:因为没有主机名;
协议匹配:都是file://;
换句话来说,如果浏览器开发人员没有考虑到file://url这种特殊格式,那么在浏览器中打开保存在你的计算机上的恶意HTML文件,我就可以读取任意本地文件中的内容。
当然,你可能会产生质疑:这并不是一个令人信服的攻击向量。因为如果从未下载过任何HTML文件,这种攻击就不会成立。此外,Windows也会阻止此类文件,因为它来自另一台计算机。的确如此,在我测试攻击时就发生过这样的情况。别着急,我们接着往下看。
这是一个真实的威胁吗?还是仅存在于理论上?
你不可否认,攻击者能够以各种方式说服潜在的受害者下载HTML文件并执行它?
由于这些攻击向量的存在,因此这绝不会仅是一个理论上的威胁。如果你不能通过浏览器传播恶意HTML文件,那么为什么不直接通过电子邮件发送给受害者呢?在过去的几年里,我们就已经开始认识到,打开诸如.exe文件、.js文件,甚至是Word文档之类的未知附件都可能使自己置于危险之中,而HTML文件同样也不例外。
我在另一台计算机上伪造了一封电子邮件,将HTML文件添加为附件,然后在“Mail and Calendar”应用中打开附件。我原以为这款应用会像Edge浏览器一样屏蔽附件,但事实并非如此。我将包含恶意附件的电子邮件发送给了测试用户,当该用户打开附件后,许多本地文件被发送到了我的服务器上,而我完全可以在我的服务器上对这些文件进行转储和读取。可能是由于没有杀毒软件将该附件识别为恶意文件,因此我还可以通过HTTPS连接来提取文件,在这种情况下实施的攻击绝对是足够隐秘的。这里顺带提一下,我所使用的“Mail and Calendar”版本为17.8600.40445.0。
需要注意的是,还有很多方式可以用来传播恶意文件,具体取决于目标计算机已安装的应用。
如何保护自己的文件?
保护自己的唯一方法是将Edge浏览器和“Mail and Calendar”应用更新至最新版本。另外,最好永远不要打开任何来自未知发件人的附件,即使扩展名看起来并非恶意的。
PoC视频
PoC代码
<html> <head> <script> let resultDiv = document.getElementById("result"); let xhr= newXMLHttpRequest(); let user =document.location.href.match(/file:\/\/\/C:\/Users\/([a-z0-9\-]*)\//i)[1]; xhr.open("GET",'file://C:/Users/${user}/Desktop/secret.txt"); xhr.onreadystatechange= ()=> { if(xhr.readyState==4) { resultDiv.innerText = xhr.responseText; } } xhr.send(); </script> </head> <body> </body> <div id="result"></div> </html>
*本文作者:Hydralab,转自FreeBuf