Android证书验证存漏洞 开发者身份信息可被篡改(转)
原帖地址:http://bbs.pediy.com/showthread.php?p=1335278#post1335278
近期在国内网易,雷锋网等网站爆出谷歌市场上的索尼官方的备份与恢复应用“Backup and Restore”被黑的消息。新闻显示:目前索尼官方的备份与恢复应用“Backup and Restore”已经被黑客彻底破解;甚至在Google Play商店里该应用的所有权都被黑客修改;目前仍不清楚使用破解修改版本的应用,会否对用户造成损害;建议用户尽量避免使用,删除已下载的应用;目前在 Google Play上应用管理权都归于“HeArt HaCkEr Group”,开发者信息显示“Nirav Patel Kanudo”。    
阿里钱盾专家分析认为,Android证书验证机制存在漏洞,开发者身份信息可以任意篡改,而不会影响应用APK的安装、升级、运行等操作。针对这一情况,阿里钱盾(qd.alibaba.com)团队也专门进行了研究和提出了相应的解决措施。    
Android证书验证机制    
首先,详细说明Android应用程序安装文件APK的证书验证机制。    
1.  基本算法    
(1)消息摘要 -Message Digest    
简称摘要,在消息数据上,执行一个单向的Hash函数,生成一个固定长度的Hash值,也称为数字指纹,消息摘要有以下特点:    
1. 通过摘要无法推算得出消息本身。    
2. 如果修改了消息,那么摘要一定会变化(除开碰撞情况)。    
3. 消息摘要只能保证消息的完整性,并不能保证消息的不可篡改性。    
在Android证书里,一般采用SHA-1算法来生成摘要值。
(2)数字签名 - Signature    
消息的发送者用自己的私钥对消息摘要进行加密,产生一个加密后的字符串,称为数字签名。因为发送者的私钥保密,可以确保别人无法伪造生成数字签名,也是对信息的发送者发送信息真实性的一个有效证明。数字签名是 非对称密钥加密技术 + 数字摘要技术 的结合。    
数字签名技术是将信息摘要用发送者的私钥加密,与原文一起传送给接收者。接收者只有用发送者的公钥才能解密被加密的信息摘要,然后接收者用相同的Hash函数对收到的原文产生一个信息摘要,与解密的信息摘要做比对。如果相同,则说明收到的信息是完整的,并且是由该发送者生成的(因为只有发送者才拥有对应的私钥)。
(3)数字证书 - Certificate    
数字证书是一个经证书授权中心数字签名的包含公开密钥拥有者信息以及公开密钥的文件。    
证书包含的有效信息有:证书版本、证书序号、证书颁发机构、证书有效期、证书拥有者和拥有者公钥,以及证书颁发机构对该证书的签名。    
需要注意的是Android APK中的CERT.RSA证书可以是自签名的,并不需要这个证书是第三方权威机构发布或者认证的,用户可以在本地机器自行生成这个自签名证书。
    
当使用某证书时,需要验证该证书的合法性:使用证书颁发者的公钥,然后对整个证书(除了证书数字签名以外)采用给定的证书签名算法计算,然后将计算结果同证书数字签名对比,相同则可以证明该证书确实由证书颁发者颁发的合法证书;不同则说明有篡改存在,证书不合法。
2.  Android证书组成    
APK文件实际上是一个压缩文件包,我们将文件后缀.APK修改为.zip,可以使用解压缩软件直接打开。如weixin.APK        
证书验证相关的文件都放在META-INF\ 文件夹中:        
(1)  MANIFEST.MF    
遍历APK包中除了META-INF\ 文件夹以外的所有文件,利用SHA1算法生成这些文件的消息摘要,然后转化为对应的base64编码。MANIFEST.MF存储的是文件的摘要值,保证完整性,防止文件被篡改。weixin的MANIFEST.MF:    
Manifest-Version: 1.0    
Created-By: 1.7.0_45 (Oracle Corporation)
Name: r/t/a3k.xml    
SHA1-Digest: c6GfCzDzRo75w7HwMzjcPXGi++I=
Name: r/v/a1m.png    
SHA1-Digest: Ao27xq4nYyBR5Z0yG07pN0MtlKI=    
……
(2)  .SF    
xx.SF文件(xx为使用者证书的自定义别名,默认为CERT,即CERT.SF),保存的是MANIFEST.MF的摘要值, 以及MANIFEST.MF中每一个摘要项的摘要值,然后转化成对应的base64编码。虽然该文件的后缀名.sf(SignatureFile)看起来是签名文件,但是并没有私钥参与运算,也不保存任何签名内容。    
weixin的COM_TENC.SF:    
Signature-Version: 1.0    
SHA1-Digest-Manifest-Main-Attributes: sY6+RQ4DWdnxCfSpiwTT6GRIwA0=    
Created-By: 1.7.0_45 (Oracle Corporation)    
SHA1-Digest-Manifest: GduDrpyEw/pgWazHpioH6+7MyKo=
Name: r/t/a3k.xml    
SHA1-Digest: b6IQQJD88w4yCVk0QHuy2cySHTE=
Name: r/v/a1m.png    
SHA1-Digest: HqlAkc/TpMyeU/jhapu/Pxg1QLQ=    
……
(3)  .RSA / .DSA    
.RSA / .DSA文件(后缀不同采用的签名算法不同,.RSA使用的是RSA算法, .DSA使用的是数字签名算法DSA,目前APK主要使用的是这两种算法),保存的是第二项.SF文件的数字签名,同时还会包括签名采用的数字证书(公钥)。特别说明,当使用多重证书签名时,每一个.sf文件必须有一个.RSA/.DSA文件与之对应,也就是说使用证书CERT1签名时有CERT1.SF和CERT1.RSA,同时采用证书CERT2签名时又会生成CERT2.SF和CERT2.RSA。    
weixin的COM_TENC.RSA(解码后):    
Certificate:    
    Data:    
        Version: 3 (0x2)    
        Serial Number: 1295447972 (0x4d36f7a4)    
    Signature Algorithm: sha1WithRSAEncryption    
        Issuer: C=86, ST=Guangdong, L=Shenzhen, O=Tencent Technology(Shenzhen) Company Limited, OU=Tencent Guangzhou Research and Development Center, CN=Tencent    
        Validity    
            Not Before: Jan 19 14:39:32 2011 GMT    
            Not After : Jan 11 14:39:32 2041 GMT    
        Subject: C=86, ST=Guangdong, L=Shenzhen, O=Tencent Technology(Shenzhen) Company Limited, OU=Tencent Guangzhou Research and Development Center, CN=Tencent    
        Subject Public Key Info:    
            Public Key Algorithm: rsaEncryption    
                Public-Key: (1024 bit)    
                Modulus:    
                    …..    
Exponent: 65537 (0x10001)    
    Signature Algorithm: sha1WithRSAEncryption    
         ……    
.SF Signature Algorithm: sha1WithRSAEncryption    
  ……
.RSA文件包括证书和.SF签名2个部分,其中证书里面也有一个签名,是证书颁发者对该证书的签名。
对APK的证书签名具体原理和算法,可以参考    
https://Android.googlesource.com/pla...K/SignAPK.java
3.  Android证书验证机制        
Android 系统不允许安装没有任何数字签名的应用APK程序,所有应用程序必须使用某个证书进行签名(一般为应用开发者自签名证书):    
APK源文件,首先由应用开发者使用自己的私钥,对整个文件进行签名,生成上述的三个文件,然后打包成签名后的APK文件;然后发布到市场,图示是Google市场。    
用户从市场下载APK安装文件,在真正安装APK前,会首先验证数字签名。具体步骤:    
(1)  首先计算除META-INF\ 文件夹以外所有文件的SHA1摘要值,同MANIFEST.MF文件中的摘要值做比对。如果不同,则证明源文件被篡改,验证不通过,拒绝安装。    
(2)  计算MANIFEST.MF的摘要值, 以及MANIFEST.MF中每一个摘要项的摘要值,同.SF文件中的摘要值做比对。如果不同,则证明.SF被篡改,验证不通过,拒绝安装。    
(3)  从.RSA 文件中取出开发者证书,然后从证书中提取开发者公钥,用该公钥对.SF文件做数字签名,并将结果同.RSA文件中的.SF签名进行比对。如果不同,则验证不通过,拒绝安装。    
存在的问题    
2014年报出来的Fake ID漏洞,是对证书链的验证方法存在漏洞,没有对证书本身的签名进行验证(不同于.SF签名),场景:证书颁发者A对证书B进行签名,然后使用证书B对APK的.SF文件签名,而安装APK时仅仅验证了证书B对.SF文件的数字签名,而没有验证颁发者A对该证书B本身的数字签名。目前,GOOGLE已经对该漏洞进行了修复,但笔者认为,该修复并不完全:仅仅修复了证书链的认证方法,没有对自签名证书中的证书数字签名进行验证,存在着一定的问题。    
代码段org.apache.harmony.security.utils. JarUtils:    
191     // Signer is self-signed    
192     if (signer.getSubjectDN().equals(signer.getIssuerDN())){    
193         return (X509Certificate[])chain.toArray(new X509Certificate[1]);    
194     }    
当采用自签名证书时,Android直接跳过验证,将证书加入了合法证书列表。这导致攻击者拿到.RSA / .DSA文件后,可以对其中的证书(除了证书拥有者公钥之外)随意篡改,包括证书序号、证书有效期、证书拥有者名字等等。而Android在安装APK时,仅仅使用了证书中的公钥,其它信息未使用也未作任何验证,只要使用公钥验证.SF文件的数字签名通过就可以正常安装使用。    
1.  证书有效期篡改    
以weixin的COM_TENC.RSA证书为例,直接修改证书有效期(仅仅改动COM_TENC.RSA文件):    
Certificate:    
    ……    
        Validity    
            Not Before: Jan 19 14:39:32 2011 GMT    
            Not After : Jan 11 14:39:32 2011 GMT    
……
很明显的证书有效期错误,结束时间比开始时间还早,但是修改后的APK依然可以正常安装、运行,因为COM_TENC.RSA文件里的公钥(证书的一部分)和.SF文件都没有修改,可以通过Android证书验证机制。    
      
联想开来,某个已过期的证书依然可以使用,假如某个拥有高权限的证书已经过期,危害会很大。例如Adobe颁发过某个证书C(使用Adobe公钥签名该证书),然后证书C过期了,但是由于用Adobe的公钥验证该证书仍然可以通过(修复过的证书链认证可以通过,除非Adobe吊销它自己的证书),而Android并没有验证证书有效性,所以用证书C签过名的APK依然拥有Adobe的高权限。    
2.  证书拥有者主体篡改    
以weixin的COM_TENC.RSA证书为例,直接修改证书拥有者名字(仅仅改动COM_TENC.RSA文件):    
Certificate:    
    ……    
        Issuer: C=86, ST=Guangdong, L=Shenzhen, O=abcdefg Technology(Shenzhen) Company Limited, OU=abcdefg Guangzhou Research and Development Center, CN=abcdefg    
        Validity    
            Not Before: Jan 19 14:39:32 2011 GMT    
            Not After : Jan 11 14:39:32 2011 GMT    
        Subject: C=86, ST=Guangdong, L=Shenzhen, O=abcdefg Technology(Shenzhen) Company Limited, OU=abcdefg Guangzhou Research and Development Center, CN=abcdefg    
……
将开发者信息修改为了abcdefg,但是修改后的APK依然可以正常安装、运行,因为COM_TENC.RSA文件里的公钥(证书的一部分)和.SF文件都没有修改,可以通过Android证书验证机制。
     联想开来,开发者主体信息很容易修改,造成知识版权问题,例如可以把Google开发的APK的开发者证书信息修改成我自己的名字,扩大影响力;或者,把自己开发的恶意APK冠上Google的名字。    
3.  证书吊销CRL    
Android证书机制并没有引入CRL吊销机制,已经吊销但拥有合法签名的证书依然可以使用,和第一项证书过期类似(证书过期,也是吊销的一种方法)。    
但是,证书吊销还有另外一个应用,当发现某个证书的私钥有泄露或是被破解时,业界常用的手法是吊销该证书,加入CRL列表,例如2012年发生的Yahoo Axis私钥泄露事件。在Android系统里,并没有采用证书吊销机制,设想场景:Adobe颁发过某个证书D(使用Adobe公钥签名该证书),然后证书D在使用过程中发生了私钥泄露,那么此时只有吊销Adobe自己的根证书才能真正使证书D失效,成本大而且会影响其他Adobe签过名的证书。    
Google的态度    
笔者就上述问题上报过Google Security。Google回复,证书机制只是用来认证开发者拥有该证书的私钥,并不验证证书本身的合法性(因为自签名系统,每个人都可以成为自己的证书颁发者)。而证书有效期问题,Google Play自己的市场有验证,但在Android系统里没有引进(为什么?),对其它第三方市场不保证。然后,证书吊销CRL机制,因为没有好的方法实现,所以没做。    
笔者认为,目前可以加强的是自签名证书的验证机制(增加一行验证代码即可),对自签名证书的数字签名也使用自签名证书的公钥进行验证,可以杜绝对.RSA/ .DSA文件的任意篡改。
Hi Yichin,    
The behavior you describe is working as intended. App signing certificates for Android are only designed to identify that the author of an app has the private key for that certificate, not to verify their actual identity. There is currently no way to effectively revoke a certificate used to sign an APK.    
This is documented here: https://source.Android.com/devices/tech/security/    
"Applications can be signed by a third-party (OEM, operator, alternative market) or self-signed. Android provides code signing using self-signed certificates that developers can generate without external assistance or permission. Applications do not have to be signed by a central authority. Android currently does not perform CA verification for application certificates."    
There is also more information here:     
http://developer.Android.com/tools/p...p-signing.html    
Regarding expired certificates, we actually enforce that APKs published in Play not expire until 2033:    
"If you plan to publish your apps on Google Play, the key you use to sign these apps must have a validity period ending after 22 October 2033. Google Play enforces this requirement to ensure that users can seamlessly upgrade apps when new versions are available."    
Although, at this time, the Android platform itself does not enforce the validity period.    
-jon    
Sony官方系统应用伪造的原因分析    
Google Play市场上出现了伪造的Sony官方系统应用,并且可以被用户覆盖升级本机的合法系统应用。Android应用的覆盖升级,前提要求是应用的覆盖前后2个版本拥有相同的开发者公钥(不是证书,仅仅是公钥),只要前后的2个公钥相同,Android默认前后2个开发者拥有相同的私钥,据此认定是同一个开发者。也就是说,伪造者和Sony使用的是相同的公钥。    
伪造者使用的是同Sony相同的公钥,却可以将应用开发者身份信息随意修改,将Sony Mobile Communications修改成Nirav Patel Kanudo。如果Android对自签名证书也进行过验证,则可以杜绝这种行为,因为一旦证书拥有者被篡改,那么该证书的数字签名不可能通过验证。    
由于新闻信息简短,而且伪造的APK已经下架(没有拿到样本),笔者做以下推论分析:    
(1)  Sony的Google账号可能有泄露,攻击者可以使用Sony账号在Google市场上传APK。    
(2)  Sony 私钥没有泄露。该APK仍然是官方出品的APK,但是被攻击者修改了证书文件里的证书拥有者信息,将Sony Mobile Communications修改成了Nirav Patel Kanudo。应用本身无害,用户使用没有问题。    
(3)  Sony私钥有泄露。攻击者修改了官方应用APK(可能植入恶意代码),然后使用Sony的私钥对修改后的APK重新打包签名,而且修改了证书文件里的证书拥有者信息(将Sony Mobile Communications修改成了Nirav Patel Kanudo),并上传到了Google Play。应用有害,用户使用有风险。    
不管是以上哪种情况,可以确认的是自签名证书中的开发者身份信息可以任意修改,Android系统缺少对自签名证书里的数字签名的验证,仅仅实现了对.SF文件的签名验证。
Android市场目前严峻形势    
1.  最权威的市场也可能存在仿冒的应用    
作为Android手机最权威的官方应用市场,Google Play一直以来都是Android应用市场中最安全的市场之一。但本次被黑应用上架的市场正是谷歌市场,可见其在审核开发者信息的过程也存在漏洞。据此前阿里移动安全的研究分析,被黑和仿冒应用的风险普遍存在,有超过80%的热门应用都存在仿冒,且平均仿冒数量高达13个。若再将开发者信息的仿冒包含在内,仿冒应用的风险形式必将更加严峻。    
在国内部分应用市场上,应用的开发者信息在应用查看,下载和安装的过程都不进行显示。且Android手机上是否允许非官方应用市场来源的应用的选项往往是打开的。国内Android的整体安全性更让人担忧。    
2.  应用不可信?用户应该如何是好?    
虽然本次事件不一定会造成严重风险,但因为Android应用安装的漏洞和Android应用市场的不规范,导致不可信应用非常普遍,用户还是需要引起注意,阿里钱盾专家提醒大家:    
(1)涉及账户,资金的应用如淘宝,支付宝,微信等 尽量在官方网站进行应用下载。    
(2)谨慎选择应用,并在手机上安装安全软件,防止自身信息的泄露。    
(3)用户可以通过安装阿里钱盾,获得最重要的网购和资金安全保护。
Android证书验证存漏洞 开发者身份信息可被篡改(转)的更多相关文章
- android签名分析及漏洞修复
		
本篇我们来看看android的签名机制.发布出来的apk都是有META-INF文件夹,里面包含如下三个文件: 下面来一一解释这三个文件的作用(打包apk时签名过程):SignApk.main() 1. ...
 - Python‘ssl.match_hostname()’函数SSL证书验证安全绕过漏洞
		
漏洞名称: Python‘ssl.match_hostname()’函数SSL证书验证安全绕过漏洞 CNNVD编号: CNNVD-201312-033 发布时间: 2013-12-04 更新时间: 2 ...
 - 【腾讯Bugly干货分享】iOS 中 HTTPS 证书验证浅析
		
本文来自于腾讯Bugly公众号(weixinBugly),未经作者同意,请勿转载,原文地址:https://mp.weixin.qq.com/s/-fLLTtip509K6pNOTkflPQ 导语 本 ...
 - 通俗的理解HTTPS以及SSL中的证书验证
		
一.HTTPS的安全性体现在哪 HTTP(超文本传输协议,Hyper Text Transfer Protocol)是我们浏览网站信息传输最广泛的一种协议.HTTPS(Hyper Text Trans ...
 - 基于X.509证书和SSL协议的身份认证过程实现(OpenSSL可以自己产生证书,有TCP通过SSL进行实际安全通讯的实际编程代码)good
		
上周帮一个童鞋做一个数字认证的实验,要求是编程实现一个基于X.509证书认证的过程,唉!可怜我那点薄弱的计算机网络安全的知识啊!只得恶补一下了. 首先来看看什么是X.509.所谓X.509其实是一种非 ...
 - 了解SSL证书从HTTPS开始 开发者绕不开的“劫”
		
微信小程序上线已经有很长一段时间了,而开发者在接入小程序的过程中,会遇到一些问题,例如小程序要求必须通过HTTPS完成服务端通信,开发者需搭建HTTPS服务,进行 SSL 证书申请.部署,完成HTTP ...
 - Android免费短信验证
		
转载请注明住处:http://blog.csdn.net/crazy1235/article/details/41912003 介绍 短信验证功能大家都很熟悉了.在很多地方都能见到,注册新用户或者短息 ...
 - 谷歌发布 Android 8.1 首个开发者预览版,优化内存效率
		
今晨,谷歌推出了 Android 8.1 首个开发者预览版,此次升级涵盖了针对多个功能的提升优化,其中包含对 Android Go (设备运行内存小于等于 1 GB)和加速设备上对机器学习的全新神经网 ...
 - 5G信令(就是用户身份信息)风暴——就是客户端通过公钥加密的消息(携带手机IMSI号)发给服务端,服务器需用私钥解密,这个解密比较消耗资源,如果短时间大量请求到来就会触发信令风暴
		
信令:手机开机后,先从USIM中读取之前运营商分配的临时身份信息GUTI/TMSI,发送携带该身份信息的信令给基站,请求接入运营商网络. 如果每个设备的每条消息都需要单独认证,则网络侧安全信令的验证需 ...
 
随机推荐
- Web应用程序开发,基于Ajax技术的JavaScript树形控件
			
感谢http://www.cnblogs.com/dgrew/p/3181769.html#undefined 在Web应用程序开发领域,基于Ajax技术的JavaScript树形控件已经被广泛使用, ...
 - python读写Excel文件_xlrd模块读取,xlwt模块写入
			
一.安装xlrd模块和xlwt模块(服务器) 1. 下载xlrd模块和xlwt模块 到python官网http://pypi.python.org/pypi/xlrd下载模块.下载的文件例如:xlrd ...
 - Go 实现 soundex 算法
			
[转]http://www.syyong.com/Go/Go-implements-the-soundex-algorithm.html SOUNDEX 返回由四个字符组成的代码 (SOUNDEX) ...
 - 【Python实例二】BeautifulSoup爬虫简单实践
			
前言 前面安装了BeautifulSoup库,现在就来实现一下吧. 目录 一.Urllib库的使用 二.BeautifulSoup的使用 三. 一个示例 ----------------------- ...
 - Logistic函数
			
Logistic函数(又称sigmoid函数) Logistic函数或Logistic曲线是一种常见的S形函数,它是皮埃尔·弗朗索瓦·韦吕勒在1844或1845年在研究它与人口增长的关系 ...
 - mongo语法和mysql语法对比学习
			
我们总是在对比中看到自己的优点和缺点,对于mongodb来说也是一样,对比学习让我们尽快的掌握关于mongodb的基础知识. mongodb与mysql命令对比 关系型数据库一般是由数据库(datab ...
 - Linux内核官方文档atomic_ops.txt【摘自Linux 内核文档】
			
摘自Linux内核文档 Documentation/atomic_ops.txt,不是本人原创 Semantics and Behavior of Atomic and Bitmask Operati ...
 - 如何在 Linux 上锁定虚拟控制台会话
			
当你在共享的系统上工作时,你可能不希望其他用户偷窥你的控制台中看你在做什么.如果是这样,我知道有个简单的技巧来锁定自己的会话,同时仍然允许其他用户在其他虚拟控制台上使用该系统.要感谢 Vlock(Vi ...
 - Linux-进程间通信(二): FIFO
			
1. FIFO: FIFO也被成为命名管道,因其通过路径关系绑定,可以用于任意进程间通信,而普通无名管道只能用于有共同祖先的进行直接通信; 命名管道也是半双工的,open管道的时候不要以读写方式打开, ...
 - ubuntu下中文输入法安装
			
个人认为ubantu下fcitx比sogo好用 安装fcitx首先到ubantu软件中心下载fcitx两个软件,一个是配置软件,一个是输入法软件 到system setting中language su ...