This lab illustrates the concept of intent spoofing where the comp2 broadcatReceiver in App1 expects to get broadcast intent with data from Comp1 activity in the App1 but instead, it gets a malicious injection via an implicit intent sent by a malicious external app App2. This is an intra-app IPC with intent spoofing which can be prevented with secure programming. This lab contains two apps, the first one has two components- an intent sender and a receiver. The second app just has a receiver which used for intent spoofing.
First, create a new Android Studio project and choose "Empty Activity". Click "Next"
Name it “BroadcastReceiver” with the company domain of "example.com" and click on Next
Right Click on "example.com.BroadcastReceiver--> New-->Java Class"
Name the class as "MyBroadCastReceiver"
Right Click on "example.com.BroadcastReceiver--> New-->Java Class" for twice
Name the class as "SecondActivity" and "ThirdActivity"
Right Click on "Layout--> XML-->Layout XML File" for twice
Name the class as "second_activity" and "third_activity"
Copy and paste all the following code in specific file
//Copy and paste the following code into “MainActivity.java”.
//MainActivity.java
package example.com.broadcastreceiver;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;
public class MainActivity extends Activity {
Button btn;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn = (Button) findViewById(R.id.button1);
btn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
Intent intent = new Intent();
intent.setAction("com.example.MyBroadcast");
intent.putExtra("number", 0);
sendBroadcast(intent);
Toast.makeText(getApplicationContext(), "Send an internal intent to BroadcastReceiver", Toast.LENGTH_LONG).show();
}
}) ;
}
}
//Copy the following code into the newly created “MyBroadCastReceiver.java”.
//MyBroadCastReceiver.java
package example.com.broadcastreceiver;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.widget.Toast;
public class MyBroadCastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
Bundle extras = intent.getExtras();
if (extras != null) {
if (extras.containsKey("number")) {
Object num = extras.get("number");
if (num.toString().equals("0")) {
Intent i = new Intent();
i.setClassName("example.com.broadcastreceiver", "example.com.broadcastreceiver.SecondActivity");
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(i);
}
else if (num.toString().equals("1")) {
Toast.makeText(context, "This is an intent spoofing example!", Toast.LENGTH_LONG).show();//This is the message which will display on the screen of intent sender
Intent i = new Intent();
i.setClassName("example.com.broadcastreceiver", "example.com.broadcastreceiver.ThirdActivity");
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(i);
}
}
}
}
}
//Copy the following code into “activity_main.xml”. Make sure to click on the “Text” tab at the bottom left of the “activity_main.xml” window
//activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="example.com.broadcastreceiver.MainActivity"
tools:ignore="MergeRootFrame" >
<TextView
android:layout_gravity="center"
android:layout_marginTop="20dp"
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Click the button"
android:textSize="30dp" />
<Button
android:layout_gravity="center"
android:id="@+id/button1"
android:layout_marginTop="20dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Send Broadcast" />
</LinearLayout>
//Copy the following code into the newly created “SecondActivity.java”. This class will handle intents come from this internal.
//SecondActivity.java
package example.com.broadcastreceiver;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
public class SecondActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.second_activity);
}
}
//Copy the following code into “second_activity.xml”
//secon_activity.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_gravity="center"
android:layout_marginTop="20dp"
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello!"
android:textSize="30dp" />
</LinearLayout>
//Copy the following code into ThirdActivity.java
//ThirdActivity.java
package example.com.broadcastreceiver;
import android.app.Activity;
import android.os.Bundle;
public class ThirdActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.third_activity);
}
}
//Copy the following code into third_activity.xml
//third_activity.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_gravity="center"
android:layout_marginTop="20dp"
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="You are attacked by intent spoofing"
android:textSize="30dp" />
</LinearLayout>
//Copy the following code into “AndroidManifest.xml”. Make sure to click on the “Text” tab at the bottom left of the “AndroidManifest.xml” window
//AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="example.com.broadcastreceiver">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.BroadcastReceiver">
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".SecondActivity"></activity>
<activity android:name=".ThirdActivity"></activity>
<receiver android:name=".MyBroadCastReceiver" android:enabled="true" android:exported="true">
<intent-filter>
<action android:name="com.example.MyBroadcast"/>
</intent-filter>
</receiver>
</application>
</manifest>
Save the project and run it on the AVD that shall show this interface
Click on "Send Broadcast", this would be the final interface
First, create a new Android Studio project and choose "Empty Activity". Click "Next"
Name it “IntentSender” with the company domain of "example.com" and click on Next
Copy and paste all the following code in specific file
//Copy and paste the following code into “MainActivity.java”.
//MainActivity.java
package example.com.intentsender;
import android.content.ComponentName;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import java.util.List;
public class MainActivity extends AppCompatActivity {
Button btn;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn = findViewById(R.id.button1);
}
public void onClick(View v) {
Intent intent = new Intent();
intent.putExtra("number", 1);
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
intent.setComponent(new ComponentName("example.com.broadcastreceiver","example.com.broadcastreceiver.MyBroadCastReceiver"));
intent.setAction("com.example.MyBroadcast");
sendBroadcast(intent);
}
}
//Copy the following code into “activity_main.xml”. Make sure to click on the “Text” tab at the bottom left of the “activity_main.xml” window
//activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="example.com.intentsender.MainActivity"
tools:ignorae="MergeRootFrame" >
<Button
android:layout_gravity="center"
android:id="@+id/button1"
android:onClick="onClick"
android:layout_marginTop="20dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Send Broadcast" />
</LinearLayout>
Save the project and run it on the AVD that shall show this interface
Click on "Send Broadcast", this would be the final interface
This figure shows the concept of intent spoofing. The BroadcastReceiver app has a filter that can receive intent either from external apps(in this case IntentSender is an external app) or internal components. When BroadcastReceiver receiving an intent from an internal component, the normal action will show "Hello", otherwise, it shows "This is an intent spoofing example".
1. In the AndroidManifest.xml file of our application, we should add the following attribute to the receiver to be secured.
2. Use explicit intent.