在编写漏洞利用时,我最初通过修改 WebRTC 源码并重新编译,改变了发送到目标设备的 SCTP 数据包。这对于攻击闭源应用并不实用,因此我最终改用 Frida 来 Hook 攻击设备的二进制程序。Frida 的 Hook 功能允许在特定原生函数调用前后执行代码,这使得我的漏洞利用能够修改外发的 SCTP 数据包,并检查传入的数据包。从功能上讲,这与修改攻击客户端的源代码等效,但修改不是在编译时在源代码中进行的,而是在运行时由 Frida 动态完成的。漏洞利用的源代码可在此处获取。
攻击设备需要 Hook 以下七个函数。
usrsctp_conninput // 接收传入的 SCTPDtlsTransport::SendPacket // 发送外发的 SCTPcricket::SctpTransport::SctpTransport // 检测 SCTP 传输何时就绪calculate_crc32c // 计算 SCTP 数据包的校验和sctp_hmac // 执行 HMAC 以猜测密钥sctp_hmac_m // 签名 SCTP 数据包SrtpTransport::ProtectRtp // 抑制 RTP 以减少堆噪声这些函数可以作为符号进行 Hook,也可以作为二进制文件中的偏移量进行 Hook。
此外,还需要目标设备二进制文件中的三个地址偏移量才能使漏洞利用生效。其中两个是系统函数与 malloc 函数之间的偏移量,以及之前文章中描述的小工具(gadget)与 malloc 函数之间的偏移量。这些偏移量位于 libc(Android 系统库)中,因此需要根据目标设备的 Android 版本确定。还需要从 cricket::SctpTransport vtable 的位置到全局偏移表中 malloc 的位置的偏移量。这必须根据正在攻击的应用程序中包含 WebRTC 的二进制文件来确定。
请注意,所提供的漏洞利用脚本有一个严重限制:每次读取内存时,仅当指针的第 31 位被设置时才有效。其原因在第 2 部分中有解释。该漏洞利用脚本提供了一个示例,说明如何使用 FWD_TSN 块修复此问题并读取任意指针,但这并未对每次读取都实现。出于测试目的,我重置了设备,直到 WebRTC 库映射到有利的位置。
通过搜索 Google Play 上的 APK 文件,查找 usrsctp 中的特定字符串,确定了大量集成 WebRTC 的热门 Android 应用。约有 200 个拥有超过 500 万用户的应用似乎使用了 WebRTC。我评估了这些应用,以确定它们是否可能受到漏洞利用中漏洞的影响,以及影响如何。
结果发现,应用使用 WebRTC 的方式多种多样,但可分为四大类。
漏洞利用中所使用漏洞的影响因这些类别而异。投影的风险较低,因为建立 WebRTC 连接需要大量用户交互,并且用户最初即可访问连接的两端,因此入侵另一端几乎无利可图。
流媒体也属于较低风险。虽然某些应用在观看人数较少时可能会使用点对点连接,但它们通常使用一个中间服务器,该服务器终止来自发送方的 WebRTC 连接,并开始与接收方建立新连接。这意味着攻击者通常无法直接向对等方发送格式错误的数据包。即使采用点对点流媒体设置,目标用户也需要交互才能观看流媒体,而且通常无法限制谁可以访问流媒体。因此,使用 WebRTC 的流媒体应用可能不适用于定向攻击。当然,这些漏洞可能会影响流媒体服务所使用的服务器,但本研究未对此进行调查。
浏览器几乎肯定容易受到 WebRTC 中大多数漏洞的影响,因为浏览器允许对 WebRTC 的配置进行大量控制。要在浏览器中利用此类漏洞,攻击者需要设置一个主机,使其像点对点连接中的另一个对等方,并诱使目标访问一个向该主机发起调用的网页。在这种情况下,该漏洞的影响与 JavaScript 中的其他内存损坏漏洞类似。
会议是 WebRTC 风险最高的使用场景,但漏洞的实际影响在很大程度上取决于应用用户之间相互联系的方式。风险最高的设计是,任何用户都可以根据标识符联系到其他任何用户。有些应用要求被叫方与主叫方有特定的交互方式后才能发起呼叫,这使得攻击者更难联系到目标,通常会降低风险。有些应用要求用户输入代码或访问链接才能开始呼叫,这也有类似效果。还有一大类应用很难甚至无法呼叫特定用户,例如随机聊天应用,以及允许用户发起客服呼叫的应用。
在本研究中,我重点关注允许用户联系特定其他用户的会议应用。这使我的 200 个应用列表减少到以下 14 个应用。