返回 登录
0

Android安全团队:从mediaserver谈Android加固

【CSDN编者按】Google I/O开发者大会日渐临近,我们期待Google对于Android系统的改进,而另一方面,Android Developers Blog于日前发布了他们5月的第一篇文章,由Android安全团队的Dan Austin和Jeff Vander Stoep联合撰写,分享了Media Hardening项目的实践,从中可以一窥Android安全团队一直以来为Android系统安全所做的种种努力。

为了提升Android系统的安全系数,我们一直欢迎并奖励任何发现漏洞的研究者。比如,2015年,mediaserver的libstagefright中被发现了一系列漏洞,我们在同年8月和9月的安全公告(Security Bulletin)中对此进行了更新。

除了每月解决这些问题,我们还在开发新的安全功能来强化现有安全模式,并提供额外的深度防护措施。防护措施主要有两个目标:

  • 防护:防止漏洞;
  • 遏制:通过降低优先等级及隔离不信任内容相关组件来保护系统。

防护(Prevention)

libstagefright中大部分漏洞都是无符号整数溢出(integer overflows)导致的堆栈溢出。且libstagefright的多个整数溢出让攻击者可以分配不为输入数据提供足够空间的缓冲区,导致堆栈中出现缓冲区溢出。

无符号整数溢出的后果已有清晰定义,但接下来的操作可能产生无法预料的风险。相比之下,有符号整数溢出在C/C++语言中未被定义,意味着不能保证溢出产生的结果,而编译者可能选择典型最快最简单的操作。我们已经调整了编译器,为有符号和无符号整数溢出均提供更加安全的预设值。

UndefinedBehaviorSanitizer(UBSan)是检测非定义或错误操作的LLVM/Clang编译器工具链。UBSan可以检查有符号和无符号整数溢出等多种非定义和不安全操作,在此过程中会在执行时间为产生的可执行的整数溢出条件测试添加新代码。比如图1显示的是:研究者提供的原始补丁应用之后,libstagefright中的MPEG4Extractor组件的parseChunk源代码。底下黑框里的修改内容是为了防止整数溢出。

无符号整数溢出

图1 源代码中难以察觉的无符号整数溢出

可惜SIZE_MAX和size为32位,而chunk_size是64位的,有可能出现检查不彻底,存在整数溢出的情况。红框里的size + chunk_size可能导致整数溢出,以及产生比size elements更小的缓冲区。因为size + chunk_size可能比蓝框标注出来的size更小,所以接下来memcpy可能导致内存崩溃。关于该漏洞潜在exploit vector的更多信息请参考Project Zero

图2将以上代码片段产生的集合与第二个带有整数净化的编译版本进行比较。红框里的是引发整数溢出的添加操作。在未净化版本中,size (r6)和chunk_size (r7)是一起添加的,可能导致r0溢出,且小于size。然后缓冲区分配到规定的r0 size,size字节被复制上去。如果r0小于r6,就会出现内存崩溃。

未经过和经过净化的编译器输出

图2 未经过和经过净化的编译器输出对比

而在净化版本中,size (r7)和chunk_size (r5)是一起添加的,结果储存在r0中。接下来对照r0和r7,如果r0小于r7,就像状态码所表示的r3设为1,而进位位已被设定,然后出现整数溢出,就会触发终止以防止内存崩溃。

注意: 补丁提供的不完全检查并不包含在图2中。溢出出现在缓冲区分配的添加操作中,触发额外的整数净化检查,从而终止漏洞。

整数净化最初只是代码净化工具,但也有效地阻止了大部分报告的libstagefright漏洞。启动整数净化检查只是第一步,找到以及修复整数溢出,阻止运行时终止则是Android媒体团队努力的结果。大部分未发现的溢出都会修复,而留下来的那些(基于性能原因)为了防止运行时终止也经过了验证,被视为安全的溢出。

在Android N中,有符号和无符号整数溢出检测在整个媒体堆栈包括libstagefright上都是启动的,降低了整数溢出的可能性,而且能防止未来新的整数溢出漏洞进入Android系统。

遏制(Containment)

对于Android M以及更早版本,mediaserver负责大部分媒体相关的任务,也意味着需要得到所有任务相关的权限。尽管mediaserver在自己的沙箱中运行,它任然可以获取不同的资源和能力。所以2015年的libstagefright漏洞尤其重要——mediaserver可能通过Android设备的摄像头、麦克风、显卡、电话、蓝牙和网络等获取多个重要资源。

根本原因分析:libstagefright漏洞主要出现在负责文件格式和解码器语法解析的代码中。这并不奇怪,语法解析复杂文件格式和解码器与优化速度同时进行本来就难度大,且大部分边缘案例中,这些代码都容易受到意外或恶意信息输入的影响。

但是媒体语法解析不要求从mediaserver那里获取大部分优先等级权限,所以媒体团队坚持最少优先等级的原则,重构了Android N的mediaserver。图3显示的是整体mediaserver及其权限是如何根据以下内容进行分割的:

  • 语法解析代码移入非优先等级的,拥有少量权限或无权限的沙箱;
  • 要求获取敏感权限的组件被分别移入仅仅提供它们单个所需资源的沙箱中。比如,只有cameraserver可以访问照摄像头,只有audioserver可以访问蓝牙,只有drmserver可以访问DRM资源。

mediaserver

图3 Android N中的mediaserver及其权限分割

对比Android N和老版本中libstagefright漏洞的潜在影响,就明白这些策略的价值所在了。获取libstagefright的代码执行预先为整体mediaserver流程,包括显卡驱动、摄像头驱动或者同样易受内核攻击的通信接口提供了所有权限和可用资源。

在Android N中,libstagefright在mediacodec沙箱中运行,没有什么权限。访问摄像头、麦克风、相片、电话、蓝牙和网络还有动态代码加载是不被SELinux允许的,与内核的交互也被seccomp进一步限制,这样一来攻击者能够获取的权限数量大大减少,也通过减少内核暴露的攻击面控制了权限提升。

总结

媒体加固项目专注于使功能移入更低优先级别的沙箱,并进一步减少权限。这篇文章中讨论的技巧曾应用于Android媒体框架,且适用于整个Android代码库。这些加固技巧正积极应用于Android额外的组件,我们一如既往地期待读者的意见和建议,帮助进一步提升与改进Android系统。

原文: Hardening the media stack
作者: Dan Austin和Jeff Vander Stoep,来自Android安全团队
译者: 张新慧
审校/责任编辑: 唐小引(@唐门教主),欢迎技术投稿、约稿,给文章纠错,请发送邮件tangxy@csdn.net

第一时间掌握最新移动开发相关信息和技术,请关注mobilehub公众微信号(ID: mobilehub)。

mobilehub

由CSDN重磅打造的2016中国云计算技术大会(CCTC 2016)将于5月13日-15日在北京举办,大会特设“中国Spark技术峰会”、“Container技术峰会”、“OpenStack技术峰会”、“大数据核心技术与应用实战峰会”等四大技术主题峰会,以及“云计算核心技术架构”、“云计算平台构建与实践”等专场技术论坛。80+位一线互联网公司的技术专家将到场分享他们在云计算、大数据领域的技术实践,目前大会剩票不多,欲购从速。详情请点击CCTC 2016大会官网

评论