
Analyseur WiFi et Bluetooth basé sur une interface graphique de nouvelle génération pour Linux
Sparrow-WiFi est un outil de conscience spectrale WiFi et Bluetooth en 2,4 GHz et 5 GHz pour Linux. Il intègre le scan WiFi, la découverte Bluetooth Low Energy et Classic, l'analyse spectrale par radio logicielle (HackRF, Ubertooth), le suivi GPS, la détection de drones FAA RemoteID, les opérations à distance montées sur drone/rover, et l'indexation ECS 8.17 dans Elasticsearch ou OpenSearch en une seule plateforme. Écrit entièrement en Python 3.
Le projet comprend quatre composants qui fonctionnent seuls ou ensemble :
| Composant | Interface | Objectif |
|---|---|---|
| Sparrow-WiFi | Interface graphique PyQt5 | Scan WiFi/BT, analyse spectrale, suivi de source, wardriving |
| Sparrow Agent | Serveur HTTP sans tête | Scan à distance, déploiements drone/rover, intégration tierce |
| Sparrow DroneID | Basé sur navigateur | Détection de drones FAA RemoteID via WiFi et Bluetooth LE |
| Sparrow Elastic Bridge | Service CLI sans tête | Indexation ECS 8.17 des observations WiFi/BT dans Elasticsearch / OpenSearch |
Le Sparrow Agent et Sparrow DroneID exposent des API REST JSON qui permettent à d'autres applications d'interroger les résultats de scan, de déclencher des scans, de récupérer les détections de drones, et d'intégrer la conscience sans fil/drone dans leurs propres flux de travail. Le Elastic Bridge consomme l'API REST de l'agent et expédie des documents ECS 8.17 avec des tableaux de bord Kibana inclus.
Cette version couvre trois améliorations significatives par rapport à la version précédente :
/wireless/networks/<iface>, l'agent lançait auparavant N appels iw scan redondants qui se sérialisaient sur le verrou par interface, multipliant la latence du scan par le nombre de clients. La première requête devient désormais « leader » qui effectue réellement le scan ; les requêtes concurrentes attendent sur un threading.Event et partagent le résultat du leader. Inclut également une correction TOCTOU lors de la création de verrous et une sécurité contre les exceptions sur les verrous par interface.droneid.*), et une interface web responsive multi-appareils. Voir la section Sparrow DroneID ci-dessous.sparrow-elastic.py a été réécrit pour produire des documents ECS 8.17 (était ECS 1.5), prend désormais en charge à la fois Elasticsearch 8.x et OpenSearch 2.x, initialise automatiquement les modèles d'index composables avec des politiques de cycle de vie ILM/ISM et des alias d'écriture rollover, effectue un enrichissement des fournisseurs OUI et une classification d'appareils basée sur des règles (avec empreinte digitale optionnelle via Fingerbank), et livre quatre tableaux de bord Kibana inclus plus six visualisations héritées préservées. Le pont ECS 1.5 hérité est conservé dans legacy/sparrow-elastic.py. Voir .L'application originale Sparrow fournit un remplacement complet basé sur une interface graphique pour des outils comme inSSIDer et LinSSID, avec des capacités bien au-delà du scan de base :
sparrowwifiagent.py) pour le scan distribué, les opérations montées sur drone/rover, et les déploiements sur Raspberry Piiw scan
Un système autonome de détection et de suivi de drones basé sur le web qui décode les diffusions d'identification à distance (RemoteID) mandatées par la FAA. Fonctionne comme un serveur HTTP Python avec une interface utilisateur accessible depuis n'importe quel appareil sur le réseau.
L'interface web est accessible à l'adresse http://localhost:8097 une fois démarrée. Voir Installation ci-dessous pour la configuration, et la référence API pour un accès programmatique.
En plus des webhooks Slack, Sparrow DroneID peut POSTer chaque alerte déclenchée vers un point de terminaison générique d'ingestion d'alertes externe. Le canal est désactivé par défaut ; configurez-le dans Paramètres → Alertes → Alertes basées sur API :
http://MY_API_HOST:PORT/API_ROOTAuthorization: Bearer ... ; masqué dans l'interface une fois stockérule.category: "test", série TEST-0000) pour que le récepteur puisse être testé de bout en bout sans attendre un vrai droneSparrow DroneID effectue deux appels vers l'URL racine configurée :
Les deux appels envoient Authorization: Bearer <token> et Content-Type: application/json.
{ "domain": "", "alert": { "message": "", "observer": { "name": "<operator_name or 'Sparrow DroneID'>", "type": "drone-sensor", "geo": {"location": {"lat": 0.0, "lon": 0.0}} }, "rule": {"name": "", "category": "drone_detection"}, "event": { "severity": 40, "category": "network", "action": "new_drone" }, "labels": { "serial": "", "vendor": "", "ua_type": "", "alert_type": "new_drone | altitude_max | speed_max | signal_lost" }, "source": {"geo": {"location": {"lat": 0.0, "lon": 0.0}}}, "details": { "operator_id": "...", "registration_id": "...", "self_id_text": "...", "mac_address": "...", "protocol": "...", "rssi": -68, "range_m": 1234.5, "bearing_deg": 215.0, "bearing_cardinal": "SW", "speed_mps": 5.2, "direction_deg": 240.0, "altitude_m_agl": 42.0, "detail": "..." } } }
`observer.geo.location` est inclus lorsque le récepteur a une fixation GPS ; `source.geo.location` est inclus lorsque le drone diffuse une position. La sévérité suit la convention ECS (plus bas = plus urgent) : les avertissements (`new_drone`, `altitude_max`, `speed_max`) sont `40`, les événements informatifs (`signal_lost`) sont `70`. Les drones marqués comme amis ne déclenchent pas d'alertes lorsque le bouton « Alerter sur les drones amis » côté opérateur est désactivé, ils n'atteignent donc pas non plus ce point de terminaison.
Les alertes de test synthétiques émises par le bouton **Envoyer un message de test** utilisent `rule.category: "test"`, `event.action: "test"`, `event.severity: 70`, et le numéro de série `TEST-0000` afin que le récepteur puisse les reconnaître et les exclure des tableaux de bord opérationnels.
---
## Configuration requise
| Exigence | Sparrow-WiFi (GUI) | Sparrow DroneID (Web) |
|-------------|-------------------|----------------------|
| **Système d’exploitation** | Ubuntu 20.04+, Kali 2020.3+, Debian 11+ | Ubuntu 20.04+, Kali, Debian 11+, Raspberry Pi OS |
| **Python** | 3.8+ | 3.8+ |
| **Root** | Required (iw scan) | Required (monitor mode, BLE) |
| **Adaptateur WiFi** | Any with `iw` support | Monitor-mode capable (e.g., rtl8812au, Intel AX200) |
| **Bluetooth** | Optional (hci adapter, Ubertooth) | Optional (any BLE-capable adapter for RemoteID) |
| **GPS** | Optional (gpsd) | Optional (gpsd or static coordinates) |
| **Affichage** | X11/Wayland desktop | Headless OK (web browser on any device) |
---
## Installation
### Sparrow-WiFi (Interface graphique bureau)```bash
git clone https://github.com/ghostop14/sparrow-wifi
cd sparrow-wifi
Paquets système (Ubuntu 22.04+ / Debian 12+ / Kali rolling):```bash
sudo apt install python3-pip python3-pyqt5 python3-pyqt5.qtchart
gpsd gpsd-clients python3-tk python3-setuptools
> **Utilisateurs de Kali:** PyQt5, PyQtChart et aircrack-ng (pour le plugin Falcon) sont généralement préinstallés. Vous aurez surtout besoin de `gpsd`, `gpsd-clients` et des dépendances Python ci-dessous.
Dépendances Python — choisissez l'une des approches suivantes:
**Option A: Installation système avec `--break-system-packages`** — la plus simple, correspond à la manière dont l'interface graphique/l'agent sont lancés (scripts appartenant à root) :```bash
# Modern systems (Ubuntu 24.04+, Kali rolling 2023+, Debian 12+) require this
# flag because Python is marked externally-managed (PEP 668). Sparrow runs as
# root anyway, so system-wide install is consistent with how it executes.
sudo pip3 install --break-system-packages -r requirements.txt
Option B : Environnement virtuel — isolé, aucun avertissement pip système, préféré par certains opérateurs :```bash python3 -m venv venv source venv/bin/activate pip install -r requirements.txt
sudo venv/bin/python3 ./sparrow-wifi.py
Dans les deux cas, exécutez :```bash
sudo ./sparrow-wifi.py
cd sparrow-droneid
sudo apt install tcpdump bluez
sudo pip3 install --break-system-packages -r sparrow_droneid/requirements.txt
python3 -m venv venv && source venv/bin/activate && pip install -r sparrow_droneid/requirements.txt
sudo python3 sparrow_droneid/app.py
Ouvrez `http://localhost:8097` dans un navigateur. Configurez l'interface de surveillance et le GPS dans Paramètres, puis cliquez sur Démarrer.
### Elasticsearch / OpenSearch Bridge (optionnel)```bash
sudo pip3 install --break-system-packages -r requirements-elastic.txt
# or via venv as above
Voir Intégration Elasticsearch / OpenSearch ci-dessous.
La plupart des adaptateurs WiFi fonctionnent pour les scans de base. Sparrow-WiFi prend en charge plusieurs backends d'énumération d'interfaces (iw, iwconfig, nmcli) afin de fonctionner sur des systèmes qui n'ont pas iw installé (par exemple, RHEL/Fedora avec NetworkManager uniquement).
Pour le mode moniteur (requis par Sparrow DroneID et le plugin Falcon), la prise en charge de l'adaptateur et du pilote varie :
iw phy <phy> info | grep monitor ou iwconfig <iface> pour vérifier les capacitésPour Sparrow DroneID en particulier, l'adaptateur doit délivrer des trames 802.11 brutes en mode moniteur. Certains adaptateurs Intel signalent le mode moniteur comme pris en charge mais suppriment silencieusement les trames au niveau du firmware. L'application le détecte et vous en avertit.
Sparrow-WiFi prend en charge plusieurs modes de scan Bluetooth :
Un adaptateur Bluetooth standard intégré ou USB suffit pour le scan des annonces BLE et la détection des drones RemoteID. Testez votre adaptateur avec bluetoothctl scan on.
Pour la découverte promiscuité complète des appareils Classic et BLE, vous aurez besoin d'un Ubertooth One et de Blue Hydra installés dans /opt/bluetooth/blue_hydra. Ceci est optionnel et n'est pas requis pour les scans BLE ou RemoteID de base.
Superpositions spectrales en temps réel sur les vues des canaux WiFi :
ubertooth-specan-uihackrf_sweep
Les deux applications utilisent gpsd pour le GPS. Configuration rapide :```bash
sudo apt install gpsd gpsd-clients
sudo gpsd -D 2 -N /dev/ttyUSB0
xgps # or: cgps -s
Pour la production, configurez `/etc/default/gpsd` avec le chemin de votre périphérique et redémarrez le service.
Sparrow DroneID prend également en charge les coordonnées statiques (configurées dans les Paramètres) pour les installations en site fixe sans récepteur GPS.
---
## Agent distant et intégration API
L'agent Sparrow (`sparrowwifiagent.py`) est un serveur HTTP sans interface qui expose toutes les capacités de balayage WiFi et Bluetooth de Sparrow sous forme d'une API REST basée sur JSON. C'est ainsi que l'interface graphique Sparrow-WiFi communique avec les capteurs distants, mais l'API est ouverte à toute application.
**Cas d'utilisation :**
- Déployer sur un Raspberry Pi, un drone ou un rover pour un balayage distant/mobile
- Intégrer la connaissance situationnelle WiFi et Bluetooth dans vos propres applications
- Alimenter les données de balayage dans un SIEM, des tableaux de bord ou des pipelines d'alerte
- Automatiser le balayage avec des scripts (déclencher des balayages, récupérer les résultats via curl/Python/etc.)
Sparrow DroneID possède également sa propre API REST ([référence API](https://github.com/ghostop14/sparrow-wifi/blob/master/sparrow-droneid/sparrow_drone_id_api.md)), offrant un accès programmatique aux détections de drones, à la gestion des alertes, aux géozones et à la configuration du système.
### Exécution de l'agent```bash
sudo ./sparrowwifiagent.py
Écoute sur le port 8020 par défaut. Options clés :
Voir --help pour la liste complète.
curl http://sensor:8020/wireless/interfaces
curl http://sensor:8020/wireless/networks/wlan0
curl "http://sensor:8020/wireless/networks/wlan0?frequencies=2412,2437,2462"
curl http://sensor:8020/gps/status
curl http://sensor:8020/bluetooth/discoverystarta
curl http://sensor:8020/bluetooth/discoverystatus
Pour Sparrow DroneID, consultez la [référence API](https://github.com/ghostop14/sparrow-wifi/blob/master/sparrow-droneid/sparrow_drone_id_api.md) dédiée.
> **Remarque pour la production :** l'agent écoute par défaut sur toutes les interfaces. Pour les déploiements en dehors d'un réseau de confiance, utilisez `--allowedips` pour restreindre les appelants, exécutez derrière un proxy inverse avec TLS, ou liez-vous à une interface privée uniquement.
---
## Plugin Falcon / Aircrack-ng
Intégration avancée de tests de pénétration sans fil. Offre un accès point-and-click à :
- Découverte de SSID caché via airodump-ng
- Énumération des stations clientes (AP connecté, SSID sondés)
- Désauthentification ciblée et broadcast
- Capture d'IV WEP
- Capture de handshake WPA avec extraction automatique de hash (nécessite JTR `wpapcap2john`)
### Prérequis```bash
# Kali users: aircrack-ng + JTR are usually pre-installed.
# Ubuntu / Debian / Raspberry Pi OS:
sudo apt install aircrack-ng john
Verify airmon-ng, airodump-ng, and wpapcap2john are on your PATH after install.
Les tests de pénétration actifs sont soumis à des réglementations légales. Il est de votre responsabilité d'obtenir une autorisation appropriée avant d'utiliser ces outils.
Le package sparrow_elastic fournit un pont ECS 8.17 qui interroge l'agent Sparrow WiFi et indexe en masse les observations WiFi et Bluetooth dans Elasticsearch 8.x ou OpenSearch 2.x. Il amorce automatiquement des modèles d'index composables, des politiques de cycle de vie ILM/ISM et des alias d'écriture de rollover ; effectue un enrichissement des fournisseurs OUI et une classification des appareils basée sur des règles (avec empreinte digitale Fingerbank en option) ; et fournit des tableaux de bord Kibana préconstruits.
sudo ./sparrowwifiagent.py
sudo pip3 install --break-system-packages -r requirements-elastic.txt
./sparrow-elastic.py --elasticserver http://user:pass@host:9200 --wifiinterface wlan1
python3 install_dashboards.py --kibana-url http://kibana:5601
--username elastic --password ''
> **Hygiène des identifiants :** intégrer `user:pass@` dans `--elasticserver` est pratique mais l'URL devient visible dans `ps`, `journalctl` et l'historique du shell. Pour la production, utilisez les options `--username`/`--password`, les variables d'environnement (`SPARROW_ES_USERNAME`, `SPARROW_ES_PASSWORD`) ou le modèle `EnvironmentFile=` dans l'exemple d'unité systemd fourni.
### Ce que le pont intègre
- **5 tableaux de bord Kibana** — Sensibilisation situationnelle, Schéma de vie, Détection de nouveaux appareils, Planification spectrale (avec carte de champs d'intensité SSID × canal) et Sensibilisation situationnelle Bluetooth (avec panneau Vega pour nouveaux appareils et table de proximité par distance estimée)
- **6 visualisations conservées de l'ancienne version** — clones renommés des visualisations originales `Sparrow*` pour que les anciens réflexes continuent de fonctionner
- **Classifieur d'appareils** — table de base de 64 règles couvrant les contrôleurs de drones (DJI/Autel/Skydio/Parrot/Yuneec), la classe d'appareil BT, l'apparence GAP, les sous-types Apple Continuity et les heuristiques de fournisseur OUI
- **Actualisation des données de référence** — `manuf` de Wireshark, identifiants de société BT SIG, UUIDs de service, valeurs d'apparence GAP et tables de sous-types Apple Continuity, avec un thread d'auto‑actualisation en arrière‑plan de 30/90 jours
- **Vérification de compatibilité pré‑vol** — refuse d'écrire dans des index ECS 1.5 hérités et affiche des étapes de correction claires au lieu de corrompre silencieusement les données
Pour la documentation complète de l'opérateur (sélection du moteur, modes d'authentification, importation des tableaux de bord, données de référence, référence complète de l'interface en ligne de commande), consultez [sparrow_elastic/README.md](https://github.com/ghostop14/sparrow-wifi/blob/master/sparrow_elastic/README.md).
Les fichiers de configuration d'exemple se trouvent à la racine du dépôt et dans `init.d_scripts/` :
- `sparrow-elastic.conf.example` — Configuration au format INI avec toutes les clés prises en charge
- `sparrow-elastic.env.example` — Fichier d'environnement au format shell pour les déploiements systemd
- `init.d_scripts/sparrow-elastic.service.example` — Modèle d'unité systemd
### Migration depuis le pont ECS 1.5 hérité
Le pont antérieur à 2026 écrivait des documents ECS 1.5 dans des index nommés par l'opérateur via `--wifiindex` / `--btindex`. Le nouveau pont écrit des documents ECS 8.17 dans des alias d'écriture gérés par rotation (par défaut `sparrow-wifi` / `sparrow-bt`).
**Le script hérité est conservé dans `legacy/sparrow-elastic.py`** accompagné de son modèle `.txt` et des fichiers de politique ILM. Son exécution nécessite toujours l'environnement hérité (modèle manuel + configuration ILM).
**Modifications des options (avec rétrocompatibilité) :**
| Option héritée | Nouvelle option | Notes |
|-----------------------|-----------------------|-----------------------------------------------------|
| `--wifiindex NAME` | `--wifi-alias NAME` | L'orthographe héritée est toujours acceptée comme alias déprécié. |
| `--btindex NAME` | `--bt-alias NAME` | L'orthographe héritée est toujours acceptée comme alias déprécié. |
| `--dont-create-indices` | inchangé | Ignore le bootstrap. |
| `--elasticserver`, `--sparrowagent`, `--sparrowport`, `--wifiinterface`, `--scandelay` | inchangé | |
Une invocation héritée comme :```bash
./sparrow-elastic.py --elasticserver=http://user:pass@host:9200 \
--wifiinterface=wlan1 \
--wifiindex=sparrowwifi-home \
--btindex=sparrowbt-home
analyse et s'exécute toujours — mais le pont refuse désormais d'écrire dans un index préexistant dont le mapping ne porte pas le marqueur de schéma ECS 8.17, se terminant avec trois options de remédiation (utiliser un alias différent, effacer et re-bootstrap, ou exécuter le pont hérité). Pour une installation propre, il suffit d'omettre --wifiindex / --btindex et d'accepter les nouveaux paramètres par défaut.
L'agent distant peut être déployé sur un Raspberry Pi monté sur un drone ou un rover pour des relevés sans fil mobiles. Testé sur un drone Solo 3DR avec intégration GPS via MAVLink.
sudo python3 ./sparrowwifiagent.py --userpileds --sendannounce --mavlinkgps 3dr --recordinterface wlan0
Indicateurs LED (Raspberry Pi) :
1. Les deux éteints — Initialisation
2. Rouge clignotant — GPS présent, non synchronisé
3. Rouge fixe — GPS synchronisé
4. Vert fixe — Agent prêt, traite les requêtes
Les enregistrements peuvent être récupérés via l'interface de gestion des agents de Sparrow-WiFi GUI.
### Notes de configuration du Pi
- Utilisez Raspberry Pi OS (Bookworm ou ultérieur) avec Python 3.8+
- Désactivez le WiFi intégré pour activer le scan 5 GHz avec des adaptateurs USB : ajoutez `dtoverlay=disable-wifi` à `/boot/firmware/config.txt` sur Bookworm et ultérieur, ou `/boot/config.txt` sur les anciennes versions
- Installez les prérequis : `sudo pip3 install --break-system-packages -r requirements.txt` (ou utilisez un venv comme dans la section [Installation](#installation))
---
## Structure du projet```
sparrow-wifi/
sparrow-wifi.py # Desktop GUI entry point
sparrowwifiagent.py # Headless remote agent
sparrow-elastic.py # Elasticsearch / OpenSearch bridge (ECS 8.17)
install_dashboards.py # One-shot Kibana dashboard installer
requirements.txt # Python dependencies (GUI)
requirements-elastic.txt # Python dependencies (Elasticsearch bridge)
wirelessengine.py # WiFi scan engine (iw)
sparrowbluetooth.py # Bluetooth scan engine
sparrowhackrf.py # HackRF spectrum engine
sparrowmap.py # Map generation
plugins/ # Falcon and other plugins
sparrow_elastic/ # ES/OS bridge package
*.py # Client abstraction, document builder, classifier...
templates/ # Composable index templates (ES + OS variants)
policies/ # ILM (ES) and ISM (OS) lifecycle policy JSON
dashboards/ # Kibana NDJSON: 5 dashboards + legacy-preserved
data/ # Bundled reference data (manuf, BT SIG, classifier rules)
README.md # Full bridge operator documentation
legacy/ # Pre-2026 ECS 1.5 bridge, frozen for reference
sparrow-elastic.py # Legacy bridge (still runnable)
sparrow_elastic_*.txt # Legacy index templates and ILM policy
sparrow-droneid/ # DroneID web application
sparrow_droneid/
app.py # Entry point (sudo python3 app.py)
__main__.py # Allows: sudo python3 -m sparrow_droneid
requirements.txt # Python dependencies (DroneID)
backend/ # API server, capture engine, database
frontend/ # HTML, JS, CSS (served by backend)
sparrow_drone_id_api.md # REST API reference
Ce projet est sous licence selon les termes inclus dans le dépôt. Consultez le fichier LICENSE pour plus de détails.
| Verbe | Chemin | Objectif |
|---|
POST | {root}/v1/alerts/verify | Vérification des identifiants — corps {"domain": "<configuré>"}. Le récepteur doit répondre 200 {"status":"ok"} en cas de succès, 401 en cas de mauvais jeton. |
POST | {root}/v1/alerts | Déclencher une alerte — le corps est le JSON ci-dessous. Le récepteur doit répondre 201 {"alert_id":"..."} en cas de succès. Les réponses 503 sont réessayées avec un backoff exponentiel (3 tentatives) ; les 4xx annulent sans réessai. Un 200 {"status":"dropped"} indique que le domaine est désactivé en amont. |
| Mode | Matériel | Ce que vous voyez |
|---|
| Scan des annonces BLE | Adaptateur BT standard | Appareils LE qui annoncent activement |
| Scan promiscuité | Ubertooth One + Blue Hydra | Tous les appareils BLE et Bluetooth Classic à portée |
| Annonce iBeacon | Adaptateur BT standard | Annoncez vos propres iBeacons |
| Scan RemoteID | Adaptateur BT standard | Identification de drone conforme à la FAA (Sparrow DroneID uniquement) |
| Drapeau | Objectif |
|---|
--port PORT | Port d'écoute HTTP |
--allowedips IP1,IP2 | Restreindre les connexions client |
--staticcoord LAT,LON,ALT | Utiliser des coordonnées GPS fixes |
--mavlinkgps 3dr | Récupérer le GPS du drone Solo 3DR |
--recordinterface IFACE | Enregistrement automatique au démarrage (sans écran) |
--userpileds | Utiliser les LED du Raspberry Pi pour le statut |
--sendannounce | Diffusion UDP pour la découverte d'agents |