59

看我如何发现Chrome浏览器阅读辅助插件SOP绕过漏洞

 5 years ago
source link: http://www.10tiao.com/html/291/201806/2651069847/2.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

本文讲述的是作者发现谷歌浏览器Chrome阅读辅助插件(Read&Write Chrome extension)1.8.0.139版本同源策略(SOP)绕过漏洞的过程。该漏洞在于Read&Write插件缺少对正常交互网页请求源的安全检查,导致任意网页都可以调用Read&Write插件的后台特权页面API来执行多种存在风险的操作。由于该版本插件的在线下载使用量较大,在漏洞上报前估计有八百万用户受到影响。

漏洞介绍

比如,利用名为 “thGetVoices”方法的后台API调用方式,可以用插件执行一个任意URL链接的检索,并用postMessage方式来进行响应通信。通过这种方式的API恶意调用,攻击者可以劫持Read&Write插件去读取一些恶意且未经验证的会话数据。

作为验证,作者在文末制作了一个漏洞利用PoC视频,在安装了存在该漏洞的Read&Write插件之后,在进行应用操作时,可以利用漏洞远程读取到用户的Gmail邮箱地址信息。在漏洞上报之后,Read&Write插件开发方Texthelp公司迅速修复了漏洞,并于第二天释出了更新补丁。目前,新版本的Read&Write插件已不存在该漏洞。

漏洞分析

Chrome的Read&Write插件利用名为“inject.js”的Google浏览器内置脚本(Content Script)来向诸如Google Docs在内的各种在线文档页面插入一个自定义工具栏,以方便读者用户可以利用该插件进行文档读写。默认情况下,此脚本将会向所有HTTP和HTTPS源执行插入,插件的使用说明中已定义了这一点:

在 “inject.js” 脚本文件中,存在一个事件监听函数addEventListener,任何被插入 “inject.js” 脚本文件的交互网页,如果以“postMessage”方式向插件发送响应消息,都能被该函数捕获到:

window.addEventListener(“message”, this.onMessage)

这个addEventListener函数还会调用另一个名为“this.onMessage”的函数,该函数用于处理任意发往页面窗口的postMessage消息:

postMessage() 方法:window.postMessage() 方法可以安全地实现跨源通信。通常,对于两个不同页面的脚本需要具备同源策略才能通信。window.postMessage() 方法被调用时,会在所有页面脚本执行完毕之后(e.g., 在该方法之后设置的事件、之前设置的timeout 事件,etc.)向目标窗口派发一个 MessageEvent 消息。 该MessageEvent消息有四个属性需要注意: message 属性表示该message 的类型; data 属性为 window.postMessage 的第一个参数;origin 属性表示调用window.postMessage() 方法时调用页面的当前状态; source 属性记录调用 window.postMessage() 方法的窗口信息。

在上述代码中,可以看到onMessage()会把所有接收到的postMessage消息通过“chrome.extension.sendRequest”方法发送到Read&Write插件的后台页面。另外,对这些消息的响应将传递回onMessage()函数,然后再通过其传递回Web页面中去。这个过程,实际上就在正常的Web访问页面和Read&Write插件后面之间形成了一个代理机制。

从Read&Write插件的使用说明中,可以发现Read&Write插件中存在很多后台页面:

虽然存在以上这么多后台页面进行消息侦听和函数调用,我们选取其中一个可漏洞利用的即可,我们就来看看页面 “background.js”吧:

上述代码显示,“chrome.extension.onRequest” .addListener监听器被触发时,其内部的“method” 参数会被设置成“thGetVoices”,“type”参数则被设置为“1757FROM_PAGERW4G”。如果这个触发事件中的“payload.refresh”参数为“true” ,则其中的XMLHTTPRequest会被请求响应为代号为200的状态码。

漏洞利用

利用上述方式的恶意调用,我们能向Read&Write插件的后台页面发送一个带有任意URL链接的消息,该消息最终会通过HTTP方式进行响应,这样,我们就能通过这种方式读取用户cookie信息,从而也可利用任意网页加载Payload去窃取其它不同Web源中的用户内容。以下就是一个跨域的信息窃取Payload:

上述Payload代码显示,可以利用该漏洞去读取跨域响应信息。这种情况下,我们用Gmail的 “Simple HTML”服务 来作示例。整个的漏洞利用方法就比较简单直接了:把上面这个Payload代码托管在任意网站上,安装了存在该漏洞的Read&Write插件用户,只要登录进入Gmail邮箱,我就可以用上述Payload来读取到用户的相关Gmail邮箱内信息。整个过程是通过之前我们说明的,以恰当的Payload设置形成postMessage消息,并结合消息响应的事件监听方式来实现的。由于Read&Write插件会向所有HTTP和HTTPS的Web页面执行应用插入,所以,在 JavaScript Promises 异步编程方式下,可以通过“exploit_get()”函数能窃取到用户经过认证的任意访问过的页面数据信息(这里假设无需特殊Header标头,能通过HTTP GET方式进行访问的页面)

Promise :是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强大。所谓Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。从语法上说,Promise 是一个对象,从它可以获取异步操作的消息。Promise 提供统一的 API,各种异步操作都可以用同样的方法进行处理。目前,Promise 已获得 JavaScript 的原生支持,能很好兼容JavaScript编程应用。

虽然上面的示例引用了“thGetVoices”后台方法调用,但这只是这些后台页面API调用时出现的一种漏洞利用方式。除了使用这种调用之外,还存在其它一些可以利用的漏洞方法:

如攻击者还能利用 “thExtBGAjaxRequest” 方法,结合参数来执行“application/x-www-form-urlencoded;charset=UTF-8” 这类型任意的POST请求,并读取消息响应内容

还有,攻击者也能利用 “OpenTab”方法来打开大量网页标签来限制用户的Web页面访问

POC验证视频如下:

漏洞原因&缓解措施

该漏洞为一种常见浏览器插件安全隐患,谷歌的 Chrome 浏览器为了更方便地与插件API之间进行通信交互,插件在功能上就无形在自身后台服务和正常访问的Web页面之间形成了一条代理通道,主要原因在于很多 Chrome 插件开发者在开发阶段,缺乏对潜在敏感功能的调用请求源进行安全检查。这种情况下,一种理想的解决方法就是把大部份逻辑处理操作放到Content Script中去,不用postMessage方式调用,而由事件侦听函数按照API isTrusted属性的适当验证来进行触发。这样可以确保所有调用都是由用户操作触发的,而不是攻击者伪造的。

漏洞上报进程

2018.6.3晚 向Texthelp上报漏洞

2018.6.3晚 Texthelp确认漏洞 回应称修复工作将于下周周一开始

2018.6.4 Texthelp推出修复补丁

由于时区原因,时间上可能有些出入,Texthelp在爱尔兰的开发团队其实在6月2号就收到漏洞,然后在6月3号就修复了漏洞。只是补丁在6月4号释出,整个漏洞响应修复周期非常及时。

*参考来源:thehackerblog,FreeBuf 小编 clouds 编译,转载请注明来自 FreeBuf.COM


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK