Listen to this Post

Introduction:
Android’s Binder is the quiet workhorse of inter-process communication (IPC), handling hundreds of transactions per second as apps request everything from location data to camera access. Yet this invisible plumbing—which allows one process to call a function in another as if it were local—presents one of the most expansive attack surfaces on the mobile operating system. Every permission check, package manager query, and keystore operation flows through Binder, making it the single most critical security boundary between an untrusted app and the system’s crown jewels.
Learning Objectives:
- Understand the complete Binder IPC flow from application-level AIDL calls down to the kernel driver and back
- Identify common Binder-related vulnerabilities including use-after-free (UAF), out-of-bounds reads, and improper locking
- Master practical reconnaissance, fuzzing, and exploitation techniques for auditing Binder services
- Learn mitigation strategies including SELinux policies, Rust-based driver implementations, and secure coding practices
- Binder IPC Deep Dive: From App to Kernel and Back
The Binder journey begins when an application invokes a method on a proxy object generated by the Android build system. This proxy marshals the method parameters into a Parcel—a flattened buffer that can travel across process boundaries. The critical transition from Java to C++ occurs in functions like android_os_Parcel_writeInt, which calls down to the native `Parcel::writeInt32` implementation in frameworks/native/libs/binder/Parcel.cpp.
From there, the `BpBinder` library makes an `ioctl` system call to the Binder kernel driver at /dev/binder. The kernel driver copies the marshaled data directly into the target process’s memory space. On the server side, threads that have been blocked on their own `ioctl` calls wake up, receive the transaction, and begin unmarshaling the data through JNI into the stub implementation that executes the actual business logic.
Code Snippet: Proxy-Side Binder Call (Generated by AIDL)
public int calculateFactorial(int n) throws android.os.RemoteException {
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
int _result;
try {
_data.writeInterfaceToken(DESCRIPTOR);
_data.writeInt(n);
boolean _status = mRemote.transact(Stub.TRANSACTION_calculateFactorial, _data, _reply, 0);
_reply.readException();
_result = _reply.readInt();
} finally {
_reply.recycle();
_data.recycle();
}
return _result;
}
Source: Medium Android Deep Dive series
Debugging Binder Transactions on a Live Device:
Enable Binder transaction logging adb shell echo "file binder.c +1" > /sys/kernel/debug/dynamic_debug/control Monitor Binder transactions in real-time adb shell cat /sys/kernel/debug/binder/transactions Dump all active Binder services adb shell service list Trace Binder calls from a specific process adb shell strace -f -e ioctl -p $(adb shell pidof com.example.app)
- The Attack Surface: Why Binder Is a Hacker’s Paradise
Binder presents a uniquely attractive attack surface because it is accessible by default to every untrusted and isolated app on the device. The driver has historically been implemented in C, making it susceptible to memory corruption vulnerabilities. All untrusted apps are sandboxed, yet they communicate with privileged system services exclusively through Binder.
Recent vulnerabilities paint a stark picture:
- CVE-2023-20938: A use-after-free in the Binder driver allowing local privilege escalation from an unprivileged shell to root (uid 0) with SELinux set to permissive. This was exploited in the wild and fixed in February 2023
- CVE-2022-20421 (“Bad Spin”): Another privilege escalation exploit from `untrusted_app` context achieving full kernel read/write primitives on kernel versions 5.4.x and 5.10.x
- CVE-2019-2215 (“Bad Binder”): The infamous UAF vulnerability that gave attackers a path from a normal app all the way to root by leaking `task_struct` and overwriting `addr_limit`
– CVE-2026-23194: An out-of-bounds bug in the Rust Binder implementation triggered by empty FDA (fd array) objects
Windows/Linux Command Equivalents for IPC Analysis:
Linux: Inspect active IPC mechanisms ipcs -a Linux: Trace system calls related to IPC strace -e trace=ipc ./target_binary Windows: View named pipes and IPC endpoints Get-1amedPipeConnection | Format-Table Windows: Monitor process communication Logman start "IPC Trace" -p "Microsoft-Windows-Kernel-Process" -o ipc.etl -ets
3. Fuzzing Binder: Finding Bugs Before Attackers Do
The NASS (Native Android System Services) fuzzing framework represents the state of the art in Binder security testing. NASS performs deserialization-guided interface extraction to analyze the underlying Binder interface exposed in native system services, automatically creating fuzzing harnesses without requiring source code access. It has outperformed prior work in interface extraction, target exploration, and bug-finding capabilities.
Practical Binder Fuzzing Setup Using Linux Kernel Library (LKL):
Clone the Android kernel source git clone https://android.googlesource.com/kernel/common cd common Build the binder driver with fuzzing instrumentation make ARCH=arm64 CROSS_COMPILE=aarch64-linux-android- binder_test Run the fuzzer against /dev/binder ./fuzz_binder -i input_corpus/ -o findings/ -t 10000 Alternative: Use syzkaller for coverage-guided fuzzing ./bin/syz-manager -config=android_binder.cfg
BinderCracker is another automated testing framework that has identified more than 100 vulnerabilities across six major Android versions, including Marshmallow. The framework supports parameter-aware fuzzing, which is critical for exercising the complex data structures passed through Binder transactions.
4. Exploitation Techniques: From UAF to Kernel R/W
The most sophisticated Binder exploits follow a predictable pattern:
Step 1: Trigger the UAF – Exploit CVE-2023-20938 by freeing a `binder_node` object through a race condition or malformed transaction.
Step 2: Spray the Heap – Allocate kernel objects (like `epitem` structures) at the same memory location using cross-cache spraying techniques.
Step 3: Leak Kernel Pointers – Read values from the allocated object to defeat KASLR (Kernel Address Space Layout Randomization).
Step 4: Achieve Arbitrary Read/Write – Overwrite function pointers or critical kernel structures to gain full control.
Binder Transaction Redirection (BiTRe) attacks represent an even more insidious approach. Instead of attacking from the client side, the attacker induces a system service to transact with a customized Binder server, then attacks from the server—an often unprotected direction. This role-reversal attack vector bypasses many traditional security assumptions.
Proof-of-Concept Exploit Skeleton (Educational Use Only):
// Simplified trigger for CVE-2019-2215 style UAF
int trigger_uaf(int fd) {
struct binder_write_read bwr;
struct binder_transaction_data tr;
// Craft malformed transaction
tr.target.handle = 0;
tr.code = 0xdeadbeef;
tr.data_size = 0x1000;
tr.data.ptr.buffer = (uintptr_t)malicious_data;
bwr.write_size = sizeof(tr);
bwr.write_buffer = (uintptr_t)&tr;
// Trigger the vulnerability
return ioctl(fd, BINDER_WRITE_READ, &bwr);
}
5. Mitigation: How Google Is Fighting Back
Google has made significant strides in hardening Binder against attacks:
Rust Rewrite: The Binder IPC interface in the kernel is now largely written in Rust and no longer exposed to memory safety corruption. However, logic bugs remain—even the Rust implementation has been found vulnerable to out-of-bounds reads and improper locking issues.
SELinux Policies: The `isolated_app` SELinux context is more restrictive than untrusted apps, limiting what Binder services can be accessed. Proper SELinux rules can prevent many attacks even if vulnerabilities exist.
Stable AIDL: Android 10 introduced Stable AIDL, allowing all processes to use `/dev/binder` while ensuring HIDL and `/dev/hwbinder` also maintain security guarantees.
Practical Hardening Commands:
Check SELinux status and enforce policies adb shell getenforce adb shell setenforce 1 View Binder-related SELinux denials adb shell cat /sys/fs/selinux/avc/log Restrict which Binder services an app can access adb shell am force-stop com.example.app adb shell settings put global binder_service_restriction 1 Monitor Binder usage per process adb shell dumpsys binder [bash]
Deadlock Prevention Rules:
- Never hold a lock while making a Binder call
- Follow strict lock ordering to prevent deadlocks
- Avoid synchronous (non-oneway) Binder transactions to cached or frozen processes
6. Auditing Binder Services: A Practical Guide
For security researchers and penetration testers, auditing Binder services requires a systematic approach:
Reconnaissance:
List all registered Binder services adb shell service list Dump detailed service information adb shell dumpsys [bash] Identify services exposed to untrusted apps adb shell ps -Z | grep untrusted_app
Interface Extraction:
Use WOOTdroid to capture Binder parcels in the kernel and decode them against a framework signature table extracted via Java reflection. This works even on locked-down devices like Pixel 9 running Android 16.
Manual Testing:
// Connect to a Binder service and invoke methods reflectively
IBinder binder = ServiceManager.getService("package");
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken("android.content.pm.IPackageManager");
data.writeString("com.malicious.app");
binder.transact(TRANSACTION_getPackageInfo, data, reply, 0);
Fuzzing with LibFuzzer:
Build Binder service with fuzzing hooks ANDROID_BUILD_TOP=~/android source build/envsetup.sh m libbinder_fuzzer Run the fuzzer on a specific service ./out/host/linux-x86/fuzzer/libbinder_fuzzer -runs=1000000 -jobs=4
What Undercode Say:
- Key Takeaway 1: Binder is not just a messaging system—it’s a remote procedure call (RPC) mechanism that allows arbitrary function invocation across process boundaries. This architectural choice creates a massive attack surface where a single UAF in the driver can compromise the entire device.
-
Key Takeaway 2: The transition from C to Rust in the Binder driver mitigates memory safety issues but does not eliminate logic bugs. Recent CVEs in the Rust implementation (CVE-2026-23194, CVE-2026-23184) prove that memory-safe languages still require rigorous auditing.
Analysis: The Android ecosystem’s reliance on Binder for virtually all privileged operations means that a single vulnerability in this component can lead to complete device compromise. The most dangerous attacks combine UAF exploitation with heap spraying techniques to achieve kernel-level arbitrary read/write primitives. Google’s multi-pronged mitigation strategy—Rust rewrites, SELinux restrictions, and fuzzing frameworks like NASS—represents the industry’s best effort, but the constant stream of new CVEs suggests that Binder will remain a prime target for years to come. The role-reversal attacks (BiTRe) demonstrate that even the most hardened systems have blind spots. Security researchers must think beyond the traditional client-server model and consider all possible attack vectors, including those where the attacker controls the server side.
Prediction:
- +1 The Rust rewrite of the Binder driver will gradually eliminate memory corruption vulnerabilities, reducing the exploitability of the most critical class of Binder bugs over the next 2-3 years.
-
-1 Logic bugs and improper locking issues will continue to plague both C and Rust implementations, with new CVEs emerging at a rate of 3-5 per year as fuzzing frameworks become more sophisticated.
-
-1 The increasing complexity of Android’s permission model will create new Binder-related attack vectors as more services are exposed through the IPC mechanism.
-
+1 Automated fuzzing frameworks like NASS and BinderCracker will shift the balance toward defenders, enabling proactive discovery and patching of vulnerabilities before they can be exploited in the wild.
-
-1 Role-reversal attacks (BiTRe) will become more prevalent as attackers realize that system services often trust data received from Binder servers without proper validation.
-
+1 Google’s investment in on-device tracing tools like WOOTdroid will enable better runtime monitoring and faster detection of Binder-based attacks.
-
-1 The 1MB transaction size limit in Binder will continue to be a double-edged sword—it prevents certain DoS attacks but also creates constraints that attackers can exploit through cleverly crafted transactions.
-
+1 The Binder capability-based security model (using binder objects as security tokens) will become more robust as the kernel improves object lifetime management and reference counting.
-
-1 Third-party vendor Binder services (NPU drivers, fastrpc, etc.) will remain a weak link, as they are often less rigorously audited than AOSP components.
-
+1 The security community’s focus on Binder fuzzing and exploitation will drive innovation in kernel hardening techniques that benefit the entire Linux ecosystem, not just Android.
▶️ Related Video (74% Match):
https://www.youtube.com/watch?v=1Fx7LuPYohQ
🎯Let’s Practice For Free:
🎓 Live Courses & Certifications:
Join Undercode Academy for Verified Certifications
🚀 Request a Custom Project:
Secure, high-velocity infrastructure and disruptive technological engineering. Contact our engineering team for high-tier development and proprietary systems:
[email protected]
💎 Smart Architecture | 🛡️ Secure by Design | ⭐ Trusted by Thousands
IT/Security Reporter URL:
Reported By: Pallis Seeing – Hackers Feeds
Extra Hub: Undercode MoN
Basic Verification: Pass ✅


