MASTG-TEST-0030: 测试 PendingIntent 的脆弱实现
此测试即将更新
此测试目前可使用,但将作为新的 OWASP MASTG v2 指南 的一部分进行全面修订。
请提交 PR 来帮助我们:MASTG v1->v2 MASTG-TEST-0030:测试 PendingIntent 的易受攻击实现 (android)
概述¶
在测试 Pending Intents 时,您必须确保它们是不可变的,并且应用程序显式指定将接收基本意图的确切包、操作和组件。
静态分析¶
为了识别易受攻击的实现,可以通过查找用于获取 PendingIntent
的 API 调用来执行静态分析。 下面列出了此类 API
PendingIntent getActivity(Context, int, Intent, int)
PendingIntent getActivity(Context, int, Intent, int, Bundle)
PendingIntent getActivities(Context, int, Intent, int, Bundle)
PendingIntent getActivities(Context, int, Intent, int)
PendingIntent getForegroundService(Context, int, Intent, int)
PendingIntent getService(Context, int, Intent, int)
一旦发现上述任何函数,请检查基本意图和 PendingIntent
的实现,以查找 Pending Intents 部分中列出的安全隐患。
例如,在 A-156959408(CVE-2020-0389) 中,基本意图是隐式的,并且 PendingIntent
也是可变的,因此使其可被利用。
private Notification createSaveNotification(Uri uri) {
Intent viewIntent = new Intent(Intent.ACTION_VIEW)
.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_GRANT_READ_URI_PERMISSION)
.setDataAndType(uri, "video/mp4"); //Implicit Intent
//... skip ...
Notification.Builder builder = new Notification.Builder(this, CHANNEL_ID)
.setSmallIcon(R.drawable.ic_android)
.setContentTitle(getResources().getString(R.string.screenrecord_name))
.setContentText(getResources().getString(R.string.screenrecord_save_message))
.setContentIntent(PendingIntent.getActivity(
this,
REQUEST_CODE,
viewIntent,
Intent.FLAG_GRANT_READ_URI_PERMISSION)) // Mutable PendingIntent.
.addAction(shareAction)
.addAction(deleteAction)
.setAutoCancel(true);
动态分析¶
Frida 可用于钩住用于获取 PendingIntent
的 API。 此信息可用于确定调用的代码位置,该位置可进一步用于执行如上所述的静态分析。
这是一个 Frida 脚本示例,可用于钩住 PendingIntent.getActivity
函数
var pendingIntent = Java.use('android.app.PendingIntent');
var getActivity_1 = pendingIntent.getActivity.overload("android.content.Context", "int", "android.content.Intent", "int");
getActivity_1.implementation = function(context, requestCode, intent, flags){
console.log("[*] Calling PendingIntent.getActivity("+intent.getAction()+")");
console.log("\t[-] Base Intent toString: " + intent.toString());
console.log("\t[-] Base Intent getExtras: " + intent.getExtras());
console.log("\t[-] Base Intent getFlags: " + intent.getFlags());
return this.getActivity(context, requestCode, intent, flags);
}
在处理具有大型代码库的应用程序时,此方法可能很有用,在这些应用程序中,确定控制流有时可能很棘手。