0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

使用WebRTC开发Android Messenger的方法解析

LiveVideoStack 来源:CSDN技术社区 作者:CSDN技术社区 2020-09-08 09:35 次阅读

WebRTC是一种开放源代码视频会议解决方案,可用于各种软件。包括浏览器,消息客户端和流媒体服务。虽然Zero Project过去曾报道过WebRTC中的多个BUG,但尚不清楚这些BUG是否可利用,尤其是在浏览器之外的BUG。我调查了流行的Android消息传递应用程序中最近的两个不知能否利用的bug。 The Bugs 我首先尝试利用两个BUG:CVE-2020-6389和CVE-2020-6387。 这两个BUG都在WebRTC的远程传输协议(RTP)的处理中。RTP是WebRTC用于从点对点传输音频和视频内容的协议。RTP支持扩展,扩展是可以包含在每个数据包中的额外数据段,以便告诉目标对等方如何显示或处理数据。例如,存在一个扩展,其中包含有关发送设备的屏幕方向的信息,而其中另一个包含音量级别。这两个BUG都发生在2019年实现的WebRTC的扩展中。 CVE-2020-6389发生在帧标记扩展中,该扩展包含有关如何将视频内容拆分为帧的信息的内容。BUG在于处理层信息的方式:WebRTC仅支持五层,但是层号在扩展中是一个三位字段,这意味着它可以高达七层。这导致在以下代码中写越界。从扩展名中的层号设置temporal_idx。

if (layer_info_it->second[temporal_idx] != -1 && AheadOf(layer_info_it->second[temporal_idx], frame->id.picture_id)) { // Not a newer frame. No subsequent layer info needs update. break; } ... layer_info_it->second[temporal_idx] = frame->id.picture_id;

代码的最后一行是发生越界时写入的地方,因为该数组仅包含五个元素。这个BUG也有一些局限性,虽然从上面的代码中看得不太明显。首先,在写的操作之前先进行检查,检查内存的当前值(转换为16位无符号整数)是否大于当前序列号。仅在为真时才执行写的操作。实际上,这并不是什么限制,当我测试它时,崩溃通常发生在两到三遍之后。一个更为严重的限制是layer_info_it-> second字段具有64位整数类型,而frame-> id.picture_id是16位整数。这意味着尽管此BUG使攻击者可以在固定大小的堆缓冲区之外最多写入三个64位整数,但是可以写入的值非常有限,并且太小而无法表示指针。 CVE-2020-6387是前向纠错(FEC)如何处理视频定时扩展的错误。 FEC复制传入RTP数据包,然后在尝试更正错误时清除某些扩展名。发生此BUG的原因是:在清除视频定时类型的扩展名之前,未验证它们是否具有预期的长度。导致此错误的代码如下:

case RTPExtensionType: { // Nullify 3 last entries: packetization delay and 2 network timestamps. // Each of them is 2 bytes. uint8_t* p = WriteAt(extension.offset) + VideoSendTiming::kPacerExitDeltaOffset; memset( p, 0, 6); break; }

VideoSendTiming :: kPacerExitDeltaOffset的值为7,因此此代码从数据包扩展名的起始位置开始,将在偏移量7到偏移量13之间写入六个零。但是,却不检查扩展数据的长度是否超过13个字节,甚至不检查数据包是否剩下此字节数。该BUG的结果是,攻击者可以在一个可变大小的堆缓冲区最多偏移七个字节的情况下,向堆中写入最多六个零。该BUG在某些方面优于CVE-2020-6389,但在其他方面则更糟。更好的是,可以溢出的堆缓冲区是可变大小的,这提供了更多关于此BUG可以覆盖堆的选项。偏移量还为写入零的位置提供了一定的灵活性,并且写入时也不必对齐。而CVE-2020-6389需要64位对齐。该错误更严重,因为写入的值必须为零,并且可以写入的区域的大小较小(六个字节对24个字节)。 Moving the Instruction Pointer 我首先查看是否有可能使用这些BUG之一来移动指令指针。现代Android使用jemalloc,这是一个平板分配器,它不使用内联堆头,因此破坏堆元数据不是一种选择。相反,我使用符号编译了适用于Android的WebRTC,并将其加载到IDA中。然后,我浏览了可用的对象类型,以查看是否存在明显可用于移动指令指针或改善错误功能的东西。结果,我什么都没找到。 我以为也许我可以使用CVE-2020-6389覆盖长度并导致更大的溢出,但这存在一些问题。首先,该BUG会写入一个64位整数,而很多长度字段都是32位整数,这意味着该写入操作还会覆盖其他内容,并且如果长度是64位对齐的,则只能写入一个非零值。BUG在处理中的位置也是有问题的,因为它会在即将处理的传入数据包的末尾进行覆盖,这意味着在此之后许多对象将不再被访问,因此任何覆盖的内存都将不再使用。 CVE-2020-6389还覆盖了固定大小为80的堆缓冲区,这限制了可能受此错误影响的对象类型。我也不认为CVE-2020-6387可以达到这个目的,因为它只能写零,而这只能使长度变短。 我不确定现在要进行什么操作,所以我在Android上触发了数十次CVE-2020-6389,以查看是否存在超过16位宽的地址崩溃,希望它们能为我提供一些方法在除了覆盖无效的16位值的指针之外,此错误可能会影响代码的行为。令我惊讶的是,它崩溃了,而且指令指针设置为一个值,该值显然已从堆中读取了大约20次。 分析崩溃后,结果发现在溢出区域之后分配了一个StunMessage对象。 StunMessage类的成员如下。

protected: std::vector> attrs_; ... private: ... uint16_t type_; uint16_t length_; std::string transaction_id_; uint32_t reduced_transaction_id_; uint32_t stun_magic_cookie_;


因此,在vtable之后,第一个成员是向量。向量如何在内存中布置?原来它的前两个成员如下。

pointer __begin_; pointer __end_;


这些指针指向内存中向量内容的开头和结尾。在崩溃期间,__end_成员被一个小的16位整数覆盖。向量迭代的工作方式是从__begin_指针开始,然后递增直到达到__end_指针,因此,此更改意味着通常下次在析构函数中对向量进行迭代时,它将超出范围。由于此向量包含StunAttribute类型的虚拟对象,因此它将对每个元素执行虚拟调用,以调用它的析构函数。对越界内存的虚拟调用正是为什么移动指令指针的原因。 除以下的这个问题外,这似乎是控制指令指针的一种合理方法:在典型配置中,WebRTC连接一端的攻击者无法将STUN发送给另一端的用户,而是他们各自与自己的STUN服务器进行通信。我问webrtchacks的Philipp Hancke是否知道某种方法。他建议使用此方法,该方法涉及将攻击者控制的TCP服务器指定为两个对等方(称为ICE候选方)之间潜在的可路由路径。然后,攻击者和目标设备都将通过此服务器进行通信,包括STUN消息。 这使我能够发送具有异常大量属性的STUN消息。这是必要的,因为为了控制指令指针,我将需要能够控制STUN属性向量之后在内存中显示的内容。 jemalloc分配相似大小的分配,这由连续内存运行中的预定义大小类确定。大小类使用的次数越少,相同大小类的两个对象被一个接一个地分配的可能性就越大。 通常,STUN消息具有少量属性,这些属性转换为32或64字节的向量缓冲区大小,它们都是非常常用的大小类。相反,我发送了具有128个属性的STUN消息,这些消息转换为1024字节的向量缓冲区大小,而这恰好是WebRTC中不常用的大小类。通过发送许多具有此数量属性的STUN消息,同时发送大小为1024的RTP数据包,其中包含所需的指针值,并散布着包含BUG的数据包,我能够对该指针值进行约1的虚拟调用五次。这足以在BUG利用中使用,所以我决定继续攻克ASLR。 Breaking ASLR 在此攻击中,有两种可能的方法可以破解ASLR。一种是使用上述BUG之一读取内存,然后以某种方式将其发送回攻击者设备或TCP服务器,另一种是使用某种故障预兆来确定内存布局。 我首先查看是否有可能使用这些BUG之一从目标设备远程中读取内存。马克·布兰德(Mark Brand)建议,可以使用CVE-2020-6387来实现这一点,方法是将指向传出数据的指针的低位字节设置为零,从而导致发送越界数据而不是实际数据。这似乎是一种很有希望的方法,因此我使用IDA寻找潜在的对象。 结果发现有不少,他们都有问题。我花了一些时间在SendPacketMessageData和DataReceivedMessageData上。这些对象用于在队列中存储指向传出RTP数据的指针。它们包含一个CopyOnWriteBuffer对象,并且它的第一个成员是指向rtc :: Buffer对象的引用计数的指针。使用CVE-2020-6387可以将此指针的最低字节设置为零。不幸的是,rtc :: Buffer的结构使以这种方式显示内存具有挑战性。

RefCountedObject vtable; size_t size_; size_t capacity_; std::unique_ptr data_;


我希望有可能使指向该结构的裁剪指针指向堆上的其他对象,该对象在data_指针的位置具有一个指针,而该数据将被发送。但是,事实证明,在发送数据的过程中,上面对象的所有四个成员都可以访问,并且需要合理有效。我遍历了与rtc :: Buffer类相同大小的所有可用对象,但是找不到具有这些确切属性的对象。 然后,我考虑使用一个已经释放的rtc :: Buffer对象,而不是使用其他对象,而使用特定的后备缓冲区大小,可以使用堆操作将其替换为包含指针的对象。这也没有解决。这在很大程度上是可靠性的问题。首先,一个rtc :: Buffer对象是36个字节,这在jemalloc中转换为48个大小类,这意味着分配了48个字节。想象一下这种类型的一些连续分配,地址如下:

0x[...]0000 buffer 0 0x[...]0030 buffer 1 0x[...]0060 buffer 2 0x[...]0090 buffer 3 0x[...]00c0 buffer 4 0x[...]00f0 buffer 5 0x[...]0120 buffer 6 ...


如果该BUG将缓冲区0到5的第一个字节设置为零,则它们将落在有效缓冲区上,但是如果缓冲区6设置为零,则它将不起作用,因为256不会平均分配为48。所以结果是,每次BUG碰到SendPacketMessageData对象时,只有三分之一的机会最终会指向有效的rtc :: Buffer。首先,击中对象也是不可靠的,因为WebRTC正在进行许多其他类似大小的分配。通过使用TCP服务器使连接非常慢,可以增加堆上这些对象的数量和发送它们之前的时间量,但即使这样,我也只能在不到10%的时间内命中结构。必须操纵堆,以便首先在一行中有许多释放的rtc :: Buffer对象,并且支持已被包含指针的东西替换。但这却增加了更多的不可靠性。我最终放弃了这种方法,因为我认为我可能既无法做到足够可靠,也无法通过合理的努力将其用于BUG利用程序中。同样地,被攻击的应用程序的崩溃行为也很重要。这可能可以适用于在崩溃的情况下立即重生的应用程序,但是对于停止重生的应用程序实用性却要差很多,除非存在一定的延迟,而这在Android上很常见。 我还大量研究了WebRTC如何生成传出数据包,尤其是对等端始终发送的远程传输控制协议(RTCP),即使它只是接收音频或视频。但是,大多数传出数据包都是在堆栈上生成的,因此无法使用堆损坏BUG对其进行更改。 我还考虑过使用崩溃Oracle来破解ASLR,但我认为使用这些特定的错误不太可能成功。首先,与它们进行堆分配是不可靠的,因此很难判断是由于特定情况还是仅由于BUG失败而导致崩溃。考虑到这些BUG的功能有限,我还不确定是否有可能创建可检测的条件。 我还考虑过使用CVE-2020-6387更改vtable或函数指针以读取内存,导致崩溃Oracle可以检测到的行为或执行不需要破坏ASLR的基于偏移的利用。我决定不走这条路,因为最终结果将取决于哪些函数和vtables在以零结尾的位置上加载,而这在各个版本之间差异很大。使用此方法编写的BUG利用程序需要进行大量修改才能在WebRTC的稍微不同的版本上运行,并且无法保证它完全可以运行。 我决定在这一点上,我需要寻找可能破坏ASLR的新BUG,因为我最近发现的两个BUG都无法轻易做到。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • Android
    +关注

    关注

    12

    文章

    3935

    浏览量

    127352
  • WebRTC
    +关注

    关注

    0

    文章

    57

    浏览量

    11240

原文标题:使用WebRTC开发Android Messenger:第1部分

文章出处:【微信号:livevideostack,微信公众号:LiveVideoStack】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    谷歌推出Android 16首个开发者预览版

    Android 16 首个开发者预览版现已推出,可用于测试您的应用。此后,Android 会开始增加 API 的发布频次,助力应用和设备的加速创新。
    的头像 发表于 12-18 09:25 219次阅读

    RK3588主板/开发Android12系统APK签名文件生成的方法,干货满满

    本文介绍瑞芯微RK3588主板/开发Android12系统下,APK签名文件生成方法。触觉智能RK3588开发板演示,音视频接口、通信接口等一应俱全,帮助企业提高产品
    的头像 发表于 12-12 10:38 226次阅读
    RK3588主板/<b class='flag-5'>开发</b>板<b class='flag-5'>Android</b>12系统APK签名文件生成的<b class='flag-5'>方法</b>,干货满满

    RTC与WebRTC的主要区别

    在数字通信领域,实时通信(RTC)和WebRTC是两个经常被提及的术语。它们都旨在提供即时的、高质量的通信体验,但它们在实现方式、应用场景和技术支持上有所不同。 1. 定义与起源 1.1 实时通信
    的头像 发表于 12-11 15:41 268次阅读

    android手机上emulate应用程序的方法

    Android手机上模拟(emulate)应用程序的方法通常涉及到使用Android模拟器(Emulator)或类似的工具来模拟Android环境,以便在没有实际物理设备的情况下运行
    的头像 发表于 12-05 15:33 248次阅读

    Android11修改摄像头前后置方法,触觉智能RK3568开发板演示

    本文介绍在Android11系统下,修改摄像头前后置属性的方法。使用触觉智能EVB3568鸿蒙开发板演示,搭载瑞芯微RK3568,四核A55处理器,主频2.0Ghz,1T算力NPU;支持
    的头像 发表于 11-28 18:40 129次阅读
    <b class='flag-5'>Android</b>11修改摄像头前后置<b class='flag-5'>方法</b>,触觉智能RK3568<b class='flag-5'>开发</b>板演示

    Android11修改摄像头前后置方法,触觉智能RK3568开发板演示

    本文介绍在Android11系统下,修改摄像头前后置属性的方法。使用触觉智能EVB3568鸿蒙开发板演示,搭载瑞芯微RK3568,四核A55处理器,主频2.0Ghz,1T算力NPU;支持OpenHarmony5.0及Linux、
    的头像 发表于 11-28 15:25 71次阅读
    <b class='flag-5'>Android</b>11修改摄像头前后置<b class='flag-5'>方法</b>,触觉智能RK3568<b class='flag-5'>开发</b>板演示

    迅为RK3588开发Android系统开发笔记-使用ADB工具

    工具在网盘资料“iTOP-3588 开发板\\\\02_【iTOP-RK3588 开发板】开发资料\\\\ 07_Android 系统开发
    发表于 11-27 10:39

    迅为RK3588开发Android12动态替换开机logo

    迅为RK3588开发Android12动态替换开机logo
    的头像 发表于 11-15 15:04 485次阅读
    迅为RK3588<b class='flag-5'>开发</b>板<b class='flag-5'>Android</b>12动态替换开机logo

    在TI开发板上启用Android Automotive

    电子发烧友网站提供《在TI开发板上启用Android Automotive.pdf》资料免费下载
    发表于 09-18 14:52 0次下载
    在TI<b class='flag-5'>开发</b>板上启用<b class='flag-5'>Android</b> Automotive

    鸿蒙ArkUI-X跨语言调用说明:【平台桥接开发指南(Android)】

    平台桥接用于客户端(ArkUI)和平台(Android或iOS)之间传递消息,即用于ArkUI与平台双向数据传递、ArkUI侧调用平台的方法、平台调用ArkUI侧的方法。本文主要介绍Andro
    的头像 发表于 05-25 16:26 665次阅读
    鸿蒙ArkUI-X跨语言调用说明:【平台桥接<b class='flag-5'>开发</b>指南(<b class='flag-5'>Android</b>)】

    鸿蒙ArkUI-X跨平台开发:【bility开发说明(Android平台)】

    本文介绍将ArkUI框架扩展到Android平台所需要的必要的类及其使用说明,开发者基于OpenHarmony,可复用大部分的应用代码(生命周期等)并可以部署到Android平台,降低跨平台应用
    的头像 发表于 05-21 10:54 950次阅读
    鸿蒙ArkUI-X跨平台<b class='flag-5'>开发</b>:【bility<b class='flag-5'>开发</b>说明(<b class='flag-5'>Android</b>平台)】

    Android 15的首个开发者预览版现已发布

    Android 15 的首个开发者预览版现已发布,以便各位开发者能与我们通力协作,打造更优秀的 Android 平台。
    的头像 发表于 03-12 14:16 913次阅读
    <b class='flag-5'>Android</b> 15的首个<b class='flag-5'>开发</b>者预览版现已发布

    Testin云测国内首发Android 15开发者预览版云真机

    Android 15来了,Testin云测助您快速抢占先机! 目前,谷歌已发布了Android 15的第一个开发者预览版本(Android 15 Developer Preview 1
    的头像 发表于 02-24 09:33 927次阅读
    Testin云测国内首发<b class='flag-5'>Android</b> 15<b class='flag-5'>开发</b>者预览版云真机

    TLT507-Android开发环境搭建

    TLT507-Android开发环境搭建
    的头像 发表于 01-26 17:03 591次阅读
    TLT507-<b class='flag-5'>Android</b><b class='flag-5'>开发</b>环境搭建

    TLT507-Android应用开发手册

    TLT507-Android应用开发手册
    的头像 发表于 01-26 15:32 538次阅读
    TLT507-<b class='flag-5'>Android</b>应用<b class='flag-5'>开发</b>手册