Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -639,6 +639,48 @@ Tools / scripts that speed-up Binder reconnaissance:
* [`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()))`

### 8. Hidden Binder APIs, confused deputies and VPN-lockdown bypasses
A hidden Java API is still reachable when the underlying **Binder transaction is exposed to apps** and the service implementation forgets to perform its own authorisation. A useful triage pattern is: **untrusted app → Binder registration of attacker-controlled state → privileged system component later replays that state**.

Typical red flags:
* A Binder method accepts a **`ParcelFileDescriptor`**, socket-like object, or raw **`byte[]`** payload from an app.
* The AIDL/service path has **no** `@EnforcePermission`, `enforceCallingOrSelfPermission()`, `checkCallingPermission()`, UID allowlist, or SELinux restriction.
* The privileged side later **recreates the socket or packet** as `system_server`/system UID and sends it on a network chosen from saved metadata.
* The payload is treated as protocol-specific data but the implementation never validates that it really matches the expected frame type.

Example pattern seen in Android 16 QUIC graceful close abuse:
1. The app enumerates visible networks with `ConnectivityManager.getAllNetworks()` and `getLinkProperties()`.
2. Instead of `Network.bindSocket()` (which enforces VPN lockdown), it creates `new DatagramSocket(new InetSocketAddress(<physical-ip>, 0))`. That path reaches the kernel `bind()` syscall, which only checks whether the local IP exists on an interface.
3. A later UDP `connect()` does **not** transmit traffic but helps associate the socket with the physical network `netId`/`SO_MARK`.
4. The app passes the connected socket plus attacker-controlled bytes to a Binder method.
5. When the socket dies, a privileged component recreates the flow and sends the bytes as **UID 1000**, bypassing per-app VPN policy because the policy is enforced against the original app UID, not the privileged deputy.

Minimal direct-transaction pattern from an app when the SDK method is hidden but the Binder entry point is reachable:
```java
IBinder svc = (IBinder) Class.forName("android.os.ServiceManager")
.getMethod("getService", String.class).invoke(null, "connectivity");
Parcel data = Parcel.obtain();
try {
data.writeInterfaceToken("android.net.IConnectivityManager");
data.writeTypedObject(pfd, 0);
data.writeByteArray(payload);
svc.transact(TXN_REGISTER, data, null, IBinder.FLAG_ONEWAY);
} finally {
data.recycle();
}
```

Practical review workflow:
* Decompile `framework*.jar`, APEX jars and vendor service jars, then map `Stub.onTransact()` cases to method names and parameter types.
* Prioritise transactions that combine **network objects + raw bytes + delayed execution**.
* Check whether the privileged path calls helpers such as `Network.bindSocket()`, `Os.write()`, or creates a fresh `DatagramSocket`/`Socket` using attacker-influenced metadata.
* Compare **kernel-local operations** (`bind()`, UDP `connect()`) with **Android policy-aware wrappers** (`Network.bindSocket()`) because the former may shape metadata without triggering the higher-level policy gate.
* For confirmation, register the state, kill the app/process, and watch for a later packet from the device's real interface or another action performed by the privileged service.

Defensive clues:
* Binder methods that should be protocol-specific must validate the payload format instead of accepting arbitrary bytes.
* Privileged services should re-check the **original caller UID/network policy** before replaying traffic or reconstructing sockets on behalf of apps.

---

## References
Expand All @@ -661,6 +703,8 @@ Tools / scripts that speed-up Binder reconnaissance:
- [Bugscale - Here We Go Again: A Five-Bug Chain to Arbitrary APK Install on Samsung S25](https://bugscale.ch/blog/here-we-go-again-a-five-bug-chain-to-arbitrary-apk-install-on-samsung-s25/)
- [bugscale/samsung-s25-research - graft_sig.py](https://github.com/bugscale/samsung-s25-research/blob/main/local-apk-install/graft_sig.py)
- [Microsoft Authenticator’s Unclaimed Deep Link: A Full Account Takeover Story (CVE-2026-26123)](https://khaledsec.medium.com/microsoft-authenticators-unclaimed-deep-link-a-full-account-takeover-story-cve-2026-26123-e0409a920a02)
- [The Tiny UDP Cannon: An Android VPN Bypass](https://lowlevel.fun/posts/tiny-udp-cannon-android-vpn-bypass/)
- [0x33c0unt/quic-vpn-bypass PoC](https://github.com/0x33c0unt/quic-vpn-bypass)

{{#include ../../banners/hacktricks-training.md}}