360CERT:CVE–2017–13156 Janus安卓签名漏洞预警分析

阅读量    75595 | 评论 5

分享到: QQ空间 新浪微博 微信 QQ facebook twitter

2017年7月31日GuardSquare向Google报告了一个签名漏洞并于当天收到确认。Google本月修复了该漏洞,编号CVE-2017-13156。

经过360CERT分析确认,该问题确实存在,影响较为严重。攻击者可以绕过签名验证机制构造恶意程序更新原有的程序。

 

0x01 事件概述

该漏洞产生的根源在于将DEX文件和APK文件拼接之后校验签名时只校验了文件的APK部分,而虚拟机执行时却执行了文件的DEX部分,导致了漏洞的发生。由于这种同时为APK文件和DEX文件的二元性,联想到罗马的二元之神Janus,将该漏洞命名为Janus漏洞。

 

0x02 事件影响

影响Android5.0-8.0的各个版本和使用安卓V1签名的APK文件。

 

0x03 事件详情

技术细节

Android支持两种应用签名方案,一种是基于JAR签名的方案(v1方案),另一种是 Android Nougat(7.0)中引入的APK签名方案v2(v2方案)。

enter image description here

v1签名不保护APK的某些部分,例如ZIP元数据。APK验证程序需要处理大量不可信(尚未经过验证)的数据结构,然后会舍弃不受签名保护的数据。这会导致相当大的受攻击面。此外,APK 验证程序必须解压所有已压缩的条目,而这需要花费更多时间和内存。为了解决这些问题,Android 7.0中引入了APK签名方案v2。在验证期间,v2方案会将APK文件视为 Blob,并对整个文件进行签名检查。对APK进行的任何修改(包括对ZIP元数据进行的修改)都会使 APK 签名作废。这种形式的APK验证不仅速度要快得多,而且能够发现更多种未经授权的修改。

enter image description here

如果开发者只勾选V1签名不会有什么影响,但是在7.0上不会使用更安全的V2签名验证方式;只勾选V2签名7.0以下无法正常安装,7.0以上则使用了V2的方式验证;同时勾选V1和V2则所有机型都没问题。此次出现问题的是V1签名方案。简单地说,把修改过的dex文件附加到V1签名的apk文件之前构造一个新的文件,V1方案只校验了新文件的apk部分,而执行时虚拟机根据magic header只执行了新文件的dex部分。

enter image description here

我们来看一下已经公布的 POC (https://github.com/V-E-O/PoC/tree/master/CVE-2017-13156) 的原理。janus.py接受dex文件和apk文件作为输入,组合起来输出。

读取dex文件:

enter image description here

读取apk文件:

enter image description here

Apk其实就是一个zip。简单地说zip文件格式由文件数据区、中央目录结构和中央目录结束节组成。

enter image description here

其中中央目录结束节有一个字段保存了中央目录结构的偏移。代码中搜索中央目录结束节的固定结束标记x06054b50定位到中央目录结构的偏移,将其加上dex文件的大小,因为我们要把dex文件插到apk前面。

enter image description here

接下来依次更新中央目录结构数组中的deHeaderOffset字段也就是本地文件头的相对位移字段。通过deHeaderOffset字段可以直接获取到对应文件的文件数据区结构的文件偏移,就可以直接获取到对应文件的压缩数据了。同样也是因为dex文件插在前面了所以直接加上dex文件的大小。

enter image description here

最后更新dex部分的file_size字段为整个dex+apk的大小,使用alder32算法和SHA1算法更新checksum和signature字段。

enter image description here

enter image description here

下面做一个非常简单的测试。 在APK文件中写一个弹出Hello的toast,同时采用V1签名方案签名:

enter image description here

安装到手机上:

enter image description here

将编译好的apk解压得到dex文件,baksmali.jar反编译dex文件得到smali代码,将hello随便改成另外一个字符串:

enter image description here

用smali.jar回编译成dex文件,使用提供的脚本把dex文件和原来的apk打包生成out.apk:

enter image description here

安装到手机上成功通过了签名校验并且执行了修改的dex中的代码:

enter image description here

在我android8.0没有打补丁的手机上如果采用了V2签名方案不受该漏洞影响,更新不了原来正常的程序:

enter image description here

补丁分析

补丁非常简单,强制校验了zip的frSignature:

enter image description here

 

0x04 修复建议

1、开发者在开发应用程序时勾选V2签名方案

2、各厂商应及时发布补丁,确保用户尽快更新系统

3、用户应在正规的应用市场下载程序

 

0x05 时间线

2017-12-4 Google发布12月安全公告

2017-12-8 公布POC

2017-12-12 360CERT进行分析并发布预警公告

 

0x06 参考文档

https://www.guardsquare.com/en/blog/new-android-vulnerability-allows-attackers-modify-apps-without-affecting-their-signatures

https://source.android.com/security/bulletin/2017-12-01

https://source.android.google.cn/security/apksigning/v2?hl=zh-cn

分享到: QQ空间 新浪微博 微信 QQ facebook twitter
|推荐阅读
|发表评论
|评论列表
加载更多