Skip to content
On this page

android第三方包上下文任意代码执行

在安卓中可以通过createPackageContext来访问和使用第三方的资源以及代码,可以利用这种机制来作为app的一种插件机制. 但是如果设计的不恰当,就有可能造成任意代码执行问题

漏洞的本质

java
    public static void processModule(Context context, String packageName)  {
        Context appContext = context.createPackageContext(packageName, CONTEXT_INCLUDE_CODE | CONTEXT_IGNORE_SECURITY);
        ClassLoader classLoader = appContext.getClassLoader();

        Object obj = classLoader.loadClass("com.example.myapplicationcallee.MainInterface").getMethod("getInterface").invoke(null);
    }

首先利用createPackageContext来获取到第三方App的Context,进而可以利用这个context来访问其代码,资源等. 这里是通过反射来执行第三方App的某个函数.

利用这种方式,可以实现动态插件的目的,但是如果因为设计不当,就可能会存在任意代码执行的漏洞,具体来说就是,可以恶意安装符合processModule规则要求的package,这些package的名称也符合我们的插件名称.

伪造同名package进行攻击

java
package com.example.myapplicationcallee;

import android.util.Log;

public class MainInterface {
    public static Object getInterface() {
        try {
           Process process=  Runtime.getRuntime().exec("ls -l /");
           Log.e("exec","code exec!!!");
            process.waitFor();
        }
        catch (Throwable th) {
        }
        return null;
    }
}

如何防止

packageName可以伪造,但是package的签名是不能伪造的,我们只要验证package的签名即可,具体来说就是:

packageManager.checkSignatures(packageName, context.getPackageName()) == PackageManager.SIGNATURE_MATCH,必须相当,然后才去执行相关代码.

java
    public static void processModule_security(Context context, String packageName) {
        PackageManager packageManager = context.getPackageManager();
        if (packageManager.checkSignatures(packageName, context.getPackageName()) == PackageManager.SIGNATURE_MATCH){
            Context appContext = context.createPackageContext(packageName, CONTEXT_INCLUDE_CODE | CONTEXT_IGNORE_SECURITY);
            ClassLoader classLoader = appContext.getClassLoader();

            Object obj = classLoader.loadClass("com.example.myapplicationcallee.MainInterface").getMethod("getInterface").invoke(null);

        }
     }

这个是改进后的安全版本.

其他问题

这个漏洞,我在android api25上是可以复现,但是在api30上却不可以,应该是高版本做了相关的安全限制.

自动扫描这一类漏洞

规则就是:

Source: android.content.Context.createPackageContext的返回值

Sink: loadClass的this指针