当前位置: 首页 > 科技观察

Edge漏洞研究团队对iOSChromium漏洞的研究

时间:2023-03-12 20:13:46 科技观察

本文将快速介绍iOSChromium浏览器的潜在攻击面和WKWebView提供的JavaScript进程间通信(IPC)。此外,我将讨论我在探索该代码区域时发现的一个UXSS漏洞。WKWebView是Apple在WWDC2014上推出的新一代webView组件,用于替代UIKit中笨重、难用、内存泄漏的UIWebView。WKWebView具有60fps滚动刷新率和与Safari相同的JavaScript引擎的优点。iOSChromium浏览器和WKWebView提供的JavaScript进程间通信(IPC)的潜在攻击面与桌面版Chromium浏览器(使用V8作为JavaScript引擎,使用Blink进行渲染和WebAPI支持)不同,而iOS版本的Chromium则没有。事实上,iOS上的所有第三方浏览器很可能都使用内置的WKWebViewAPI为其应用程序添加Web支持,Chromium也不例外。原因是iOS平台上的代码签名限制以及Apple不愿允许开发人员提交启用了动态协同设计权限的应用程序。特别是,此权限允许应用程序映射RWX内存。此功能将允许实现高效的JavaScript引擎,而不是Chromium在平台上表现不佳,WKWebView像其他浏览器一样使用。IPC使用WKWebView而不是你自己的渲染和JavaScript引擎的一个不幸的副作用是你不能再直接修改底层代码。这意味着您不能直接向网站公开新的本机功能。WKWebViewAPI使用WKUserContentController对象补救了这个问题。这可以在创建WKWebView对象期间通过WKWebViewConfiguration对象传递。此对象不仅可用于将JavaScript直接注入网页,还可用于通过JavaScript公开本机或objective-c代码。这些JavaScript接口通过window.webkit.messageHandlers对象暴露出来,支持通过postMessage接口调用。在撰写本文时,每个网页都有四个可用的消息处理程序,找到这些代码的最简单方法是查找“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对象。与Chromium的桌面版本不同,其中RenderFrameHost等对象与框架的生命周期完全同步,WebFrameImpl对象的生命周期完全由JavaScript控制。如果一个网页随机调用FrameBecomeAvailable或FrameBecomeUnavailable,该框架可能没有对应的WebFrameImpl对象,或者可能有10个,但目前我还没有注意到API被暴露并以这种方式使用会导致内存安全问题。这些处理程序通常通过//ios/web/js_message/resources目录中的代码调用。要创建WebFrameImpl对象,需要以下代码片段。要销毁WebFrameImpl对象,以下代码片段就足够了。在上面的代码片段中,唯一需要销毁框架的WebFrameImpl对象的是它的标识符,除了主框架的标识符外,它是公共的。这是因为,如果浏览器的本机端要在子框架中执行JavaScript,它会首先通过主框架路由消息。这是通过调用WebFrameImpl::CallJavaScriptFunction方法完成的,该方法使用目标框架的加密密钥加密函数名称和参数,然后将对__gCrWeb.message.routeMessage的调用注入页面的主框架。然后接收帧将消息中的目标帧字段与它自己的帧ID进行比较。如果不匹配,它会遍历所有子帧并重新发布消息。最终,消息将转到正确的子帧,消息将被解密并调用所需的函数。子框架的框架ID之所以是公开的,是因为任何子框架都可以安装消息侦听器并检查通过它的消息的目标框架ID字段。这些routeMessage调用的构建方式,加上FrameBecameAvailable处理程序中的疏忽,实际上导致了一个相当严重的漏洞。将routeMessage调用注入主框架时使用以下代码。如您所见,脚本是使用格式字符串构建的,该格式字符串使用WebFrameImpl的encrypted_message_json、encrypted_function_json和frame_id_成员。最初,frame_id_成员对您可以提供的名称没有限制。因此子框架可以执行以下代码:这将导致创建一个新的WebFrameImpl,其框架ID为foobar');alert(window['origin']+'。创建框架后,浏览器将尝试将消息路由到它。将尝试从框架中获取表单信息以进行自动填充,因为在主框架中注入了JavaScript,这将结束在主框架中运行以下代码:广告框架)并允许该框架在托管该框架的网页中运行任意JavaScript。然而,该漏洞已经被修补,补丁本身就像确保帧ID仅包含十六进制数字(0-9和A-F)一样简单。crwebinvokecrwebinvoke处理程序用于处理绑定到标签的WebState对象的消息,这些处理程序通过调用WebStateImpl::AddScriptCommandCallBack添加,回调本身具有以下签名。ScriptCommandCallbacksenderFrame的第四个参数的有趣之处在于,它完全取决于消息的crwFrameId字段中传递的ID。这一点,再加上子帧的帧ID可能被泄露的事实,可能会在未来导致漏洞。目前,我还没有注意到这种行为导致的任何漏洞。值得注意的是,很多回调在做某事之前会做一些类似if(sender_frame->IsMainFrame()请注意执行此操作的任何方法。作为接口示例,它与任何安全问题无关,它是处理window.print调用的代码。如果执行上述代码,将打开打印对话框。crwebinvoke接口提供的另一个功能是调用从注入的JavaScript发送结果的通道。每当通过routeMessage调用该方法时,浏览器会在内部向列表添加一个回调处理程序。通过发送frameMessaging_这个实现的潜在问题细节是,伪造响应所需的全部是发送请求的帧ID和请求的消息ID。事实证明,消息ID最终只是一个32位递增整数fromcrwFrameLastReceivedMessageId参数。对于新帧,此消息ID从0开始。这意味着理论上任何子帧都可以伪造任何其他子帧的回调。但是,我没有注意到使用子帧消息的任何问题。FindElementResultHandler最后,FindElementResultHandler处理程序负责通知浏览器已修改的HTML元素。每当修改网页时,浏览器都会在主框架中调用__gCrWeb.findElementAtPoint。当findElementAtPoint检测到修改后的元素位于不同origin的子框架中时,会在子框架上发布一条消息,以便它可以处理通知浏览器该操作。这用于生成长按上下文菜单,并在CRWContextMenuController类中实现。总结尽管本文中讨论的大部分概念都特定于基于Chromium的iOS浏览器,但所有WKWebView消费者都可以访问messageHandler功能。在审查基于WKWebView的浏览器时,这是一个很好的第一手资源。MessageHandler是一个抽象类。开发者可以在自己的项目中创建自己的类,继承和实现(覆盖)MessageHandler中提供的方法。本文翻译自:https://microsoftedge.github.io/edgevr/posts/Hacking-Chrome-iOS/如有转载请注明出处。