<% dim ModuleName,InfoID,ChannelShortName,CorrelativeArticle,InstallDir,ChannelDir,Keyword,PageTitle,ArticleIntro,Articlecontent Keyword=stripHTML("Android Minikin,拒绝服务,漏洞,漏洞分析") PageTitle=stripHTML("Android Minikin 库越界写拒绝服务漏洞分析") ArticleIntro=stripHTML("在本月的Android补丁中,谷歌修复了Minikin库中的一个拒绝服务漏洞(CVE-2016-2414) 。早在今年3月初我就向谷歌报告了这个漏洞,但谷歌方面确认说该漏洞与去年11月份另一位专家报告") Articlecontent=stripHTML("                在本文,我将给大家深入的分析该漏洞。该漏洞是由于Minikin库无法正确解析.TTF字体文件,正因如此一位本地攻击者是能够暂时阻…") ModuleName = stripHTML("netadmin") InfoID = stripHTML("226299") ChannelShortName=stripHTML("网管") InstallDir=stripHTML("http://www.77169.com/") ChannelDir=stripHTML("netadmin") %> Android Minikin 库越界写拒绝服务漏洞分析 - 华盟网 - http://www.77169.com
您现在的位置: 华盟网 >> 网管 >> 应用安全 >> 正文

[组图]Android Minikin 库越界写拒绝服务漏洞分析

2016/4/28 作者:Mickeyyy… 来源: 网络收集
导读 <% if len(ArticleIntro)<3 then Response.Write Articlecontent 'Response.Write "Articlecontent" else Response.Write ArticleIntro 'Response.Write "ArticleIntro" end if %>

       

        在本文,我将给大家深入的分析该漏洞。该漏洞是由于Minikin库无法正确解析.TTF字体文件,正因如此一位本地攻击者是能够暂时阻止受该漏洞影响的Android设备访问。攻击者可以加载一份不可信字体文件,让Minikin组件溢出,这将会导致崩溃。

  由于崩溃会导致Android设备连续的重启,所以该问题被谷歌评级为高危漏洞。

  受影响的Android版本

  Android 5.0.2, 5.1.1, 6.0, 6.0.1

  概念验证

  下面的代码片段能够触发该漏洞,setTypeface函数用于从外部在TextView中加载以及设置自定义字体。

      

  以下为崩溃日志:

      

  分析

  该漏洞是由于Minikin库无法正确解析.TTF字体文件,进而造成了一个越界写拒绝服务漏洞。

  首先我们来看看这个经过特殊构造的.TTF字体文件,注意这个简化版本的PoC在偏移地址0×60, 0x58D, 0x5D6, 0xAD60的不同差异。以下为正常的TTF文件与我们的简化版本PoC比较

  CVE-2016-2414 1.png

  图1:偏移地址0×60

  CVE-2016-2414 2.png

  图2:偏移地址0x58D以及0x5D6

  CVE-2016-2414 3.png

  图3:偏移地址0xAD60

  在上面的图1和图3中,我们对TTFTemplate使用16进制编辑器来解析TTF字体文件。偏移地址0×60

  的4个字节为cmap表单中checksum字段,偏移地址0xAD60的4个字节为thead头结构中的checkSumAdjustment字段,这两个校验和字段在fuzzing的时候就已经进行重新计算了。他们不触发漏洞,这里就直接略过。以下为使用TTFTemplate解析简化版本PoC

  CVE-2016-2414 4.png

  从上图中,我们能够看到偏移地址0x58D和0x5D6中cmap表中被修改的字节。关于cmap表的详细说明可以看看https://www.microsoft.com/typography/otspec/cmap.htm,其中的Format 4部分如下:

    CVE-2016-2414 5.png

  以下为‘startCount[]’ 和 ‘endCount[]’的对比:

  CVE-2016-2414 6.png

  一般来说,startCount[]和endCount[]数组中每一个元素的值都会逐渐增大。与此同时,对于一个给定的索引i,endCount[i]大于或等于startCount[i]。我们将简化版PoC文件中的startCount[30]修改为0x1E78,让startCount[30] > endCount[30]。再将 startCount[67] 修改为0xE0FF,让startCount[67] < startCount[66]。根据说明文档我们知道startCount[67]是最后一个元素且为0xFFFF。

  从堆栈跟踪反馈来看,我们看到在android::SparseBitSet::initFromRanges函数中SIGSEGV重现并获得代码崩溃的位置,以下为SparseBitSet::initFromRanges函数:

      

  接下来,使用 IDA Pro进行动态分析。在SparseBitSet::initFromRanges函数入口设置一个断点。然后运行调试器可以看到下面的代码:

  CVE-2016-2414 7.png

  从上图中得知,R1为第一个参数(const uint32_t* ranges),R2为第二个参数 (size_t nRanges),下面为R1指向的内存:

  CVE-2016-2414 8.png

  我们看到偏移地址0xAB1734F0中的4个字节 |78 1E 00 00|存储 startCount[30] (|1E 78|)的值,随后的4个字节|0C 1E 00 00|存储endCount[30]+1 (|1E 0B|+1)的值,接着继续跟踪直到程序处理到ranges[30] (|78 1E 00 00 0C 1E 00 00|)

  CVE-2016-2414 9.png

  从上图中我们可以看到当R2等于0x1E,R10寄存器指向ranges[30] (0xAB1734F0),继续分析

  CVE-2016-2414 10.png

  之后跳转到loc_B5DB0176

  CVE-2016-2414 11.png

  接下来进入loc_B5DB01D2循环, [R4+8]存储mBitmaps值,并且R9指向值mBitmaps(从源代码)。如下所示:

  CVE-2016-2414 12.png

  之后在地址B5DB01E0,它会执行一个STR指令并向内存 [R9+R0<<2]写入0xFFFFFFFF

  CVE-2016-2414 13.png

  当我们运行调试器(F9),弹出如下对话框

  CVE-2016-2414 14.png

  出现一个分段违规(segmentation violation)错误,检查下内存信息和寄存器

  CVE-2016-2414 15.png

  以下为源代码的分析:

       

  总结

  简单来说该漏洞是由于Minikin未能检测cmap表中的有效长度引起,一个损坏的或者一个恶意的字体文件可能包含一个负数范围大小,反过来导致了内存的泄漏。一个攻击者可以加载一个损坏的字体文件并导致Minikin组件发生溢出。这个崩溃会导致Android设备连续重启。



  • 上一篇网管:

  • 下一篇网管: 没有了