Mikey Strauss

A Zero-Day in Android’s Wi-Fi Direct: Any App Can Steal Your Password, Zero Permissions

October 6, 2026 vulnerabilityzero-daycybersecurityandroidwifihacking

Security research · Oats Solutions

Any app can flip one flag and read your live Wi-Fi Direct password — zero permissions, no prompt.

By Mikey Strauss, Dani Levenfeld & Tal Dim — Oats Solutions

TL;DR — Android’s Wi‑Fi Direct service (the thing behind Quick Share, screen mirroring, and camera companion apps) has a permission check any app can skip by setting one boolean flag on its own request. No permission. No prompt. The framework hands back the live WPA2 password.

We independently discovered this through a mix of static and dynamic analysis — reading AOSP source and confirming it with a purpose‑built test harness — then used Runzee, Oats Solutions’ dynamic-analysis platform for Android, to corroborate it at the kernel level while the exploit actually ran. More on how below; first, the bug itself.

Runzee isn’t only a tool we reach for after the fact, either. Day to day it’s also how we map an attack surface before a live process is ever touched — walking call graphs, enumerating exported components, inspecting APK/DEX/ELF layouts to find where to even start looking — alongside the live Binder/JNI/network capture that did the confirming here.

The gate

One function, checkNearbyDevicesPermission(), is the single check protecting every Wi‑Fi Direct operation — including the one that returns a live group’s passphrase. Here’s the actual code, straight from AOSP:

AOSPWifiP2pServiceImpl.java

private boolean checkNearbyDevicesPermission(int uid, String packageName, Bundle extras,
        String message, Object attributionSource) {
    if (extras != null
            && extras.getBoolean(WifiP2pManager.EXTRA_PARAM_KEY_INTERNAL_MESSAGE)) {
        // bypass permission check for internal call.
        return true;
    }
    ...
}

That flag exists for the framework’s own internal messages. But it’s just a boolean in a Bundle the caller builds itself — nothing stops any ordinary, zero-permission app from setting it and walking straight past the check.

Proving it, not just reading it

Here’s the problem with finding a bug by reading source: it tells you what the code can do. It doesn’t tell you what’s actually happening on a real phone in front of you — and if all you have is your own test app’s logs, a skeptic can always ask “how do you know your app isn’t just lying about what it did?”

That’s the job Runzee did here: an independent, kernel-level witness the app under test can’t fake, watching the kernel’s own record of what crossed the Binder IPC boundary instead of the app’s self-reported logs. The probe itself is a few lines of Python, compiled by Runzee into an eBPF program running live on the device:

@probe.user(lib="libbinder.so", method="android::BpBinder::transact")
def transact(args, save):
    save(
        code=args.code,
        iface=args.data.deref("mInterfaceName").str(128),
    )

No app instrumentation, no rooting the target. Here’s what it actually captured, mid-exploit, from the zero-permission test app:

process=main  iface=android.net.wifi.p2p.IWifiP2pManager  method=getMessenger  0.2ms  ✓
process=main  iface=android.os.IMessenger                 method=send          0.2ms  ✓

That’s confirmation the test app can’t fake. A zero-permission app really did reach the P2P service and really did get a successful reply — straight from the kernel’s own view, independent of anything our own harness reported.

Here’s that same call sitting in Runzee’s UI, captured live off the device while the exploit ran — no manual log-scraping, just the Binder view filtered down to the P2P interface:

Runzee’s live Binder view, filtered to the Wi-Fi Direct (P2P) interface — the zero-permission app’s getMessenger() call captured straight off the device, detail panel showing category, sensitivity, timing, and an OK status.

This ran on a real, non-rooted, locked-bootloader phone — a Xiaomi/POCO device on Android 14 — not a rooted lab rig with the safety net removed. It’s not a one-build fluke, either: the same vulnerable code sits byte-identical across AOSP’s Android 15 and Android 16 (shipping) branches, Android 16 QPR2, Android 17, and the public main branch.

Why it matters

Wi‑Fi Direct underlies more everyday features than people realize: Quick Share, screen mirroring, camera companion apps, local multiplayer games. This bug meant any app already on your phone could silently harvest the real password the moment any of those were active.

The fix is simple: never trust a client-supplied flag for a security decision. The class already derives the real caller UID correctly elsewhere — the same signal just needs to gate this check too. Reported to Google through the Android Security Rewards program, following standard coordinated disclosure.

Found using Runzee, Oats Solutions’ dynamic-analysis platform for Android — built to show you what a device is actually doing at the Binder, JNI, filesystem, and network layers, independent of anything the app under test claims about itself.

Originally published on Medium.