首页
社区
课程
招聘
Android第三个签名漏洞#9950697分析
发表于: 2013-11-14 10:44 722

Android第三个签名漏洞#9950697分析

2013-11-14 10:44
722
新闻链接:http://safe.baidu.com/2013-11/masterkey-9950697.html

新闻时间:2013/11/07

新闻正文:

注意!!原文是有图的,请注意!要看详细,最好看原文!!!

上周末Google发布了Android 4.4,随着一系列新功能包括安全措施的发布,我们也从AOSP的源码中看到了google悄悄修复了一个bug:
https://android.googlesource.com/platform/libcore/+/2da1bf57a6631f1cbd47cdd7692ba8743c993ad9%5E%21/#F0

这个bug编号为9950697,bug存在于“filename 字段的长度在central directory和在local file entry里解析不一致”,而且这个bug早在7月23号就已经被修复:

下面我们分析一下该漏洞的具体成因。我们在《Android第二个签名漏洞》一文中详细解释了APK包的文件结构。为了方便理解,我们至下往上把一个Zip文件分为:目录段、索引段、数据段。在索引段和数据段中,每一个ZipEntry的header里都存储了关于这个ZipEntry的信息,包括filename,CRC等。索引段和数据段中的这两份相同的信息,用来做Zip文件的完整性检验。

Android在校验签名时,解析Apk包用的是java代码(ZipFile.java和ZipEntry.java),而在安装apk时,包括解压、dexopt等,用的是c代码(ZipArchive.cpp),这两份代码在解析ZipEntry时的步骤都是先从索引段读取ZipEntry的信息,然后定位到数据段。

数据段中的ZipEntry的Data[]字段是用来存放真正的压缩数据的。Java和c定位到Data[]字段的方法都是根据Data[]字段之前的字段的长度计算偏移:

Data[]的偏移 = ZipEntry的偏移 + 固定header的长度 + extraFieldLength + fileNameLength

我们在之前的文章中讨论过针对索引段的extraField和comment的攻击,这次轮到了fileName。Java使用的fileNameLength是从索引段的ZipEntry获得的,而C则是从数据段的ZipEntry获得的,所以就这里造成了不一致性,导致java和c定位到的data[]不一致。因此可以在数据段的ZipEntry中构造一个不一样的fileNameLength,进而让java校验签名时读取的是合法的文件,而c在安装是读取的是恶意的文件,绕过签名验证。

不过需要注意的是,由于fileNameLength这个字段的类型是一个无符号short,最大值为64K,所以为了能让C代码成功能跳转到fake classes.dex,必须要求 real classes.dex加上“classes.dex”字符串的长度小于64k。也就是说,对这个漏洞的利用要求被绕过的原始正常文件的大小必须小于64k,这对这个漏洞的利用带来了很大的限制,所以实际的危害并不很大。

百度安全实验室近期发布了新的漏洞解决方案:Droidsploit,可以保护你免受Android漏洞的威胁。

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 0
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回
//