Getting the BCM4389 in Pixel 6 into monitor mode for tcpdump/Wireshark WIFI sniffing

A little side project to debug a WIFI 6E TP-Link mesh network in my house, went from "This sounds easy!" to "This is impossible!" to "It can't be this easy, can it?" Anyway: since I couldn't find any online instructions to sniff WIFI packets on my Pixel 6 Pro, I figured I should do a quick writeup for others to follow.  I feel sure that the firmware and binaries used here could be leveraged in a custom ROM for Pixel 6 and maybe even pilfered for monitor mode on other devices that use BCM4389.

Here's how I got my Pixel 6 Pro (raven) to sniff WIFI packets, specifically beacons coming from my AP.  The same directions will work on Pixel 6, and probably Bluejay (6a).  It seems likely to work on Pixel 7 but I don't have one to try.

Prerequisites:  Platform Tools from Android, for ADB, installed on your PC.  You might also want to install Wireshark, but you don't strictly need it.

Step 1: Enable bootloader unlocking, then unlock the bootloader.
(Yes, this erases userdata! Also, be careful!)
You can find instructions on the web for doing this.

Step 2: Flash an aosp_raven-userdebug (or aosp_oriole-userdebug for Pixel 6) build
This build worked for me: Android/aosp_raven/raven:UpsideDownCake/AOSP.MASTER/9344440:userdebug/test-keys

Here's a direct link to flash.android.com for that build, just pick the right device and target.

If the flash tool can't see your phone, try "adb kill-server", make sure to enable ADB in developer options, or put the phone into fastboot by rebooting with volume-down key held. The flash tool (Thanks Google for the awesome flash tool!) will prompt you to complete unlocking the bootloader if needed. When you're done, you can return your Pixel 6 to its original state with flash.android.com/back-to-public

If you just want to see network traffic to your phone, stop here, and use ADB to run "tcpdump" with your favorite options.  "-w" can store it to a .pcap file and then you can pull it to open with Wireshark.  There's also an androiddump external input on Wireshark, that can supposedly use tcpdump, but I didn't figure it out in the short time I tried to make it work.

Step 3: Configure and enable monitor mode
(step 3.1: How did I figure this out: separate blog post)
Hopefully ADB is already in your path, but if not, just navigate to the path where you unzipped it, adb root and adb shell.

  C:\...\platform-tools_r33.0.2-windows\platform-tools> adb root
  * daemon not running; starting now at tcp:5037
  * daemon started successfully
  restarting adbd as root

  C:\...\platform-tools_r33.0.2-windows\platform-tools> adb shell
  raven:/ #


Now, you have a root shell on your phone (Notice, the prompt ends with #). 

Configure frequency and bandwidth

Next, you're going to configure the options for frequency and bandwidth with these two system properties. Here's one example for 5 GHz. (For 2.4 GHz, try 2412 as the frequency)

  # Set bandwidth to 160 MHz for sniffing on 5 GHz
  raven:/ # setprop persist.vendor.wifi.sniffer.bandwidth 160
  # Set 5GHz band
  raven:/ # setprop persist.vendor.wifi.sniffer.freq 5180

Notice, these two properties are persistent and the values will survive a reboot. (They're stored to disk in /data/property/persistent_properties.)

Also notice, for the 5 GHz band, only "5180" works.  If you set an adjacent channel it'll capture 2.4 GHz instead (2412 MHz). I was able to capture on multiple other channels like 2432, 6135 (WIFI 6E), etc., so I'm not sure why I struggled with other 5GHz frequencies earlier.

Enable Monitor Mode

Let's watch the output of our helper utility called "wifi_sniffer", by running this logcat in the background: (You could run it in a second ADB shell window if you want, too)

  raven:/ # logcat | grep SNIFFER &

Last, the exciting part! Reload your BCM4389 with firmware that enables monitor mode.  When it works, it looks like this:

  raven:/ # wifi_sniffer start
  11-30 16:21:03.761 26583 26583 I WIFI_SNIFFER: Starting monitor on frequence 2412 <- from persist.vendor.wifi.sniffer.freq
  11-30 16:21:03.761 26583 26583 D WIFI_SNIFFER: update_sys_param:   /sys/wifi/firmware_path fw_bcmdhd_monitor.bin
  raven:/ # 

Really? That's it? Thanks Google! You can see the logcat logs with tag WIFI_SNIFFER mixed into my console here, which makes it easy to see if it worked.

Errors you might see in logcat:

  11-30 15:57:15.462 4779 4779 E WIFI_SNIFFER: frequency is empty
  11-30 15:59:50.231 9527 9527 E WIFI_SNIFFER: ERROR: freq is zero
Make sure you have set persist.vendor.wifi.sniffer.bandwidth to a number in megahertz. Check it with this command: getprop persist.vendor.wifi.sniffer.bandwidth

  11-30 16:00:06.113 10026 10026 E WIFI_SNIFFER: Failed to up radiotap0
Android, or wpa_supplicant etc., has interfered with what you're doing to the wifi driver. The small hammer fix: Forget any WIFI networks, turn off WIFI via the UI, maybe turn off location, and try "wifi_sniffer start" again, it will eventually work. The big hammer fix: Stop android altogether, and try "wifi_sniffer start" again.  C:\> adb shell stop
(you can use "adb shell start" or failsafe "adb reboot" to restart android.)

Step 4: Run tcpdump

At last, you can run tcpdump on interface radiotap0, with your favorite options.

  # Stream some sniffed packets to stdio to see what it's capturing, make sure you have the right frequency and the bandwidth makes sense
  raven:/ # tcpdump -i radiotap0
  tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
  listening on radiotap0, link-type IEEE802_11_RADIO (802.11 plus radiotap header), snapshot length 262144 bytes
  16:03:43.048182 18833711us tsft 1.0 Mb/s 2412 MHz 11g -72dBm signal -89dBm noise antenna 0 Beacon () [1.0* 2.0* 5.5* 11.0* 18.0 24.0 36.0 54.0 Mbit] ESS CH: 2, PRIVACY
  ...

  # Save beacon packets to a .pcap file for Wireshark to open later
  raven:/ # tcpdump -i radiotap0 type mgt subtype beacon -w /data/beacon-capture.pcap
  tcpdump: listening on radiotap0, link-type IEEE802_11_RADIO (802.11 plus radiotap header), snapshot length 262144 bytes
  ^C120 packets captured
  144 packets received by filter
  0 packets dropped by kernel

  # Pull the pcap file using ADB, from the phone to your host.
  C:\...\platform-tools_r33.0.2-windows\platform-tools\> adb pull /data/beacon-capture.pcap
  /data/beacon-capture.pcap: 1 file pulled, 0 skipped. 4.7 MB/s (48779 bytes in 0.010s)

  # now open the .pcap file with Wireshark

I hope you found this useful!  

Comments

Popular posts from this blog

How did I figure Pixel 6 could sniff WIFI?