About Fox ESP32 Firmware
Fox ESP32 Firmware is a single Arduino sketch that runs on a cheap ESP32 dev board and talks to your Flipper Zero over a plain wired UART connection (no BLE pairing, no WiFi bridge between the two devices β just four wires). Your Flipper sends it plain-text commands one line at a time; the ESP32 does the actual WiFi/Bluetooth/internet work and reports back. A suite of companion Flipper Zero apps gives you a menu-driven interface to the firmware so you never have to type raw commands by hand β though you always can, via the Terminal.
The eight pieces of the project:
What you can do with it:
- WiFi reconnaissance β scan access points and stations, monitor signal strength, sniff beacons/deauths/probes/raw frames, flag likely PMKID/SAE handshake activity, export a real
.pcapfile straight to Wireshark, or log a GPS-tagged wardrive to CSV. - WiFi attacks (gated) β broadcast or targeted deauth, custom or random beacon spam, probe flood, a joke SSID list, malformed-frame bursts, spoofed channel-switch/power-save frames, and a plain TCP port scanner.
- MAC address tools β randomize, clone a specific address, clone the selected AP's address, or reset to the factory MAC. Software-only, no extra hardware.
- Bluetooth LE tools β a general BLE bridge (built for a Chameleon Ultra but usable for general scan/connect/notify work), a gated multi-vendor pairing-popup spam tool, and non-gated item-tracker detection (Apple Find My, Samsung SmartTag, Tile).
- FoxChat β post messages to a Discord channel and read the most recent ones back, straight from your Flipper's screen, with basic outgoing content filtering.
- FoxPortal β stand up an open WiFi network with a custom enquiry-form landing page, auto-detect whatever fields the form submits, log them to a per-session text file, and hand out a join QR code β fully reconfigurable copy/HTML without a reflash.
- FoxScript β a small embedded scripting language (14 native modules covering WiFi, HTTP, BLE, GPIO, storage, and more) for automating multi-step actions without a computer involved.
- A real FlipperHTTP-compatible internet bridge β GET/POST/PUT/PATCH/DELETE (including binary-safe base64 variants), a WebSocket client, and simple JSON field extraction β usable directly from Terminal, or by other Flipper apps built on the real jblanked/FlipperHTTP client library (verified against its actual source, and against a bundled app's own request/response parsing, not just its documentation). See HTTP & internet bridge for exactly what's covered and the couple of things that deliberately aren't.
- Optional hardware add-ons β RFID (PN532), Sub-GHz (CC1101), IR, and GPS support, each gated behind a build-time flag for boards that have the extra breakout wired up.
Web Installer
The ESP32 side of this project is flashed from your browser β no Arduino IDE, no esptool command line, nothing to install. You only need a USB cable and a Chrome- or Edge-based desktop browser (Web Serial support is required; Safari and Firefox cannot do this).
Hosted alongside the Flipper firmware flasher on the FoxFW GitHub Pages site.
Choosing your board
You don't have to. The Model dropdown starts on Auto-detect on connect: when you click Connect, the flasher asks the chip what it is and loads the matching Fox firmware for you. Leave it on auto unless you have a reason not to.
| Model entry | Chip | Bootloader address |
|---|---|---|
| ESP32-S2 β Flipper Wi-Fi Dev Board (official) | ESP32-S2 | 0x1000 |
| ESP32 (original) β WROOM / WROVER / ESP32-CAM | ESP32 | 0x1000 |
| ESP32-S3 | ESP32-S3 | 0x0 |
| ESP32-C3 | ESP32-C3 | 0x0 |
| ESP32-C5 | ESP32-C5 | 0x2000 |
| ESP32-C6 | ESP32-C6 | 0x0 |
Every board flashes the same four files β Bootloader, Partitions, Boot App0, and Firmware β at the same addresses except for the bootloader itself, whose address differs by chip family. The flasher fills these in for you.
Step by step
- Open the Web Flasher link above in Chrome or Edge on desktop.
- Plug your ESP32 into your computer with a USB data cable. Flipper Wi-Fi Dev Board: hold BOOT, tap RESET, release BOOT.
- Click Connect and pick your device from the browser's own serial port picker.
- The flasher identifies the chip, selects the matching board and downloads the Fox firmware for it. The hint under the Connect button tells you when it's ready.
- Click Program. A progress bar tracks each of the four files as they're written, and each one is read back and verified.
- When it finishes, the board restarts into the new firmware and the flasher disconnects. If the board doesn't come up, press RESET once or unplug and replug it.
To flash your own build instead, switch to the Select Custom Firmware Files tab and choose each of the four files (the ones Arduino IDE's Sketch β Export Compiled Binary produces, see Hardware Setup).
Wrong-board protection
The chip that answers on the port always decides which firmware is used. If you picked a model by hand and it doesn't match the connected chip, the flasher switches to the right one and says so in the console; while a board is connected it won't let you switch to another chip's firmware. Custom files are checked too: an image built for a different chip is refused before anything is written, because it would leave the board unable to start.
Erasing the flash
The Erase button wipes the entire flash chip. You'll get a confirmation prompt first. This is useful if a previous flash left the board in a bad state, or before switching a board between firmware projects.
Statistics
At the bottom of the Web Flasher there is a Statistics bar. Click it to see how many installs have finished, by month, day, country, chip, firmware version, connection type, operating system and browser, and where failed attempts stopped. Use < and > to move between months. The same panel is on the FoxFW Web Installer and the FAP Compiler, where it also lists the most compiled and most recently compiled apps.
The numbers are public and anonymous: each install adds one to a counter. No IP addresses, cookies, device IDs or personal details are stored.
Flashing via Flipper Zero (no PC required)
If you already have FoxFW installed on your Flipper, you can flash the ESP32 directly from the device β no browser, no USB cable to a computer, no files to download. The firmware for every supported board is bundled into FoxFW and deployed to your SD card automatically during the standard qFlipper install.
- Connect your ESP32 to the Flipper Zero GPIO header: TX (GPIO1) β Pin 14, RX (GPIO3) β Pin 13, GND β GND, 3.3V β 3.3V.
- On your Flipper go to Apps β Fox β Fox ESP32 Flasher.
- The app detects your connected ESP32 automatically. If nothing is found, check your wiring and try again.
- Select Flash Firmware, then choose your board type from the list.
- Confirm the firmware files shown and press Flash. The app writes the bootloader, partition table, and firmware in a single pass and shows a progress bar.
- Press Done when complete β the ESP32 resets automatically.
Hardware Setup
Wiring the UART link
The Flipper and the ESP32 talk over a plain 4-wire UART connection β no special adapter needed, just jumper wires from the Flipper's GPIO header to the ESP32's RX/TX/GND/5V (or 3V3) pins. Every Flipper-side app in this project (Detector, FoxHub, Fox Chat, Fox Portal) probes the same two standard pin pairs automatically at boot, so as long as you wire into one of these two pairs, every app will find your ESP32 without any manual configuration:
| Pair | Flipper GPIO pins | Internal name |
|---|---|---|
| Pair 1 | 13 / 14 | USART |
| Pair 2 | 15 / 16 | LPUART |
All communication runs at a fixed 115200 baud.
Board differences
Fox ESP32 Firmware supports the classic ESP32 and its variants, with real differences in what each one can do:
Optional add-on hardware
Four extra hardware peripherals can be wired to the ESP32 for expanded functionality. Each one is a separate breakout board you add yourself β none of them ship as part of the base kit β and each is controlled by its own build-time flag in the firmware, off by default. If you want one of these, you (or whoever builds your firmware image) needs to turn the flag on and recompile; it can't be toggled at runtime like the Attacks setting can.
| Peripheral | Chip / interface | Wiring | What it adds |
|---|---|---|---|
| RFID | PN532 breakout, I2C | IRQ β GPIO 25, Reset β GPIO 26 (SDA/SCL use the ESP32's default I2C pins) | Mifare Classic scan / read / write |
| Sub-GHz | CC1101 breakout, SPI | SCK β 18, MISO β 19, MOSI β 23, CS β 27, GDO0 β 32 | Raw sub-GHz RX/TX (300β928 MHz) β no protocol decoding, raw capture/replay only |
| IR | IR LED + demodulating receiver | Send β GPIO 4, Receive β GPIO 5 | Send/receive/decode across dozens of IR protocols, plus a small TV-power-toggle sweep |
| GPS | Any NMEA 0183 GPS breakout (e.g. NEO-6M/8M) | RX β GPIO 16, TX β GPIO 17, 9600 baud (UART2) | Live fix/position/track data, POI marking, and GPS-tagged WiFi wardriving |
With a peripheral's flag left off, every command for that hardware
replies with a specific error (ERROR:NORFID,
ERROR:NOSUBGHZ, ERROR:NOIR,
ERROR:NOGPS) rather than doing nothing silently, so it's
always clear whether a missing feature is "not wired up" versus "not
working."
Fox ESP32 Detector
A single-purpose diagnostic app: it tells you whether anything is actually talking on your Flipper's GPIO header, and if so, which pins, which baud rate, and β where it can tell β which firmware. There's no menu, no configuration, and nothing is saved. Point it at a freshly wired board when you're not sure the wiring is right, or when Fox ESP32 FoxHub reports "not detected" and you want to know why.
How it works
Press Scan and watch a live progress bar work through every combination of the two Flipper pin pairs and nine common baud rates β 18 combinations total. For each one, it tries up to four detection tiers in order, stopping at the first one that answers:
(NMEA sentences, no command sent)
ATESP-AT firmware check
infoKnown non-AT firmware (Bruce, Fox ESP32 Firmware)
?Generic fallback, requires a repeatable response
Baud rates tested: 9600, 19200, 38400, 57600, 74880, 115200,
230400, 460800, 921600. A full scan of a board with nothing
connected takes roughly 30 seconds, since every combination has to time
out before moving on.
FoxHub
The main control app for the firmware β WiFi, Bluetooth, item-tracker detection, automation scripts, the safety toggle, and a raw Terminal, all in one menu tree. This is the app you'll spend the most time in.
First run & detection
Opening the app always follows the same sequence:
If nothing answers on either pin pair, you'll see a short message β "Fox ESP32 Firmware required on ESP32 connected via GPIO." β with two options: Retry (probes both pin pairs again, useful if you just plugged something in) and Settings (opens Connect Settings, below).
Main menu:
WiFi menu
Connect / Connection
The network list merges a live scan with your saved networks (saved ones shown first), as rounded Fox-styled rows showing SSID, signal strength, security type, and whether it's saved. Selecting a saved network reconnects immediately. Selecting a new one prompts for a password (leave blank for open networks) and saves it for next time. Once connected, the same menu item relabels itself Connection and opens a submenu instead: Disconnect, Status (current SSID + IP), Connect to Network (switch to a different saved/new network), and Forget Network (removes the saved password and disconnects).
My IP & HTTP Request
My IP fetches your ESP32's public internet-facing IP address and prints it to Terminal. HTTP Request gives you a quick GET (just a URL prompt) or POST (URL, then a body prompt) without needing to type bracket-command syntax yourself β the raw response is shown in Terminal either way. This is deliberately just GET/POST with no custom headers or other verbs; Terminal is there for anything more advanced (see the full HTTP command reference).
Recon
Scan APs and Scan Stations populate the network/station lists used elsewhere in this menu. Signal Monitor and Packet Count are quick, bounded checks (10 and 5 seconds respectively) that stream straight to Terminal. Wardrive and Packet Capture are the two data-logging tools:
.pcap file β opens
directly in Wireshark, no conversion needed.
Attacks Gated
Every item in this submenu requires Attacks to be turned on in Settings β with it off, every action here replies with a plain "disabled" message instead of doing anything. All attack primitives run for a fixed 5-second burst and then stop on their own; no separate stop button exists because none is needed.
- Deauth (Broadcast) β deauthenticates every client of the currently selected AP.
- Deauth (Targeted) β deauthenticates one specific station (pick it via Select Station first).
- Beacon Spam (Random) β floods the air with 8 randomly-named fake networks.
- Beacon Spam (Custom) β same idea, but you type a comma-separated list of SSIDs to cycle through.
- Probe Flood β sends a burst of probe requests.
Bluetooth menu
This menu is BLE spam only β five gated items, each cycling a proximity-pairing-shaped advertisement for 8 seconds to trigger the matching OS's pairing popup nearby.
BLEINIT,
BLESCAN, BLECONN, etc.) built into the
firmware for talking to other BLE devices β those commands are reachable
from Terminal but don't have a dedicated menu screen in this app.
Tag Detection menu
Each item runs a bounded 8-second BLE scan for that tracker family's broadcast signature and prints any matches straight to Terminal β mac address, signal strength, and (for Find My only) a decoded battery hint. This is not gated by the Attacks toggle β detecting nearby trackers is passive listening, not an attack.
Scripts menu
Lists every script currently saved on the ESP32, plus a trailing New Script item. Selecting an existing script opens Run / Show / Delete (deliberately not run-on-select, so Delete is never one accidental press away). New Script prompts for a name, then the script's source code, and saves it.
SCRIPTSAVE: command instead β see
FoxScript for the
full language reference.
Settings & Terminal
< > pair appears inside the box
to remind you which direction to press. Changes apply immediately over
serial β there's no separate save step. Attacks adds WiFi/BLE attacks
to the relevant menus when turned on. Expert Mode adds a
Terminal Command item to the main menu for sending a
single raw command without opening the full Terminal. This screen
always queries the firmware's real, persisted value when you open it,
so it never drifts out of sync with what the ESP32 actually has
stored. This is different from Connect Settings (pin/baud override),
which only appears from the not-detected Retry screen.
Fox Chat
Post to and read from a Discord text channel, straight from your Flipper's screen, using your ESP32's internet connection. You'll need an active WiFi connection (set up via FoxHub's WiFi menu) β nothing else to configure.
MyFlipper: hello β so
anyone reading the channel can tell which device posted it. If the
message is blocked by the content filter you'll see "Blocked -
message flagged by content filter"; if you're posting too quickly
you'll see "Too soon - wait a few seconds and try again."
DeviceName: prefix
(i.e. anything posted through Fox Chat, from any Flipper), the device
name renders in bold with the rest of the message
following normally. The ESP32 probes an IP-geolocation service for
your local UTC offset the first time it connects to WiFi, then
converts every message's timestamp to that local time automatically β
no setup needed. The date is only shown alongside the time if the
message wasn't sent today; if the ESP32 hasn't been able to determine
your timezone yet, times fall back to plain UTC (labelled accordingly).
Content moderation β what's protected and what isn't
- Every outgoing message is checked against a built-in word/phrase filter before sending (toggle in FoxHub's Settings β on by default). It's plain word-matching, not spacing- or leetspeak-aware, so it can occasionally false-positive on an innocent word that contains a blocked substring.
- Mentions are always sent inert β
@everyone,@here, and role pings render as plain text and can't actually ping anyone, regardless of what you type. - A short minimum gap is enforced between posts to prevent accidental flooding.
- Discord's own AutoMod does not see bot-posted messages β AutoMod only scans human-account messages, so whatever protections your server has configured there won't apply here. The built-in filter above is the only thing standing between what you type and the channel.
- Anything genuinely abusive or illegal posted through the bot is still a Discord Terms of Service violation on the bot account (and, by extension, whoever's Discord developer account created it).
Fox AI Chat
Chat with Google Gemini directly from your Flipper's screen, using your ESP32's WiFi connection. You'll need an active WiFi connection (set up via FoxHub's WiFi menu) β nothing else to configure, no API key to enter.
chat.ai on the SD card β your messages appear as
<YourFlipperName>: <message>, replies as
FOX-AI: <reply>.
chat.ai and starts a fresh one, stamped with the
date and time it was created. This is the third menu item β since
only two show on screen at once, scroll down to reach it.
Fox Portal
Stands up an open WiFi network with a small enquiry-form landing page β anyone who joins sees your page, fills it in, and gets a confirmation screen, with every submission logged to a text file. Unlike a typical "evil portal," this one is built for consent-based lead capture: the visitor is knowingly opting in and the confirmation page shows them exactly what was recorded, not a credential phishing trap.
portal.txt
on your SD card. You don't need to select this to actually get your
results onto the Flipper β see "Submission logging" below for how that
happens automatically. This screen just displays what's already there
(scroll with Up/Down; if the file has grown large, only the most recent
portion is shown on-screen, with a note at the top β the full history
always remains in the file itself).
Customizing the pages β start.html, finish.html, portal.cfg
These three plain files live on your Flipper's own SD card and are the real source of truth for what visitors see β nothing here is compiled into the ESP32 firmware, so editing them never requires a reflash.
| File | Path | What it controls |
|---|---|---|
start.html | /ext/apps_data/fox_portal/ | The enquiry-form page visitors see first |
finish.html | The confirmation page after submitting | |
portal.cfg | Just one line: the last-used (or default) SSID, pre-filled into the Start prompt next time |
Open and edit these directly β via qFlipper's file browser, the Flipper
Mobile App, or by pulling the SD card into a computer. Add or rename
fields in start.html by editing its
<input name="<fieldname>"> tags directly β
whatever names actually get submitted are auto-detected and logged, so
there's no separate field list to keep in sync. In
finish.html, use {{FIELD:<fieldname>}}
anywhere you want to echo back what the visitor submitted for that field.
name and
phone fields, styled with a dark background and orange accent
β is bundled into the firmware and deployed to
/ext/apps_data/fox_portal/ on your SD card during the
standard qFlipper install. No manual copying required. Edit the files
from there to customise your portal. The first time Fox Portal runs,
portal.cfg is created the same way if it isn't already
there, seeded with the built-in default SSID ("Fox Portal Demo").
Each HTML file has a 1024-byte size limit once flattened to a single line (a transfer-safety limit, not an HTML restriction) β the included starter templates use under 1000 bytes each, leaving room to adjust copy or light styling.
Submission logging
Every submission is appended as its own self-describing line β
SSID=...;fieldname=value;fieldname=value... β to a text
file on the ESP32 named for that portal session's start time, so each
time you run Start gets a fresh file. Whatever fields a visitor's page
actually submits are the fields that get logged for that line; there's
no fixed column list, so different sessions can collect different
fields without anything lining up wrong.
Those session log files only ever live on the ESP32 temporarily.
Loading the Fox Portal app immediately triggers a transfer of anything
waiting there into portal.txt on your Flipper's SD card
(/ext/apps_data/fox_portal/portal.txt), clearing it from
the ESP32 to free that flash up for new submissions. From then on,
while you stay on Fox Portal's menu, it automatically checks again
every 5 seconds and pulls over anything new β you don't
need to back out and re-open the app, or select View Saved Results, for
a submission to make it across; leave the menu open and it shows up
within a few seconds. Nothing queued just means a quiet no-op. Use
View Saved Results to read back what's accumulated in
portal.txt so far.
LOGLINE:<seq>:..., cross-checked against
LOGFILE:/LOGFILEEND:/LOGDONE:
totals). The Flipper stages the data on its SD card and checks every
number lines up before writing it into portal.txt -
and only after that write succeeds does it send
WIFIFOXPORTAL:EXPORTCONFIRM, which is the one and only thing
that tells the ESP32 it can delete its copy. If anything drops or
doesn't add up along the way, nothing is written and nothing is
deleted - the same data just gets resent automatically on the next
sync, whether that's opening the menu or the 5-second auto-check. The
only edge case that can still happen is a
duplicate row already safely on your SD card, if the very last
confirmation step itself doesn't get through - never a row that
disappears without a trace. If that ever happens, Fox Portal's action
log says so explicitly rather than staying quiet about it.
...[TRUNCATED-TOO-LONG] before sending it - the row still
exports and still counts normally, so it never breaks the
verification above. You'd only ever see this with several fields set
to unusually long values; if you spot it in portal.txt,
that submission's later fields were cut off and it's worth trimming
your field lengths going forward.
Fox Update Downloader
Checks GitHub for newer releases of both FoxFW and Fox ESP32 Firmware, downloads whichever one you pick, and hands off straight to install β no PC, no browser, no manual file copying. Because the Flipper itself has no internet connection of its own, this app reaches GitHub over your already-wired ESP32 the same way FoxHub does β it needs the same UART wiring and a WiFi network for the ESP32 to join.
Checking for an update
Pick a row and the app connects to your ESP32, asks it to fetch the latest release from GitHub, and shows a progress screen while it compares versions. You'll land on one of three outcomes:
Selecting your ESP32 board
Choosing Fox ESP32 Firmware adds one extra screen before the check begins: Select Board. Use Left/Right to cycle through the six supported targets β ESP32 Classic, ESP32-S2, ESP32-S3, ESP32-C3, ESP32-C5, ESP32-C6 β then Down and OK on Continue. This tells the app which three files to fetch (bootloader, partition table, and firmware image are downloaded separately for this flow) and which board profile to hand to the flasher afterwards.
Downloading
A progress screen shows the file currently being fetched by name, a
percentage, and a running KB / KB total β for the ESP32
flow this cycles through all three files in turn (bootloader β partition
table β firmware) under one combined progress bar. Press Back at any
point to cancel; anything already written to your SD card is cleaned up
automatically rather than left as a partial, unusable file.
Installing
Once the download finishes you'll see Downloaded with two options: Install hands off immediately, or Later keeps the file on your SD card and returns you to the menu without installing. Choosing Later shows a Not Installed screen with Menu (just go back) and Restart (install the already-downloaded copy right now) β so you never have to download the same release twice just because you weren't ready to install the first time.
.fuf from the Fox File Browser. See the FoxFW guide's Installing Firmware Updates chapter for what happens next (the Fox Setup Wizard runs once on first boot).Fox File Downloader
Downloads files onto your SD card over the ESP32's internet connection β
a direct URL, a browsable App Catalog, or a .fap straight off
a GitHub repo β plus its own WiFi menu for connecting, scanning, and (if
Attacks is on) the same recon/attack tools as FoxHub.
File Download (URL)
Prompts for a single URL β there's no separate filename prompt. The
filename is worked out automatically from the last segment of the URL; if
a file with that name already exists it's saved as name (2).ext,
name (3).ext, and so on rather than overwriting anything.
Files land at /ext/downloads/. The field remembers the last
URL you entered (pre-filled next time), or starts at http://
the very first time.
Opening this menu item doesn't necessarily show that keyboard right away β it checks two things first, in order:
Once a URL is confirmed, the flow is a single continuous connection:
Download.txt queue
A plain text file at /ext/download.txt (SD card root, not in
apps_data) β created automatically the first time you open
the app if it doesn't already exist, with a header comment explaining
itself. One URL per line; blank lines and lines starting with
# are ignored. Opening File Download (URL)
checks this file for the first non-comment line and downloads it
automatically, no keyboard shown β once it starts, that line gets a
# inserted in front of it so it's not picked up again, but
it stays in the file as a record rather than being deleted. Only one URL
is taken per visit, so queue up as many as you like and reopen File
Download (URL) to work through them one at a time.
App Catalog
Browses catalog.flipperzero.one
by category β Bluetooth, Games, GPIO, Infrared, iButton, Media, NFC,
RFID, Sub-GHz, Tools, USB β showing one app at a time with its
description, version, and position in the list. Left/Right moves between
apps (and pages, once you reach either end); OK installs the highlighted
app straight to /ext/apps/<Category>/, matching the
category folder Flipper itself expects.
GitHub Repos
Type a repo as owner/repo (not a full URL) β e.g.
jblanked/FlipDownloader. The app fetches the repo's default
branch and scans its entire file tree for anything ending in
.fap, wherever it lives in the repo (this looks at the raw
tree, not GitHub Releases or a build workflow β the app needs to already
contain a built .fap file checked into the branch). Pick one
from the list and it downloads straight from
raw.githubusercontent.com to
/ext/apps/GitHub/<filename>.
.fap in the repo.
Manage Apps
Lists every .fap under /ext/apps (skipping any
folder literally named assets, so bundled app resources
aren't shown or touched) as a path relative to that folder, e.g.
Tools/myapp.fap. Selecting one shows a confirm screen β
OK deletes it, Back cancels β and the
list refreshes afterward.
Download Settings
The main menu's Settings item goes straight here β this app doesn't have a separate Connect Settings screen reachable from the menu the way FoxHub does. Four rows, Left/Right to cycle, saved automatically on every change:
WiFi, Recon & Attacks
Same shared WiFi module as FoxHub β full network connect/manage plus Recon and (if enabled) Attacks, not a trimmed-down "just connect" menu. The main menu's WiFi item disappears once you're connected, replaced by nothing (there's no menu-level shortcut to the Connection submenu here the way FoxHub has one) β reopen WiFi from Terminal/Settings context if you need to check status without disconnecting.
.pcap format, saved-network handling, and so on).
Attacks is turned on and off from FoxHub's Settings screen β
it's one shared toggle stored on the ESP32 itself, not per-app.
FoxDeFlock
A Flock Safety / ALPR (automatic license plate reader) camera detector, using your ESP32 as the WiFi/BLE radio. Based on FlipDeFlock by ReconGrunt (GPL-3.0-or-later) β this port reuses FlipDeFlock's OUI/SSID confidence-scoring and BLE-advert decoding logic verbatim, rebuilt against Fox ESP32 Firmware's own command set instead of FlipDeFlock's Marauder-based backend.
Setup
Requires Fox ESP32 Firmware wired via UART at 115200 baud (standard Fox pinout). On launch the app checks for an ESP32; if it isn't found, you get an ESP32 not found screen with Settings (pick which UART pin pair to use β 13/14 or 15/16) and Retry buttons. Nothing destructive happens if no ESP32 is present β the app just never sees any hits.
Scanning
Once connected, FoxDeFlock rotates through three scan modes every ~8.5 seconds, shown in the top-right corner of the hit list:
| Mode | What it scans |
|---|---|
| WiFi:Probe | WiFi probe requests |
| WiFi:Beacon | WiFi beacon frames |
| BLE:Flock | Flock external-battery BLE adverts (BLETAGSCAN:FLOCK) |
Each hit is shown as a single row: source (WiFi/BLE), the last two MAC
bytes, an SSID or BLE name if one was broadcast, and a confidence code
(CONF/FP?/LIKE/POSS).
Up and Down move the selection; OK on a hit opens its
detail screen (full MAC, confidence, device class, source, SSID/BLE
name, channel/RSSI for WiFi or RSSI for BLE, and a sightings count);
hold OK from the hit list opens an About screen with
attribution. Back returns to the previous screen from either.
BLETAGSCAN:FLOCK doesn't yet
surface BLE service UUIDs, so BLE hits report as a generic Flock battery
unit rather than either model by name); no GPS/mapping, no "guardian"
continuous-monitoring mode, no deflock.me QR handoff, no
signature-database sync, and no Marauder-flashing UI β FoxDeFlock only
ever talks to Fox ESP32 Firmware.
Status Bar WiFi / CC1101 Icon
Your Flipper's own desktop status bar shows a small icon, immediately to the left of the battery indicator, that does double duty: it reflects your ESP32's WiFi connection state as last reported by Fox ESP32 FoxHub's WiFi menu, and β only when WiFi isn't connected β whether Sub-GHz Garage/Gate/Other has found an external CC1101 module attached. See the FoxFW2.0 guide for what the CC1101 module itself does.
| State | Appearance |
|---|---|
| WiFi connected | Three bold, solid ascending bars β always shown first, regardless of the CC1101 module |
| WiFi not connected, CC1101 module connected | A small antenna glyph |
| Neither connected | The same three bars, drawn as thin lines instead of solid β still visible, not an error indicator |
The icon stays visible even when disconnected on purpose β if it vanished entirely, someone who hasn't discovered the Fox ESP32 apps yet would have no hint that this feature exists at all. You can hide it entirely from Settings β Desktop β WiFi/CC1101 Icon β that one toggle hides both halves together, not just WiFi.
Full Command Reference
Every command the firmware understands, sent over serial at 115200 baud. You'll rarely need to type these by hand β FoxHub, Fox Chat, and Fox Portal send them for you β but they're all reachable from FoxHub's Terminal screen if you want raw access, and knowing them helps make sense of what each menu action is actually doing.
AT replies OK.
info replies Fox ESP32 Firmware β this exact
string is what Fox ESP32 Detector and every app's detection screen look
for to confirm they're talking to this firmware and not something else.
WiFi reconnaissance
| Command | What it does |
|---|---|
WIFISCANAP | Scans for nearby access points, prints AP: lines, ends with SCANDONE |
WIFISCANSTA | 8-second promiscuous sniff for stations (devices), prints STA: lines, ends with SCANDONE |
WIFISCANALL | Runs both scans in sequence |
WIFILIST:AP / WIFILIST:STA | Reprints the last cached scan without rescanning |
WIFISELECT:AP:<index> | Selects an AP as the target for AP-info, signal monitor, and attacks |
WIFISELECT:STA:<index> | Selects a station as the target for targeted deauth |
WIFIAPINFO:<index> | Detailed info on one scanned AP |
WIFICHANNEL / WIFICHANNEL:<1-14> | Reads or sets the current WiFi channel |
WIFISIGMON | 10 seconds of live RSSI readings for the selected AP |
WIFIPACKETCOUNT | 5-second promiscuous packet count, replies COUNT:<n> |
Sniff modes β WIFISNIFF:<mode> (all 8 seconds)
| Mode | Prints |
|---|---|
BEACON | BEACON:<bssid> rssi:<n> per beacon frame seen |
DEAUTH | DEAUTH:/DISASSOC:<src>-><dst> β spot deauth/disassoc activity nearby |
PROBE | PROBEREQ:/PROBERESP:<src> |
RAW | RAW:len:<n> rssi:<n> per frame β general traffic volume |
MULTISSID | Flags likely beacon-flood activity nearby |
PMKID | Flags EAPOL frames seen β best-effort frame-shape match, not a parsed PMKID |
SAE | Flags WPA3 SAE Commit authentication frames β best-effort, not a full SAE state machine |
MAC address tools
WIFIMAC:GET | Shows the current station MAC |
WIFIMAC:RAND | Randomizes the station MAC (software only) |
WIFIMAC:CLONE:<mac> | Sets the station MAC to a specific address |
WIFIMAC:CLONEAP | Sets the station MAC to the selected AP's BSSID |
WIFIMAC:RESET | Restores the original factory MAC |
Wardriving & packet capture
WIFIWARDRIVE | AP scan tagged with your current GPS fix (needs the optional GPS module). FoxHub logs results to /ext/apps_data/fox_esp32/wardrive/wardrive_<YYYY-MM-DD>.csv β columns bssid,ssid,latitude,longitude,rssi,channel,encryption_type,timestamp. |
WIFIPCAP | 15-second raw capture, hopping channels 1β11 every 400ms. FoxHub saves a standard .pcap to /ext/apps_data/fox_esp32/captures/capture_<timestamp>.pcap β opens directly in Wireshark. Frames truncated to 256 bytes, capped at 150 frames per capture. |
WiFi attacks gated
All attack commands below are blocked with ERROR:DISABLED unless SETTINGS:ATTACKS:ON is active. Every attack self-limits to a 5-second burst and ends on its own with ATTACKDONE β there's no separate stop command needed.
| Command | What it does |
|---|---|
WIFIATTACK:DEAUTH | Broadcast deauth against the selected AP |
WIFIATTACK:DEAUTH:<sta-mac> | Targeted deauth against one station |
WIFIATTACK:BEACON:<ssid1,ssid2,...> | Beacon spam cycling your own SSID list |
WIFIATTACK:BEACON:RANDOM:<n> | Beacon spam with n randomly generated SSIDs |
WIFIATTACK:PROBE | Probe request flood |
WIFIATTACK:RICKROLL | Beacon spam using a preset joke SSID list |
WIFIATTACK:BADPACKET | Malformed/fuzzed beacon-shaped frame burst |
WIFIATTACK:CSA | Spoofed Channel Switch Announcement against the selected AP |
WIFIATTACK:SLEEP | Spoofed power-save frame against the selected AP + station |
WIFIPORTSCAN:<ip>:<start>:<end> | Plain TCP connect-scan (also gated), prints PORTOPEN:<port> per open port, ends with PORTSCANDONE. Capped at 100 ports per run. |
WIFISELECT:AP first. SLEEP additionally needs WIFISELECT:STA (run a station scan first).
Bluetooth & Tag Detection
Not available on ESP32-S2 boards (no BLE radio) β every command below replies ERROR:Incompatible ESP32-S2 Module has no BLE on that chip.
BLE bridge (general BLE / Chameleon Ultra)
BLEINIT | Starts the BLE stack |
BLESCAN | General BLE scan (unfiltered) |
BLECONN:<mac> | Connects to a device |
BLESTATUS | Current connection status |
BLEDISC | Disconnects |
BLESVC:<uuid> | Selects a GATT service |
BLECHAR:<write-uuid>,<notify-uuid> | Selects the write/notify characteristics to use |
BLEWRITE:<hex> | Writes raw bytes to the selected write characteristic |
Incoming notifications arrive asynchronously as NOTIFY:<hex>.
BLE spam gated
BLESPAM:IOS | Apple proximity-pairing-shaped advertising spam |
BLESPAM:WINDOWS | Windows Swift Pair-shaped spam |
BLESPAM:SAMSUNG | Samsung Easy Setup-shaped spam |
BLESPAM:ANDROID | Fast Pair-shaped spam (alias: BLESPAM:GOOGLE) |
BLESPAM:ALL | Rotates through all four |
Each runs an 8-second advertising burst, then ATTACKDONE.
Tag Detection β snapshot scans, not a stalking detector
BLETAGSCAN:FINDMY | 8s scan for Apple Find My broadcasts (AirTag and any other Find My accessory β the protocol can't tell them apart) β TAG:FINDMY:<mac> rssi:<n> batt:<full|medium|low|verylow|unknown> |
BLETAGSCAN:SMARTTAG | 8s scan for Samsung SmartTag broadcasts β TAG:SMARTTAG:<mac> rssi:<n> |
BLETAGSCAN:TILE | 8s scan for Tile broadcasts β TAG:TILE:<mac> rssi:<n> |
BLETAGSCAN:FLOCK | 8s scan for Flock Safety external-battery BLE adverts (used by FoxDeFlock) β TAG:FLOCK:<mac> rssi:<n> name:"<name>" mfg:<hex> |
Each ends with TAGSCANDONE:<count>. A match means a tag is broadcasting nearby right now β it is not a history of whether something has been following you.
HTTP & internet bridge
Bracket-style commands. The GET/POST/PUT/PATCH/DELETE, WiFi, PING,
LIST, IP/ADDRESS, and PARSE commands below reproduce the real
jblanked/FlipperHTTP
wire protocol on purpose β verified against that project's own
firmware source and against a bundled app's actual request/response
parsing code, not just its documentation β so any Flipper app built
on the standard flipper_http.c client should work
against this board without modification. [GET]/
[GET/HTTP]/[POST/HTTP]/[PUT/HTTP]/
[DELETE/HTTP] all reply with the same shape a real
FlipperHTTP board uses:
[GET/SUCCESS]{"Status-Code":200,"Content-Length":128}
<response body, raw - may span more than one physical line>
[GET/END]
β a status/length header line, the body (sent as-is; any real
newlines it contains become extra physical lines, exactly like the
official firmware), a blank line, then a method-specific terminator:
[GET/END], [POST/END],
[PUT/END], or [DELETE/END]. Keep reading
until that line shows up rather than stopping after the first one.
Note that [GET/HTTP] replies with [GET/SUCCESS]
too (not [GET/HTTP/SUCCESS]) β the real protocol tags by
HTTP method, not by which bracket command triggered the request, so
a client can't tell the two apart and neither can this firmware.
[PATCH/HTTP] is a Fox-only extension (real FlipperHTTP
doesn't define PATCH) and uses its own [PATCH/SUCCESS] /
[PATCH/END] pair.
| Command | What it does |
|---|---|
[PING] | Replies [PONG] |
[LIST] | Lists every bracket command the firmware supports, both Fox's own multi-line listing and the exact single-line reply real FlipperHTTP clients send |
[REBOOT] | Restarts the board |
[VERSION] | Firmware version string |
[WIFI/SCAN] | Replies [GET/SUCCESS] / {"networks":["ssid1",...],"details":[{"ssid","rssi","secure"},...]} / [GET/END] β networks is the exact key real clients (e.g. FlipWiFi's own scan parser) read; details is a Fox-only extra with the richer per-network data |
[WIFI/SAVE]{"ssid":"x","password":"y"} | Saves credentials (password optional, for open networks); replies with both Fox's own [WIFI/SAVE/SUCCESS] and the real-spec [SUCCESS] Wifi settings saved. line real clients check for |
[WIFI/CONNECT] | Tries saved networks in order |
[WIFI/CONNECT]{"ssid":"x"} | Connects using a saved network's saved password |
[WIFI/CONNECT]{"ssid":"x","password":"y"} | Connects directly, no prior save needed; success replies with both [WIFI/CONNECT/SUCCESS]<ssid> and [SUCCESS] Connected to Wifi. |
[WIFI/DISCONNECT] | Disconnects; replies [DISCONNECTED] WiFi has been disconnected. (the exact real-spec line) |
[WIFI/LIST] | Lists saved SSIDs only, never passwords β a deliberate deviation from real FlipperHTTP, which dumps the whole saved-credentials file (including cleartext passwords) unframed; leaking saved WiFi passwords over an exposed serial line wasn't a tradeoff worth making just for byte-parity on a feature most apps don't use |
[WIFI/IP] | Your public IP β does a GET to https://httpbin.org/get and replies with the parsed "origin" field, framed like a GET ([GET/SUCCESS] / origin / [GET/END]); matches the real protocol's exact endpoint and field name |
[WIFI/SSID] | SSID of the currently connected network |
[WIFI/STATUS] | true/false β connected or not |
[IP/ADDRESS] | Local IP address, bare (no tag) β matches real FlipperHTTP exactly |
[WIFI/AP]{"ssid":"x","password":"y"} | Starts a WiFi access point (password 8+ characters, or omit for open), replies immediately with the AP's IP β not real FlipperHTTP's blocking [AP/CONNECTED]/bridge-until-[AP/DISCONNECTED] loop (some apps, e.g. FlipWiFi's AP feature, expect that specific blocking flow and won't work here β Fox Portal's own captive-portal AP mode covers the same ground better anyway) |
[GET]<url> | Simple GET, returns the response body |
[GET/HTTP]{"url":"...","headers":{...}} | GET with custom headers |
[POST/HTTP] / [PUT/HTTP] / [PATCH/HTTP] / [DELETE/HTTP] | {"url":"...","payload":"...","headers":{...}} |
[GET/BYTES]<url> | Base64-encoded response body β binary-safe, but a Fox-only encoding; real FlipperHTTP streams raw bytes over the wire instead, so this one isn't compatible with third-party clients yet |
[POST/BYTES]{"url":"...","payload_b64":"..."} | Base64-encoded request/response β same caveat as [GET/BYTES] |
[SOCKET/START]{"url":"wss://host:port/path"} | Opens a WebSocket connection |
[SOCKET/SEND]<text> | Sends a text frame on the open socket |
[SOCKET/STOP] | Closes the socket; replies with both Fox's own [SOCKET/STOP/SUCCESS] and the real-spec [SOCKET/STOPPED] |
[PARSE]{"json":"...","key":"..."} | Extracts one flat field from a JSON object, replies with just the bare value (no tag) β matches real FlipperHTTP's [PARSE] exactly |
[PARSE/ARRAY]{"json":"[...]","index":N} | Extracts the Nth element of a JSON array, same bare-value reply |
[LED/ON] / [LED/OFF] | Controls the status LED |
Async WebSocket traffic arrives as [SOCKET/CONNECTED], [SOCKET/DISCONNECTED], [SOCKET/MSG]<text> (or [SOCKET/MSG/BIN]<base64>), and [SOCKET/ERROR]. Everything not covered above still follows Fox's own long-standing shape, [COMMAND/SUCCESS]<data> or [ERROR] <message>.
setInsecure() β no root CA store). Fine for casual API calls; don't route sensitive credentials through it.
[WIFI/LIST] doesn't leak saved passwords (see above), [WIFI/AP] doesn't implement the blocking AP-bridge loop some apps expect, and [GET/BYTES]/[POST/BYTES] are still base64 rather than raw-byte streaming. Deauth-style commands some third-party apps ship their own buttons for (e.g. FlipWiFi's [DEAUTH]) aren't part of the real FlipperHTTP protocol either β use FoxHub's own WiFi Attacks menu for that instead.
FoxScript
SCRIPTLIST | Lists saved scripts |
SCRIPTSAVE:<name>:<source> | Saves a script (must be a single line β see below) |
SCRIPTSHOW:<name> | Prints a saved script's source |
SCRIPTDEL:<name> | Deletes a saved script |
SCRIPTRUN:<name> | Runs a saved script |
FoxScript is a small purpose-built scripting language (not JavaScript,
though the syntax looks familiar) β variables, if/else,
repeat(n) loops, numbers, strings, arithmetic/comparison/logical
operators, and function calls including dotted native calls. No
user-defined functions, arrays, objects, or while/for.
Scripts run straight off the ESP32's own storage β no SD card, no reflash.
let name = "world";
print("hello " + name);
if (wifi.connect("MySSID", "MyPassword")) {
let body = http.get("http://api.ipify.org");
print("my IP is " + body);
} else {
print("wifi connect failed");
}
repeat (3) {
print("free heap: " + device.freeHeap());
delay(1000);
}
repeat is capped at 1000 iterations, and a whole script run is capped at 200,000 evaluation steps as a safety net against a mistyped infinite loop.
Native functions
| Namespace | Functions |
|---|---|
| (global) | print(...), delay(ms) |
wifi | connect(ssid, password), disconnect(), ip(), ssid(), status(), scan() |
http | get(url), post(url, body) |
ble | write(hex), connected(), scan(), spam(mode) gated |
wifiattack | deauth(), beacon(ssid), portscan(ip, startPort, endPort) gated |
gpio | mode(pin, mode), write(pin, value), read(pin) β any GPIO 0β39 |
led | on(), off() |
storage | set(key, value), get(key) β small on-device key/value store |
device | name(), freeHeap(), uptime(), reboot() |
settings | attacksEnabled() |
rfid / subghz / ir / gps | Placeholders today β return a "NOTIMPLEMENTED"/"NORFID"-style string rather than touching real hardware. Use the native commands below directly for real RFID/Sub-GHz/IR/GPS access. |
; to separate statements and write loop bodies without literal line breaks, exactly like the example above.
Fox Chat (Discord bridge)
DISCORDPOST:<message> | Posts a message to the shared FoxFW Discord channel |
DISCORDREAD | Reads the 5 most recent messages |
DISCORDREAD:<count> | Reads up to <count> messages (max 10) |
Reads reply with one DISCORDMSG:<HH:MM>|<full date and time>|<content> line per message (oldest first), ending with DISCORDREADDONE.
Fox AI Chat (Gemini relay)
| Command | What it does |
|---|---|
AIASK:<message> | Sends your message to the Gemini relay and waits for a reply β AIREPLY:<text> (newlines escaped as \n), or one of the errors below |
AICOOLDOWN | Reports remaining cooldown seconds without making any network call β COOLDOWN:<n> (0 if clear to send) |
AIASK errors: ERROR:NOWIFI, ERROR:EMPTY,
ERROR:RATELIMIT:<seconds> (still cooling down β the ESP32
enforces this itself before ever reaching the relay), ERROR:BLOCKED
(Gemini's own safety filter), ERROR:NOREPLY, or
ERROR:HTTP:<code>.
Fox Portal
WIFIFOXPORTAL:START:<ssid>:<date> | Starts the portal (both arguments can be left blank) |
WIFIFOXPORTAL:STOP | Stops the access point, DNS redirect, and web server |
WIFIFOXPORTAL:EXPORTLOG | Streams every queued submission back as sequence-numbered LOGFILE:<name>:<count> / LOGLINE:<seq>:<content> / LOGFILEEND:<name>:<count> lines ending in LOGDONE:<files>:<lines> (or just LOGEMPTY if nothing's queued). Deletes nothing by itself. Fox Portal's own menu calls this for you - see "Submission logging" in Chapter 7. |
WIFIFOXPORTAL:EXPORTCONFIRM | Deletes exactly the files most recently sent by EXPORTLOG, replies OK. The Flipper app only sends this after verifying every count/sequence number above and safely writing the data to its own SD card - see the verification note in Chapter 8. |
WIFIFOXPORTAL:SETTITLE:<text> | Sets the page heading (built-in default page only) |
WIFIFOXPORTAL:SETINTRO:<text> | Sets the intro paragraph (built-in default page only) |
WIFIFOXPORTAL:SETNOTE:<text> | Sets the closing note on the confirmation page (built-in default only) |
WIFIFOXPORTAL:SETPAGE:START:<html> | Full override of the enquiry-form page |
WIFIFOXPORTAL:SETPAGE:THANKS:<html> | Full override of the confirmation page (supports {{FIELD:<name>}} placeholders) |
WIFIFOXPORTAL:QR | Returns WiFi-join text for the currently active SSID |
These commands are gated behind SETTINGS:ATTACKS:ON. See Chapter 8 for the full behavior of each β the Fox Portal app is the intended way to drive all of this.
Optional hardware β RFID, Sub-GHz, IR, GPS
These only work if the corresponding hardware flag was enabled at
compile time (FOX_HAS_RFID/FOX_HAS_SUBGHZ/FOX_HAS_IR/FOX_HAS_GPS,
all off by default). With a flag off, its whole command family replies
a fixed error instead β ERROR:NORFID, ERROR:NOSUBGHZ,
ERROR:NOIR, or ERROR:NOGPS.
RFID (PN532 breakout, I2C)
RFIDINIT | Starts the PN532 β ERROR:NOTFOUND if it can't be reached |
RFIDSCAN | Waits up to 2s for a tag β UID:<hex>, or ERROR:NOTAG |
RFIDREAD:<block> | Authenticates (factory default key) and reads a 16-byte Mifare block β BLOCK:<n>:<hex> |
RFIDWRITE:<block>:<hex> | Authenticates and writes a 16-byte Mifare block β OK |
RFIDEMULATE:<uid> | Not yet implemented β ERROR:NOTIMPLEMENTED |
Sub-GHz (CC1101 breakout, SPI)
SUBGHZINIT | Starts the CC1101 β ERROR:NOTFOUND if it can't be reached |
SUBGHZFREQ:<mhz> | Sets frequency, 300β928 MHz β OK |
SUBGHZRX | Waits up to 10s for a raw packet β SUBGHZRX:<hex>, or ERROR:NOSIGNAL |
SUBGHZTX:<hex> | Sends raw bytes β OK |
Raw RX/TX only β no rolling-code or OOK protocol decoding.
Infrared
IRSEND:<protocol>:<hex>[:<bits>] | Sends a code β protocol name e.g. NEC/SONY/RC5, bits defaults to 32 β OK |
IRRECV | Waits up to 10s for a code β IRRECV:<protocol>:0x<hex>:<bits>, or ERROR:NOSIGNAL |
IRTVBGONE | Sends a small starter set of common TV power-toggle codes β TVBGONEDONE |
GPS (UART, NMEA 0183)
GPSINIT | Starts the GPS UART β OK |
GPS:FIX | FIX:1 or FIX:0 |
GPS:SAT | SAT:<count> |
GPS:LAT / GPS:LON / GPS:ALT | Current position β ERROR:NOFIX if no fix yet |
GPS:DATE | DATE:<ddmmyy> TIME:<hhmmss> |
GPSTRACK | Streams FIX:<lat>,<lon> for 30s as position changes, ends with TRACKDONE |
GPSPOI:START | Clears the point-of-interest list and starts marking |
GPSPOI:MARK[:<label>] | Marks the current fix as a POI β POI:<index> <label> <lat>,<lon> |
GPSPOI:END | Stops marking β POICOUNT:<n> |
Safety, Legal & the Attacks Toggle
The Attacks toggle
All WiFi attacks, BLE spam, the TCP port scanner, and Fox Portal are
gated behind one setting, checked with SETTINGS and changed
with SETTINGS:ATTACKS:ON / SETTINGS:ATTACKS:OFF
β reachable from FoxHub's Settings screen
as a single "Attacks: ON/OFF" row that applies immediately.
While attacks are off, every gated command replies plainly with
ERROR:DISABLED β nothing is hidden or silently ignored.
Built-in self-limits
Every attack primitive (deauth, beacon spam, probe flood, BLE spam, the
novelty attacks, the port scanner) runs for a fixed, short burst β 5
seconds for WiFi/port-scan attacks, 8 seconds for BLE spam β and then
stops on its own, replying ATTACKDONE. There's no
"run forever" mode and no separate stop command to remember; re-run the
command if you want another burst.
Content moderation in Fox Chat
Outgoing Discord messages are checked against a built-in word filter
before sending (toggle: SETTINGS:PROFANITY:ON/OFF,
on by default), and every post is sent with mentions disabled so
@everyone/@here/role pings can never actually
ping anyone. See Chapter 6 for the full detail, including what this
protection does not cover (Discord's own AutoMod doesn't scan
bot-posted messages).
Fox Portal is consent-based
Fox Portal is a lead-capture tool, not a credential-phishing "evil portal" β visitors knowingly join an open network and see exactly what they're submitting, with a confirmation page that echoes it back. Don't use it to impersonate another organization's network or to collect information from people who haven't knowingly agreed to give it.
Known Limitations
An honest list of rough edges, so nothing here catches you by surprise. None of these are dealbreakers for normal use β most are "this hasn't been battle-tested against every possible target/accessory yet," not "this is broken."
Firmware
- HTTPS requests don't validate the server's certificate β fine for casual API calls, not for anything sensitive.
- The JSON field extractor only understands flat objects plus one level of nested
headersβ not deeply nested or general array-valued JSON (beyond the dedicated[PARSE/ARRAY]command). - FoxScript is a small custom language, not real JavaScript β no user-defined functions, arrays, objects, or
while/forloops. WIFISNIFF:PMKID/SAEflag frame shapes (an EAPOL frame was seen; a SAE Commit frame was seen) rather than performing full protocol extraction.RFIDEMULATEis not implemented β everything else in the RFID/Sub-GHz/IR/GPS command families is real, working driver code.- The BLE spam payloads match each vendor's proximity-pairing packet framing (AD structure, company ID, UUID) correctly, but the exact inner payload bytes beyond that framing are a best-effort approximation.
FoxHub
- The AP/station scan-result list re-scans every time you open it β there's no caching between visits.
- SSIDs, passwords, URLs, and script text sent to the firmware aren't JSON-escaped β a literal quote or backslash in one of these can break the request.
- Custom-SSID beacon spam and targeted deauth only check that the field isn't empty, not that it's well-formed.
- The Connect Settings baud-rate row only offers 115200 today (built to support more rates later).
Fox ESP32 Detector
- Scans the two standard pin pairs (13/14, 15/16) across 9 baud rates each β a full scan with nothing connected takes about 30 seconds.
- Only recognizes a small, growing list of non-AT firmware signatures by name (currently this firmware and Bruce) β anything else that responds is reported generically as "Unidentified" rather than misidentified.
- Doesn't detect raw unflashed ESP32 chips, I2C/SPI sensor modules, or Flipper's own built-in IR β by design, out of scope for this tool.
Tag Detection
- A snapshot tool, not a stalking/tracking detector β a positive result means a tag is broadcasting nearby right now, not that anything has been following you over time.
- Find My detection catches any Find My-network accessory (AirTag, Chipolo, Pebblebee, etc.), not AirTags specifically β the broadcast protocol itself doesn't distinguish between them.
General
- ESP32-S2 boards have no Bluetooth radio at all β Bluetooth menu, Tag Detection, and every BLE command are unavailable on that chip.
- The status bar WiFi icon reflects only the last action taken through FoxHub's WiFi menu β it does not live-poll the ESP32 and doesn't reflect WiFi state from Fox Chat or Fox Portal, since those apps never change the connection themselves.
Support & Troubleshooting
.fap against FoxFW v2.0 straight from a GitHub URL β
no toolchain install required.
Nothing responds / apps say "not detected"
- Run Fox ESP32 Detector first β it's built exactly for this. It'll tell you which pin pair and baud rate (if any) something is answering on.
- Double-check wiring against Chapter 3 β pins 13/14 (USART) or 15/16 (LPUART), plus a shared ground.
- Confirm the ESP32 is actually powered β a USB cable that only carries data and not power, or a loose connection, is a common culprit.
- Make sure the firmware was actually flashed successfully β re-run the Web Installer's Erase, then Program again.
- If one app detects it but another doesn't, try Connect Settings (reachable from that app's Retry screen) to manually pick the pin pair Detector identified.
qFlipper "Unknown Error" during firmware install
If qFlipper stops at around 23% with "Verifying existing filesβ¦"
and then shows Unknown Error / "Operation timeout
(generic)" on Storage Md5Sum resources.ths, the most
common cause is a stale Update folder left on the SD card
from a previous install attempt. The checksum qFlipper computed no longer
matches what is on the card.
Fix: delete the /Update folder from the
root of your SD card (accessible via qFlipper's file browser or the
Flipper Mobile App), then try installing again. If you cannot easily
locate the folder, formatting the SD card achieves the same result β
your FoxFW apps and settings will be re-deployed on the next successful
install.
Web Installer issues
| Symptom | Likely cause / fix |
|---|---|
| Connect button does nothing | Web Serial requires Chrome or Edge on desktop β Firefox and Safari don't support it, and it's not available on mobile. |
| Board isn't in the port list, or "Failed to set control signals" | Boards without a USB-to-serial chip (the Flipper Wi-Fi Dev Board and other ESP32-S2 boards) must be in bootloader mode: hold BOOT, tap RESET, release BOOT, then click Connect and pick the port. Also check the cable is a data cable. |
| "The board didn't answer" | Hold the board's BOOT button while you click Connect, and let go once it says Connected. |
| "That port is being used by something else" | Close the Arduino IDE, serial monitors, qFlipper and any other flasher tab, then Connect again. |
| "Fox ESP32 firmware isn't available for β¦" | The connected chip isn't one Fox ESP32 firmware is built for (ESP32, S2, S3, C3, C5, C6). |
| Flashing fails partway through | Keep the browser tab in focus the entire time β backgrounding it can interrupt the serial transfer. Try a lower baud rate if it keeps failing. |
| Device unresponsive after flashing | Press RESET on the board once, or unplug and replug it β a board flashed from bootloader mode sometimes stays there until it is reset. Then verify with AT/info from FoxHub or Detector. |
Attacks say "ERROR:DISABLED"
This is the Attacks safety toggle, not a fault β turn it on from FoxHub's Settings screen (see Chapter 13).
Fox Chat issues
| Symptom | Likely cause / fix |
|---|---|
| "Blocked - message flagged by content filter" | Your message matched a word in the built-in filter. Reword it, or turn the filter off via SETTINGS:PROFANITY:OFF if that's intentional. |
| "Too soon - wait a few seconds and try again." | The flood guard β wait a few seconds between posts. |
| Messages post/read fine before you've set up your own bot | Expected β Fox Chat falls back to a pre-configured demo bot/channel until you run Bot Settings. See Chapter 6. |
| Your own bot doesn't work after Bot Settings | Re-check Message Content Intent is enabled and the bot was actually invited with Send Messages + Read Message History permissions. |
Fox Portal issues
| Symptom | Likely cause / fix |
|---|---|
| Page looks like a plain generic form, not your custom design | start.html/finish.html were empty or missing when Start ran β the ESP32 fell back to its built-in default page. The files are auto-installed to /ext/apps_data/fox_portal/ on a standard qFlipper install; if they're missing, re-install the firmware. |
| Edits to start.html don't show up | Every Start re-reads all three files fresh, so this shouldn't happen β double check you saved to /ext/apps_data/fox_portal/ specifically and re-ran Start (not just Show QR). |
General questions
This guide aims to cover everything end to end β install, hardware, every app and menu, and the full command set. If something's still unclear after reading the relevant chapter, that's useful feedback: check the project's GitHub Pages site (the same place hosting the Web Installer) for the latest release notes and any additional notes posted there.