Edge 漏洞研究团队对 iOS Chromium 漏洞的研究
2020-12-18 10:13:33 Author: www.4hou.com(查看原文) 阅读量:240 收藏

本文我将快速介绍iOS Chromium浏览器以及WKWebView提供的JavaScript进程间通信(IPC)的潜在攻击面。另外,我还讲讨论在探索此代码区域时发现的一个UXSS漏洞。WKWebView 是苹果在 WWDC 2014 上推出的新一代 webView 组件,用以替代 UIKit 中笨重难用、内存泄漏的 UIWebView。WKWebView 拥有60fps滚动刷新率、和 safari 相同的 JavaScript 引擎等优势。

iOS Chromium浏览器以及WKWebView提供的JavaScript进程间通信(IPC)的潜在攻击面

与Chromium浏览器的桌面版(使用V8作为JavaScript引擎,使用Blink进行渲染和WebAPI支持)不同,iOS版的Chromium没有。实际上,iOS上所有第三方浏览器很可能都使用内置的WKWebView API向其应用程序添加Web支持,Chromium也不例外。原因是iOS平台上的代码签名限制以及Apple不愿意允许开发人员提交启用了动态协同设计权限的应用程序。特别是,此权限允许应用程序映射RWX内存。这个功能将允许实现一个高效的JavaScript引擎,与其让Chromium在平台上遭受性能不佳的困扰,不如像其他浏览器一样使用WKWebView。

IPC

使用WKWebView而不是自己的渲染和JavaScript引擎的一个不幸的副作用是,你不能再对底层代码进行直接修改。这意味着你不能直接向网站公开新的本机功能。 WKWebView API通过WKUserContentController对象对此进行了补救。在创建WKWebView对象期间,可以通过WKWebViewConfiguration对象传递该对象。

该对象不仅可以用于将JavaScript直接注入网页中,还可以通过JavaScript公开本机或目标c代码。这些JavaScript接口通过window.webkit.messageHandlers对象公开,并通过postMessage接口支持调用。在撰写本文时,每个网页都有四个消息处理程序可用,找到这些代码的最简单方法是grep“setScriptMessageHandler”的代码

window.webkit.messageHandlers.FrameBecameAvailable.postMessage(...)
window.webkit.messageHandlers.FrameBecameUnavailable.postMessage(...)
window.webkit.messageHandlers.crwebinvoke.postMessage(...)
window.webkit.messageHandlers.FindElementResultHandler.postMessage(...)

先让我们一起讨论前两个消息处理程序,这些是控制WebFrameImpl对象的创建和销毁的处理程序。该对象的唯一责任是管理浏览器进程与页面内框架之间的IPC通信。在内部,这些对象由WebStateImpl拥有的WebFramesManagerImpl管理。 WebStateImpl对象是代表选项卡的主要对象,在桌面上与之等效的是WebContents对象。

1.jpg

与桌面版的Chromium不同,在Chromium的桌面版本中,诸如RenderFrameHost之类的对象与框架的生命周期完全同步,而WebFrameImpl对象的生命周期则完全由JavaScript控制。如果网页随机调用FrameBecomeAvailable或FrameBecomeUnavailable,则框架可能没有相应的WebFrameImpl对象,或者可能有10个,不过此时我还没有注意到由该API公开并以这种方式使用而引起的任何内存安全问题。

这些处理程序通常通过//ios/web/js_message/resources目录中的代码调用,要创建WebFrameImpl对象,需要以下代码段。

2.png

要销毁一个WebFrameImpl对象,下面的代码片段就足够了。

3.png

在上面的代码段中,销毁框架的WebFrameImpl对象唯一需要的就是其标识符,除主框架的标识符外,这些标识符都是公开的。

这是因为,如果浏览器的本机端要在子框架中执行JavaScript,它将首先通过主框架路由消息。这是通过调用WebFrameImpl :: CallJavaScriptFunction方法来完成的,此方法使用目标框架的加密密钥对函数名称和参数进行加密,然后将对__gCrWeb.message.routeMessage的调用注入到页面的主框架中。然后,接收框架将消息中的目标框架字段与其自身的框架ID相对照。如果不匹配,它将遍历所有子框架并重新发布消息。最终,消息将进入正确的子框架,并且将解密消息并调用所需的函数。之所以子框架的框架ID是公开的,是因为任何子框架都可以安装消息侦听器,并检查通过它传递的消息的目标框架ID字段。

这些routeMessage调用的构建方式与FrameBecameAvailable处理程序中的监督相结合,实际上导致了一个相当严重的漏洞。在将routeMessage调用注入主框架时,使用了以下代码。

4.png

可以看到,脚本是使用格式字符串构建的,该格式字符串使用了WebFrameImpl的encryption_message_json,encrypted_function_json和frame_id_成员。最初,frame_id_成员对你可以提供的名称没有任何限制。因此,子框架可以执行以下代码:

5.png

这将导致创建一个新的WebFrameImpl,其框架ID为foobar'); alert(window ['origin'] +'。创建框架后,浏览器将尝试向其路由消息。会尝试从框架中获取表单信息以进行自动填充,因为将JavaScript注入到主框架中,这将以在主框架中运行的以下代码结尾:

6.png

此漏洞的影响是,它启用了从子框架(例如托管广告的框架)中的UXSS,并允许该框架在托管框架的网页中运行任意JavaScript。不过该漏洞已经进行了修复,该修补程序本身很简单,可以确保框架ID仅包含十六进制数字(0-9和A-F)。

crwebinvoke

crwebinvoke处理程序用于处理绑定到标签的WebState对象的消息,通过调用WebStateImpl :: AddScriptCommandCallBack添加这些处理程序,并且回调本身具有以下签名。

7.png

ScriptCommandCallback senderFrame的第四个参数有趣的是,它完全取决于在消息的crwFrameId字段中传递的ID。再加上子框架的框架ID可能会泄漏的事实,可能会在将来导致漏洞。目前,我还没有注意到此行为引起任何漏洞。值得注意的是,许多回调在执行某些操作之前会执行类似于if(sender_frame->IsMainFrame()的操作。这意味着,如果你可以泄漏表示主机框架ID的128位值,则可以模拟主机框架。幸运的是,我没有注意到执行此操作的任何方法。

就像该接口的一个示例一样,它与任何安全问题都不相关,它是处理window.print调用的代码。

8.png

如果你在网页中执行上述代码,则将打开打印对话框。

crwebinvoke界面提供的另一个功能是从注入的JavaScript调用发送结果的通道,每当通过routeMessage调用方法时,浏览器都会在内部向列表添加回调处理程序。通过发送frameMessaging_

此实现细节的一个潜在问题是,伪造回应所需要的只是发送请求的框架ID和请求的消息ID的知识。事实证明,消息ID最终只是一个32位的递增整数,它来自创建框架时的crwFrameLastReceivedMessageId参数。对于新的框架,这个消息ID从0开始。这意味着任何子框架理论上都可以伪造任何其他子框架的回调。然而,我还没有注意到任何利用子框架消息的问题。

FindElementResultHandler

最后,FindElementResultHandler处理程序负责将被修改的HTML元素通知浏览器。每当修改网页时,浏览器就会在主框架中调用__gCrWeb.findElementAtPoint。当findElementAtPoint检测到所修改的元素位于不同来源的子框架中时,会在子框架上发布一条消息,以便它可以处理通知浏览器的操作。这用于生成长按上下文菜单,并在CRWContextMenuController类中实现。

总结

尽管本文讨论的大多数概念都专门针对基于Chromium的iOS浏览器,但所有WKWebView使用者都可以访问messageHandler功能。在审核基于WKWebView的浏览器时,它是一个很好的第一手资料。MessageHandler是一个抽象类,开发者可以在自己的项目中创建自己的类,继承并实现(重写)MessageHandler中提供的方法。

本文翻译自:https://microsoftedge.github.io/edgevr/posts/Hacking-Chrome-iOS/如若转载,请注明原文地址:


文章来源: https://www.4hou.com/posts/o7qA
如有侵权请联系:admin#unsafe.sh