Android应用完整性保护总结

栏目: 编程工具 · 发布时间: 5年前

内容简介:对 Dex 文件的局部(可以是头部、代码段等等)求MD5值,并将MD5写入dex文件的末尾或其他不影响dex文件加载运行的位置(本人暂时还没碰到)

一、静态完整性校验

1、对Dex文件进行完整性校验

由于  Android 稍高版本在安装 APK 的过程中会把 classes.dex 抠出来转化为odex或者 vdex 等其他格式的优化文件,原 APK 中无 classes.dex ,但是会存在除  classes.dex  外的其他多dex文件(比如 classes2.dex classes3.dex 等),故 无法校验 classes.dex ,也无法校验整个 APK 文件哈希值。

通过读取 APK  包中的除 classes.dex 外的其他 dex 文件,并计算其 CRC 的值,将得到的 CRC 与原始 CRC 进行比较,判断是否被修改过,原始 CRC 值保存在资源文件或其他自定义文件中相关代码:

String apkPath=context.getPackageCodePath();//获取Apk的路径
ZipFile zipFile=new ZipFile(apkPath);
ZipEntry dexEntry=ZipFile.getEntry("classes.dex");//读取zip包中的classes.dex文件
String dexCRC=dexEntry.getCrc().toString();//计算dex的CRC文件值

对 Dex 文件的局部(可以是头部、代码段等等)求MD5值,并将MD5写入dex文件的末尾或其他不影响dex文件加载运行的位置(本人暂时还没碰到)


相关代码:

MessageDigest digest=MessageDigest.getInstance("MD5");
byte[] bytes=new byte[1024];
FileInputStream fileinputStream=new FileInputStream(new File(dexPath));
int byteCount; 
while(fileinputStream.read(bytes)!=-1){
 digest.update(bytes,0,byteCount);
}
BigInteger bigInteger=new BigInteger(1,digest.digest());//计算dex的哈希
String MD5=bigInteger.toString();//dex的哈希值

2、对Apk文件进行完整性校验(Android 5.0以下)

通过 APK 包的 MD5 摘要进行判断文件是否被修改过,这里需要计算 APK 的 MD5 值,然后将 MD5 上传到服务器进行判断,或者等待服务器下发原始文件的 MD5 值,进行比较判断。

相关代码:

String apkPath=context.getPackageCodePath();//获取Apk的路径
MessageDigest digest=MessageDigest.getInstance("MD5");
byte[] bytes=new byte[1024];
FileInputStream fileinputStream=new FileInputStream(new File(apkPath));//读取apk文件
int byteCount;
while(fileinputStream.read(bytes)!=-1){
 digest.update(bytes,0,byteCount);
}
BigInteger bigInteger=new BigInteger(1,digest.digest());//计算apk的哈希
String MD5=bigInteger.toString();//apk的哈希值

3、签名信息校验

(1)通过 A ndroid.content.pm.PackageInfo.getPacketInfo()  函数获取包信息,然后拿到签名信息。

(2)该签名信息为一个 byte 数组,可以转换成 X.509 格式的证书信息,或者直接对该签名信息求哈希。

(3)现阶段为了增加分析的难度,通常都会将部分代码放到.so文件中。

相关代码:

PackageInfo packageInfo=content.getPackageManager()
.getPackageInfo(content.getPackageName()
PackageManager.GET_SIGNATURES);//获取包信息
 Signature[] signature=packageInfo.signatures;
 Signature sign=signature[0];
MessageDigest digest=MessageDigest.getInstance("MD5");
digest.update(sign);

二、静态完整性校验apk的一些逆向思路

1、获取apk签名需要获取APK的路径

我们可以在获取APK路径的地方下断点。这样可以定位到相关校验代码。通过修改参数,传入一个官方APK路径,也可以绕过校验。

Context.getPackageCodePath() 用来获得当前应用程序对应的 apk 文件的路径:/data/app/包名/xxx.apk
Context.getPackageResourcePath() 获取该程序的安装包路径 : /data/app/包名/xxx.apk
packageInfo.applicationInfo.sourceDir 这里面也可以获取apk路径

2、在相关API下断

大部分应用在获取签名信息时都会调用系统API,我们可以在相关的API下断:

V1签名( Android 7.0 以下):

android.content.pm.PackageInfo.getPacketInfo(ClassName,flags).signatures

这里需要注意 当 flags 为64的时候,该函数会获取签名信息。 所以需要在 getpackageinfo 下断点,当flags为64的时候,就是获取签名信息。

V2签名( Android 7-9 ):

// 1.反射实例化PackageParser对象
Object packageParser = getPackageParser(path);
// 2.反射获取parsePackage方法
Object packageObject = getPackageInfo(path,packageParser);
// 3.调用collectCertificates方法
Method collectCertificatesMethod = packageParser.getClass(). getDeclaredMethod("collectCertificates",packageObject.getClass(),int.class);
collectCertificatesMethod.invoke(packageParser,packageObject,0);
// 4.获取mSignatures属性
Field signaturesField = packageObject.getClass().getDeclaredField("mSignatures");
signaturesField.setAccessible(true);
Signature[] mSignatures = (Signature[]) signaturesField.get(packageObject);

V3签名( Android 9 及以上):

这几个是v3签名的系统验证函数

PackageManagerService.InstallPackageLI()
PackageParser.collectCertificates()
ApkSignatureVerifier.verify()
ApkSignatureSchemeV3Verifier.verify()
ApkSigningBlockUtils.findSignature()
ApkSigningBlockUtils.findApkSigningBlock()
ApkSigningBlockUtils.findApkSignatureSchemeBlock()
SignatureInfo.SignatureInfo()
ApkSignatureSchemeV3Verifier.verify()
ApkSignatureSchemeV3Verifier.verifySigner()
ApkSignatureSchemeV3Verifier.verifyAdditionalAttributes()
ApkSignatureSchemeV3Verifier.verifyProofOfRotationStruct()
ApkSignatureSchemeV3Verifier.VerifiedProofOfRotation()

3、可以在获取哈希相关的API处下断。

4、可以通过弹出窗口或者toast提示进行代码回溯,定位到签名校验的附近。

三、动态完整性

1、Xpose Hook 检测

(1)检测关键字

de.robv.android.xposed.XposedHelpers类的
静态fieldCache字段 保存被hook的字段信息
静态methodCache字段 保存被hook的方法信息
静态constructorCache字段 保存被hook的类信息

(2)检测内存

检测内存映射列表中是否包含如下文件:

XposedBridge.so
XposedBridge.jar

(3)检测方法的调用栈

handleHookMethod
invokeOriginalMethodNative

注:

(1)在 dalvik.system.NativeStart.main 方法后出现   de.robv.android.xposed.XposedBridge.main 的方法调用

(2)如果Xposed hook了调用栈里的一个方法, 还会有 de.robv.android.xposed.XposedBridge.handleHookedMethod de.robv.android.xposed.XposedBridge.invokeOriginalMethodNative 调用

(3)检测标记位

d e.robv.android.xposed.XposedBridge 类, 静态  disableHooks  成员变量, 这个字段表示是否对当前应用进行hook操作。

2、Frida Hook 检测

(1)检测进程

FridaServer 通过 TCP PC 上的 Frida 进行通信,所以可以检测进程中是否存在 FridaServer 进程

(2)检测端口

默认端口: 2704 7

非默认端口:

A. 用 nmap -sV 来找到开放端口

B. 对每个开放端口发送 D-Bus 认证协议

C. 哪个端口回复了哪个就是 FridaServer 进程的端口

(3)检测内存

搜索内存是否存在以下两个文件

frida-gadget.so

frida-agent.so`

(4)暴力扫描

在映射的s o 文件中扫描Frida的库特征,例如:“ gadgets ”,“ LIBFRIDA ”等等,这 两个在Frida的所有版本中都有存在

3、Cydia Substrate Hook检测

(1)检测包名

检测设备安装目录是否存在 com.saurik.substrate

(2)检测调用栈

com.android.internal.os.ZygoteInit

com.saurik.substrate.MS$2

注:

(1) 在dalvik.system.NativeStart.main 调用后会出现2次

com.android.internal.os.ZygoteInit.main ,而不是一次。

(2) 如果Substrate hook了调用栈里的一个方法,还会出现 com.saurik.substrate.MS$2.invoked、

com.saurik.substrate.MS$MethodPointer.invok e和跟S ubstrat e扩展相关的方法。

(3)检测内存

检测内存映射中是否存在 com.saurik.substrate 文件

4、动态完整性校验的一些逆向思路

(1)搜索字符串

例如:搜索 d e.robv.android.xposed.XposedBridge 或者搜索上述字符串的base64编码后的值。

(2)获取堆栈的函数下断

大部分应用都是主动触发异常,然后获取堆栈信息,判断里面是否有相关hook的关键字, 可以对 getStackTrace() 下断,这个是获取堆栈的API。

(3)对文件读取函数下断

如果获取内存,需要打开当前进程的 / proc 文件,可以对文件读取相关的 API 下断, 例如: new file 、new FildeReader。

(4)对相关的获取包名下断

函数  getPackageName() 获取相关的包名信息,判断参数里是否包含 hook 工具的包名。

- End -

Android应用完整性保护总结

看雪ID: 陌殇  

https://bbs.pediy.com/user-759951.htm   

本文由看雪论坛  陌殇  原创

转载请注明来自看雪社区

:warning: 注意

2019 看雪安全开发者峰会门票正在热售中!

长按识别下方 二维码 即可享受  2.5折  优惠!

Android应用完整性保护总结

Android应用完整性保护总结

公众号ID:ikanxue

官方微博:看雪安全

商务合作:wsc@kanxue.com

点击下方“阅读原文”,查看更多干货


以上所述就是小编给大家介绍的《Android应用完整性保护总结》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Python网络编程基础

Python网络编程基础

John Goerzen / 莫迟 等 / 电子工业出版社 / 2007 / 68.00元

《Python网络编程基础》可以作为各层次Python、Web和网络程序的开发人员的参考书,在实际工作中使用书中的技术,效果更佳。一起来看看 《Python网络编程基础》 这本书的介绍吧!

在线进制转换器
在线进制转换器

各进制数互转换器

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具