Skip to main content

Passive RF detection of Flock Safety ALPR cameras from WiGLE wardriving data

Project description

flockdar

Passive RF detection of Flock Safety ALPR (automatic license plate reader) cameras from WiGLE wardriving data.

Works with both the WiGLE Android app SQLite backup and WiGLE CSV exports (.csv.gz). All detection runs fully offline. Optional enrichment queries cross-reference hits against DeFlock/OSM, ALPRWatch, and the WiGLE API.


What it detects

Device RF signature Confidence
Flock camera WiFi SSID Flock-XXXXXX where XXXXXX matches last 6 of MAC High
Flock camera backhaul WiFi SSID flocknet on eero hardware (80:da:13) High
Flock Safety hardware MAC prefix b4:1e:52 (direct IEEE registration) High
Raven firmware (1.2+) Custom BLE services 0x31000x3500 High
Penguin surveillance BLE name Penguin-XXXXXXXXXX (10-digit numeric) High
Penguin surveillance BLE manufacturer ID 2504 Medium
Any Flock camera OUI + WPA2-no-WPS + 2.4 GHz channel 1/6/11 Medium
FS Ext Battery BLE name FS Ext Battery Medium
Raven firmware (1.1.7) BLE services 0x1809 / 0x1819 Low–Medium
Flock-family hardware Chip-vendor OUI match (38 prefixes) Low
Other surveillance Axis, FLIR, Hanwha, Avigilon, etc. OUIs Informational

Quick start

Requires uv.

uv sync
uv run tui.py wigle_backup.sqlite
uv run tui.py WigleWifi_export.csv.gz
# or via installed script:
flockdar wigle_backup.sqlite

TUI keybindings

Key Action
/ Navigate device list
m Open selected location in Google Maps
v Open in Google Street View
c Copy MAC address(es) to clipboard
n Enrich visible hits (OSM/DeFlock, ALPRWatch, WiGLE)
w Configure WiGLE API credentials
e Export visible hits to CSV
k Export visible hits to KML
g Export visible hits to GeoJSON
o Open iD editor + copy OSM tags for selected camera
r Reload / re-scan file
q Quit

The left sidebar has Confidence and Type filters and a Group nearby checkbox that collapses devices within 75 m of each other into a single cluster row.


Enrichment

Press n to cross-reference all visible hits against external databases. Results appear live in the Enriched table column and the detail panel.

Source Signal Auth
DeFlock / OpenStreetMap OSM_ALPR_NEARBY — confirmed ALPR node within 150 m None
ALPRWatch ALPRWATCH_NEARBY — daily KMZ, cached 24 h None
WiGLE API WIGLE_SEEN — first/last seen dates, sighting count API key

WiGLE credentials — press w in the TUI, or set environment variables:

export WIGLE_API_NAME=your_api_name
export WIGLE_API_TOKEN=your_api_token
uv run tui.py wigle_backup.sqlite

Credentials are stored in ~/.config/flock-wigle/config.json (Unix: chmod 600).


Getting your WiGLE data

SQLite DB (preferred) — richer data, includes BLE service UUIDs and manufacturer IDs: Open the WiGLE WiFi Wardriving app → Menu → Backup Database → copy wigle.sqlite off the device.

CSV export — no BLE service UUID data: wigle.net → My Account → Downloads, or app → Menu → Export to SD.


Running tests

uv run pytest

102 tests cover detect.py signal logic, enrich.py enrichers (via httpx.MockTransport), and signatures.py pattern correctness.


How detection works

detect.py runs every record through signatures.py and appends (label, detail) signal tuples to each Hit. Confidence is derived from which labels are present — no stored score:

  • HIGH (3): FLOCK_DIRECT_OUI, RAVEN_UUID_HIGH, FLOCKNET_SSID, FLOCK_CAMERA_SSID, PENGUIN_BLE_SSID
  • MEDIUM (2): FLOCK_CAMERA_SSID_PATTERN, BLE_NAME, BACKHAUL_OUI_HIDDEN, FLOCK_WIFI_FP, FLOCK_MFGRID
  • LOW (1): CHIP_OUI, SSID_PATTERN, RAVEN_UUID_OLD, SURVEILLANCE_OUI

Cluster groups nearby hits (union-find, 75 m radius) and reports the highest confidence across members.

What WiGLE passive scanning misses

Flock cameras spend most of their duty cycle asleep, waking briefly to upload. A passive WiGLE scan will miss cameras during sleep. The flock-you and FlockSquawk projects implement promiscuous 802.11 mode on ESP32 hardware, matching addr1 (receiver) as well as addr2 (transmitter) to catch cameras even while they sleep. Newer Flock firmware also emits wildcard probe requests (SSID length = 0) on wake-up — detectable only via raw frame capture.

Active GATT interrogation

Raven firmware exposes a readable GATT tree without authentication when within BLE range (~10 m). See signatures.py:RAVEN_CHARACTERISTICS for the full characteristic map. Key characteristics:

UUID Field
0x2a26 Firmware version (1.1.7, 1.2.0, 1.3.1)
0x3002 Serial number
0x3101 / 0x3102 Camera's own GPS latitude / longitude
0x3303 LTE operator
0x3402 Most recent upload time

Files

tui.py           Textual TUI — main entry point
detect.py        Detection logic (no UI dependency, importable)
enrich.py        Async enrichers: OSM/DeFlock, ALPRWatch, WiGLE API
discover.py      WiGLE-based discovery of unseen Flock cameras (cached)
signatures.py    All OUI prefixes, BLE UUIDs, SSID/name patterns
esp32/           Planned ESP32 companion firmware (design phase)
tests/           pytest suite (asyncio_mode=auto)
pyproject.toml   uv project — dependencies and scripts
CLAUDE.md        Architecture notes for AI coding assistants

ESP32 companion (planned)

esp32/ contains the design spec for a companion firmware module that runs on an ESP32 and detects Flock cameras in real time via:

  • WiFi promiscuous mode — OUI-matched probe requests + addr1 receiver matching
  • BLE scanningFS Ext Battery, manufacturer ID 2504, etc.
  • JSON over USB serial — output consumed by flockdar --serial /dev/ttyUSB0

See esp32/README.md for hardware list, output format, and integration details. esp32/gen_oui_header.py generates the C header from signatures.py so the OUI list stays in sync.


Headless / scripted use

from pathlib import Path
import asyncio
import detect
from enrich import build_enrichers, enrich_hits_async

hits, total = detect.run_detection(Path("wigle_backup.sqlite"))
enrichers = build_enrichers()                    # OSM + ALPRWatch; add WiGLE creds if wanted
asyncio.run(enrich_hits_async(hits, enrichers))

for h in hits:
    print(h.confidence_label, h.mac, repr(h.ssid), h.signals_str())

Signature sources

Research attribution — cite these projects when reusing signature data:

  • NitekryDPaul — WiFi OUI list via promiscuous-mode 802.11 analysis (flock-you dataset)
  • NSM-Barii — Raven BLE service UUIDs, BLE name patterns, newer firmware probe-request technique (flock-back)
  • f1yaw4y — Combined OUI list, surveillance OUIs, FlockSquawk firmware (FlockSquawk)
  • DeFlock / FoggedLens — OSM ALPR crowdsourcing and enrichment API (deflock.org)
  • ALPRWatch — ALPR location database (alprwatch.org)

Known false positives

OUI / Pattern Common non-Flock device How to distinguish
f4:6a:dd Barco ClickShare AV gear SSID contains "ClickShare"
e4:aa:ea Cisco CX20 conferencing SSID is CX20-N
14:5a:fc Generic BT consumer chips Named laptop/headphone SSID
74:4c:a1 Vizio soundbars SSID starts VIZIO
0000180a UUID Nearly all BLE devices Do not use alone
eero 80:da:13 (named SSID) Home/business mesh routers Only flag blank or flocknet SSIDs

License

MIT — see LICENSE. Research and educational use. Cite original researchers when reusing signature data.

This tool is for privacy research, transparency advocacy, and understanding the RF footprint of surveillance infrastructure. It does not interact with cameras or any live systems.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

flockdar-0.1.0.tar.gz (14.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

flockdar-0.1.0-py3-none-any.whl (8.1 kB view details)

Uploaded Python 3

File details

Details for the file flockdar-0.1.0.tar.gz.

File metadata

  • Download URL: flockdar-0.1.0.tar.gz
  • Upload date:
  • Size: 14.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.6.6

File hashes

Hashes for flockdar-0.1.0.tar.gz
Algorithm Hash digest
SHA256 773fa81b0380eea61a9ca98d116710708f6fcb16f2adaecd9dac3f3435d0be6f
MD5 a9fcee09b5bc6c08f2579ac43e4b47ee
BLAKE2b-256 d14ccb44282095671c508377f3562c118a09edab86ef24dc048dda2716e955b1

See more details on using hashes here.

File details

Details for the file flockdar-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: flockdar-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 8.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.6.6

File hashes

Hashes for flockdar-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 7278dd3bdf2cabfed011baaf86eec47738e8ad19ceb409ffab5a2b49d9c327f7
MD5 5b80a657320e42ea16d1da436a307484
BLAKE2b-256 563849bddb92d6891d1282c688c672464602a53782274af6119eb9427918eba6

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page