2016年10月10日星期一

Android 逆向学习笔记 (四)- 签名校验突破

有的时候在篡改 apk 并且重新打包之后不能直接运行,此时部分情况是因为存在软件的签名校验机制。在前面几篇的学习中可以知道,软件打包之后需要重新签名才可以安装到安卓机器上,此时重新签名一般用的都是公开的  platform.x509.pem 和 platform.pk8 , 有的软件为达到防篡改的目的会对新老签名进行比较,如果存在差异则确定被篡改,程序终止。

除了签名校验之外,还有一种情况是 classes.dex 的 MD5 检验,也可以发现被篡改的 classes.dex。怎么区分这两种不同的校验呢?拿到 apk 之后对其重新签名,如果仍然可以正常安装运行的即说明是 classes.dex 的 MD5 校验,反之则是签名校验。

一般在程序内进行的校验有两种途径,在线比对和离线比对,逆向者在意的是比对的这个过程及其参数。在线比对和离线比对的区别是:在断网情况下仍旧闪退的是离线比对,断网后先提示没有网络连接再闪退的是在线比对。

既然校验的过程是在本地程序进行的,那么在反编译得到代码之后,只要修改一下比较时的对应条件就可以简单的绕过校验了,整个校验过程有点掩耳盗铃的意思。

Signature · smali

获取当前 apk 签名的 Java 代码如下:

PackageInfo packageInfo = getPackageManager().getPackageInfo(
                    "xx.xxx.xx", PackageManager.GET_SIGNATURES);
Signature[] signs = packageInfo.signatures;

对应的 smali 代码为:

Landroid/content/pm/PackageInfo;->signatures:[Landroid/content/pm/Signature

所以对付签名校验,只要通过这段关键代码找到对应的调用位置,不断跟进,确定最终判断的位置然后修改比较条件即可。

另外有的时候会进入 native 层判断,这个时候搜索关键字 signature 然后判断跟进即可。

MD5 · smali

这类首先会在 smali 层获取当前 apk 的目录,然后再传入 native 层面进行比较,典型代码如下所示:

iget-object v1, v0,Landroid/content/pm/ApplicationInfo;->sourceDir:Ljava/lang/String;
const-string v1, "/sdcard/buyudaren.apk" # 本行目的是 bypass 校验,路径为原版 apk 路径,覆盖 v1
invoke-static {v1}, Lorg/cocos2dx/lib/Cocos2dxHelper;->nativeSetApkPath(Ljava/lang/String;)V

简单添加中间一行即可绕过 MD5 的判断,因为此时进入 native 层的是原版 apk 的路径,所以校验的也是原版 apk,此时当然没有问题。可以看到,看似复杂的进入 native 层面有的时候只是掩耳盗铃的一种方式。

如果要进入 native 层面去 Bypass 检查,在把 .so 文件拖入 IDA Pro 后搜索 “classes.dex” 即可,跟进可以发现 MD5 字符串或是进行比对的特征值。

另外有时存在 .so 和 classes.dex 文件相互验证的情况,这个时候就对应的搜索 “classes.dex” 和 “xxx.so” 两个特征字符串,找到程序运行中校验的文件路径,然后对应地修改成原版文件的路径即可。

REFERENCE



* 另外说一下,有的时候两个程序的 AndroidManifest.xml 中定义了 SharedUserId 并进行交互,这时必须两个程序的签名相同才可以正常安装。

Related Posts:

  • Android 逆向学习笔记 (五)- ARM 和 Thumb 指令集学习学习安卓逆向,ARM 和 Thumb 是两个绕不开的内容。Thumb 可以看作是 ARM 指令集压缩形式的子集,是针对指令长度问题而提出的,它具有 16 位的指令长度(ARM:32 位),但操作数、指令地址这两项 Thumb 均和 ARM 相同,为 32 位,所以如果想要区分当前指令是 ARM 还是… Read More
  • Android 逆向学习笔记 (七)- ELF 简单介绍现在越来越多的安卓 app 为了保证软件的安全性,会使用 NDK 来进行 Native 开发,最后会产生一个 .so 这样的 ELF 文件,通过动态加载这个 ELF 文件调用隐藏在 .so 文件里的方法。 不过有的时候经过处理的 ELF 文件直接拖入 IDA 会报错,像下面这样,如果强行在 IDA… Read More
  • ANDROID 逆向学习笔记 (三)- IDA 动态调试 so 前面几篇所说的均是对安卓进行 smali 静态分析的内容,本节探讨一下动态的调试和分析,将会使用到的是 IDA Pro (金山 leak)和 Android Studio 的部分工具(模拟器,ddms,adb 等)。 Android Studio 的官方网址是: https://dev… Read More
  • Android 逆向学习笔记 (四)- 签名校验突破有的时候在篡改 apk 并且重新打包之后不能直接运行,此时部分情况是因为存在软件的签名校验机制。在前面几篇的学习中可以知道,软件打包之后需要重新签名才可以安装到安卓机器上,此时重新签名一般用的都是公开的  platform.x509.pem 和 platform.pk8 , 有的软件为达到… Read More
  • Android 逆向学习笔记 (六)- 安卓脱壳之 dvmDexFileOpenPartial 加壳 学习脱壳之前,首先先学习一下什么是加壳,加壳是在二进制的程序中植入一段代码,在运行的时候这段植入的代码会优先取得程序的控制权,做一些额外的工作(将原来的代码还原出来执行,以达到保护原来的代码直接暴露的问题)。大多数病毒就是基于此原理。 Android 作为新兴出现的平台,加壳方式不像 PC… Read More