diff --git a/src/mobile-pentesting/android-app-pentesting/android-applications-basics.md b/src/mobile-pentesting/android-app-pentesting/android-applications-basics.md index 84e58be323e..451f5b0a8cc 100644 --- a/src/mobile-pentesting/android-app-pentesting/android-applications-basics.md +++ b/src/mobile-pentesting/android-app-pentesting/android-applications-basics.md @@ -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 [type value ...]` + +Common argument specifiers: +* `i32 ` – signed 32-bit value +* `i64 ` – signed 64-bit value +* `s16 ` – 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}}