-
-
Android第三个签名漏洞#9950697分析
-
发表于: 2013-11-14 10:44 802
-
新闻链接:a93K9s2c8@1M7q4)9K6b7g2)9J5c8W2)9J5c8Y4y4S2k6X3g2Q4x3X3g2T1j5h3W2V1N6g2)9J5k6h3y4G2L8g2)9J5c8U0t1H3x3e0y4Q4x3X3b7I4x3g2)9J5c8X3#2S2M7%4c8W2M7X3E0W2P5g2)9J5k6o6V1&6y4e0l9$3z5e0N6Q4x3X3g2Z5N6r3#2D9
新闻时间:2013/11/07
新闻正文:
注意!!原文是有图的,请注意!要看详细,最好看原文!!!
上周末Google发布了Android 4.4,随着一系列新功能包括安全措施的发布,我们也从AOSP的源码中看到了google悄悄修复了一个bug:
ef6K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6S2L8X3c8J5L8$3W2V1i4K6u0W2k6$3!0G2k6$3I4W2M7$3!0#2M7X3y4W2i4K6u0W2j5$3!0E0i4K6u0r3M7r3I4S2N6r3k6G2M7X3#2Q4x3V1k6D9K9h3u0U0L8%4u0W2i4K6u0r3i4K6u0n7i4K6u0r3x3X3c8S2x3h3u0X3y4e0N6S2y4U0j5K6x3h3j5I4j5$3u0V1y4o6N6U0k6r3b7%4y4U0V1J5j5X3p5^5y4K6b7K6j5K6V1&6x3$3q4V1z5g2)9J5y4e0g2q4i4K6t1#2x3U0q4Q4x3V1k6Q4x3U0y4r3x3l9`.`.
这个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漏洞的威胁。
新闻时间:2013/11/07
新闻正文:
注意!!原文是有图的,请注意!要看详细,最好看原文!!!
上周末Google发布了Android 4.4,随着一系列新功能包括安全措施的发布,我们也从AOSP的源码中看到了google悄悄修复了一个bug:
ef6K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6S2L8X3c8J5L8$3W2V1i4K6u0W2k6$3!0G2k6$3I4W2M7$3!0#2M7X3y4W2i4K6u0W2j5$3!0E0i4K6u0r3M7r3I4S2N6r3k6G2M7X3#2Q4x3V1k6D9K9h3u0U0L8%4u0W2i4K6u0r3i4K6u0n7i4K6u0r3x3X3c8S2x3h3u0X3y4e0N6S2y4U0j5K6x3h3j5I4j5$3u0V1y4o6N6U0k6r3b7%4y4U0V1J5j5X3p5^5y4K6b7K6j5K6V1&6x3$3q4V1z5g2)9J5y4e0g2q4i4K6t1#2x3U0q4Q4x3V1k6Q4x3U0y4r3x3l9`.`.
这个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漏洞的威胁。
赞赏
赞赏
雪币:
留言: