检测 Apk 中的代码篡改

Posted

技术标签:

【中文标题】检测 Apk 中的代码篡改【英文标题】:Detecting code tampering in Apk 【发布时间】:2018-10-12 02:22:40 【问题描述】:

我对应用程序开发特别陌生,最近了解了 apk 的整个签名过程,为什么它是强制性的,以及防止未经授权和篡改应用程序的重要性。 Signature 的著名检查之一是使用 PackageManager 类进行签名验证。是否有任何其他方法可以检查 apk 本身中的 META-INF 目录是否存在篡改或其他滥用活动,以验证应用未被篡改且其原始签名完好无损?

【问题讨论】:

【参考方案1】:

此代码获取 Classes.dex 文件的 CRC Checksum 并与提供的文件进行比较。

private void crcTest() throws IOException 
    boolean modified = false;
    // required dex crc value stored as a text string.
    // it could be any invisible layout element
    long dexCrc = Long.parseLong(Main.MyContext.getString(R.string.dex_crc));

    ZipFile zf = new ZipFile(Main.MyContext.getPackageCodePath());
    ZipEntry ze = zf.getEntry("classes.dex");

    if ( ze.getCrc() != dexCrc ) 
        // dex has been modified
        modified = true;
    
    else 
        // dex not tampered with
        modified = false;
    

【讨论】:

只有当存储在 R.string.dex_crc 中的值被加密时,这可能是一个解决方案,因为它在 xml 文件中清晰可读。 加密与否,这将失败并且只能劝阻少数没有经验的小伙子。现在很容易克服这些技巧。【参考方案2】:

最佳实践是服务器端篡改检测,无法修补。

方法如下:

使用安卓SafetyNet。这就是 android Pay 自我验证的方式。

基本流程是:

您的服务器会生成一个随机数并将其发送到客户端应用程序。 应用通过 Google Play 服务发送带有 nonce 的验证请求。 SafetyNet 验证本地设备未修改并通过 CTS。 Google 签名的响应(“证明”)会返回到您的应用,其中包含通过/失败结果以及有关您应用的 APK(哈希和签名证书)的信息。 您的应用将证明发送到您的服务器。 您的服务器验证 nonce 和 APK 签名,然后将证明提交到 Google 服务器进行验证。 Google 检查证明签名并告诉您它是否真实。

如果通过,您可以相当确信用户正在未修改的系统上运行您的应用的正版版本。应用程序在启动时应该得到一个证明,并随每个事务请求一起发送到您的服务器。

但是请注意,这意味着:

root 手机的用户将无法通过这些检查 已安装自定义或第三方 ROM/固件/操作系统(例如 Cyanogen)的用户将无法通过这些检查

无法访问 Google Play 服务的用户(例如亚马逊 设备,中国人)不会通过这些检查

...因此将无法使用您的应用程序。您的公司需要就这些限制(以及随之而来的不安用户)是否可以接受做出商业决策。

最后,要意识到这不是一个完全密封的解决方案。通过 root 访问权限和 Xposed,可以修改 SafetyNet 库以欺骗 Google 的服务器,告诉他们“正确”的答案以获得 Google 签署的验证通过结果。实际上,SafetyNet 只是移动了球门柱,让恶意行为者更难对付。由于这些检查最终必须在您无法控制的设备上运行,因此设计一个完全安全的系统确实是不可能的。

Read an excellent analysis of how the internals of SafetyNet work here.

【讨论】:

确实如此。我会要求人们考虑 Snapchat 之类的应用程序,以获取最佳示例。 您能否引用最佳实践背后的来源或扩展它?

以上是关于检测 Apk 中的代码篡改的主要内容,如果未能解决你的问题,请参考以下文章

一次简单的绕过apk签名校验

# yyds干货盘点 # 手把手教你进行安卓逆向之篡改apk名称和图标

Matlab/CV系列基于帧间相关性和K-means的视频篡改检测matlab实现

如何保护 Flutter 中的代码篡改?

Android签名验证与反调试机制的对抗技术

Android签名验证与反调试机制的对抗技术