起点开始 发表于 2015-7-25 18:31

iPhone蓝屏0day漏洞分析:播放视频触发内核拒绝服务

作者:360的iOS研究团队Nirvan Team

  近期发现有人会在微信群中分享视频链接,当使用苹果设备的用户点击这个视频链接播放视频时会造成苹果设备重启。发现这个问题后,360NirvanTeam核心成员@Proteas第一时间拿到样本进行分析,在非越狱iPhone设备iOS 8.0.2、 iOS 8.4、iOS 8.4.1 Beta 1、iOS 9 Beta 3 系统上进行测试,均导致设备蓝屏并重启,判断为0Day所致,决定详细分析导致iPhone蓝屏的原因。
  通过dump arm64位内核及Panic Log详细分析,确定崩溃发生在内核扩展 AppleVXD393.kext 中。该内核扩展主要用来解码视频帧,导致漏洞利用的原因为:没有校验指针的合法性,对空指针进行解引用所致;此外在分析过程中,我们发现了该扩展模块还存在另外一个漏洞利用的0Day,已经提交苹果官方等待确认。
  为了方便测试,我们首先编写了一个简单 App,目的是便于测试、触发系统崩溃,触发后导致蓝屏重启如下图(视频演示:ht tp://v.youku.com/v_show/id_XMTI5MTgzNjc2NA),接着为了定位内核崩溃发生的模块及具体代码,下文将做详细分析。
  http://image17.poco.cn/mypoco/myphoto/20150725/17/5385596120150725174718069.gif
      
漏洞影响

  一、该DoS影响非越狱设备,综合手中的测试设备及逆向分析,可影响iOS 8 以上的所有64位设备:iPhone 5s,iPhone 6, iPhone 6 Plus,iPad Air, iPad mini 等。
  二、如果利用网站或者借助某个平台,可以造成大规模的拒绝服务。

编写辅助崩溃的程序

  由于在分析的过程中我们很可能需要多次造成内核崩溃,如果每次都从微信中触发崩溃会很麻烦,也很不合理,因此我们需要先获取视频,然后用自己的程序来播放视频。
  这个程序很简单,运行起来的界面如下图:
  http://image17.poco.cn/mypoco/myphoto/20150725/17/53855961201507251748537744085654344_023.jpg

  只要点击“Play Video”就会调起播放器播放相应视频,进而引起系统崩溃。这里遇到个小问题,之前播放视频都是使用 MPMoviePlayerController,但是 MPMoviePlayerController 在播放有问题的视频时一直处于加载状态,于是换 AVPlayer 来播放视频,为了方便大家构建 Demo 进行测试,给出 “Play Video”的相应代码:
  http://image17.poco.cn/mypoco/myphoto/20150725/17/53855961201507251748537744085654344_022.jpg
  http://image17.poco.cn/mypoco/myphoto/20150725/17/53855961201507251748537744085654344_021.jpg

定位崩溃点与相关模块

  首先播放视频,系统会发生崩溃,在设备重启后,从设备上读取崩溃日志,崩溃日志的主要内容如下:
  http://image17.poco.cn/mypoco/myphoto/20150725/17/53855961201507251748537744085654344_020.gif

  上图中比较重要的值已经被圈出来了,其中 pc 与 lr 用来定位崩溃点。另外 kernel slide 也非常重要,因为上图中的寄存器值都是经过 slide 后的值,且这个 slide 每次启动都会变化(KASLR),我们首先需要换算出真实的地址:
  http://image17.poco.cn/mypoco/myphoto/20150725/17/53855961201507251748537744085654344_019.jpg

  在获得真实的崩溃地址后,我们 dump 内核(因为目前还没有可以解密的 arm64 内核):
  http://image17.poco.cn/mypoco/myphoto/20150725/17/53855961201507251748537744085654344_018.jpg

  可以看到这次启动的 slide 的值与崩溃时的内核 slide 是不同的,接下来我们将崩溃地址换算到当前 dump 到的内核:
  http://image17.poco.cn/mypoco/myphoto/20150725/17/53855961201507251748537744085654344_017.jpg

  然后在 IDA Pro 定位到相应的地址, PC指向如下图:
  http://image17.poco.cn/mypoco/myphoto/20150725/17/53855961201507251748537744085654344_016.gif

  LR 指向如下图:
  http://image17.poco.cn/mypoco/myphoto/20150725/17/53855961201507251748537744085654344_015.gif

  从崩溃日志中可以知道崩溃时 x0 = 0x0000000000000000,可以确定崩溃的原因是由于对空指针解引用,即:没有校验入口参数的合法性。
  我们知道 iOS 内核(xnu)本身不包含视频处理相关的功能,视频相关的功能基本是由某个内核扩展进行处理的,下面就需要找出具体是哪个内核扩展出问题。
  比较幸运的是, LR 指向的地址周围包含了内核扩展的信息:
  http://image17.poco.cn/mypoco/myphoto/20150725/17/53855961201507251748537744085654344_014.gif
  http://image17.poco.cn/mypoco/myphoto/20150725/17/53855961201507251748537744085654344_013.gif

  我们获取运行时内核扩展信息,看看有没有与 AppleVXD393 相关的内核扩展,结果如下:
  http://image17.poco.cn/mypoco/myphoto/20150725/17/53855961201507251748537744085654344_012.gif

  可以看到我们找到了相关的内核扩展。
  由于目前已经可以解密较新的 armv7 的内核,查看相关的内核没有发现这个内核扩展,且在 iOS 7.x 的 armv7 设备上测试播放视频,内核并没有崩溃。综合相关信息,这个问题可能只影响 arm64 设备。

确定用户空间中调用 AppleVXD393 服务的模块

  首先需要确定这个内核扩展是不是在沙盒内使用的,经过测试发现:这个内核扩展不是在沙盒中调用的,下面就需要确定具体是哪个模块在使用这个服务。
  因为调用内核扩展的服务时,需要根据服务名称来获取服务,于是在 grep 了下 iOS 8.0.2 的系统库,得到如下信息:
  http://image17.poco.cn/mypoco/myphoto/20150725/17/53855961201507251748537744085654344_011.jpg

  由于播放 mp4 引起的崩溃,所以 MP4VH6.videodecoder 让我们更感兴趣,grep MP4VH6 得到的信息如下:
  http://image17.poco.cn/mypoco/myphoto/20150725/17/53855961201507251748537744085654344_010.jpg

  结合对 VideoToolBox 的反汇编分析,可以知道 VideoToolBox 利用 MP4VH6.videodecoder 来做 MP4 解码,将 MP4VH6.videodecoder 拖到 IDA Pro 中,查看导出表:
  http://image17.poco.cn/mypoco/myphoto/20150725/17/53855961201507251748537744085654344_009.gif

  可以看到与 AppleVXD393 相关的函数,MP4VH6.videodecoder 应该封装了内核扩展com.apple.driver.AppleVXD393 的用户空间接口。

确定视频解码服务

  通过上面的分析我们已经知道:1、MP4VH6.videodecoder 封装了视频解码服务的用户空间接口;2、VideoToolBox.framework 直接调用了 MP4VH6.videodecoder。接下来我们需要知道哪个后台进程通过 xpc 对外提供视频解码服务,ps + grep:
  http://image17.poco.cn/mypoco/myphoto/20150725/17/53855961201507251748537744085654344_008.jpg

  由于 xpc 服务都需要checkin,逆向分析这三个程序,最后发现 mediaserverd checkin 了如下两个服务:
  http://image17.poco.cn/mypoco/myphoto/20150725/17/53855961201507251748537744085654344_007.jpg

  mediaserverd 可能是我们要找的后台服务。为了确定这一点,又调试了下 mediaserverd,断点命中后,得到信息如下:
  http://image17.poco.cn/mypoco/myphoto/20150725/17/53855961201507251748537744085654344_006.jpg

  至此确定 mediaserverd 负责提供视频解码服务,也可以大概知道 iOS 平台的视频解码功能的大致架构。

分析可控性

  首先看下视频解码时的调用栈:
  http://image17.poco.cn/mypoco/myphoto/20150725/17/53855961201507251748537744085654344_005.jpg

  为了确定可控性,于是编写了一个 Tweak 来 Hook mediaserverd,并 Hook IOConnectCallStructMethod,在发现待解码的视频帧序号与引起内核崩溃的视频帧序号一致时,修改交由内核解码的数据,查看、对比崩溃日志,总结输入对崩溃时寄存器值的影响。
  对缓冲区一共进行如下几个填充测试:
  http://image17.poco.cn/mypoco/myphoto/20150725/17/53855961201507251748537744085654344_004.gif

  缓冲区填充测试,0x00 vs. 0x01:
  http://image17.poco.cn/mypoco/myphoto/20150725/17/53855961201507251748537744085654344_003.gif

  可以看到 PC 寄存器有差别,说明走的不是相同的代码路径。在对缓冲填充 0x01 时,内核的崩溃点为:
  http://image17.poco.cn/mypoco/myphoto/20150725/17/53855961201507251748537744085654344_001.gif
  http://image17.poco.cn/mypoco/myphoto/20150725/17/53855961201507251748537744085654344_000.gif

  缓冲区填充测试,0x01 vs. 0x02:
  http://image17.poco.cn/mypoco/myphoto/20150725/17/53855961201507251748537744085654344_002.gif

  可以看到 x0 的部分位是可控的,x12, x13 是从 x1 指向的地址处加载的。至此已经完成了对问题的分析,至于利用,就大家各显神通吧。

其他

  一、经过处理的只包含单帧的视频,
  链接:ht tp://yunpan.cn/cc5KWG7p368yN
  提取码:4e17
  MD5:f4260553b0628f2e6bbb88e2c7b124e6
  二、如果大家有利用思路,欢迎关注微博交流:@NirvanTeam

此外,对iOS安全领域开发、漏洞分析、挖掘感兴趣的同学可以关注微博@NirvanTeam私信或者发邮件到nirvanteam@ 360.cn联系我们。要求:
  1. 对iOS/Mac OSX平台安全相关领域有浓厚的兴趣
  2. 有一定iOS/Mac OSX平台安全研究or漏洞挖掘or安全开发相关工作经验

wolf001 发表于 2015-7-25 20:23

这个好像太深奥了,还有就是本人没有IPHONE

千里云 发表于 2015-7-26 09:31

不明觉厉
没有肾果

子山 发表于 2015-7-26 09:47

越狱后装插件重启时蓝屏闪了一下,但进系统一切正常,莫名其妙啊

cookoo001 发表于 2015-7-26 10:09

楼主先送我一个苹果,我再来学习

snjatyd 发表于 2016-3-10 12:37

这都能分析出来牛
页: [1]
查看完整版本: iPhone蓝屏0day漏洞分析:播放视频触发内核拒绝服务