移动安全(二)|APK打包流程及签名安全机制初探

2020-07-09 17:21:35 Author: www.secpulse.com
觉得文章还不错?,点我收藏



0x00、今天我们聊什么?

  今天我们聊些啥?许久不见,是该聊些啥了,话不多说,先来个五毛钱得,聊一聊胡小毛Android逆向之路吧,当然,你们想知道的一定不是走了这么远的路,胡小毛今年是不是又长高了,那么我们开始看看他又Get到的新zishi吧(本文内容为MaoXH总结,喜大奔普,胡小毛的新id:MaoXH<毛小胡>)。



0x01、切入正题,apk文件结构

    切入正题,胡小毛在学习Android逆向的过程中又有所总结,先来看看apk文件结构:

    首先拿一款普通app讲解,用zip压缩文件打开会出现以下文件夹:


  • Assets目录用来存放需要打包到 Android 应用程序的静态资源文件,例如图片资源文件、JSON 配置文件、渠道配置文件、二进制数据文件、HTML5离线资源文件等。与res/raw 目录不同的是,assets 目录支持任意深度的子目录,同时该目录下面的文件不会生成资源ID

  • Lib目录存放的是当前app所用得到的so动态链接库文件,so文件就是利用底层的cc++代码实现的。

  • META-INF目录存放的是所用到的证书签名文件,包括:MANIFEST.MF(摘要文件)、CERT.SFCERT.RSA。其中MANIFEST.MF文件是对每个文件的SHA-256-DigestCERT.SF是对每个文件的头3行进行SHA-256-DigestCERT.RSA这个文件保存了签名和公钥证书。

  • Res目录放应用的资源文件,包括图片资源、字符串资源、颜色资源、尺寸资源等,这个目录下面的资源都会出现在资源清单文件 R.java 的索引中。

  • AndroidManifest.xmlAndroid项目的系统清单文件,Android应用的四大组件(ActivityServiceBroadcastReceiver ContentProvider )均在此配置和声明。

  • classes.dex:应用程序的可执行文件。若APP有多个dex,是因为当前的方法数超过65535,进行了分包处理。如果未超过,则只有一个dexAndroid的所有代码都集中在此。可以通过反编译工具dex2jar转化成jar包,再通过jd-gui查看其代码。

  • resources.arsc:资源索引表,用来描述具有ID值的资源的配置信息。

0x02、开始正戏,apk打包流程

   看完了上面的apk的文件结构,我就要开始我们的正戏了,首先是“小二,上图~,上长图~

放心,不是表情包

上图就是一个apk包的细化打包流程,包含了每个细化过程可能会用到的工具,各位看官可多注意橘色标注字体部分。然后我们再看一下应用安装涉及到的如下几个目录:

system/app ---------------系统自带的应用程序,获得adb root权限才能删除

data/app  ---------------用户程序安装的目录。安装时把apk文件复制到此目录

data/data ---------------存放应用程序的数据

data/dalvik-cache--------apk中的dex文件安装到dalvik-cache目录下(dex文件是dalvik虚拟机的可执行文件,其大小约为原始apk文件大小的四分之一)

安装过程具体表现为:

复制APK安装包到data/app目录下,解压并扫描安装包,把dex文件(Dalvik字节码)保存到dalvik-cache目录,并在data/data目录下创建对应的应用数据目录。

对应的卸载过程为:

删除安装过程中在上述三个目录下创建的文件及目录。

0x03、正戏ING,虚拟机

     有事好好说,没事干啥提虚拟机啊,胡小毛也是搞得我晕头转向,莫慌,仔细瞧瞧,发现小毛得学习思路还是可圈可点得。上面提到得dalvik虚拟机,可能并未引起各位看官的注意力,所以这边再多唠叨一遍。

首先是java虚拟机,我们知道java语言有一个很重要的特性就是跨平台可以做到一次编译,到处运行的效果。怎样才能有这样的特性呢?主要就是依靠的java虚拟机(JVM)。当我们编写好一个java程序之后如test.java。然后将其编译为一个字节码文件test.class。在java虚拟机上运行这个字节码文件,java虚拟机就可以把字节码文件解释成具体平台上的机器指令执行,而实现了java的跨平台特性。

然后我们需要知道的是Android是基于Dalvik虚拟机(DVM)art虚拟机(aot机制)的。Dalvik虚拟机主要应用于Android5.0及以前,而ART(Android Runtime)虚拟机是 Android 4.4 发布的,用来替换 Dalvik 虚拟机,Android 4.4 默认采用 DVM,但是可以选择使用 ART。在 Android 5.0 版本中默认使用 ART,DVM 从此退出历史舞台。

具体可参考:https://www.jianshu.com/p/a37d3be0a341。

而JDM、DVM、ART之间的关系可参考下图:



0x04、拓展知识,Android签名机制

  还记得之前提到的META-INF目录吗?里面的签名证书文件就是对apk进行签名过程中生成,apk签名过程可以总结如下:

 1、对Apk中的每个文件做一次算法(数据SHA1摘要+Base64编码),保存到MANIFEST.MF文件中,具体作法可以理解为程序遍历APK包中的所有文件,对非目录、非签名文件的文件,逐个用SHA1生成摘要信息,再用Base64进行编码后保存。基于此文件的安全机制可以进行文件完整性校验:如果APK包的文件被修改,在APK安装校验时,被修改的文件与MANIFEST.MF的校验信息不同,程序将无法正常安装,同理CERT.SF和CERT.RSA文件同样应用于apk的完整性校验。    

MANIFEST.MF文件格式如下:

        

2、对MANIFEST.MF整个文件做一次算法(数据SHA1摘要+Base64编码),存放到CERT.SF文件的头属性中,再对MANIFEST.MF文件中各个属性块做一次算法(数据SHA1摘要+Base64编码),存到到一个属性块中。

CERT.SF文件格式如下:

      

 3、对CERT.SF文件做签名,内容存档到CERT.RSA中,所以CERT.RSA是一个加密文件,所以它长的很难看,不信的自己去看:

了解了上面apk的签名过程,我们可以深入思考一下下面这段话(某大神原话):

假如我们是一个非法者,想要篡改apk内容,我们怎么做呢?如果我们只把原文件改动了(比如加入了自己的病毒代码),那么重新打包后系统就会认为文件的SHA1-Base64值和MF的不一致导致安装失败,既然这样,那我们就改一下MF让他们一致呗?如果只是这样那么系统就会发现MF文件的内容的SHA1-Base64与SF不一致,还是会安装失败,既然这样,那我们就改一下SF和MF一致呗?如果这么做了,系统就会发现RSA解密后的值和SF的SHA1不一致,安装失败。那么我们让加密后的值和SF的SHA1一致就好了呗,但是呢,这个用来签名加密的是私钥,公钥随便玩,但是私钥我们却没有,所以没法做到一致。所以说上面的过程环环相扣,最后指向了RSA非对称加密的保证。

最后我们必须要知道签名机制只是保证了apk的完整性,具体是不是自己的apk包,系统并不知道,所以对于上面的通过apk签名进行完整性校验,攻击者可以通过直接重签名,让所有的信息都一致就能绕过校验,这样重签名后就可以安装了。所以对于应用签名是否被篡改,那就是另一门学问了……

 

参考链接:

1、https://blog.csdn.net/loongago/article/details/89646920

2、https://www.jianshu.com/p/a37d3be0a341

3、https://blog.csdn.net/lostinai/article/details/54694564?utm_source=blogxgwz3

往期经典推荐:

----------------------------------------------------------------------

移动安全(一)|Android设备root及神器Xposed框架安装



>>关于我们:

WhITECat安全小组隶属于起源实验室分支安全小组,主要致力于分享小组成员技术研究成果、最新的漏洞新闻、安全招聘以及其他安全相关内容。团队成员暂时由起源实验室核心成员、一线安全厂商、某研究院、漏洞盒TOP10白帽子等人员组成。

本文作者:辞令_WhITECat

本文为安全脉搏专栏作者发布,转载请注明:https://www.secpulse.com/archives/134960.html




觉得文章还不错?,点我收藏



如果文章侵犯到您的版权,请联系我:buaq.net[#]pm.me