Activity-Intent安全
Activity(Intent安全)
Intent基础
隐式Intent启动方式
首先在安卓App主配置文件里面注册Activity
<acitivty android:name=".activity.SecondActivity"></activity>
Java代码
通过Intent明确指明调用源和目的Activity
Intent intent = new Intent(FistActivity.this, SencondActivity.class);
startActivity(Intent)
隐式Intent
启动方式和显示Intent
的启动方式不同的是,在安卓App主配置文件里面设置了intent-filter
AndroidMainifest.xml
<activity android:name=".activity.ThirdActivity">
<intent-filter>
<action android:name="cn.com.demo.activityACTION_START"/>
<category android:name"c.com.demo.activity.MY_CATEGORY"/>
</intent-filter>
</activity>
Java代码,通过指定action和category值来启动activity,这种方式由于没有指明要启动的Activity
类名,因此称为隐式启动方式
Intent intent = new Intent("cn.com.demo.activity.ACTION_START");
intent.addCategory("cn.com.demo.activity.MY_CATEGORY");
starActivity(intent);
漏洞原理
Activity劫持
安卓设备安装了应用A和应用B,应用A上面有一个Acitvity X
他的可导出属性为false
,并且设置了intent-filter
,action
值为budi
,在应用B上面有一个Activity Y
,他的可导出属性为true
,并且也设置了intent-filter
值为budi
,这时我们的应用A有一段代码是通过隐式启动的方式设置了intent-filter
值为budi
,运行这段代码会弹出一个对话框让用户选择启动X
还是Y
,如果我们的应用B是一个恶意的App,这时我们可以将Y
做成和X
一模一样,用户在选择时有可能会选择错误,造成Activity启动时的劫持
信息泄露
接着上图,因为Intent
可以携带参数传递,如果应用A的这段代码传递敏感信息,用户在选择X
和Y
时,选择了Y
这时应用B可以获得敏感信息,导致泄露
示例
在我们进行代码审计或者黑盒测试时,反编译之后查看App
的主配置文件,检查注册的所有Activity
是否定义了intent-filter
,然后在检查Java代码
是否是通过隐式intent
的启动方式
AndroidManifest.xml
<activity android:name=".ReadTaskActivity">
<intent-filter>
<action android:name="cn.com.budi.START_HIJACK" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
Java代码
Button btnHijack = (Button) findViewById(R.id.BtnHijack);
btnHijack.setOnClickListener(new OnClickListener(){
@Override
Public void onClick(View V){
Intent intent = new Intent(cn.com.budi.START_HIJACK);
intent.addCategory("android.intent.category.DEFAULT");
intent.putExtra("appsetup",100);
startActivity(intent)
}
});
测试方法
*Apktool反编译:
查看androidManifest.xml中所有Activity组件配置;
检查源代码中Activity隐式启动方式;
*Jadx、Jeb都可..
*Adb shell
am start -a android.intent,action.MAIN -n package/component
am start -n com.android.mypackage/com.android.MyPackageLaunchMeAcitvity
正常App审计,那主配置文件审计
定义了intent-filter
并且设置了action
和category
值
<!-- 演示隐式Intent启动劫持 -->
<activity android:name=".HijackActivity">
<intent-filter >
<action android:name="cn.com.budi.START_HIJACK"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
在查看Activity
在他的MainAcitvity
里面有一个Button
,这个button
设置了一个onClick
事件,单击事件通过隐私启动的方式启动HIjackActivity
,
// Activity劫持
Button btnHijack = (Button) findViewById(R.id.btnHijack);
btnHijack.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
Intent intent = new Intent("cn.com.budi.START_HIJACK");
intent.addCategory("android.intent.category.DEFAULT");
intent.putExtra("appsetup", 100);
startActivity(intent);
}
});
恶意App
需要注册一个intent-filter
,action
和category
的值设置成HijackActivity
一样即可(这里使用adb的方式也可进行测试)
安全建议
- 调用App内部Activity
此时我们可以明确指明要调用的Acitvity
的类名来进行显式启动
Intent intent = new Intent(this, PictureActivity.class);
intent.putExtra("BARCODE",barcode);
startActivity(intent);
- 调用其他App Activity
这时我们可以通过setClassName
指明package name
和完整的类名进行显式启动
Intent intent = new intent();
intent.setClassName("cn,com.demo.normal.activity","cn.com.demo.normal.activity.PublicActivity");
startActivity(intent);