小心阅读模式下的猫腻——看看我如何在Edge的阅读模式下绕过SOP

本文讲的是小心阅读模式下的猫腻——看看我如何在Edge的阅读模式下绕过SOP

Microsoft Edge全新的浏览器让人眼前一亮,而阅读模式可以说是其中的亮点之一。不过今天我们并不是要评价它的这个功能,而是要对运行在Edge浏览器 阅读模式下的各种伪协议运行机制进行一个详细的解剖。

要打开阅读模式,可以进入Edge浏览器,点击像一本书一样的图标,即可进入阅读模式:

使用阅读模式,阅读效果会更好一些:

但是,阅读模式页面下的真实地址是什么呢?打开开发者工具(F12)并在控制台中输入 location.href 。从下图可以很明显的看到,此时,Edge浏览器 在 URL 前面添加了 read: 伪协议:

以下我所描述的这些漏洞适用于所有的Edge版本,但本文所提到的PoC则是专门针对Edge浏览器15.0以后的版本而构建的。 如果有人想要15.0以前的旧版本上执行这个POC的话,必须进行相应的修改,以确保在阅读模式下呈现出来。

实际上阅读模式下的网站是一种内部资源

阅读模式下的网页并不是常规阅读模式下的那个网站,如果你按Ctrl+U快捷键来看看源代码的话,你会惊奇的发现,你根本找不到原始页面的任何踪迹,实际上阅读模式下的网站是一个托管在文件系统中的内部资源: 

C:WindowsSystemAppsMicrosoft.MicrosoftEdge_8wekyb3d8bbweAssetsReadingView

Edge浏览器会解析原始网页的内容,删除iframe / scripts及其他html标签,最后将其呈现在内部阅读视图html中托管的iframe中。不过所有这些操作都发生在后台,用户根本就一无所知,当用户切换到阅读模式时,他们会以为这些内容的浏览地址还是停留在刚刚的网站上,因为他们并没有对网址进行过改动。

但如果在Edge浏览器的原始URL之前设置“read:”协议,然后再在阅读模式下呈现网页的话,我还可以利用脚本来执行吗? 我可以自动在阅读模式下随意加载网址吗?

随意强制一个网站进入阅读模式

我们来看看是否可以通过前置read:协议来强制把任意的URL从正常阅读模式切换为阅读模式:

location.href = "read:http://www.cracking.com.ar"; // prepending read: does the trick

虽然这种做法的效果非常好,但仍有一些进程引起了我的注意,比如虽然地址栏中的URL是crack.com.ar,但切换到阅读模式后,URL却是brokenbrowser.com。这是怎么发生的呢?

于是我试着检测了一下crack.com.ar,如下图所示,我看到看到 location.replace 将其跳转到了brokenbrowser.com,但Edge浏览器却并没有更新地址栏! 

所以我总结的第一个漏洞便是:当脚本或 http 重定向发生时,Edge并不会更新地址栏:

寻找一个重定向

以上的操作意味着我们可以利用重定向这个机会把阅读模式下的网站伪装成任意网站,甚至可以对所有重定向到我们控制之下的网站进行伪装,反正用户在阅读模式下的视觉呈现效果不会发生什么变化。 例如,如果我可以把google.com重定向为一个恶意的页面,但用户还会认为他们的阅读内容来自谷歌,实际上它是来自evil.com。

另外,考虑到所有搜索结果都是重定向至目标的形式,所以伪装成google进行重定向并不是不会很难。 例如,google从crack.com.ar索引了一个 “crack-01.html” 页面,如果能找到重定向到“crack-01.html”页面的原始链接的话,那操作就轻而易举了,因为这是我自己的服务器,所以可以任意修改它。不信,你可以打开Chrome,找到一个重定向到crack.com.ar服务器的链接。 

不过请注意:由于你的目标是找到一个重定向到crack.com.ar的google URL,所以该网站正好处于我的控制之中:

在阅读模式下重定向

现在,我已经有一个重定向到crack.com.ar的google.com.ar的 URL了,下面,我要做的就是在crack.com.ar中的网页中写一些文字,例如“该网站是伪装的Google网站”等类似的提醒语句,这样我就可以很容易地确定阅读模式下看到的内容的真正网址了。 以下是前置了read: 伪协议的google重定向,在Edge浏览器中打开时的界面如下所示: 

read:https://www.google.com.ar/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&cad=rja&uact=8&ved=0ahUKEwiRx_eksaTTAhURl5AKHcrxCuoQFgggMAA&url=http%3A%2F%2Fwww.cracking.com.ar%2Fcracking-01.html&usg=AFQjCNGa3PACMDlI6RdBOnoEfySVh1C2ZQ

从上图可以看出,虽然伪装的网页非常成功,但别忘了,我们是在阅读模式下完成的这些。这也就意味着我还没有完全控制页面的阅读形式的呈现外观。因为在呈现页面之前,Edge浏览器还会删除大量的HTML内容。例如,iframe 和 script 都会被删除,并且JavaScript链接的进程也被停止了。那么,我该如何自定义这个页面并删掉后面的淡黄色背景呢?又怎么在其中运行脚本呢?

在阅读模式下运行脚本

处于阅读模式下,Edge浏览器会尽力把所有呈现出的内容都保持成静态的,即不允许任何脚本,连iframe等也会被删除。也就是说,阅读模式下的内容最终要像一本书那样静静的呈现出来,而不是向网页那样动态变化。下面我就将试着处理保持这种静态阅读模式的一些障碍。

我先手动测试了几个html标签,比如iframe / script / meta,但是它们都会被删除。然后,我尝试了一下object/html标签,令我惊讶的是,这两个标签竟可以正常运行,看来事情比我想象的要更容易一些,object/html 标签类似 iframe :,它们都是可以运行 script 的 html 容器 。

所以我总结的第二个漏洞便是:当在阅读模式下呈现页面时, Edge浏览器并不会删除object/html标签。

所以,如果我在crack.com.ar中的页面中添加一个object/html 标签,然后触发一个提示的话,那么一切看起来就顺其自然了:

<!-- prompt.html does a window.prompt with the hard coded "google.com needs..." message --><object data="http://www.cracking.com.ar/prompt.html"></object>

现在,Edge浏览器会认为所阅读的网页源自google.com.ar,事实上,它是源自crack.com.ar,因为object/html是源自crack.com.ar。但问题是,虽然我可以触发提示或警报提示,但我还是无法访问真正的网站。

假设我要将网站的背景颜色便为白色或使用其它更有说服力的攻击手段,就需要绕过SOP或设置网站顶部的 URL,而不更改地址栏。下面,就让我来尝试SOP 绕过吧!

浏览器有一个很重要的概念——同源策略(Same-Origin Policy,SOP)。所谓同源是指,域名,协议,端口相同。不同源的客户端脚本(javascript、ActionScript)在没明确授权的情况下,不能读写对方的资源。

简单的来说,浏览器允许包含在页面A的脚本访问第二个页面B的数据资源,这一切是建立在A和B页面是同源的基础上。

如果Web世界没有同源策略,当你登录嘶吼的官网并打开另一个站点时,这个站点上的JavaScript可以跨域读取你的嘶吼账号数据,这样整个Web世界就无隐私可言了。

寻求父页面的相匹配

如何让顶部的域来呈现任意 html 代码,以实现对真实网页的访问?也许data uri 是个不错的选择。与在 cracking.com.ar 上托管的内容不同,在 data uri中呈现html,如下所示:

 <!-- object rendering a data uri --><object data="data:,<script>alert(top.location)</script>"></object><!-- ACCESS DENIED data uris have their own unique origin -->

不过事情没那么简单,因为Edge浏览器不允许我利用data uri访问任何其他文档。所有浏览器都把data uris当作不同于其创建者的独立源进行处理,但在Edge浏览器上,这个限制却很容易被绕过。页面加载后,仅仅使用一个self-document.write就足以匹配父页面的域了。

所以我总结的第三个漏洞便是:在data: uris中,可以通过document.write设置源,使其与其父页面相匹配:

<object data="data:,<script>window.onload = function(){ // Executing a document.write in a data uri after the onload  // changes the location of the object to its parent URL.  document.write('<script>alert(top.location.href)</script>');  document.close();}</script>"></object><!-- Now we have the same location as our top -->

现在我已经成功绕过SOP,让我们来看看能否 访问真正 的Google 的顶级域名?现在,我完全可以在不用改变任何设置的情况下,访问阅读模式状态下的内部 html 代码了,用 top.document.write 即可把淡黄色的背景改为白色的了。

<object data="data:,<script>window.onload = function(){  document.write(    '<script>'+        'top.document.write('Trust me, we are on Google =)');'+        'top.document.close()'+    '</script>');  document.close();}</script>"></object>

本文的技术手段如果要总结成一句话,那就是利用Edge浏览器的阅读模式(read: 伪协议)实现地址栏欺骗,然后进一步利用 <object data:> 实现完整的页面伪造。

原文发布时间为:2017年4月21日

本文作者:xiaohui 

本文来自合作伙伴嘶吼,了解相关信息可以关注嘶吼网站。

原文链接

时间: 2025-01-30 10:38:34

小心阅读模式下的猫腻——看看我如何在Edge的阅读模式下绕过SOP的相关文章

用好Edge的阅读模式

  Windows 10其全新的Edge浏览器让人眼前一亮,而阅读模式可以说是其中的亮点之一.Edge浏览器的阅读模式功能默认就处于地址栏的后面,并不需要什么特别的操作即已激活(图3).但如果用户想对阅读模式进行调整以适应自己习惯的话,那么就点击右上角的"更多操作"按钮,在弹出的菜单里面点击"设置"命令.然抈在"阅读视图风格"和"阅读视图字号"选项中,就可以分别对背景和字体大小等进行设置操作了. Edge中也有一个类似于Poc

如何在Safari的阅读视图中开启夜间模式?

  在 iOS 9 之前苹果自带的 Safari 是不支持夜间模式的,那么如何在 iOS 9 的设备中开启 Safari 的夜间模式呢?下面小编就给大家介绍一下如何在Safari的阅读视图中开启夜间模式的方法. 1.打开你要在 Safari 中阅读的文章 2.如果该网页支持阅读视图模式,有一个多条横线的按钮会出现在 Safari 地址栏的左侧,点击它 3.现在你就进入了 Safari 的阅读视图模式(阅读视图模式简化了网页,隐藏了不必要展示的内容,例如广告.侧边栏项目) 4.点击地址栏右侧的 A

linux 环境下 isap 环境如何搭建 (开发 语言 java ,b/s模式)

问题描述 linux环境下isap环境如何搭建(开发语言java,b/s模式)谢了 解决方案 解决方案二:该回复于2011-04-19 15:05:21被版主删除

PHP 命令行模式实战之cli+mysql 模拟队列批量发送邮件(在Linux环境下PHP 异步执行脚本发送事件通知消息实际案例)

源码地址:https://github.com/Tinywan/PHP_Experience 测试环境配置: 环境:Windows 7系统 .PHP7.0.Apache服务器 PHP框架:ThinkPHP框架(3.2) Redis数据库:测试数据回调函数:通过一个Redis的自增incr来测试异步脚本执行的次数和访问的时间(平时都是用Redis测试写日志的) 编辑器:Visual Studio Code (CLI运行环境好看点) PHP 的命令行模式       从版本 4.3.0 开始,PHP

三星Galaxy S6 edge私密模式是什么?S6私密模式怎么使用?

三星Galaxy S6 edge开启私密模式 1. 在待机页面下,点击[应用程序].    2. 点击[设定].    3. 向上滑动屏幕,选择[私密模式].    4. 根据私密模式向导提示内容,点击[下一步].    5. 阅读私密模式免责声明后,点击[下一步].    6. 阅读"使用私密模式" 所适用的应用程序提示后,点击[下一步].      7. 点击[开始].    8. 选择一种私密模式访问类型,这里以点击[PIN码]为例.    9. 输入要设置的PIN码,然后点击[

Android下拉刷新完全解析,教你如何一分钟实现下拉刷新功能

以下是我自己花功夫编写了一种非常简单的下拉刷新实现方案,现在拿出来和大家分享一下.相信在阅读完本篇文章之后,大家都可以在自己的项目中一分钟引入下拉刷新功能   最近项目中需要用到ListView下拉刷新的功能,一开始想图省事,在网上直接找一个现成的,可是尝试了网上多个版本的下拉刷新之后发现效果都不 怎么理想.有些是因为功能不完整或有Bug,有些是因为使用起来太复杂,十全十美的还真没找到.因此我也是放弃了在网上找现成代码的想法,自己花功夫编写 了一种非常简单的下拉刷新实现方案,现在拿出来和大家分享

ServiceLoader服务提供者模式,实现动态插件加载,类责任链模式

Edit ServiceLoader服务提供者模式,实现动态插件加载,类责任链模式 ServiceLoader的功能比ClassLoader简单,它可以帮我们获取所有实现了某接口或基类的类.当然前提是ClassLoader已经加载过的类.举个例子: 定义一个接口: public interface IService { public String sayHello(); public String getScheme(); } 以及两个实现类: public class HDFSService

企业公众服务号微信红包编程是否要进入开发者模式,如果消息推送 给了别的服务器 开发模式关闭怎么办?

问题描述 企业公众服务号微信红包编程是否要进入开发者模式,如果消息推送 给了别的服务器 开发模式关闭怎么办? 企业公众服务号微信红包编程是否要进入开发者模式,如果消息推送 给了别的服务器 开发模式关闭怎么办? 解决方案 公众号,如果想要响应外部程序调用,就必须使用开发者模式 消息推送给别的服务器?我没完全弄明白你的意思. 你的程序,如果需要调用公众号的接口,必须要在该公众号中填写程序所在服务器的URL.KEY和TOKEN, 当程序调用的时候,公众号会根据这些信息来响应,通过接口推送的信息,只会出

ActiveX(已经花钱签过名)在XP系统下IE6中使用一切正常,但是在vista系统下IE7中不能使用

问题描述 ActiveX(已经花钱签过名)在XP系统下IE6中使用一切正常,但是在vista系统下IE7中不能正常使用,发现只要在IE属性中关了保护模式就行了,但是不可能要求来访用户关保护模式阿,怎么办?(知道问题很难,但是真的只有最后二十分了,请帮帮忙) 解决方案 解决方案二:虽然偶不懂,但貌似这个问题很难.IE7比IE6的安全性提高了很多,所以你要不让用户关一下,要不,绕过去.....解决方案三:activex问题,只能要求用户自己来设定许可了如果不用设定,那就是病毒了(莫非你是3721的?