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的这段代码传递敏感信息,用户在选择XY时,选择了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并且设置了actioncategory

<!-- 演示隐式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,actioncategory的值设置成HijackActivity一样即可(这里使用adb的方式也可进行测试)

安全建议

  1. 调用App内部Activity

此时我们可以明确指明要调用的Acitvity的类名来进行显式启动

Intent intent = new Intent(this, PictureActivity.class);
intent.putExtra("BARCODE",barcode);
startActivity(intent);
  1. 调用其他App Activity

这时我们可以通过setClassName指明package name和完整的类名进行显式启动

Intent intent = new intent();
intent.setClassName("cn,com.demo.normal.activity","cn.com.demo.normal.activity.PublicActivity");
startActivity(intent);

本文链接:

https://www.linqi.net.cn/index.php/archives/422/