
Un outil de reconnaissance pour capturer et afficher les SSIDs à partir de la liste des réseaux préférés de l'appareil.

Sniffeur de Liste de Réseaux Préférés (PNLS) est un outil d'audit Wi-Fi pour équipes rouges, doté d'une interface web simple, capable d'intercepter les SSID1 de la liste des réseaux préférés (PNL)2 d'un appareil. Cela est réalisé en reniflant les Probe Requests à proximité, qui sont ensuite analysées pour en extraire le SSID et d'autres informations, et enfin propagées vers l'interface web. La motivation principale de ce projet était d'étudier les Probe Requests 802.11 et les risques pour la vie privée associés aux données qu'elles transmettent.
Fig. 1 : Aperçu du système PNLS
[!WARNING] Tout le contenu de ce projet est destiné uniquement à des fins de recherche en sécurité.
[!NOTE]
Ce projet fait partie de ma recherche en cours sur la .
Pour suivre les travaux en cours sur le PNLS, consultez le tableau du projet.
Voici ce dont vous aurez besoin pour dupliquer et déployer ce projet, incluant à la fois les composants matériels et logiciels. Une fois votre environnement de travail prêt, rendez-vous dans la section Installation.
sudo airmon-ng start wlan0 [2].[!NOTE]
L'image Kali utilise le noyau Re4son, qui inclut les pilotes pour les cartes Wi-Fi externes et le firmware Nexmon pour la carte sans fil intégrée du RPi 3 et 4 [3].
Fig. 2 : PNLS fonctionnant sur un RPi 4 avec une antenne externe et une batterie externe
Fig. 3 : PNLS fonctionnant sur un RPi 4 avec un boîtier équipé d'une antenne AWUS036ACS
Fig. 4 : PNLS fonctionnant sur un RPi 4 avec une antenne AWUS036ACM
Si vous ne souhaitez pas utiliser Docker, rendez-vous dans la section installation sans Docker.
Configurez rapidement une instance de développement :
# Clonez d'abord ce dépôt.
git clone https://github.com/AleksaMCode/Preferred-Network-List-Sniffer.git
# Placez-vous dans le dossier racine du projet.
cd Preferred-Network-List-Sniffer
# Construisez l'image du backend et du frontend.
docker compose build
# Lancez à la fois le serveur backend et le serveur frontend.
docker compose up
# Placez-vous dans le dossier sniffer.
cd sniffer
# Lancez le service Sniffer.
sudo python3 sniffer.py
Actuellement, les images multi-plateformes ne sont pas disponibles et le projet ne supporte que l'architecture ARM64v8. Téléchargez les dernières images préconstruites depuis le GitHub Container Registry et exécutez-les localement.
# Clonez d'abord ce dépôt.
git clone https://github.com/AleksaMCode/Preferred-Network-List-Sniffer.git
# Placez-vous dans le dossier racine du projet.
cd Preferred-Network-List-Sniffer
# Téléchargez les images préconstruites.
docker pull ghcr.io/aleksamcode/pnls-backend-ghcr:latest
docker pull ghcr.io/aleksamcode/pnls-frontend-ghcr:latest
# Lancez à la fois le serveur backend et le serveur frontend.
docker compose up
# Placez-vous dans le dossier sniffer.
cd sniffer
# Lancez le service Sniffer.
sudo python3 sniffer.py
Backend : pour démarrer les serveurs ASGI et Redis et exécuter les services nécessaires, consultez ces instructions.
Frontend : pour exécuter le serveur React, consultez ces instructions.
Voici une capture d'écran lorsque tout a été lancé « manuellement » :
Fig. 5 : Capture d'écran PNLS
Les Probe Requests sont des trames de gestion 802.11 utilisées pour connecter les appareils aux points d'accès (AP) sans fil précédemment associés. Chaque fois qu'un appareil a le Wi-Fi activé mais n'est pas connecté à un réseau, il envoie périodiquement une salve de Probe Requests contenant les SSID de sa PNL. Ces trames sont envoyées en clair, et toute personne effectuant une surveillance radiofréquence (RF) peut les capturer et les lire. Les probes sont envoyées à l'adresse DA de diffusion (ff:ff:ff:ff:ff:ff). Une fois envoyées, l'appareil démarre le Probe Timer. À la fin du timer, l'appareil traite la réponse reçue. Si l'appareil n'a pas reçu de réponse, il passe au canal suivant et répète le processus. Il existe deux types de Probe Requests :
Probe Requests dirigées : utilisant un SSID spécifique de la PNL de l'appareil
Probe Requests nulles : utilisant un SSID générique (SSID vide)
Les requêtes vides sont envoyées pour obtenir une réponse de tous les AP disponibles à portée.
En plus de filtrer les trames 802.11 Probe Request parmi tous les paquets capturés, le Sniffer filtrera également les SSID génériques.
Lors de la capture de Probe Requests dans des endroits où se trouve un grand réseau local avec de nombreux clients Wi-Fi, PNLS capturera inévitablement de nombreuses Probe Requests contenant le SSID dudit réseau. Le filtrage de ces SSID peut être avantageux, car ils n'ont aucune valeur pour nous et peuvent entraîner une augmentation de la charge des sockets. Filtrer ces SSID réduira non seulement la charge sur les connexions socket, mais évitera également le spam des SSID susmentionnés sur l'interface web.
Lorsque vous utilisez cette fonctionnalité, vous devrez apporter de légères modifications au code source. Plus précisément, vous devrez mettre à jour la liste SSID_FILTER dans le fichier settings.py avec la valeur que vous souhaitez que le Sniffer ignore. Une fois mise à jour, reconstruisez le projet et démarrez le PNLS.
Ce projet utilise une architecture orientée événements (EDA), conçue au-dessus d'architectures orientées messages. Bien que ce projet utilise une solution centralisée (tout est exécuté depuis le RPi), en raison de composants faiblement couplés grâce à l'utilisation de l'EDA, il est possible de créer une solution décentralisée si nécessaire. PNLS se compose d'un éditeur d'événements (sniffer), d'un consommateur d'événements (application web) et d'un canal d'événements. Ici, le canal d'événements est implémenté comme un middleware orienté message (MOM).
Fig. 6 : Diagramme de déploiement du système PNLS
L'interface de passerelle de serveur asynchrone (ASGI) fournit une interface standardisée entre les serveurs web Python compatibles asynchrones et les services [4]. L'ASGI a été choisie en raison du besoin du projet d'une connexion WebSocket persistante afin de faciliter les communications asynchrones entre différents clients. De plus, elle permet également l'utilisation de coroutines en arrière-plan lors des appels API. PNLS utilise l'implémentation uvicorn pour Python afin d'utiliser le serveur web ASGI.
Grâce à l'utilisation du protocole de communication WebSocket, nous pouvons faciliter une communication bidirectionnelle en full-duplex. Bien que ce projet n'ait pas besoin de communication bidirectionnelle, il a besoin d'une interaction en temps réel entre les composants du système. Ainsi, les données sniffées seront disponibles pour l'utilisateur final dès leur capture.
Le middleware orienté message du projet est réalisé via le courtier de messages utilisant Redis. Dans le modèle publication-abonnement (pub-sub), le Sniffer est responsable de la production des messages, tandis que l'application web (abonné) s'enregistre pour le sujet spécifique (canal Redis). Lorsque le Sniffer envoie un message à un sujet, il est distribué à tous les consommateurs abonnés, permettant une communication asynchrone et évolutive. PNLS utilise le protocole de messagerie léger Redis Pub/Sub pour la diffusion de messages afin de propager des messages à courte durée de vie avec une faible latence et un débit élevé [5][6]. Ainsi, les surcharges liées à l'encodage des structures de données sous une forme pouvant être écrite sur disque ont été évitées. Ce faisant, cette solution aura potentiellement de meilleures performances [7]. La figure ci-dessous montre l'activité simplifiée du système à travers le flux de travail orienté événements.
Fig. 7 : Diagramme de séquence du modèle Pub-Sub PNLS
[!NOTE] Le MOM implémenté ne fournit pas de stockage persistant ni de file d'attente de messages pour l'accumulation de données, ce qui signifie que les messages seront perdus s'ils sont publiés sur un sujet sans abonnés.
Ci-dessous un exemple d'interface web affichant des SSID de test publiés.
Fig. 8 : PNLS web - exemple avec des SSID de test
| PNL | Liste de réseaux préférés |
| PNLS | Sniffeur de liste de réseaux préférés |
| SSID | Identifiant de jeu de services |
| UI | Interface utilisateur |
| RPi | Raspberry Pi |
| OS | Système d'exploitation |
| AP | Points d'accès |
| RF | Radiofréquence |
| EDA | Architecture orientée événements |
| MOM | Middleware orienté message |
| ASGI | Interface de passerelle de serveur asynchrone |
| pub-sub | publication-abonnement |
Un identifiant de jeu de services (SSID) est un ID 802.11 utilisé pour nommer un réseau Wi-Fi, composé d'un maximum de 32 caractères pouvant contenir des lettres sensibles à la casse, des chiffres et des caractères spéciaux, sans dépasser 32 caractères. ↩
Une liste de réseaux préférés est une collection de SSID enregistrés avec des paramètres supplémentaires, que vous avez créée la première fois que vous avez connecté votre appareil à ces réseaux. ↩
Broadcom n'a jamais officiellement pris en charge le mode moniteur, ce qui limitait l'utilité des cartes sans fil des appareils Raspberry Pi [8]. Le projet Nexmon est un patch de firmware pour les puces Broadcom utilisées dans les appareils RPi [1]. Ce patch vous permettra d'utiliser le mode moniteur sur votre appareil RPi. ↩
Le framework de patching de firmware basé en C pour les puces Wi-Fi Broadcom/Cypress, permettant le mode moniteur, l'injection de trames et bien plus encore. ↩