WatchFlock
README
WatchFlock
ESP32-C5 firmware for spotting Flock Safety ALPR cameras and SoundThinking (formerly ShotSpotter) acoustic gunshot sensors in the wild. Privacy-research tooling, passive detection only, no jamming, no offensive payloads.
Why this exists. Flock Safety quietly switched their Falcon V2 cameras to hidden SSIDs and probe-requests, which killed the old "scan for a broadcast SSID" detection approach. This fork is the response. Original research that surfaced the change can be found on my IG reel.
The majority of the work is based off of a fork of justcallmekoko/ESP32Marauder. All credit for the underlying firmware goes to kokollc. This fork adds three things: a WiFi-side ALPR detector, a BLE-side Penguin-battery detector, and a tagged-text protocol that streams hits to a Flipper Zero companion app over UART.
Quick start
What you need:
- ESP32-C5-DevKitC-1 (N8R8, 8MB flash, 8MB PSRAM)
- kokollc Marauder C5 Adapter for Flipper Zero (link)
- Flipper Zero, stock firmware
- A Mac/Linux box with
arduino-cli+ufbtinstalled
1. Build the C5 firmware
arduino-cli core install esp32:esp32@3.3.0
arduino-cli compile \
-b "esp32:esp32:esp32c5:FlashSize=8M,PartitionScheme=default_8MB,PSRAM=enabled,CDCOnBoot=default" \
--build-property "compiler.cpp.extra_flags=-DMARAUDER_C5 -DSWIZ_FLIPPER_PROTOCOL" \
--build-property "compiler.c.extra_flags=-DMARAUDER_C5 -DSWIZ_FLIPPER_PROTOCOL" \
--libraries ./libraries \
--output-dir ./build \
esp32_marauder
Pin the core to 3.3.0. 3.3.8 has a PSRAM init regression that crashes the N8R8 bootloader. Don't change CDCOnBoot=default to cdc, it masks real error messages at boot. Long version: BUILD-C5.md.
2. Flash the C5
Plug the C5 alone (not yet on the koko adapter) into your computer via its USB-C. Find its port with ls /dev/cu.usbmodem*.
python3 -m esptool --chip esp32c5 --port /dev/cu.usbmodemXXXX --baud 460800 write_flash \
0x2000 build/esp32_marauder.ino.bootloader.bin \
0x8000 build/esp32_marauder.ino.partitions.bin \
0x10000 build/esp32_marauder.ino.bin
Offsets are 0x2000 / 0x8000 / 0x10000, not the classic ESP32 0x1000. Wrong offsets boot-loop the chip with invalid header. Easier alternative if you don't want to memorize that:
python3 C5_Py_Flasher/c5_flasher.py build/esp32_marauder.ino.bin
3. Sideload the Flipper FAP
Connect the Flipper to your computer. Close qFlipper if it's open, it holds the port.
cd flipper
ufbt launch
That builds the FAP, pushes it to /ext/apps/GPIO/swiz_flock_hunter.fap on the Flipper's SD, and launches it.
4. Run it
Stack the C5 on top of the koko adapter, plug the adapter into the Flipper's expansion header. Power via USB-C to the C5 (or run the Flipper on battery, the adapter pulls power down through the Flipper).
On the Flipper: Apps → GPIO → Swiz's WatchFlock.
Pick a band (Dual (2.4+5GHz), 2.4 GHz only, 5.0 GHz only, or BLE):
Walk near suspected hardware. Hits show up live with vendor, RSSI, channel, and GPS coords if you have a fix:
Notifications. The Flipper buzzes + beeps on:
- The first sighting of each unique device (per-MAC, so you don't get spammed, second packet from the same MAC stays quiet)
- GPS fix acquired, the moment
gps=okflips true, so you know coords will now be tagged onto subsequent hits
where are my pcaps and gps data?
Both kinds of capture are written to the Flipper SD card under /ext/apps_data/swiz_flock_hunter/:
| File | What it is |
|---|---|
WatchFlock-hits.csv |
One row per unique device hit. Columns: timestamp, MAC, OUI, vendor, rule, SSID, RSSI, channel, confidence, GPS-fix flag, lat, lon, alt, GPS time, Flipper time. |
flockwifi-YYYYMMDD-HHMMSS.pcap |
Raw 802.11 frames from each scan session, framed with a radiotap header carrying channel + RSSI. Open in Wireshark. |
Why these matter. The CSV is your findings record, pop it into a spreadsheet or onto a map and you've got a list of where each Flock camera lives, when you saw it, and how strong the signal was. The PCAPs are RF evidence, the actual probe-req/beacon frames the cameras emit. Useful for confirming OUI matches, sharing findings with other researchers, or reproducing detections offline.
Getting the files off the Flipper:
- qFlipper (easiest): open qFlipper → File Manager tab → navigate to
SD Card → apps_data → swiz_flock_hunter→ right-click any file → Save As. - Flipper CLI (no GUI needed): connect to
/dev/cu.usbmodemflip_*at 115200 8N1 (e.g.screen /dev/cu.usbmodemflip_XXXX 115200), then:
storage list /ext/apps_data/swiz_flock_hunter storage read /ext/apps_data/swiz_flock_hunter/WatchFlock-hits.csv
storage readprints small text files directly to the terminal. For binary PCAPs, stick to qFlipper.
what's new
Two scan modes on top of upstream Marauder:
| Mode | CLI command | Detects |
|---|---|---|
WIFI_SCAN_FLOCK_AP |
sniffflockwifi [-b 2g\|5g\|all] |
Pole-mounted Falcon V2s probing for hidden uplink SSIDs |
BT_SCAN_FLOCK_BLE |
sniffflockble |
External Penguin batteries advertising via BLE (XUNTONG mfg ID 0x09C8) |
Plus a build flag, -DSWIZ_FLIPPER_PROTOCOL, that turns on tagged-text records over UART (HIT, STAT, HIDE, SWIZ ready). That's what the Flipper FAP parses to render the live dashboard.
Detection rules
WiFi side (probe-req, probe-resp, beacon parsing in promiscuous mode):
- 21 direct Flock OUIs incl.
b4:1e:52(Flock Safety) ande4:aa:ea(Liteon, field-confirmed in St. Pete FL) - Contract-manufacturer OUIs: Liteon, USI
- ShotSpotter / SoundThinking OUI
d4:11:d6 - SSID patterns:
Flock-XXXXXX,test_flck(CVE-2025-59409),*flock*substring (case-insensitive)
BLE side (BLE adverts via NimBLE):
- Penguin battery: XUNTONG manufacturer ID
0x09C8+ 10-digit name pattern (or legacyPenguin-XXXXXXXXXX/FS Ext Battery) - Serial extraction: pulls TN-prefix + digits out of the manufacturer data block
Hits are streamed to UART (115200 baud) and dumped to SD as flockwifi-XXXX.pcap and flock-XXXX.pcap per session, with GPS-tagged CSV when a fix is available.
Why
Stock Marauder's "Flock Sniff" only looks for BLE chatter from the optional Penguin battery. Most pole-mounted Falcon V2s run on internal battery + solar and never advertise BLE, but they do continuously probe WiFi for a hidden uplink SSID with predictable OUIs. This fork catches both surfaces.
WatchFlock is for understanding where surveillance hardware is installed in your community, defensive recon for journalists, researchers, civil-liberties groups, and curious civilians. It is not a jamming tool.
Firmware (esp32_marauder/)
The C5 sniffer with WIFI_SCAN_FLOCK_AP and BT_SCAN_FLOCK_BLE modes. Build and flash via BUILD-C5.md. Pin Arduino ESP32 core to 3.3.0 (3.3.8 has a PSRAM regression on the N8R8 chip), use CDCOnBoot=default, partition default_8MB.
Flipper companion (flipper/)
Live dashboard for the SWIZ tagged-text records the firmware emits over UART. Per-MAC unique counter, peak RSSI, haptic + audio alerts on first detection per device, BACK to the band picker. Build with ufbt from inside the flipper/ dir. See flipper/README.md.
Emitter (emitter/)
WROVER-E sketch that spoofs four Flock-OUI WiFi identities and three Penguin BLE identities on rotation. Lets you test the firmware + FAP end to end without driving to a real ALPR pole. Plus debug scripts (c5-tail.sh, c5-cmd.sh) for monitoring the C5 over USB-CDC without auto-resetting it. See emitter/README.md.
Inspired by the Watch_Dogs games. Turning the city's sensors back on the people who installed them.
source code
files
- .github/FUNDING.yml
- .github/ISSUE_TEMPLATE/bug_report.md
- .github/ISSUE_TEMPLATE/config.yml
- .github/ISSUE_TEMPLATE/feature_request.md
- .github/workflows/build_parallel.yml
- .github/workflows/close_stale.yml
- .github/workflows/nightly_build.yml
- .travis.yml
- BUILD-C5.md
- C5_Py_Flasher/c5_flasher.py
- FlashFiles/MarauderV4/README.md
- FlashFiles/flash_cmd.txt
- FlashFiles/flash_download_tool_3.9.5.zip
- LICENSE
- PCBs/FlipperZero/References/1.PNG
- PCBs/FlipperZero/References/2.PNG
- PCBs/FlipperZero/References/3.PNG
- PCBs/FlipperZero/WiFi-Devboard-Pro/Manufacturing/WiFi-Devboard-Pro-Gerber.zip
- PCBs/FlipperZero/WiFi-Devboard-Pro/README.md
- PCBs/FlipperZero/WiFi-Devboard-Pro/WiFi-Devboard-Pro-backups/WiFi-Devboard-Pro-2022-12-14_183029.zip
- PCBs/FlipperZero/WiFi-Devboard-Pro/WiFi-Devboard-Pro-backups/WiFi-Devboard-Pro-2022-12-14_184109.zip
- PCBs/FlipperZero/WiFi-Devboard-Pro/WiFi-Devboard-Pro-backups/WiFi-Devboard-Pro-2022-12-14_184753.zip
- PCBs/FlipperZero/WiFi-Devboard-Pro/WiFi-Devboard-Pro-backups/WiFi-Devboard-Pro-2022-12-15_170532.zip
- PCBs/FlipperZero/WiFi-Devboard-Pro/WiFi-Devboard-Pro-backups/WiFi-Devboard-Pro-2022-12-15_171233.zip
- PCBs/FlipperZero/WiFi-Devboard-Pro/WiFi-Devboard-Pro-backups/WiFi-Devboard-Pro-2022-12-15_172033.zip
- PCBs/FlipperZero/WiFi-Devboard-Pro/WiFi-Devboard-Pro-backups/WiFi-Devboard-Pro-2022-12-15_172621.zip
- PCBs/FlipperZero/WiFi-Devboard-Pro/WiFi-Devboard-Pro-backups/WiFi-Devboard-Pro-2022-12-15_174813.zip
- PCBs/FlipperZero/WiFi-Devboard-Pro/WiFi-Devboard-Pro-backups/WiFi-Devboard-Pro-2022-12-20_154142.zip
- PCBs/FlipperZero/WiFi-Devboard-Pro/WiFi-Devboard-Pro-backups/WiFi-Devboard-Pro-2022-12-20_164720.zip
- PCBs/FlipperZero/WiFi-Devboard-Pro/WiFi-Devboard-Pro-backups/WiFi-Devboard-Pro-2022-12-20_175819.zip
- PCBs/FlipperZero/WiFi-Devboard-Pro/WiFi-Devboard-Pro-backups/WiFi-Devboard-Pro-2022-12-21_100159.zip
- PCBs/FlipperZero/WiFi-Devboard-Pro/WiFi-Devboard-Pro-backups/WiFi-Devboard-Pro-2022-12-21_101146.zip
- PCBs/FlipperZero/WiFi-Devboard-Pro/WiFi-Devboard-Pro-backups/WiFi-Devboard-Pro-2023-01-02_125523.zip
- PCBs/FlipperZero/WiFi-Devboard-Pro/WiFi-Devboard-Pro-backups/WiFi-Devboard-Pro-2023-01-02_131014.zip
- PCBs/FlipperZero/WiFi-Devboard-Pro/WiFi-Devboard-Pro-backups/WiFi-Devboard-Pro-2023-01-02_134751.zip
- PCBs/FlipperZero/WiFi-Devboard-Pro/WiFi-Devboard-Pro-backups/WiFi-Devboard-Pro-2023-01-02_142120.zip
- PCBs/FlipperZero/WiFi-Devboard-Pro/WiFi-Devboard-Pro-backups/WiFi-Devboard-Pro-2023-01-02_144208.zip
- PCBs/FlipperZero/WiFi-Devboard-Pro/WiFi-Devboard-Pro-backups/WiFi-Devboard-Pro-2023-01-16_011850.zip
- PCBs/FlipperZero/WiFi-Devboard-Pro/WiFi-Devboard-Pro-backups/WiFi-Devboard-Pro-2023-01-17_082750.zip
- PCBs/FlipperZero/WiFi-Devboard-Pro/WiFi-Devboard-Pro-backups/WiFi-Devboard-Pro-2024-07-17_184006.zip
- PCBs/FlipperZero/WiFi-Devboard-Pro/WiFi-Devboard-Pro-backups/WiFi-Devboard-Pro-2024-07-21_114536.zip
- PCBs/FlipperZero/WiFi-Devboard-Pro/WiFi-Devboard-Pro-backups/WiFi-Devboard-Pro-2025-01-28_225838.zip
- PCBs/FlipperZero/WiFi-Devboard-Pro/WiFi-Devboard-Pro-backups/WiFi-Devboard-Pro-2025-03-26_155226.zip
- PCBs/FlipperZero/WiFi-Devboard-Pro/WiFi-Devboard-Pro-backups/WiFi-Devboard-Pro-2025-05-28_160712.zip
- PCBs/FlipperZero/WiFi-Devboard-Pro/WiFi-Devboard-Pro-backups/WiFi-Devboard-Pro-2025-05-28_182343.zip
- PCBs/FlipperZero/WiFi-Devboard-Pro/WiFi-Devboard-Pro.xml
- PCBs/Kit/PCB_ESP32 Marauder 3.5 Kit V3 PCB_2022-04-29.json
- PCBs/v4(OG)/Marauder Screen PCB Measurements.png
- PCBs/v4(OG)/PCB_ESP32 Marauder 3.7 OG PCB_2022-04-29.json
- PCBs/v4(OG)/README.md
- PCBs/v6/PCB_ESP32 Marauder 6 PCB_2022-04-29.json
- README.md
- User_Setup.h
- User_Setup_Select.h
- User_Setup_cyd_2usb.h
- User_Setup_cyd_3_5_inch.h
- User_Setup_cyd_guition.h
- User_Setup_cyd_micro.h
- User_Setup_dual_nrf24.h
- User_Setup_marauder_m5cardputer.h
- User_Setup_marauder_m5cardputer_adv.h
- User_Setup_marauder_m5stickc.h
- User_Setup_marauder_m5stickcp2.h
- User_Setup_marauder_mini.h
- User_Setup_marauder_rev_feather.h
- User_Setup_og_marauder.h
- User_Setup_pocket_sdr_3.h
- emitter/README.md
- emitter/c5-cmd.sh
- emitter/c5-tail.sh
- esp32_marauder/.theia/launch.json
- esp32_marauder/AXP192.cpp
- esp32_marauder/AXP192.h
- esp32_marauder/Assets.h
- esp32_marauder/BatteryInterface.cpp
- esp32_marauder/BatteryInterface.h
- esp32_marauder/Buffer.cpp
- esp32_marauder/Buffer.h
- esp32_marauder/CommandLine.cpp
- esp32_marauder/CommandLine.h
- esp32_marauder/Display.cpp
- esp32_marauder/Display.h
- esp32_marauder/EvilPortal.cpp
- esp32_marauder/EvilPortal.h
- esp32_marauder/GpsInterface.cpp
- esp32_marauder/GpsInterface.h
- esp32_marauder/Keyboard.cpp
- esp32_marauder/Keyboard.h
- esp32_marauder/Keyboard_def.h
- esp32_marauder/LedInterface.cpp
- esp32_marauder/LedInterface.h
- esp32_marauder/MenuFunctions.cpp
- esp32_marauder/MenuFunctions.h
- esp32_marauder/SDInterface.cpp
- esp32_marauder/SDInterface.h
- esp32_marauder/Switches.cpp
- esp32_marauder/Switches.h
- esp32_marauder/TouchKeyboard.cpp
- esp32_marauder/TouchKeyboard.h
- esp32_marauder/WiFiScan.cpp
- esp32_marauder/WiFiScan.h
- esp32_marauder/configs.h
- esp32_marauder/data/marauder3L.jpg
- esp32_marauder/data/marauder3L1.jpg
- esp32_marauder/data/marauder_mini.jpg
- esp32_marauder/flipperLED.cpp
- esp32_marauder/flipperLED.h
- esp32_marauder/lang_var.h
- esp32_marauder/settings.cpp
- esp32_marauder/settings.h
- esp32_marauder/stickcLED.cpp
- esp32_marauder/stickcLED.h
- esp32_marauder/utils.h
- esp32_marauder/xiaoLED.cpp
- esp32_marauder/xiaoLED.h
- flipper/README.md
- flipper/flock_log.c
- flipper/flock_log.h
- flipper/flock_oui.c
- flipper/flock_oui.h
- flipper/flock_parser.c
- flipper/flock_parser.h
- flipper/flock_pcap.c
- flipper/flock_pcap.h
- flipper/flock_uart.c
- flipper/flock_uart.h
- flipper/flock_view.c
- flipper/flock_view.h
- flipper/icon.png
- flipper/icon_S.png
- flipper/make_icon_S.py
- flipper/swiz_flock_hunter.c
- flipper/swiz_flock_hunter.h
- libraries/Adafruit_TCA8418/Adafruit_TCA8418.cpp
- libraries/Adafruit_TCA8418/Adafruit_TCA8418.h
- libraries/Adafruit_TCA8418/Adafruit_TCA8418_registers.h
- libraries/ESPAsyncWebServer/LICENSE
- libraries/ESPAsyncWebServer/README.md
- libraries/ESPAsyncWebServer/docs/_config.yml
- libraries/ESPAsyncWebServer/docs/index.md
- libraries/ESPAsyncWebServer/examples/StreamFiles/StreamConcat.h
- libraries/ESPAsyncWebServer/examples/StreamFiles/StreamString.h
- libraries/ESPAsyncWebServer/library.json
- libraries/ESPAsyncWebServer/src/AsyncEventSource.cpp
- libraries/ESPAsyncWebServer/src/AsyncEventSource.h
- libraries/ESPAsyncWebServer/src/AsyncJson.h
- libraries/ESPAsyncWebServer/src/AsyncWebSocket.cpp
- libraries/ESPAsyncWebServer/src/AsyncWebSocket.h
- libraries/ESPAsyncWebServer/src/AsyncWebSynchronization.h
- libraries/ESPAsyncWebServer/src/ESPAsyncWebServer.h
- libraries/ESPAsyncWebServer/src/ESP_Async_WebServer.h
- libraries/ESPAsyncWebServer/src/StringArray.h
- libraries/ESPAsyncWebServer/src/WebAuthentication.cpp
- libraries/ESPAsyncWebServer/src/WebAuthentication.h
- libraries/ESPAsyncWebServer/src/WebHandlerImpl.h
- libraries/ESPAsyncWebServer/src/WebHandlers.cpp
- libraries/ESPAsyncWebServer/src/WebRequest.cpp
- libraries/ESPAsyncWebServer/src/WebResponseImpl.h
- libraries/ESPAsyncWebServer/src/WebResponses.cpp
- libraries/ESPAsyncWebServer/src/WebServer.cpp
- old_README.md
- pictures/BFFB NRF24 Fix/DSC05049-Edit.jpg
- pictures/BFFB NRF24 Fix/DSC05050.jpg
- pictures/IMG_0124.JPG
- pictures/IMG_0125.JPG
- pictures/IMG_0126.JPG
- pictures/IMG_0127.JPG
- pictures/IMG_0128.JPG
- pictures/IMG_0129.JPG
- pictures/IMG_0130.JPG
- pictures/IMG_0131.JPG
- pictures/IMG_0132.JPG
- pictures/IMG_0133.JPG
- pictures/IMG_0134.JPG
- pictures/IMG_0135.JPG
- pictures/IMG_0136.JPG
- pictures/IMG_0137.JPG
- pictures/IMG_0420.JPG
- pictures/IMG_0421.JPG
- pictures/IMG_0423.JPG
- pictures/IMG_0424.JPG
- pictures/IMG_0425.JPG
- pictures/IMG_0426.JPG
- pictures/IMG_1838.JPG
- pictures/IMG_1840.JPG
- pictures/IMG_1841.JPG
- pictures/IMG_1842.JPG
- pictures/IMG_1844.JPG
- pictures/IMG_1845.JPG
- pictures/IMG_1848.JPG
- pictures/IMG_1849.JPG
- pictures/IMG_1851.JPG
- pictures/IMG_1852.JPG
- pictures/IMG_1853.JPG
- pictures/IMG_2519 - Copy.jpg
- pictures/IMG_2520 - Copy.jpg
- pictures/IMG_3475 - Copy.jpg
- pictures/IMG_3484 - Copy.jpg
- pictures/IMG_3485 - Copy.jpg
- pictures/IMG_3491 - Copy.jpg
- pictures/IMG_5876 - Copy.jpg
- pictures/IMG_5877 - Copy.jpg
- pictures/IMG_5878 - Copy.jpg
- pictures/IMG_5879 - Copy.jpg
- pictures/IMG_7745 - Copy.jpg
- pictures/IMG_7746 - Copy.jpg
- pictures/IMG_7748 - Copy.jpg
- pictures/IMG_7749 - Copy.jpg
- pictures/IMG_7750 - Copy.jpg
- pictures/IMG_7751 - Copy.jpg
- pictures/IMG_7752 - Copy.jpg
- pictures/IMG_7753 - Copy.jpg
- pictures/Marauder_Horse.svg
- pictures/WiFiDevBoardPro/IMG_2264 - Copy.JPG
- pictures/WiFiDevBoardPro/IMG_2265 - Copy.JPG
- pictures/WiFiDevBoardPro/IMG_2266 - Copy.JPG
- pictures/WiFiDevBoardPro/IMG_2267 - Copy.JPG
- pictures/WiFiDevBoardPro/IMG_2268 - Copy.JPG
- pictures/WiFiDevBoardPro/IMG_2269 - Copy.JPG
- pictures/WiFiDevBoardPro/IMG_2270 - Copy.JPG
- pictures/c5_marauder_flipper_adapter.png
- pictures/diy.png
- pictures/esp32marauder_thumbnail.jpg
- pictures/jcmk_icon_black.png
- pictures/jcmk_icon_black.svg
- pictures/jcmk_icon_white.jpg
- pictures/jcmk_square_sticker_500px.png
- pictures/jcmkllc.svg
- pictures/m5stack.jpg
- pictures/marauder.svg
- pictures/marauder3L.jpg
- pictures/marauder_skull_240x320-01-01.png
- pictures/marauder_skull_patch_04_full_final.png
- pictures/no_step_on_snek.jpg
- pictures/odroid_marauder.jpg
- pictures/screenshots/flipper-apps-menu.png
- pictures/screenshots/flipper-band-picker.png
- pictures/screenshots/flipper-running.png
- pictures/wifi-dev-board-pro-3v3-orientation.png
- schematics/Schematic_ESP32-Marauder-2_ESP32-Marauder-2-Schematic_20191007113616_png.png
viewer
// click a file to view source