Map Flock Safety ALPR surveillance cameras using WiGLE WiFi data and OUI fingerprinting.
An open-source project that queries the WiGLE crowdsourced WiFi database for networks matching known Flock Safety camera OUI (MAC address) prefixes, then plots them on an interactive map.
Inspired by DeFlock and track-openroaming-passpoint.
| Metric | Value |
|---|---|
| πΈ Cameras Mapped (actionable) | 91,032 |
| π of which SSID-confirmed | 5,062 |
| π°οΈ of which OUI-suspected (high tier) | 76,837 |
| π§© of which OUI-suspected (contract-mfr tier) | 9,133 |
| π« Excluded β SSID is other hardware | 62,920 |
| π Flagged outside the US | 73,853 |
| π‘ OUI Prefixes with Data | 38 / 39 |
| π Countries | 137 |
| πΊοΈ Regions / provinces (distinct) | 2,048 |
| π Last Updated | 2026-10-13 |
| π¦ Data Retention | 730 days (2 years) |
Stats update automatically after each scan via GitHub Actions. βCameras Mappedβ counts only the records that pass evidence classification β the breakdown is below.
Every published record carries a confidence field, because an OUI match on its own is weak evidence. The map and the headline count only the records that survive that classification.
| Confidence | Records | Share | Meaning |
|---|---|---|---|
ssid_confirmed |
5,062 | 3.3% | SSID is a Flock naming pattern (Flock, Flock-XXXXXX, Flock Camera net., FS Ext Battery) β strongest signal passive WiFi can give |
oui_high |
76,837 | 49.9% | High-confidence Flock OUI, SSID absent/hidden/unrecognised β suspected, unverified |
oui_mfr |
9,133 | 5.9% | Contract-manufacturer OUI (Liteon/USI) β weakest evidence, expect false positives |
identified_other |
62,920 | 40.9% | SSID positively identifies other hardware β excluded from the map and from the camera count above |
| All records | 153,952 | 100.0% |
SSID denylist hits: clickshare* 52,175 Β· smartgate_* 6,130 Β· direct-* 3,709 Β· androidap* 599 Β· audi hud* 140 Β· max-printer* 140 Β· detector_verdict* 27.
Detector output ingested as data. 27 records carry another detector's verdict string in the SSID column (Flock ALPR [wifi_receiver_oui;low] and similar) β self-tagged low 23 Β· medium 4 by the tool that produced them. They are a downstream copy of a detection, not an observation of a camera, so they are excluded outright instead of being counted in the SSID-confirmed subset.
Per-prefix signal, measured. Of the 33 prefixes with β₯200 records, the ones whose records mostly name other hardware:
| OUI prefix | Records | SSID-confirmed | Excluded as other hardware |
|---|---|---|---|
F4:6A:DD |
11,985 | 397 | 8,487 (71%) |
74:4C:A1 |
12,037 | 260 | 8,455 (70%) |
D0:39:57 |
11,943 | 571 | 8,388 (70%) |
9C:2F:9D |
6,619 | 324 | 4,576 (69%) |
C0:35:32 |
5,861 | 132 | 3,828 (65%) |
70:08:94 |
3,791 | 137 | 2,409 (64%) |
D8:F3:BC |
4,042 | 196 | 2,560 (63%) |
B8:1E:A4 |
3,796 | 122 | 2,288 (60%) |
The most Flock-confirmed, for contrast: 70:C9:4E (34% SSID-confirmed, 194 of 569 records), 00:F4:8D (24% SSID-confirmed, 162 of 679 records), 3C:91:80 (18% SSID-confirmed, 178 of 974 records).
11 prefixes are neither confirmed nor contradicted β under 2% of their records carry a Flock SSID and under half name other hardware, so their MACs are simply unverifiable from SSID evidence: 64:6E:69 (3,711 records, 18 confirmed), 58:00:E3 (4,918 records, 43 confirmed), E0:4F:43 (22,704 records, 94 confirmed), 5C:93:A2 (3,891 records, 16 confirmed), A4:CF:12 (4,371 records, 4 confirmed), 3C:71:BF (3,931 records, 13 confirmed) and 5 more. These are the weakest entries in the list: an OUI match there means little on its own.
The tier field in data/flock_ouis.csv is the curated (firmware-parity) judgement; these numbers are the measurement. Where they disagree, the measurement is the honest summary of what this dataset actually contains.
Market: 73,853 records (48.0%) are outside the primary US market and carry "out_of_market": true. They are flagged, not deleted β Flock has expanded internationally β so consumers can filter them.
Every record is still suspected: the tiers describe the strength of the evidence, not a confirmation from Flock that a device is theirs. See docs/DATA_POLICY.md.
Warning
Take this map with a grain of salt. WiGLE is a crowdsourced, passively-collected dataset that is updated sporadically on a per-location basis β it is not a live feed. Flock cameras do not broadcast continuously; they wake briefly only to upload data, meaning WiGLE records depend entirely on someone happening to be wardriving in the right place at the right time. Locations may be stale, incomplete, or reflect cameras that have since been moved or removed.
This dashboard is a general awareness tool, not a source of truth. For accurate, real-time, local detection use the hardware devices by STSCollective described below β they implement @NitekryDPaul's actual detection method directly on an ESP32 and can detect Flock cameras as you drive past them. Use discount code FLOCKFINDER at checkout for 20% off your order.
Flock Safety ALPR cameras have WiFi transceivers that periodically wake to upload captured license plate data. These transmissions use MAC addresses with identifiable OUI (Organizationally Unique Identifier) prefixes.
@NitekryDPaul discovered 30 of these OUI prefixes through promiscuous-mode 2.4 GHz analysis. A 31st was contributed by Michael / DeFlockJoplin during field testing in Joplin, MO. Seven more have since been promoted into the canonical list:
B4:1E:52β IEEE registration held directly by Flock Safety (the most authoritative signal in the list: it is Flock's own assignment, not a chipset vendor's).04:0D:84,F0:82:C0,1C:34:F1,38:5B:44,94:34:69,B4:E3:F9β the FS Ext Battery accessory / battery-pack series (dougborg/PR#39). These packs broadcast anFS Ext Batteryβ¦SSID, which is why that naming pattern is now queried alongsideFlock%/FLOCK%.
This project:
- Takes those 39 known Flock Safety WiFi OUI prefixes
- Queries the WiGLE WiFi database for networks matching each prefix
- Deduplicates and exports results as GeoJSON + CSV
- Displays camera locations on a dark-themed interactive Leaflet map
Note: WiGLE is a historical, crowdsourced WiFi survey database β it does not use @NitekryDPaul's active detection technique. WiGLE entries are submitted by volunteers wardriving with passive scanners, so coverage is uneven and timestamps may be months or years old. The map is best used as a rough geographic reference, not a definitive or current inventory.
Flock cameras spend most of their duty cycle asleep, waking briefly to upload. The key insight is matching on addr1 (receiver/destination) in addition to addr2 (transmitter) β revealing devices that a transmitter-only sniff would miss.
Combined with wildcard probe request detection (802.11 management frames type=0 subtype=4 with empty SSID), this yields a very tight signature: 11 of 12 cameras caught with only 2 false positives in field testing.
This is the gold-standard detection method β and it requires dedicated hardware running in the field. The WiGLE-based map in this repo does not implement addr1 matching; it can only see what WiGLE volunteers have already passively logged. For real-time, on-the-ground detection using this exact technique, see the STSCollective FlockYou devices β ESP32-based detectors that scan for Flock OUI signatures as you drive, with LED and/or audio alerts the moment a camera is detected. Use discount code
FLOCKFINDERat checkout for 20% off your order.
- Python 3.8+
- A WiGLE account with API credentials
# Clone the repo
git clone https://github.com/simeononsecurity/flock-finder.git
cd flock-finder
# Install dependencies
pip install -r requirements.txt
# Create your .env file with WiGLE credentials (NOT tracked by git)
cp .env.example .env
# Edit .env with your API Name and Token from https://wigle.net/account# Full scan β all 39 OUI prefixes, worldwide
python3 scripts/wigle_query.py
# Single OUI test
python3 scripts/wigle_query.py --oui 70:C9:4E
# US only
python3 scripts/wigle_query.py --country US
# Specific region (bounding box: lat1,lon1,lat2,lon2)
python3 scripts/wigle_query.py --bbox 37,-97,39,-94
# Dry run β verify auth, print OUI list, no API queries
python3 scripts/wigle_query.py --dry-run# Serve the docs directory locally
python3 -m http.server 8080 --directory docs/
# Open in browser
open http://localhost:8080Or just open docs/index.html directly in your browser.
flock-finder/
βββ .env # WiGLE API credentials (gitignored)
βββ .env.example # Template for .env
βββ .gitignore
βββ README.md
βββ requirements.txt
βββ scripts/
β βββ wigle_query.py # WiGLE API query script
βββ data/
β βββ flock_ouis.csv # 39 known Flock Safety OUI prefixes (canonical, tiers)
β βββ flock_cameras.geojson # GENERATED + published (not committed) β see βWhere Is the Data?β
β βββ flock_cameras.csv # GENERATED + published (not committed)
β βββ by_oui/ # GENERATED per-OUI splits (not committed)
β βββ scan_stats.json # Output: scan + evidence-tier statistics
βββ docs/
β βββ index.html # Interactive web map (Leaflet + dark theme)
βββ .github/
βββ workflows/
βββ update-data.yml # GitHub Actions: daily auto-update
39 known prefixes identified by @NitekryDPaul + DeFlockJoplin + dougborg/PR#39:
| # | OUI Prefix | Source |
|---|---|---|
| 1 | 70:C9:4E |
@NitekryDPaul |
| 2 | 3C:91:80 |
@NitekryDPaul |
| 3 | D8:F3:BC |
@NitekryDPaul |
| 4 | 80:30:49 |
@NitekryDPaul |
| 5 | B8:35:32 |
@NitekryDPaul |
| 6 | 14:5A:FC |
@NitekryDPaul |
| 7 | 74:4C:A1 |
@NitekryDPaul |
| 8 | 08:3A:88 |
@NitekryDPaul |
| 9 | 9C:2F:9D |
@NitekryDPaul |
| 10 | C0:35:32 |
@NitekryDPaul |
| 11 | 94:08:53 |
@NitekryDPaul |
| 12 | E4:AA:EA |
@NitekryDPaul |
| 13 | F4:6A:DD |
@NitekryDPaul |
| 14 | F8:A2:D6 |
@NitekryDPaul |
| 15 | 24:B2:B9 |
@NitekryDPaul |
| 16 | 00:F4:8D |
@NitekryDPaul |
| 17 | D0:39:57 |
@NitekryDPaul |
| 18 | E8:D0:FC |
@NitekryDPaul |
| 19 | E0:4F:43 |
@NitekryDPaul |
| 20 | B8:1E:A4 |
@NitekryDPaul |
| 21 | 70:08:94 |
@NitekryDPaul |
| 22 | 58:8E:81 |
@NitekryDPaul |
| 23 | EC:1B:BD |
@NitekryDPaul |
| 24 | 3C:71:BF |
@NitekryDPaul |
| 25 | 58:00:E3 |
@NitekryDPaul |
| 26 | 90:35:EA |
@NitekryDPaul |
| 27 | 5C:93:A2 |
@NitekryDPaul |
| 28 | 64:6E:69 |
@NitekryDPaul |
| 29 | 48:27:EA |
@NitekryDPaul |
| 30 | A4:CF:12 |
@NitekryDPaul |
| 31 | 82:6B:F2 |
DeFlockJoplin |
| 32 | B4:1E:52 |
dougborg/PR#39 β direct IEEE registration to Flock Safety |
| 33 | 04:0D:84 |
dougborg/PR#39 β FS Ext Battery series |
| 34 | F0:82:C0 |
dougborg/PR#39 β FS Ext Battery series |
| 35 | 1C:34:F1 |
dougborg/PR#39 β FS Ext Battery series |
| 36 | 38:5B:44 |
dougborg/PR#39 β FS Ext Battery series |
| 37 | 94:34:69 |
dougborg/PR#39 β FS Ext Battery series |
| 38 | B4:E3:F9 |
dougborg/PR#39 β FS Ext Battery series |
| 39 | E0:0A:F6 |
dougborg/PR#39 β contract-manufacturer silicon (mfr tier) |
Reconciled with flock-you-esp32. That firmware carries 41 prefixes; this list carries 39. The two deliberate omissions are
00:03:7F(generic Qualcomm Atheros QCA9377 β see the data policy) andD4:11:D6(SoundThinking/ShotSpotter, a different device class that the firmware alerts on but which is not a Flock camera). The remaining delta that this list was missing βE0:0A:F6β is now included.The per-prefix
vendorcolumn is the IEEE registrant, which is usually not Flock Safety: the hardware here runs on Liteon, Silicon Labs, USI and Espressif radio silicon, which is precisely why an OUI match needs the tier and the measured signal column.
The table below lists the ten most frequently observed SSID values across all WiGLE records matching a known Flock Safety OUI prefix. Because most Flock cameras transmit a hidden SSID (empty broadcast), the entries below represent the minority of records where a network name was visible to the WiGLE wardrive scanner. They are published here as a community reference for researchers and detection tool authors.
β οΈ These SSIDs are not exclusive to Flock cameras. They appear in records whose OUI prefix matches the known Flock Safety list β but many of these network names (e.g.,ClickShare,TEST) are generic and may simply co-occupy the same MAC space. Treat them as correlated observations, not confirmed Flock identifiers.
| # | SSID | Occurrences |
|---|---|---|
| 1 | Flock |
4,894 |
| 2 | SMARTGATE_123456 |
867 |
| 3 | ______________________ |
337 |
| 4 | TEST |
302 |
| 5 | AndroidAP |
297 |
| 6 | ClickShare |
228 |
| 7 | ClickShare-Boardroom |
222 |
| 8 | Compudopt Connect |
221 |
| 9 | ClickShare-Conference Room |
139 |
| 10 | MAX-PRINTER |
139 |
Computed from 127,774 SSID-bearing records (114,099 unique values) across all 38 OUI files in data/by_oui/. Stats update automatically after each scan.
Filtering for only Flock*-prefixed SSIDs yields 172 unique variants across 5,088 total records. These fall into five distinct patterns:
| Pattern | Unique SSIDs | Records | Description |
|---|---|---|---|
Flock |
1 | 4,894 | Bare name β fully configured / deployed cameras |
Flock-XXXXXX |
159 | 159 | Mixed-case with 6-char uppercase hex suffix |
FLOCK-XXXXXX |
5 | 5 | All-caps variant with 6-char hex suffix |
Flock-XXXX |
1 | 1 | Shorter 4-char hex suffix (Flock-6361) |
FlockXXX |
2 | 2 | Numeric suffix, no dash (Flock001, Flock003) |
| Other | 4 | 27 | Other / non-standard patterns |
The Flock-XXXXXX / FLOCK-XXXXXX naming convention is consistent with camera provisioning SSIDs β each device appears to broadcast a unique hex identifier (likely derived from its MAC address) before being claimed and configured through the Flock Safety platform. Once provisioned, the SSID collapses to the bare Flock name.
This pattern is a strong secondary confirmation signal: observing a
Flock-XXXXXXSSID on a matching OUI prefix is highly indicative of an unconfigured or recently factory-reset Flock Safety camera.
Note
New SSID pattern observed in the wild β Flock Camera net.
A community member (flock-you issue #43) reported a Flock Safety camera broadcasting as Flock Camera net. β a naming format completely invisible to Flock-* pattern searches. The same camera simultaneously broadcast on both 2.4 GHz (channel 1) and 5 GHz (channel 157) using sequential locally administered MACs (e.g. 52:64:CF:9F:A2:DE / :DF). The locally administered addressing is likely a deliberate anti-fingerprinting measure β these MACs will never match IEEE OUI lookups, making SSID-pattern detection the only viable passive identification path for cameras using this scheme.
This section is populated automatically by querying WiGLE for any SSID matching Flock%, FLOCK% or FS Ext Battery%, then extracting OUI prefixes from the results that are not in the canonical flock_ouis.csv. Only OUIs observed β₯5 times are reported here to reduce false positives.
No candidate OUI prefixes identified yet β SSID-pattern incremental queries are running. Candidate prefixes will appear here once any novel OUI is observed β₯5 times in Flock-SSID-bearing WiGLE records.
LAA-MAC camera class (Flock Camera net.): zero records. No published record has an SSID containing Flock Camera net., so the one camera class that defeats OUI matching entirely (locally-administered MACs β flock-you issue #43) currently has no coverage at all. This is a data gap, not a pattern gap: the Flock% pattern is a prefix match that already covers Flock Camera net., so the search is correct β either no wardrive has passed one of these cameras yet, or they broadcast a hidden SSID. If it stays at zero across several scans, the next widening step is %Camera net.% (any prefix before Camera), which trades precision for coverage.
Locally-administered (LAA) records: 23 β all from 82:6B:F2 (23). That prefix is a confirmed Flock OUI whose first octet happens to set the LAA bit, so it is not the anti-fingerprinting class; LAA-randomised cameras remain unrepresented.
FS Ext Battery pattern: 1 published record(s) carry an FS Ext Batteryβ¦ SSID β the class the FS Ext Battery% discovery pattern was added for.
| SSID pattern | Records matched (this pass) |
|---|---|
Flock% |
0 |
FLOCK% |
0 |
FS Ext Battery% |
0 |
fs ext battery% |
0 |
The included workflow runs daily and auto-commits updated camera data:
-
Add your WiGLE credentials as repository secrets:
WIGLE_API_NAMEβ your API name from wigle.net/accountWIGLE_API_TOKENβ your API token
-
The workflow runs at 6 AM UTC daily, or manually via "Run workflow"
-
If new data is found, it commits updated GeoJSON/CSV/stats automatically
The dataset is published, not committed. flock_cameras.geojson (~90 MB,
rewritten in full on every daily scan), flock_cameras.csv and the per-OUI
splits under data/by_oui/ used to be committed; because each scan rewrites them
completely, they grew the repository to ~1.6 GB and made it slow to clone. They
now live in three places instead:
| What | Where |
|---|---|
Live map (unchanged /data/β¦ paths) |
the GitHub Pages site β the deploy jobs restore the files from the release before publishing |
| Downloadable dataset | the rolling data-latest release: flock_cameras.geojson, flock_cameras.csv, by_oui.zip |
| A local checkout | run python3 scripts/wigle_query.py (needs WiGLE credentials), or fetch the published copy: gh release download data-latest -p 'flock_cameras.geojson' -D data |
What stays in git are the small, diffable artifacts: data/flock_ouis.csv (the
canonical OUI list), scan_stats.json, candidate_ouis.json and
ssid_candidate_cameras.*.
History note. Untracking stops the growth; the old blobs are still in history. Reclaiming the existing ~1.6 GB requires a history rewrite (
git filter-repo --path data/flock_cameras.geojson --path data/flock_cameras.csv --path data/by_oui --invert-paths), which is a maintainer call because it rewrites every commit hash.
- The
.envfile containing your WiGLE API credentials is gitignored β it will never be committed - For GitHub Actions, credentials are stored as repository secrets (encrypted)
- Never commit API keys to the repository
- OUI Research: @NitekryDPaul β all 30 original OUI prefixes and the promiscuous-mode detection strategy
- Field Testing: DeFlockJoplin β 31st OUI prefix (
82:6B:F2) and wildcard probe tightening - Additional OUI prefixes: dougborg/PR#39 β Flock Safety's own IEEE registration (
B4:1E:52) and the six-prefix FS Ext Battery series - Inspired by: DeFlock (ALPR mapping) and track-openroaming-passpoint (WiGLE data mining)
- Data Source: WiGLE β crowdsourced WiFi/cell network database
- Map: Leaflet + OpenStreetMap
- Data Policy, Provenance & Corrections β every record is suspected (OUI match only), coordinates are published at full precision, and here's how to request a correction.
- Data Dictionary β field-level schema for every file under
data/. - Contributing Guide β local setup, lint/test/validate commands, and how to add an OUI prefix.
β οΈ These are suspected Flock devices, not confirmed. An OUI match is a heuristic β OUIs can be shared, reassigned, or spoofed. Coordinates are published at full precision, exactly as WiGLE reports them. See the Data Policy.
This project uses only publicly available data from the WiGLE database, which aggregates voluntarily contributed WiFi survey data. No hacking, unauthorized access, or proprietary systems are involved.
The goal is transparency β communities have a right to know where surveillance infrastructure is deployed in their neighborhoods.
MIT License β see LICENSE for details.