mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
Add content from: Android Services 101
This commit is contained in:
parent
d753b3ed2f
commit
ac02b2826b
@ -395,6 +395,112 @@ if (dpm.isAdminActive(adminComponent)) {
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
## Enumerating and Exploiting AIDL / Binder Services
|
||||
|
||||
Android *Binder* IPC exposes many **system and vendor-provided services**. Those services become an **attack surface** when they are exported without a proper permission check (the AIDL layer itself performs *no* access-control).
|
||||
|
||||
### 1. Discover running services
|
||||
|
||||
```bash
|
||||
# from an adb shell (USB or wireless)
|
||||
service list # simple one-liner
|
||||
am list services # identical output, ActivityManager wrapper
|
||||
```
|
||||
|
||||
Output is a numbered list such as:
|
||||
```
|
||||
145 mtkconnmetrics: [com.mediatek.net.connectivity.IMtkIpConnectivityMetrics]
|
||||
146 wifi : [android.net.wifi.IWifiManager]
|
||||
```
|
||||
* The **index** (first column) is assigned at runtime – do ***not*** rely on it across reboots.
|
||||
* The **Binder name** (e.g. `mtkconnmetrics`) is what will be passed to `service call`.
|
||||
* The value inside the brackets is the fully-qualified **AIDL interface** that the stub was generated from.
|
||||
|
||||
### 2. Obtain the interface descriptor (PING)
|
||||
Every Binder stub automatically implements **transaction code `0x5f4e5446`** (`1598968902` decimal, ASCII "_NTF").
|
||||
|
||||
```bash
|
||||
# "ping" the service
|
||||
service call mtkconnmetrics 1 # 1 == decimal 1598968902 mod 2^32
|
||||
```
|
||||
A valid reply returns the interface name encoded as a UTF-16 string inside a `Parcel`.
|
||||
|
||||
### 3. Calling a transaction
|
||||
Syntax: `service call <name> <code> [type value ...]`
|
||||
|
||||
Common argument specifiers:
|
||||
* `i32 <int>` – signed 32-bit value
|
||||
* `i64 <long>` – signed 64-bit value
|
||||
* `s16 <string>` – UTF-16 string (Android 13+ uses `utf16`)
|
||||
|
||||
Example – start network monitoring with uid **1** on a MediaTek handset:
|
||||
```bash
|
||||
service call mtkconnmetrics 8 i32 1
|
||||
```
|
||||
|
||||
### 4. Brute-forcing unknown methods
|
||||
When header files are unavailable you can **iterate the code** until the error changes from:
|
||||
```
|
||||
Result: Parcel(00000000 00000000) # "Not a data message"
|
||||
```
|
||||
to a normal `Parcel` response or `SecurityException`.
|
||||
|
||||
```bash
|
||||
for i in $(seq 1 50); do
|
||||
printf "[+] %2d -> " $i
|
||||
service call mtkconnmetrics $i 2>/dev/null | head -1
|
||||
done
|
||||
```
|
||||
|
||||
If the service was compiled **with proguard** the mapping must be guessed – see next step.
|
||||
|
||||
### 5. Mapping codes ↔ methods via onTransact()
|
||||
Decompile the jar/odex that implements the interface (for AOSP stubs check `/system/framework`; OEMs often use `/system_ext` or `/vendor`).
|
||||
Search for `Stub.onTransact()` – it contains a giant `switch(transactionCode)`:
|
||||
|
||||
```java
|
||||
case TRANSACTION_updateCtaAppStatus: // 5
|
||||
data.enforceInterface(DESCRIPTOR);
|
||||
int appId = data.readInt();
|
||||
boolean ok = data.readInt() != 0;
|
||||
updateCtaAppStatus(appId, ok);
|
||||
reply.writeNoException();
|
||||
return true;
|
||||
```
|
||||
|
||||
Now the prototype and **parameter types** are crystal clear.
|
||||
|
||||
### 6. Spotting missing permission checks
|
||||
The implementation (often an inner `Impl` class) is responsible for authorisation:
|
||||
|
||||
```java
|
||||
private void updateCtaAppStatus(int uid, boolean status) {
|
||||
if (!isPermissionAllowed()) {
|
||||
throw new SecurityException("uid " + uid + " rejected");
|
||||
}
|
||||
/* privileged code */
|
||||
}
|
||||
```
|
||||
Absence of such logic or a whitelist of privileged UIDs (e.g. `uid == 1000 /*system*/`) is a **vulnerability indicator**.
|
||||
|
||||
Case study – *MediaTek* `startMonitorProcessWithUid()` (transaction **8**) fully executes a Netlink message **without** any permission gate, allowing an unprivileged app to interact with the kernel’s Netfilter module and spam the system log.
|
||||
|
||||
### 7. Automating the assessment
|
||||
Tools / scripts that speed-up Binder reconnaissance:
|
||||
* [binderfs](https://android.googlesource.com/platform/frameworks/native/+/master/cmds/binderfs/) – exposes `/dev/binderfs` with per-service nodes
|
||||
* [`binder-scanner.py`](https://github.com/adenflare/binder-scanner) – walks the binder table and prints ACLs
|
||||
* Frida shortcut: `Java.perform(()=>console.log(android.os.ServiceManager.listServices().toArray()))`
|
||||
|
||||
---
|
||||
|
||||
## References
|
||||
|
||||
- [Android Services 101 – Pentest Partners](https://www.pentestpartners.com/security-blog/android-services-101/)
|
||||
- [Android Developer Docs – AIDL](https://developer.android.com/guide/components/aidl)
|
||||
- [Android Developer Docs – IBinder](https://developer.android.com/reference/android/os/IBinder)
|
||||
- [Understanding Binder, Talk @ Google](https://www.youtube.com/watch?v=O-UHvFjxwZ8)
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user