Android 系统提供了一种类加载器DexClassLoader,其能够在运行时动态加载并解释执行包含在JAR或APK文件内的DEX文件。外部动态加载DEX文件的安全风险源于:Anroid4.1以前的系统版本允许Android应用将动态加载的DEX文件存储在被其余应用任意读写的目录中(如sdcard),所以不可以保护应用免遭恶意代码的注入;所加载的DEX易被恶意应用所替换或者代码注入,若是没有对外部所加载的DEX文件作完整性校验,应用将会被恶意代码注入,从而执行的是恶意代码;
若是应用没有正确的动态加载DEX文件,将会致使攻击者的任意代码被自动执行,进一步实施欺诈、获取帐号密码或其余恶意行为等危害,如在乌云漏洞平台上的相似漏洞:QQ游戏Android客户端漏洞致使任意代码执行和密码泄漏[1]。html
Android 系统java
public DexClassLoader (String dexPath, String optimizedDirectory, String libraryPath, ClassLoader parent)[2]
动态加载的DEX文件存储在被其余应用任意读写的目录中(如sdcard),若是没有对外部所加载的DEX文件作完整性校验,应用将会被恶意代码注入,从而执行的是恶意代码;android
利用DexClassLoader()运行时加载JAR/DEX文件,该将恶意代码替换掉被加载的DEX文件,或向该被加载的DEX文件注入恶意代码。安全
被替换的所加载的JAR/DEX class的恶意代码以下:网络
动态加载JAR/DEX的调用代码:app
Android 4.1以前系统版本,结果显示成功动态加载JAR/DEX以下图所示:google
Android 4.1以后系统版本,结果抛出异常“Optimized data directory /mnt/sdcard is not owned by the current user. Shared storage cannot protect your application from code injection attacks.”:加密
因为Android 4.1以后Android版本增长了对JAR/DEX存放目录文件的user_id 和动态加载JAR/DEX的进程的user_id是否一致的判断,若是不一致将抛出异常致使加载失败,以下图所示:spa
4.1以前版本的Android系统DexFile.java代码片断[3]:3d
4.1及其以后版本的Android系统DexFile.java代码片断[4]:
为了所加载的DEX/APK不被恶意代码注入,阿里聚安全建议将要动态加载的DEX/APK放置在APK内部;
阿里聚安全建议使用加密网络协议进行下载并将下载的DEX或APK放置在应用的私有目录;
若是应用必须将所加载的DEX或APK放置在能被其余应用人意读写的目录中(如sdcard)或使用没有加密的网络协议进行下载加载源,阿里聚安全建议对这些不可信的加载源进行完整性校验和白名单处理,以保证不被恶意代码注入。
引用
[1] http://www.wooyun.org/bugs/wooyun-2010-09299
[2] http://developer.android.com/reference/dalvik/system/DexClassLoader.html
[3] https://android.googlesource.com/platform/libcore-snapshot/+/ics-mr1/dalvik/src/main/java/dalvik/system/DexFile.java
[4]https://android.googlesource.com/platform/libcore/+/45e02606b35996f61487f512ee91d0df83e75c9e/dalvik/src/main/java/dalvik/system/DexFile.java
[5] http://developer.android.com/training/articles/security-tips.html#DynamicCode