How did I figure Pixel 6 could sniff WIFI?
I just wrote a quick post on how to sniff WIFI packets with Pixel 6 Pro in monitor mode.
But, how did I figure it out? I'm not a WIFI engineer, and only really pretend to know how it works, but I have been hacking on Android phones for the last 13 years, starting with the Motorola Droid (Eclair launch device, OMAP3) and especially Motorola Cliq (launched on Cupcake, MSM72xx).
I started by flashing the aosp_raven-userdebug build, because I knew I wanted root access for tcpdump etc., and it was pretty easy to do it this way.
From here, I started with tcpdump on wlan0, which works but you can't sniff and it's not monitor mode. I naively started searching the phone for an "iwconfig" or "iw" or other tools that might help me reconfigure the chip. I neglected to find /system/bin/iw which was right there, but instead I stumbled into:
raven:/vendor/bin # ls -ld *w*
-rwxr-xr-x 1 root shell 147400 2009-01-01 00:00 awk
lrwxr-xr-x 1 root shell 13 2009-01-01 00:00 chown -> toybox_vendor
-rwxr-xr-x 1 root shell 147824 2009-01-01 00:00 chre_power_test_client
drwxr-x--x 2 root shell 4096 2009-01-01 00:00 hw
lrwxr-xr-x 1 root shell 13 2009-01-01 00:00 hwclock -> toybox_vendor
-rwxr-xr-x 1 root shell 592 2009-01-01 00:00 init.uwb.calib.sh
-rwxr-xr-x 1 root shell 19888 2009-01-01 00:00 logwrapper
-rwxr-xr-x 1 root shell 92720 2009-01-01 00:00 misc_writer
lrwxr-xr-x 1 root shell 13 2009-01-01 00:00 mkswap -> toybox_vendor
-rwxr-xr-x 1 root shell 134856 2009-01-01 00:00 powerstats_util
lrwxr-xr-x 1 root shell 13 2009-01-01 00:00 pwd -> toybox_vendor
-rwxr-xr-x 1 root shell 70536 2009-01-01 00:00 rainbow_test
lrwxr-xr-x 1 root shell 13 2009-01-01 00:00 rtcwake -> toybox_vendor
lrwxr-xr-x 1 root shell 13 2009-01-01 00:00 swapoff -> toybox_vendor
lrwxr-xr-x 1 root shell 13 2009-01-01 00:00 swapon -> toybox_vendor
-rwxr-xr-x 1 root shell 336568 2009-01-01 00:00 twoshay
lrwxr-xr-x 1 root shell 13 2009-01-01 00:00 watch -> toybox_vendor
lrwxr-xr-x 1 root shell 13 2009-01-01 00:00 wc -> toybox_vendor
-rwxr-xr-x 1 root shell 40504 2009-01-01 00:00 wfc-pkt-router
lrwxr-xr-x 1 root shell 13 2009-01-01 00:00 which -> toybox_vendor
lrwxr-xr-x 1 root shell 13 2009-01-01 00:00 whoami -> toybox_vendor
-rwxr-xr-x 1 root shell 66856 2009-01-01 00:00 wifi_perf_diag
-rwxr-xr-x 1 root shell 19696 2009-01-01 00:00 wifi_sniffer
drwxr-x--x 2 root shell 4096 2009-01-01 00:00 wlc_upt
-rwxr-xr-x 1 root shell 178944 2009-01-01 00:00 wpa_cli
raven:/vendor/bin #
Wait, what the heck is "wifi_sniffer"?
raven:/vendor/bin # wifi_sniffer
raven:/vendor/bin # wifi_sniffer asdf
raven:/vendor/bin # wifi_sniffer /help
raven:/vendor/bin # wifi_sniffer -?
raven:/vendor/bin # wifi_sniffer have a coke and a smile
raven:/vendor/bin # logcat | grep -i sniffer
^C
130|raven:/vendor/bin #
That didn't help. How about a clue from a .rc file?
raven:/vendor/bin # grep -r wifi_sniffer /vendor
...
/vendor/etc/init/init.wifi_sniffer.rc:service wifi_sniffer_start /vendor/bin/wifi_sniffer start
/vendor/etc/init/init.wifi_sniffer.rc:service wifi_sniffer_stop /vendor/bin/wifi_sniffer stop
OK, great, I found start and stop, but what does it even do? Here's two big clues:
raven:/vendor/bin # strings wifi_sniffer | grep monitor
Starting monitor on frequence %d
fw_bcmdhd_monitor.bin
Wait... fw_bcmdhd_monitor.bin? Is that firmware for the Broadcom Dongle Host Driver that puts it in monitor mode 😅
raven:/vendor/bin # find /vendor -name fw_bcmdhd_monitor.bin
/vendor/firmware/fw_bcmdhd_monitor.bin
I literally can't even, at this point. I'd found blogs and papers from folks like NexMon that are hacking firmware to enable monitor mode, but here we are with a legit firmware file distributed by Google themselves.
raven:/vendor/bin # strings wifi_sniffer | grep vendor
persist.vendor.wifi.sniffer.freq
persist.vendor.wifi.sniffer.bandwidth
raven:/vendor/bin #
What next? I bet these system properties are important. I fumbled with strings like "2.4" and "5GHz", and notice that most everything that's a digit gets me packet capture on 2412 MHz as a default. So, I try "5180" and find that works for 5 GHz bands.
I find that this wifi_sniffer is logging into logcat with tags "WIFI_SNIFFER" that make it pretty easy to figure out from here. dmesg also helpfully shares
Last, I find that most of my 5 GHz capture is garbage and I don't see packets from my AP (but some to my AP). Turns out setting the bandwidth to 160 (capture bandwidth of 160 MHz) fixed that issue.
Acknowledgements:
- Parker Hu at TP-Link Shenzhen who suggested I should sniff WIFI, and very patiently helped confirm when captures were correct
- This random blog that helped me understand what options I should start trying on tcpdump
- @nexmon_dev who showed me that it could be hard to enable monitor mode :)
- Reddit and xda-forums for having lots of other people asking questions, that taught me that "monitor mode" is a thing.
Comments
Post a Comment