转自CSDN《程序员杂志》         作者:火点,三金

7月30号,新闻又爆出Bluebox安全研究团队发布的安卓新的签名漏洞 “假 ID”,除了最新的4.4版本,几乎所有安卓设备都有此漏洞,本文通过技术分析漏洞细节,发现竟然能制作盗版支付宝,绕开360手机卫士的病毒查杀和支付保镖检测。

  • 爆出漏洞

7月30号,Bluebox安全研究团队又对外纰漏新的签名漏洞,这是自去年轰动一时的master key漏洞后又一爆点。号称这一漏洞会影响安卓2.1以上系统所有设备,尽管最新的安卓系统4.4或者称KitKat已经修复了这一漏洞,但是仍然有10几亿的安卓设备受到影响。每一个安卓应用程序都有自己的数字签名,本质上来说就是一张ID卡,该漏洞通过伪造假的ID,能模拟Adobe flash插件,注入到浏览器,获得用户在浏览器输入的隐私信息,或者冒充谷歌钱包,然后获得付款和财务数据。

在今年的Blackhat大会上,Bluebox成员Jeff也有一个关于漏洞细节以及如何利用的精彩演讲,有兴趣的读者可以看看相关文档和视频。

  • 签名那点事儿

Google在4.4上已经打上patch修补了这个签名漏洞,虽然只有短短10几行代码,但是背后的技术原理却极其复杂,请跟我一起来深入剖析,解开安卓签名技术的神秘面纱。

如果你之前对于数字签名不太了解的话,建议先了解PKI,PKCS,RSA,X509等等这些概念。

简单的说,PKI(Public Key Infrastructure)是一套利用公钥加密技术的规范,包括PKCS(Public Key Cryptography Standards)公钥密码系列,X509数字证书系列等等。RSA则是应用最广的公钥加密算法。

X509证书标准用到了公钥加密,引入CA (CertificateAuthority)发证书,作为可信第三方。然而,Google在设计应用签名的时候做了简化,去掉了CA,每个应用变成了自签名,也就是说应用自己生成证书,然后对自己的应用签名,发布出去,在安装应用的时候,系统只是通过安装包证书来验证安装包的完整性,却无法鉴别证书的真假。这个设计留下了巨大的安全设计缺陷,从此安卓的世界里盗版泛滥,广告,病毒,木马可以轻松的通过二次打包嵌入到原本干净的应用中,这个生态圈将永无宁日。

有人会问,这么简单的设计缺陷,Google那帮精英难道不知道吗?当然知道!那为神马要这么做呢?原因很简单,开源,免费。如果引入CA,CA肯定会通过给应用开发者发签名证书收费,除非Google愿意自己搭建免费CA,况且即便是Google搭建了,由于安卓系统可以定制,下游的手机厂商也不一定会买单,不想被Google控制束缚,而且应用市场也不是Google Play这一家,普及起来就更困难了,Google想想还是算了。

回到技术细节,来看看安卓应用签名的实现原理吧。安卓应用APK签名和以前jar签名是一个原理,签名信息会放在META-INF目录下,以RSA签名为例,会生成3个文件。

1    MANIFEST.MF :标准清单文件,记录压缩包的基本信息,其中跟签名相关会记录压缩包中每个文件的hash值,用Base64转码保存如下,称为一个attribute。

Name:res/drawable-xhdpi/ic_launcher.png

SHA1-Digest: h5qMn5HNV9J4T42+TizyymqBqko=

2.   CERT.SF:首先记录MANIFEST.MF整个文件的hash,然后是对1中每个attribute分别hash,生成一个entry,用Base64转码保存,和1的attribute很像,但是意义完全不同。有人会问有了MF整个hash,为什么还要对每个attribute再做hash,不是啰嗦,这个问题嘛,其实是早期Jar包为了多次打包多次签名使用的,所以MANIFEST.MF的hash就不一致了,安卓APK不存在这个情况,只是为了兼容标准实现。

SHA1-Digest-Manifest:veBzu0Shy8A3Y9LbBu1pCzVFv8Q=

Name:res/drawable-xhdpi/ic_launcher.png

SHA1-Digest:urIZIkZ1uHqF6dEXkraM62bnjlU=

3.    CERT.RSA :这个才是真正的X509证书文件。X509证书有两种格式PEM和DER,两者是等价的,可以通过openssl工具互相转换,CERT.RSA使用的DER格式,这个格式使用的是ASN1编码。巴拉巴拉一堆名词,可能会晕。简单的说CERT.RSA就是一个二进制文件,可以通过工具ASN1 Editor查看编辑。证书里面包含最重要的信息如下:issuer签发者,subject使用者,由于是自签名,所以issuer和subject是相同的。对CERT.SF经过hash和加密后放到signer info中就和原始证书构成了一个带签名信息的证书。

图1-生成带签名信息的证书

常见的签名工具有如下两类:

Oracle Java提供的keytool生成证书, jarsigner签名。

Openssl工具生成证书,Google工具signapk签名。

Android签名的核心过程主要集中在以下几个类和方法中:

PackageParser: collectCertificates()

PackageParser: loadCertificates()

JarFile: getInputStream()

JarVerifier: readCertificates()

JarVerifier: verifyCertificate()

JarUtil: verifySignature()

JarUtil: createChain()

JarUtil. findCert()

核心流程也非常简单:循环遍历APK中的每个文件,第一步验证对应的证书是否正确,证书可能有多个,所以也要循环验证,通过验证证书可以保证CERT.SF中对应在MANIFEST.MF的attribute项是没有篡改的;第二步就是读取这个文件,通过hash对比MANIFEST.MF中的项,保证文件没有篡改。

第一步中验证单个证书是否正确的流程主要是JarVerifier: verifyCertificate()方法中,详细步骤如下:

·        对CERT.SF文件做hash,对证书中signer info的加密数据用public key解密,然后比对比是否相等,调用了JarUtils.verifySignature(),同时也会生成证书链,用于后续返回。

·        第一步验证通过了,说明CERT.SF没有篡改,然后利用CERT.SF去验证整个MANIFEST.MF的hash是否相等,如果不相等,退而求其次验证CERT.SF中的entry和MANIFEST.MF对应attribute的hash是否相等。

·        第二步验证通过,则返回第一步生成的证书链。

细心读者会发现,怎么突然冒出一个证书链的概念?没错,问题就出在这里,Google的数字签名是支持X509的,前面提到CA的概念,如果引入CA,那么证书就会有两级,一个CA,一个自己的,当然实际情况很复杂,会有很多级CA形成树形结构,所以就有证书链的概念,下级的issuer等于上一级的subject,以此类推,直到issuer和subject相等,就是根CA。实际的证书链就会变成如下形式。这个模型的安全关键是上一级证书的issuer会对下一级有一个签名,放到下一级证书的issuer signature节点,从而保证这个证书是我发的,别人没法伪造,在验证证书链的时候,通过上一级的public key对下一级的issuer signature进行解密验证保证合法性。

图2-带证书链的证书

在JarUtils.verifySignature()代码会调用createChain(),代码如下,首先根据证书文件的signer info,找到了第一个证书,然后根据它的issuer遍历找到上级证书,直到找到根证书(issuer和subject相同)。Google解决漏洞的patch关键就在红色标记部分,如果没有这部分代码,建立证书链只要匹配到issuer就可以了,显然通过上面的分析没有验证issuer signature,那么这个证书链就无法保证合法性,攻击者可以简单地通过修改证书的issuer和subject字段很容易伪造一个证书,瞒天过海,通过验证。

实际上安卓APK都是自签名,只会有一个证书,压根就不会有包含多个证书的证书链,但是代码中又支持了X509证书链,像这种旮旯角落的代码,Google肯定没人去测试过,所以这么多年过去了(从android2.1版本开始),漏洞影响的设备就越来越多。

  • 影响到底有多大

这个漏洞的危害到底有多大呢?这就涉及到android系统对证书签名的验证情况,网上有一篇360安全研究员申迪写的《FakeID签名漏洞分析及利用》很详细的描述了如果利用这个漏洞伪造一个Adobe Flash插件,注入到浏览器,形成攻击。

其核心在以下签名验证代码,浏览器内核Webkit在验证签名的时候只要有一个签名相等,就授权,Bluebox声称的冒充谷歌钱包应该也是类似原理。

安卓系统中还有哪些地方用到签名呢?是不是也有类似的问题呢?

安卓系统用到签名有两个地方,一个是签名权限,一个是share UID。对于权限,大部分安卓开发者都知道,要用的时候在AndroidManifest.xml中申请就可以了,但是很少有人知道权限有个分级属性protection level,有dangerous, normal,signature,system等,平常大家用的大多是dangerous或normal,只要申请了就可以用,但是signature权限,必须要求定义权限的APK和申请权限的APK相同签名。

另外一个是share UID,同样是在AndroidManifest.xml申明,这样就可以在让自己的组件运行在另外一个APK的进程中,如果你申明share UID是system,基本上在系统中可以畅通无阻,但提前也是相同签名。

Google开发framework核心的大牛还是逻辑很清晰的,以上两个功能在比较签名的时候都用到同一个方法: PackageManagerService.compareSignatures(),要求两个APK的签名必须签名个数相同,每个签名也必须相同,这么严格的限制使伪造证书链无法绕开验证,因为证书个数不一样,大牛果然是大牛,能够防患于未然,致敬!

只能说开发Webkit内核的工程师对签名的理解就没有那么深刻,所以才会出现上面的逻辑。

  • 联想攻击

于是我们开始头脑风暴,脱离系统层面,还会有哪些场景用到了签名比较。前面提到了安卓二次打包泛滥,滋生了很多恶意程序,国内各大市场引入了正版验证技术,在正版应用首发的时候通过解析APK中的证书拿到真实自签名证书,后续再有安装包上传市场,就可以通过签名比对确认是否是盗版,360助手,豌豆荚等都有类似功能。

由于移动支付的普及流行,二次打包危害最严重的就是移动金融应用。因此,几乎所有安全软件都退出支付安全功能,其中一个重要的保障就是对盗版金融应用的检查,帮助用户鉴别盗版应用,免收欺诈。

除此之外,一些支付应用自身也会在程序逻辑中做远程签名验证,就是将APK中的签名上传服务器验证,一旦检查不相同,立刻封号。

我们设想上述提到的应用在做正版签名时是否也会犯类似的错误?只验证根证书或者只要匹配一个证书成功就可以了。

于是我们选取支付宝作为测试,被测对象我们选取了360手机卫士,腾讯手机管家和豌豆荚应用市场,攻击步骤如下:

§  通过以下脚本构造证书链

# need to create folder demoCA, demoCA/certs, demoCA/newcerts under current folder

# need to create empty file demoCA/index.txt under current folder

# need to create file serial under current folder, then echo 01 to the file

openssl genrsa -out ca.key 1024

openssl req -days 3650 -new -x509 -key ca.key -out ca.crt

keytool -genkey -alias cert -validity 365 -keyalg RSA -keysize 1024 -keypass 123456  -storepass 123456 -keystore server_keystore

keytool -certreq -alias cert -sigalg MD5withRSA -file cert.csr -keypass 123456 -storepass 123456 -keystore server_keystore

openssl ca -in cert.csr -out cert.crt -cert ca.crt -keyfile ca.key -notext -config openssl.cnf

keytool -import -v -trustcacerts -alias my_ca_root -file ca.crt -storepass 123456 -keystore server_keystore

keytool -import -v -alias cert -file cert.crt -storepass 123456 -keystore server_keystore

keytool -list -v -keystore server_keystore -storepass 123456

  • 提取正版APK中的CERT.RSA文件
  • 删除支付宝APK中的META-INF文件夹,对支付宝进行重签名

jarsigner -keystore server_keystore-storepass 123456 -signedjar alipay_fake.apk alipay.apk cert

  • 将盗版支付宝APK中的CERT.RSA文件提取出来,用ASN1 Editor(本来是写了tool改的,后来发现这个神器,一切都简单了)分别打开正版和盗版CERT.RSA,删除掉假证书的根证书节点,将真证书中的根节点复制到假证书中,参考alipay证书中issuer节点修改signerinfo中的issuer节点。
  • 安装在手机上,抓取系统中保存所有安装包信息的文件/data/system/packages.xml,对比发现盗版支付宝有2个签名证书,其中一个和真证书相同

图3-系统中真假支付宝签名信息

  • 然后分别用3款软件进行扫描(版本信息如下),看是否有盗版提示,检查结果如下,只有360手机卫士没有检测出盗版,另外2款都检测出来了。
  支付宝   8.2.0
  360手机助手   5.2.3
  腾讯手机管家   5.0.0
  豌豆荚   4.13.1

图4-盗版支付宝检测结果,从左到右依次是腾讯手机管家,豌豆荚,360手机卫士

最后,我们又做了一个实验,只用一个假证书做成盗版支付宝,结果除了支付宝自身,其他3家都可以检测出来。于是我们断定支付宝没有实现自我签名验证,也就是说如果用户手机上没有装盗版检测的软件,那存在很大的可能性,用户的支付宝账户被盗,财产受损。

  • 小结

我曾在8月7号通过CSDN发过一篇短评,披露360盗版检测的问题,当时使用版本是5.2.3,360手机卫士最新版5.2.5.1038已经能检测盗版的问题,用户升级后可以放心使用。同时我们也希望支付宝作为支付行业龙头,这种基本的自我保护是必须做的,不能完全依赖于第三方软件检测,这也是对用户最基本的责任。

Android“FakeID”签名漏洞分析和利用相关推荐

  1. Android Parcelable反序列化漏洞分析与利用

    文章目录 前言 背景知识 Parcelable序列化 Bundle的数据结构 LaunchAnyWhere CVE-2017-13288 漏洞利用原理解析 POC程序攻击演示 CVE-2017-133 ...

  2. Android BlueBorne (CVE-2017-0781)漏洞分析和利用

    导语:几天前,Armis公司发布了一个通过蓝牙攻击Android系统的远程代码执行安全漏洞(CVE-2017-0781)的PoC,这个漏洞也叫做BlueBorne.尽管BlueBorne是一组8个漏洞 ...

  3. 易想团购 注入 user.php,易想团购系统通杀SQL注入漏洞分析及利用漏洞预警 -电脑资料...

    刚打开红黑看到J8基友写的一个{易想团购系统 最新版 通杀}的文章,看他贴的代码里面有个get_client_ip()函数,哈哈,我猜没过滤,果断下了一套程序, 找到get_client_ip()函数 ...

  4. php5漏洞汇总,ThinkPHP 5.x RCE 漏洞分析与利用总结

    一.ThinkPHP 5.0.23 rce漏洞复现与总结 漏洞复现 thinkphp 5.0.23 rce thinkphp 5.0.23 rce源码下载: github:https://github ...

  5. Free CD to MP3 Converter V3.1 栈溢出漏洞分析与利用

    Free CD to MP3 Converter V3.1 栈溢出漏洞分析与利用 测试环境及工具: windbg IDA winxp sp3 这算是正式调试分析的第一个漏洞,也是跟着一位学长的博客做一 ...

  6. 网络***实战:老Y文章管理系统V2.2注入漏洞分析与利用

    网络***实战:老Y文章管理系统V2.2注入漏洞分析与利用 安天365团队     同学说让我帮忙架设一个网站,同时要保证整个网站的安全.自己开发,开玩笑,工作量巨大,还是通过网络,在别人的基础上进行 ...

  7. CVE-2014-7911 Android本地提权漏洞分析与利用

    概述 前面我们了解了Android Binder机制的基本原理,当然仅仅了解是不够的,我们要做到:Know it and hack it.这篇文章我们就来分析一个和Binder相关的漏洞:CVE-20 ...

  8. CVE-2015-3636(pingpong root) android内核 UAF漏洞分析

    前言 去年差不多这个时候就计划把这个漏洞给分析了,由于android没有经常搞,所以踩了很多坑,中间一度因为各种原因停滞放弃,最近遇到一个事情让我下定决心把它了结,也算是解决一个心病.过程会写详细一点 ...

  9. android mediaserver Stagefright 漏洞分析

    转自:http://drops.wooyun.org/papers/7558 使用Stagefright库的应用程序以Media权限运行,成功利用漏洞,允许攻击者浏览器媒体库相应的文件,但通过权限提升 ...

最新文章

  1. hadoop系统 hdfs 命令行操作
  2. 121.买卖股票的最佳时机
  3. c++面试题之内存分配
  4. Mysql的体系结构概览
  5. A Network in a Laptop: Rapid Prototyping for Software-Defined Networks
  6. aws mysql价格_mysql – AWS RDS“转出”成本有多贵?
  7. DevExpress.Utils.ToolTipLocation
  8. css 改变输入框光标颜色
  9. java技术学习路线
  10. java初级程序员需要掌握技能,快来看鸭~
  11. 【学术 | 比赛】比赛?论文?先收藏!29个学术网站,比赛论文不再困难
  12. SD卡格式化重建分区
  13. java工程师怎么接私单_Java开发者如何接私活?
  14. 咸蛋超人的CxImage学习之路(一)
  15. 读遍装修书,我们帮你选出了最有用的10本
  16. Mansory之一 :mas_equalTo和equalTo区别与使用
  17. 电压比较器采样电路调试
  18. IDEATerminate vs Disconnect
  19. 【NOI模拟赛】纸老虎博弈(博弈论SG函数,长链剖分)
  20. 解决iframe中引入页面的js失效

热门文章

  1. 协同办公工具:在线白板初起步,在线设计已红海
  2. Android 开发飞机大战
  3. JsTreeの使用-yellowcong
  4. java 视频压缩转码_java实现视频压缩转码
  5. mybatis开启二级缓存
  6. ZYNQ_MP启动过程分析
  7. pythonturtle画小丸子_小丸子成长记---在stylus下用DIV+CSS一步一步打造小丸子
  8. SQL SERVER: 行转列
  9. Excel VBA 快速访问 Power Query 表格数据
  10. Golang教程:(十一)数组和切片