Releases: lukeswitz/AntiHunter
v0.9.3
DIGINODE FW v0.9.3
What's New
-
WebUI Rebuilt: Tabs for fast navigation, toolkit organized, results revamped
-
Ghost Trace Device Randomization Sniffer
- Display device SSID/names/CIDs
- Detects leaked MAC of anchor device with new packet inspections
- Scan for targets using the Track ID (ex:
T-004D) to include all linked MACs - Added channel sorting
- Marks leaked MAC (anchor) with SSIDs and BLE names/CIDs
- Fixes results not including names until completion
- Better icons for results header
-
Baseline Anomaly Scanner
- Phase-1 block now shows devices seen, elapsed time, animated progress bar, and completion percentage instead of a static spinner
- Make list sortable during all phases
- Fixed: history.wasPresent = true now set before return in the new-device anomaly block — device will never fire twice
- Fix devices not appearing with phases card
- Sightings guard added — device must be seen 2+ times within a 60s window before "new device" anomaly fires; single probe frames from passing devices are ignored
- Fixed loop (full only): antihunter::lastResults written every 2s in both phase 1 and phase 2 loops via getBaselineResults() — results now appear in the #r div automatically via tick()
- appendCacheDeviceLines() helper eliminates the duplicate 14-line loop; both phases
- reserve() before all loops — eliminates repeated heap realloc on ESP32
- getBaselineResults() only rebuilt when cache or anomalies actually changed
- nextResultsUpdate += 2000 — no more timer drift under load
- sightings initialized to 0 — sightings guard now actually requires 2 separate checkForAnomalies calls before firing (was firing on first call due to init=1 then immediate increment to 2)
Other Fixes
- Fix garbage RSSI values, unsigned promotion bug
- Update diagnostics and device/frame counts correctly in System tab
- Radio-busy guard for all scan endpoints 89757e
- False positives from NimBLE bug: NimBLE periodically returns -8 dBm which was swinging the baseline results
- dB threshold: Explicit Min:[-\d]+dBm\s+Max:[-\d]+dBm regex — no more silent garbage tolerance between fields
- Results in full FW not appearing/updating within 3s
- Device names and SSIDs not appearing until end of scan in full FW
- Remove redundant WiFi radio reset in full FW scans (fixes a few dropouts)
- Heartbeat message configuration persistence & state logic
Low Level Hunt:
High Severity Issues Addressed:
- cleanupBaselineMemory now removes from lruMap/lruList before erasing from baselineCache
- loadBaselineFromSD now populates lruList/lruMap on each device loaded
- Shadowed BLE_SCAN_INTERVAL/WIFI_SCAN_INTERVAL locals removed from snifferScanTask
- baselineEstablished = false gated on baselineDeviceCount == 0
- getDiagnostics reads uniqueMacs and detectedDrones under portMUX
- static removed from lastTimeSyncBroadcast and lastBLEScan in listScanTask
- currentScanMode only assigned inside if (!workerTaskHandle) blocks
- triangulateAcks reads now under triangulationMutex
- lastUIUpdate de-staticized in coordinatorSetupTask
- Double-correction block removed from propagation delay calculation
Medium:
- hitCount promoted to uint32_t, overflow-guarded
- parseFrenchDrone TLV bounds checked against actual buffer length
- detectDeauthFrame now queues via xQueueSendFromISR; attack classification + side effects moved to blueTeamTask
- processDronePacket no longer called from ISR; droneFrameQueue consumed in droneDetectorTask
- correlateAuthFrameToRandomizedSession no longer acquires std::mutex from ISR; authFrameQueue consumed in randomizationDetectionTask
- pBLEScan = nullptr before BLEDevice::deinit in snifferScanTask
Full Changelog: v0.9.2...v0.9.3
v0.9.2
DIGINODE FW v0.9.2
What's New
- Heartbeat Configuration: Status messages can be toggled and duration set with new
HB_ON/OFFandHB_INTERVALcommands/endpoints
Fixes
- Correct
uartForwardTaskmutex andsniffer_cblength guard-
uartForwardTaskcould give a mutex it didn't hold if the re-acquire timed out. Replaced with read-all-under-mutex into a chunk buffer. -
sniffer_cb lengthguard moved before first payload access; was firing after detectDeauthFrame already ran on truncated frames. -
Applies to full and headless variants
-
Dependencies
-
AsyncTCP3.3.6 → 3.4.10: stability and memory leak fixes -
NimBLE-Arduino2.3.7 → 2.3.9- 2.3.8: Fixes crash on init with Arduino core 3.3.
- 2.3.9: Fixes crash when scanning with esp32c5/c6/c2/h2
-
ArduinoJson6.21.5 → 6.21.6: Fixes a buffer overrun -
ESPAsyncWebServer3.9.5 → 3.10.0: WebSocket performance refactoring (3.10.1 is officially tagged "DO NOT USE" by the maintainers — the JsonHandlerTypes error is a confirmed upstream bug)
Full Changelog: v0.9.1...v0.9.2
v0.9.1
DIGINODE FW v0.9.1
What's New
- Privacy Mode: toggle to hide the MAC and name of devices in the webUI
- Battery Saver: initial feature release to reduce overhead
- Faster UI: fixes bugs causing a slow experience with the AP FW
Fixes
- Addresses bug where the WiFi radio would wait for the mesh device queue to finish
- Baseline scan display in light mode, colors fixed
- Add missing stop radio call to headless fw scanner
Full Changelog: v0.9.0...v0.9.1
v0.9 Beta
DIGINODE FW v0.9
Features
- RF Environment Presets - New configurable RF environment for triangulation accuracy
- Improved Scanning - LoRa scan slots now work for all message types
- Distance Calibration Multipliers - Optional WiFi/BLE fine-tuning (0.1-5.0x range)
- Rebuilt triangulation engine - Requires less time, is more accurate and reliable
- Battery saving - Sleep mode (Experimental). Readme for details
RF Environment Options
| Value | Name | Use Case |
|---|---|---|
| 0 | RF_ENV_OPEN_SKY | Clear LOS, minimal obstruction |
| 1 | RF_ENV_SUBURBAN | Light foliage, some buildings |
| 2 | RF_ENV_INDOOR | Typical indoor, some walls (default) |
| 3 | RF_ENV_INDOOR_DENSE | Office, many partitions |
| 4 | RF_ENV_INDUSTRIAL | Heavy obstruction, machinery |
Where it's used:
- Set via
rfEnvparameter when starting triangulation (web API) - Propagated to all nodes in mesh via
TRIANGULATE_STARTcommand - Controls path loss exponent (n) and reference RSSI values used in distance estimation from WiFi/BLE signals
Distance Calibration Parameters (Optional)
wifiPwr(0.1-5.0, default 1.0) - WiFi distance multiplierblePwr(0.1-5.0, default 1.0) - BLE distance multiplier
Mesh Command Format:
TRIANGULATE_START:target:duration:rfEnv:wifiPwr:blePwr
target- MAC address or identity (T-XXXX)duration- Scan duration in secondsrfEnv- RF environment (0-4, optional)wifiPwr- WiFi multiplier (optional)blePwr- BLE multiplier (optional)
Fixes
- Fixed late ACKs from T_D messages
- Memory fixes in baseline scan and other tasks
- Dual-radio devices appearing as BLE and WiFi in triangulation
- FW-wide task protection for memory and thread safety
- GPS update loop blocking
- Deadlock from function name/bool confusion
- Blocking operations during scans
- Message coordination logic and mesh token slots
- Triangulation threshold weighting bug
- Mesh parsing delimiter handling
- Hitslog overflow and mesh cycles
Hardware
- DigiNode V4 - New case design by @TheRealSirHaXalot
Documentation
- DigiNode V4 assembly manual by @TheRealSirHaXalot
- Mesh command updates
Updated ESP32 Deps
NimBLE
RTClib
AsyncTCP
ESPAsyncWebServer
What's Changed
- Production memory and RTC changes by @lukeswitz in #17
Full Changelog: v0.8...v0.9.0
v0.8.0 Beta
What's New in 0.8.0
Bug fixes
- Addresses potential issues in file and identity handling
- Fix potential crash in force ending triagulation
- Fix autoerase in AP FW: bug where it would not enable via webUI
- Fix POST data to FormData not urlencoded
- Fixed countdown timer calculation using server's time scale
- Fix triangulation slot assignment with separate task
- Fix mesh serial token refill timer
Changes & Improvements
- Overhaul triangulation and data reporting
- Use static buffer for config writes
- Add timer for auto erase setup mode countdown
- Add dynamic countdown to autoerase setup
- Fix when SD under 1kb showing 0 in UI, add ui for capacity/used.
- Added last vibration in webUI
- Make erase optional in flasher script
- Maintain C2 backwards compatibility
- Changed mesh report commands for lower data on report
- Dedupe device scans to avoid mesh congestion
Full Changelog: v0.7.0...v0.8
v0.7.0
What's New in v0.7.0
Team AntiHunter is excited to announce the AH Command Center is available now!
Breaking Changes
-
Node name syntax: 2-5 alphanumeric characters. Example
AH029. Auto truncates if name set >5 on SD card. -
Default AP SSID password changed from
ouispy123toantihunt3r123. Saved config will persist.
Important
If updating from a previous version, format the SD card (FAT32) first. Then, for good measure, erase the flash memory to clear legacy configuration data. Use any of these methods:
- Updated script:
flashAntihunter.sh - PlatformIO:
pio run -t erase -e AntiHunter-full - esptool.py:
esptool.py --port /dev/ttyUSB0 erase_flash
Bug Fixes
-
Fixed triangulation orchestration using node slot timing and assignment. Allow headless activation from non-nodes (radio/C2)
-
Fixed
ERASE_REQUESTconfusion (full & headless): was starting the erase countdown immediately, which meant users had to race against the timer after getting the token. This was confusing and dangerous. Solution:ERASE_REQUESTnow only generates and returns the token (no countdown)- Token is valid for 5 minutes
ERASE_FORCEvalidates the token and executes the erase immediately
-
Fixed MAC randomization of the ESP32 timing to ensure interface is configured before change
-
Fixed headless FW not clearing old BLE scans
-
Fixed multiple full FW webUI performance and reliability issues
-
MAJOR fix: preferences persistence: some config settings were missing NVS calls, resulting in unexpected behavior without an SD card. Settings now write to both, falling back to NVS when SD is unavailable.
Note
Formatting SD card/erase & flash ensure fix is applied- Be sure you follow the instructions at the top
New Features
-
RSSI threshold: RF Settings menu in webUI has RSSI slider to filter devices with a signal strength below user defined threshold.
- Also configurable with new mesh command
CONFIG_RSSI(-128 to -10 range, -90 default).
- Also configurable with new mesh command
-
Headless triangulation: Allows C2/mesh radios to initiate the process. Results show in AP or by message (see command/alert reference)
- Detailed data resembling the AP results are now logged to SD including uncertainty, RTC sync, geometric error, distance, area and RSSI error coefficients.
- New FINAL message (see below) mimics the AP calculations and sends uncertainty in meters and confidence percentage.
-
Easter egg: Enable the original green and black Terminal UI theme
Enhancements
- New webUI interface with dark/light themes
- Updated flashing script to include all config variables for chosen FW
- Reworked triangulation results in webUI
- Triangulation uses slots to assign node delays, ensuring all can report simultaneously
- Serial boot messages now display actual node ID and AP settings instead of hardcoded defaults
- Added 15s delay on startup to allow mesh device boot sequence to complete
- NVS checkup added to hardware init with auto-recover and config backup/restore from SD.
- AP webUI results/diagnostic caching improvements (Full FW) removes lag in UI updates
Mesh Communication Changes
New Commands
| Command | Description | Example |
|---|---|---|
CONFIG_RSSI |
Sets RSSI threshold for sniffer scans. Baseline, Triangulation, List and Target scans unaffected. (-128 to -10 range) | @ALL CONFIG_RSSI:-40 |
CONFIG_NODEID |
Sets Node ID (2-5 alphanumeric characters). Includes error feedback. | @AH02 CONFIG_NODEID:AH03 |
TRIANGULATION_FINAL |
Returns final triangulation result with latitude, longitude, confidence level (%), uncertainty margin (m). | AH02: TRIANGULATION_FINAL:40.712800,-74.006000,85.5,12.3 |
AUTOERASE_ENABLE |
Enables auto-erase with optional parameters: [setupDelay:eraseDelay:vibs:window:cooldown] (all in seconds). Defaults: 120s setup, 30s erase, 3 vibs, 20s window, 300s cooldown |
@AH01 AUTOERASE_ENABLE or @AH01 AUTOERASE_ENABLE:60:30:3:20:300 |
AUTOERASE_DISABLE |
Disables auto-erase feature | @AH01 AUTOERASE_DISABLE |
AUTOERASE_STATUS |
Reports auto-erase configuration and status | @AH01 AUTOERASE_STATUS |
ERASE_REQUEST |
Requests erase token from device (auto-generates if none exists) | @AH01 ERASE_REQUEST |
Changed Commands
| Command | Description | Example |
|---|---|---|
STATUS |
Now uses Celsius temp only, adds HDOP, removes SD status, Unique | NODE_ABC: STATUS: Mode:WiFi+BLE Scan:ACTIVE Hits:142 Temp:42.3C Up:03:24:15 GPS=40.712800,-74.006000 HDOP=1.2 |
DRONE |
Alert message now includes RSSI, MAC, ID, Altitude, Speed & Operator location. SD logs now include MAC. | NODE_ABC: DRONE: AA:BB:CC:DD:EE:FF ID:1234567890ABCDEF R-65 GPS:40.712800,-74.006000 ALT:123.5 SPD:25.5 OP:40.712800,-74.006000 |
HB |
Heartbeat format: NODE_ABC: Time:2025-10-28_14:32:15 Temp:42.3C GPS:40.7128,-74.0060 |
NODE_ABC: Time:2025-10-28_14:32:15 Temp:42.3C GPS:40.7128,-74.0060 |
Build & CI/CD
- Added cppscan static analysis checks
- Added PlatformIO build pipeline for automated builds
- Fixed compatibility with GCC 14+
New Contributors
- @nitekry - made their first contribution: Added dev puck case STL files
Full Changelog: v0.6.0...v0.7.0
v0.6
AntiHunter Beta v0.6
Version Note:v0.6.8 Includes fixes and improvements tov0.6.0- Both versions are included in the assets below for testing.
Breaking Changes
- NimBLE upgraded from 1.4.3 to 2.3.6
- ESP32 MAC address randomized on boot
- Persistent APSTA mode implementation
- Split source into full & headless (with WiFi AP or mesh connection only) (
v0.6.8)
New Features
Flash Configuration
- Utility script now allows for assigning node names, scan mode, channels etc. to deployments (
v0.6.8)
RF Scan Settings
- Presets and customized : channel dwell time, intervals, duration for BLE/WiFi
- Set WiFi channels for all scans (
v0.6.8) - Allows tweaking for your use case- be stealthy or aggressive in your recon (
v0.6.8)
MAC De-Randomization Scanner
EXPERIMENTAL
- Behavioral signature tracking across randomized MAC addresses using IE fingerprinting, channel sequencing, RSSI analysis, and sequence number correlation
- Identity management: 30 device identities with up to 50 linked MACs each, persistent SD storage, survives reboots
- Confidence-based linking with adaptive thresholds
- WiFi-BLE cross-protocol device correlation
- Clear old IDs and results controls
Deauthentication Attack Detection
- WiFi deauth/disassoc attack sniffer with frame filtering and real-time detection
- Integration with randomization tracking for source identification
Triangulation/Trilateration Target Scan
EXPERIMENTAL
- Multi-node time-synchronized positioning using RTC timestamps and TDOA calculations
- Requires 3+ nodes with GPS and RTC
- HDOP prioritization over GDOP for 2D accuracy
- Adaptive path loss calibration, Kalman filtering
- Fixed subordinate/dominant role assignment, mesh communication, and node accumulation
- Minimum 60s scan duration enforcement
Baseline Detection
- Temporal tracking with configurable anomaly detection
- SD card logging, duplicate alert prevention
- Rate limiting for mesh broadcasts
- Fixes for caching and SD lookups
Drone RID Scan
- Added deduplication of randomized drones
- Shows MACs associated with the first seen
Web Interface
- Complete UI overhaul (
v0.6.8) - WiFi AP credentials configuration
- Network & Hardware tabs show more relevant data (
v0.6.8) - Real-time result updates during active scans
- Dynamic scan buttons with status feedback
- Optimized layout and improved responsiveness
Bug Fixes
- Add missing UI elements for self-destruct mechanism (
v0.6.8) - Target list called mistakenly for single target
- BlueTeam task crash, MAC parsing for mesh ACKs
- Sniffer and other scan tasks incorrectly using WiFi and BLE when only one is selected (
v0.6.8) - Backend frame count logic, device scanning sync
- Triangulation: sub/dom comms, path loss circular logic, device type tracking
- Baseline config loading incorrectly(
v0.6.8)
System Improvements
- UART serial rate limiting with token bucket algorithm and yield logic
- Mesh transmission interval: 3s to 5s and now configurable from webui and mesh c2 (
v0.6.8) - RTC synchronization priority: NTP > System Time > GPS
- SD card configuration persistence with memory fallback
- Global allowlist to ignore devices in all scans
- Completed secure data destruction with auto-erase (
v0.6.8)
Hardware
- I2C stability fixes, RTC 400kHz with 100kHz fallback
- Vibration motor pin pulldown
- T114 hardware & mesh serial optimizations
- 3D-printable enclosure STL files
Contributors
Full Changelog: v0.5.0...v0.6.0
v0.5.0
AntiHunter v0.5.0 Beta
Release Date: September 29, 2025
Status: Beta - Experimental PCB Build
Full Changelog: v4...v5
Real-Time Clock
- Added DS3231 RTC module support for accurate triangulation across distributed nodes
- GPS synchronization when available
- Removed buzzer hardware to accommodate RTC
Baseline Anomaly Detection
- New two-phase detection system: establish baseline, then monitor for anomalies
- Configurable RSSI threshold (-40 to -80 dBm) and duration (1-10 minutes)
- Real-time progress tracking with WiFi/BLE device breakdown
- LRU eviction and memory management for 500 max devices, 100k to SD
- Automatic stale device cleanup (10-minute timeout)
- Configurable re-detection alerts
Hardware Configuration
- Added SW-420 vibration sensor support with improved debounce
- Removed DS18B20 temperature sensor
- Updated hardware definitions for experimental PCB
Detection Capabilities
Device Discovery Scanning
- WiFi-only, BLE-only, or combined WiFi+BLE scan modes
- Captures all devices in range without filtering
- Records MAC addresses, SSIDs, device names, RSSI, and channels
- Provides complete wireless spectrum visibility
- SD card logging with GPS coordinates when available
- Real-time results via /results endpoint
Drone Detection (Remote ID)
- Full ASTM F3411 OpenDroneID support with NAN action frames and beacon frames
- French drone ID format detection (OUI 0x6a5c35)
- Extracts UAV ID, operator ID, and operator location
- Flight telemetry: altitude (MSL/AGL), speed, heading, vertical speed, GPS coordinates
- Drone type, classification, and status information
- JSON event log (100 entry limit) with duplicate prevention (5-minute window)
- Mesh alerts with drone position data
- Web endpoints: /drone-log, /drone-results, /api/drone/status
- Stale drone cleanup (5 minutes since last detection)
Baseline Anomaly Detection
- Establishes normal environment baseline, then monitors for new devices
- Only alerts on devices exceeding RSSI threshold to reduce false positives
- Tracks device RSSI profiles (min/max/average)
- Mesh network alerts include GPS coordinates when available
- Real-time web UI updates with device/anomaly counts
Security Features
Tamper Detection & Auto-Erase
- SW-420 vibration sensor integration for physical tamper detection
- Configurable auto-erase with vibration threshold (default: 3 detections within 20 seconds)
- Setup mode with configurable delay (default: 2 minutes) prevents accidental triggers
- Secure erase: wipes SD card, clears preferences, randomizes memory, creates a “config file” for an IoT weather sensor
- Remote mesh command support for distributed erase operations
- Token-based authorization for remote erase
- Configurable cooldown period (default: 5 minutes) between erase attempts
- Web UI controls for configuration and manual trigger
- Real-time status monitoring via /api/config/autoerase endpoint
Network Improvements
- Enhanced USB to mesh message processing
- Persistent AP, doesn’t drop out
- Removed insecure fallback tests
- Send node ID periodically for better network identification in C2
- Better WiFi mode switching and error handling
Web Interface
- Updated dashboard layout with unified detection dropdown (Device Discovery, Baseline, Drone Detection)
- Fixed HTML rendering issues and Ajax handling
- Real-time baseline progress indicators
- Improved form routing and validation
- Context-sensitive action buttons
- Auto-erase configuration panel with status display
Code Maintenance
- Refactored AP and scanning systems
- Removed attack scans until stable (deauth, beacon flood, karma)
- Migrated to unified distribution system
- Updated bin and flasher
Configuration
- SD card-based JSON configuration (/config.json)
- Configuration persists across power cycles
- Stores: node ID, scan mode, channels, targets, auto-erase settings
- Automatic migration from preferences on first boot
Monitoring & Diagnostics
- Implemented 10 minute heartbeat/SD save interval
- Slowed down diagnostic polling for stability
- Enhanced status reporting for GPS, RTC, sensors, vibration
- Improved SD card error handling and retry logic
- Tamper detection event logging
Bug Fixes
- Fixed timer overflow crash in long scans
- Resolved AsyncTCP bind error -8
- Corrected WiFi mode switching conflicts
- Fixed GPS lock detection false positives
- Fixed memory leaks in baseline detection
- Better queue memory management
Known Issues
- Triangulation requires 3+ nodes with GPS and RTC for best accuracy
- Baseline detection limited to 500 devices
- Some attack detection features temporarily disabled pending stability improvements
Migration Notes: Configuration now stored on SD card (/config.json). All mesh nodes should be updated together for protocol compatibility. Hardware changes optional but recommended for full feature set. Auto-erase functionality requires SW-420 vibration sensor.
AntiHunter v0.4.0
What's New
- Mesh commands for node configuration and communication
- Flasher and bins for continued MeshDetect, OUI-SPY support
View the Readme for mesh communication examples and documentation.
Important
This is an early release, breaking changes and other unexpected behavior may occur.
Full Changelog: v0.3.0...v0.4.0
