0x01 前言

在上一篇的Edge – 阅读模式下的 SOP 绕过中我们就讨论过阅读模式的SOP绕过了,今天我们继续探索另一个微软Edge的SOP绕过,在滥用data/meta的情况下,domainless页面可以自由访问domained的页面。

如果你不想看这篇文章,你可以看59秒的利用视频Tweeting like Charles Darwin (automatic)和两分钟的Tweeting like Charles Darwin (explained)

如果你是刚刚学习SOP绕过,请先阅读:SOP bypass / UXSS – Adventures in a Domainless World (Edge)SOP bypass / UXSS – More Adventures in a Domainless World (IE),文章以下内容是基于相同的思路,只是另一种新手法。

这里我们先了解一个重要的概念:about:blank页面始终是其引荐来源的domain。这意味着twitter’s iframe的about:blank无法访问google’s的空白页面。即使地址之间匹配(about:blank),document.domain也不同。

以前,我们可以创建about:blanks的domains或者about:blanks的domainless。我们有权限可以访问每个about:blank ,无论其domain是怎样的。例如,假设我们有一个空白domainless在主页面上使一个iframe指向twitter,另一个指向google。那些iframe内有空白的sub-iframes,它们的domains当然是twitter和google。在这样的情况下,top窗口可以访问被控制的空白,着意味着访问google和twitter的DOM

00-domainless-blank-chart

在以前的时候,上述的场景可以完美的运行起来,但是微软在三月前使用了一个技巧来修补了这个漏洞:空白domainless不再是真正的域名,它们始终设置随机GUID作为其domain,就像这样: {53394a4f-8c04-46ab-94af-3ab86ffcfd4c}。但后来有人给我展示了一些更有趣的东西:domain看起来像是blank/empty,但其实不是,也就是说,Edge将隐藏GUID并返回空,但在内部,它仍然是GUID

让我们一起来试试。启用Edge的DevTools enabled(F12),并在地址栏中输入about:blank。这用于创建一个空白的domainless,它可能看起来没有什么变化,但这只是Edge给我们展示的一些小把戏罢了。我们可以慢慢的欣赏它,因为我们又足够的时间来绕过这个问题。

01-about-lies

在这里我们可以看到,DevTools认为我们在一个空白的domain中,但它不是。

0x02 绕过小把戏

如果连DevTools的检测都是这样,我们怎样能看到这究竟发生了什么呢?其实很容易,只要尝试加载任何具有相对路径的文件,或者改变这个窗口的位置,甚至直接document.write就可以揭开这个小把戏了。让我们使用location.href = 1看看会发生什么。

02-real-url

0x03 uri补丁和Flash禁用

我们以前的创建空白domainless的漏洞已经修补了。在这里,我们我们使用Flash/GetURL,在主(top)窗口上设置一个uri数据。但问题关键是补丁已经打上了,而且更糟的是,我们不能自动运行Flash了!在Windows Creators Update上Edge会在执行Flash之前发出请求许可。

看看以前的漏洞,以前文章中的PoCs现在看起来是多么的丑陋啊!如果你和我们一样想减少SOP中的攻击面,你可以和我们联系。

03-enable-flash-madam

0x04 寻找一个新的空白domainless

我们已有的top的data:uri 已经不再起作用了,那我们怎样去克服呢?首先,我现在开始玩iframe而不是top,因为正如我们在以前看到那样,Edge其实不喜欢data:uris在主窗口。

top.location.href = "data:text/html,SOMETHING"; // Fails badly, error page

但是设置一个data:uri作为iframe的位置很好。但是,这不是一个bug,而是在top隔离了iframe domain而已。

04-setting-data-uri

正如我们在SOP阅读器模式中所看到的那样,data:uri“隔离”限制时是微不足道的(只要一个self document.write就可以访问来源了),但我们现在不行这样。访问top现在没有任何意义,我们需要的是获得一个空白domainless的方法。为此,我们需要将它们三合一: data-meta-data。这可以使Edge把我们需要返回的东西返回给我们。

具体来说,我们将使用一个data uri来设置iframe的位置,该data uri会显示重定向到另一个data uri中。那一刻,无论是谁都会在Edge上迷路。

创建空白domainless方法:

  1. 将iframe的位置设置为data:uri
  2. data:uri呈现meta refresh标记
  3. 将meta refresh重定向到另一个data:uri

现在我们来构建一个URL,将一个常规(domained)iframe转换为一个domainless。如果我在我的脑海里不停重复“data-meta-data”,这对我来说更容易,因为在现实中,这就是全部。

05-domainless-recipe

我知道它不如E = mc2那么美丽,但是我们的这个技巧可以用来窃取其他人(包括爱因斯坦)的凭据,电子邮件,paypal账户,甚至用他的名字发短信。让我们先测试一下我们所学到的东西,直到这一点真的有效的被实现了。如果我们会玩bing.com这是很容易的,因为它有一个内部的空白iframe,它不使用XFO

0x05 在bing.com上测试

我们将创建一个带有两个框架的网页:一个是bing.com和一个domainless。在domainless中,我们可以在bing的内部空白iframe中执行代码。Bing imager非常适合我们的测试。你也可以打开Chrome,和我一起来测试。

06-bing-is-easy

这很好,现在我们将借助我们的domainless data-meta-data来构建该页面,并且将代码注入到空白的iframe中。这里我有些话没有说出来,你还记得我们在原始domainless SOP中与nature.com的命名问题吗?如果不记得,你可以先去快速的看一遍。

在这一点上,我们的domainless能够访问bing的空白,但访问机制是非常重要的。我们不能直接访问DOM,我们必须使用window.open方法。换句话说,如果bing位于主页面的第一个iframe中,我们将无法以这种方式访问其内部iframe:

alert(top[0][0].document.cookie); // ACCESS DENIED

我们甚至不能这样做:

top[0][0].location.href = "javascript:alert(document.cookie)"; // ACCESS DENIED

那么我们该怎么办呢?很容易,在一个窗口中打开一个javascript urliframe的名称。如果bing的内部iframe名称是“ INNER_IFRAME ”,以下代码就可以很好的运行了:

window.open("javascript:alert(document.cookie)", "INNER_IFRAME"); // SOP BYPASSED!

但是问题来了!Bing中嵌套的iframe没有名字!不过不用惊慌,我们可以要求Bing团队为我们设置一个名称,或者我们可以继续pushing。继续更好的pushing!

0x06 设置一个iframe名称

我们不能设置我们不拥有的iframe的名称,除非它与我们在同一个domain中。我们要渲染一个内部有空白的iframe。外部iframe位于不同的domain上,但标签本身(元素,对象)位于我们的domain中,因此我们可以设置我们想要的任何名称。

<iframe name="ANY_NAME" src="http://bing.com">
 <iframe src="about:blank"></iframe>
</iframe>

但是内部iframe是通过bing渲染的,即使它是空白的,它的domain仍然是bing.com。更改其名称的唯一方法是首先将其位置设置为我们可以访问的位置,然后才能更改其名称。现在,如果我们想改变about:blank的位置,我们就需要成为bing.com,所以我们以后可以访问空白domainless 。

记住:我们的目标是从空白domainless访问到一个domained。如果我们将domain设置为我们所匹配的,那么访问它是没有意义的!所以这里是我们将要做的是:我们将设置位置,更改iframe名称,然后以这样的方式恢复位置,使其保持原始domain。听起来很复杂?

设置为an x-domain-iframe的名称:

  1. 将iframe的位置设置为about:blank,将其domain更改为我们控制的domain:crack.com.ar
  2. 随意更改iframe名称。
  3. 将其位置重新设置为about:blank,但这次使用一个meta refresh,使得它的domain==它的creator:bing.com在这种情况下。

现在,内部iframe有一个名字,它的域恢复到bing.com!这是代码:

// Sets the location of Bing's inner iframe to about:blank
// But now it is in our domain so we can set a name to it.
window[0][0].location = "about:blank";
 
// Set the inner iframe name to "CHARLES" so we can later inject code
// using a window.open("javascript:[...]","CHARLES");
window[0][0].name = "CHARLES";
 
// Restore Bing's domain to the about:blank that we've just renamed.
window[0][0].document.write('<meta http-equiv="refresh" content="0;url=about:blank">');
window[0][0].document.close();

让我给你一个好消息:我们真的不需要网站“about:blank” iframes,因为我们可以像上面那样做。换句话说,如果bing的内部iframe是about:blank并不是因为我们最终将它设置为空的原始domain!

现在应该可以了。我们可以从我们的data-meta-data iframe中运行window.open

window.open("javascript:alert(document.cookie)", "CHARLES"); // Fireeeeeeeeeee!!!

07-bing-likes-cookies

关于PoC,bug hunter有一个重要事项:在上面的示例中,我们使用http(不安全)连接,因为在https(安全)中,数据的meta refresh被阻止,所以它不会重定向到最终的数据uri。Edge错误地认为重定向是不安全的。然而,这可以通过使用document.write而不是第一个data uri来轻松绕过。所以代替data-meta-data应该是document.write(meta-data)。说得通?

我们没有在上述的PoC中使用它,因为在进行演示交互时(让你按下按钮来运行它)Edge non-exploitable崩溃了三分之一的时间。所以,我选择在http和https中使用自动可控制的和可靠的PoC。但是无论如何,如下所示,它并不重要:我们的不安全(http)空白domainless能够访问安全页面,所以这里我们建立了一个真实的例子。

0x07 真正的攻击:窃取查尔斯(Charles)的cookies

我们这里建立一个假设,查尔斯知道黑客的存在,所以他以十分偏执的模式使用他的电脑:他从来没有打开过他的Gmail,Twitter和个人文档中的跳转链接。

这是他正在任务栏上打开一个新的InPrivate窗口!

08-paranoid-charles

他的心情很好,直到他用Twitter的账号打开了另一个标签,并为阿尔弗雷德·华莱士(Alfred Wallace)提供了一些关于谁先发布的信息。

09-charles-tweeting

几分钟后,华莱士的回应就包括了支持他的声明的证据。但是请记住,查尔斯不信任何人,所以他复制了链接,并将其粘贴到一个新的窗口中,远离他拥有个人数据(gmail,twitter)的窗口。

09-wallace-response

在这里什么可以出现不小心的错误?一切!Twitter有几个iframe,就像世界上大多数网站一样。其实它有两个命名about:blank的iframe,所以这应该比Bing更容易!但在回到我们的故事之前,我们列举twitter的iframe使用DevTools找到一个很好的候选人。我在这里打开一个不同的窗口,与查尔斯会话无关。

10-twitter-enumeration

很好!dm-post-iframe看起来不错,所以我们拥有了我们需要接管查理的帐户。

查尔斯打开了一个新的私人窗口,并加载了华莱士给他的网址。他不知道的是,即使在私人的浏览器窗口,也可以相互通信。那么,如果我们在domainless iframe中执行下面的代码,会发生什么?

window.open("javascript:alert(document.cookie)", "dm-post-iframe");

你是完全正确的,我们现在拥有了查尔斯·达尔文的cookies

11-charles-has-cookies

警告:以上的概念证明只是提醒(仅在你的屏幕上显示)你要注意Twitter Cookie的安全。

请记住,我们真的不需要InPrivate窗口。上面的例子只是说明在一个偏执用户的情景下是怎样发生攻击的,但通常情况下更容易,因为人们点击链接,而不用完成Charles所做的所有工作来防止攻击。此外,考虑到攻击者使用恶意软件,将其坏的位置从流行网站的廉价横幅中部署出来。如果一个攻击者把攻击托管在雅虎横幅内,用户登录到她的Twitter帐户,用户和攻击者之间就不会拥有任何互动,而攻击者就已经拥有了用户的Twitter cookie

0x08 总结

在像查尔斯·达尔文这样的推特中,我们建立了一个更好的PoC。我们将以他的名字发短信,甚至尝试抓住他的密码,而不是阅读他的cookies。其实大多数用户(如查理)都使用自动填写密码的密码管理员。Edge密码管理器没有什么不同,所以如果查尔斯保存了他的密码,我们就可以得到它。这不是很难,只是强迫他注销,登录页面将被自动加载,其所有的数据(用户名和密码)保存到我们的银色的播放器中。事实上,在这种情况下,除非用户进行交互,否则窗体是隐藏的,但是Edge会自动填充它,所以我们甚至不必使窗体可见。

在运行PoC之前,请考虑这是你的帐户,请不要攻击其他人并用于其他非法用途,一切责任请自行负责。如果你没有使用自动填充密码,而是每次都自己输入,请注意你身后是否有人,她可以在一个常规警报对话框中看到你的密码。小心!

我想到的快速问题:
我们可以在网站中使用这个吗?空白iframe? 当然!我们甚至可以在没有iframe的网站上进行。请阅读这两篇文章,在其中注入一个不同来源的iframe。同样在Internet Explorer上的SOP绕过。

在Facebook上可以做同样的事情吗? 我没有Facebook帐户,所以我没有测试。但我相信SOP旁路能够访问地球上的每一个domain ,Period。这可能会有点难度,但请更加努力。

这在其他浏览器中有效吗? 我没有尝试其他浏览器,但显然应该是可以的。UXSS / SOP旁路往往在每个浏览器都存在的。

漏洞利用代码很简单。你可以把它打开看一看,如果你有任何疑问,可以在我的twitter上留言!

祝你今天愉快!

本文存在攻击性,请勿用于非法用途,一切责任请自行负责。

 

*作者:brokenbrowser

源链接

Hacking more

...