lucidiot's cybrecluster

Warwalking avec des ESP

Lucidiot Informatique 2021-06-30
Enfin un peu de contexte dans l'actuelle série d'articles…


J'ai déjà mentionné plusieurs fois dans mes précédents articles au sujet du GPX que je mettrai un peu de contexte dans ce que je dis, et il est largement temps de le faire. Enfin un article avec plus de texte que de SQL ! Depuis fin mai, nous tentons de collecter des données sur les réseaux Wi-Fi autour de nous tout en marchant en ville. L'objectif principal était de pouvoir découvrir des réseaux ouverts et indiquer sur OpenStreetMap la présence de ces réseaux, pour permettre plus tard à quelqu'un de trouver rapidement un endroit où avoir du Wi-Fi gratuit. Au fil de nos sorties et de notre exploitation des données, d'autres objectifs sont apparus, comme faire des statistiques sur les fournisseurs d'accès ou tester l'efficacité de aircrack-ng sur le terrain, mais OpenStreetMap reste prioritaire.

On m'a fait remarquer que ce genre de scan s'appelle le warwalking, une variante du wardriving mais qui se fait à pied. Je ne sais pas vraiment d'où vient le "war" cela dit ; on peut dire que je pars en guerre contre les réseaux peu sécurisés peut-être ?

Nous avons initialement tenté d'utiliser des applications Android capables de scanner les réseaux Wi-Fi et de les stocker dans un fichier simple type JSON ou CSV, avec en plus les coordonnées GPS. Nous avons notamment testé Wifi Tracker, et avons constaté que l'application ne fonctionnait pas sur tous les téléphones, n'était plus maintenue, et consommait une grande quantité de batterie. Android 9 restreint aussi le scan des réseaux Wi-Fi, ce qui réduit considérablement la quantité de données qu'on récupère. Il nous fallait au moins quelque chose de capable de tenir une après-midi, et probablement aussi quelque chose avec une meilleure antenne.

Premier essai

Durant un dimanche où on a transformé une œuvre d'art en antenne radio, on a fait un premier essai de scan à l'aide d'un microcontrôleur TTGO T-Beam, que nous avons surnommé la Poutre puisque la traduction automatique de AliExpress a bien compris le mot « beam ». Le T-Beam incorpore un ESP32, une antenne GPS et une antenne LoRa, et un petit écran LCD est fourni. On s'en est servi pour scanner les réseaux Wi-Fi, les associer à la position GPS, et tout transmettre par Bluetooth à un téléphone via l'application Bluetooth Terminal HC-05, tout en retransmettant aussi la position en APRS pour qu'on puisse nous localiser sur une carte en ligne juste parce que c'est drôle. Enfin, « on »… c'est Valentin qui a tout fait. Je n'ai fait que donner de l'inspiration pour le scanner Wi-Fi et pour l'œuvre d'art. Le code du scanner est disponible sur GitLab.

Pendant qu'il utilisait ladite œuvre d'art pour contacter quelqu'un dans la principauté d'Androrre, j'ai ouvert Tank pour charger les données dans une base SQLite et faire très rapidement de premières requêtes SQL pour trouver des infos. D'après le .sqlite_history sur Tank, voilà ce que j'ai fait :

.separator ','
.import /tmp/scan.csv wifi
.mode csv
.headers on
SELECT DISTINCT lat, lon, ssid
FROM wifi
INNER JOIN (
    SELECT mac, FIRST_VALUE(time) OVER (PARTITION BY mac ORDER BY signal) AS time FROM wifi
) AS best_measurement USING (mac, time)
WHERE wifi.encryption = 1;

J'ai d'abord importé un fichier CSV dans une table, et j'ai activé le format de sortie CSV pour que les résultats fournis par SQLite soient aussi en CSV. J'ai ensuite lancé une requête pour récupérer juste les coordonnées GPS et les noms des réseaux trouvés qui étaient "protégés" en WEP. Puisqu'on peut avoir scanné plusieurs fois le même réseau, j'ai utilisé une sous-requête pour trouver le moment où le réseau a été reçu avec le signal le plus élevé, et on utilisera les coordonnées GPS enregistrées à ce moment-là seulement. La requête était sortie en CSV pour pouvoir envoyer ça directement à uMap, l'équivalent pour OpenStreetMap de Google My Maps, et donc voir les réseaux sur une carte.

Encore plus low-tech

Le lendemain, je me suis rappelé que j'avais en stock des LoLin ESP8266 NodeMCU v3 que je comptais utiliser pour divers projets de contrôle de lampes, de station météo ou de matrice LED. Ils étaient là et inutilisés depuis un bon moment, alors je me suis dit que je pourrais en utiliser un pour faire des scans. Cela dit, je n'ai rien à mettre dessus pour avoir du GPS ou du Bluetooth. J'ai découvert des applications Android permettant d'utiliser des ports série en USB comme Serial USB Terminal (et sa version Bluetooth Serial Bluetooth Terminal qui finira par remplacer HC-05 parce qu'il n'y a pas de pubs), et j'ai pu tester et confirmer que je pouvais utiliser l'enregistreur d'itinéraire de OsmAnd pour enregistrer la localisation de mon téléphone directement. Je me suis dépêché de faire mon propre firmware pour mon scanner, et je suis sorti faire un tour.

Et c'est ainsi que je me suis retrouvé pendant toute une semaine à marcher sur des kilomètres tous les soirs, parfois plusieurs fois par jour, tout ça pour scanner autant de Wi-Fi que possible. J'ai battu mon record personnel de marche en une journée. J'ai passé quelques soirées à traiter toutes ces données avec des requêtes SQL de plus en plus bizarres dont vous avez déjà pu avoir un aperçu, et à l'heure de l'écriture de l'article nous en sommes à plus de 300 000 mesures effectuées pour plus de 25 000 réseaux Wi-Fi distincts connus dans une seule ville.

Après que mon seul câble USB OTG se soit cassé, et vu que mon scanner n'a pas de Bluetooth, j'ai eu l'honneur de disposer de la Poutre pendant quelques jours. Maintenant que j'ai retrouvé un câble, mon sac à dos est donc rempli d'un tas d'antennes, j'enregistre de 2 à 4 réseaux par seconde en moyenne, et je capte parfois des réseaux à plus de 50 mètres. Là où je passe, mes fichiers TSV trépassent.

Format d'enregistrement

Vous l'avez déjà bien vu, les données GPS que j'enregistre sur mon téléphone sont au format GPX. Mais il y a eu aussi deux formats pour les données renvoyées par les scanners ; un par implémentation. On a commencé à standardiser un peu plus et heureusement !

Le format original utilisait du bon vieux CSV. Cependant, les ESSID peuvent contenir tout et n'importe quoi, y compris des virgules, et nous avons rencontrés des virgules sur le terrain. Pour éviter de trop complexifier nos firmwares avec une gestion correcte de l'échappement de caractères, et surtout parce qu'on a la flemme, nous avons changé de format pour le TSV. Il pourrait y avoir des tabulations dans les ESSID, mais nous n'en avons encore jamais vues vu qu'il faut vraiment le vouloir pour en insérer dans les pages de configuration des routeurs. Il a été brièvement envisagé d'utiliser les caractères standards ASCII 30 "Record separator" et 31 "Unit separator", qui permettent de séparer des lignes et des colonnes respectivement et sont pris en charge par le client en ligne de commande de SQLite, mais on a laissé tomber vu que ça perturbait pas mal un affichage correct par les applications Android. Les colonnes renvoyées sont les suivantes :

lat
Uniquement sur la Poutre. Latitude, en degrés au format WGS84, lorsqu'une position GPS est acquise et qu'elle a été modifiée depuis les derniers logs ; sinon, colonne vide.
lon
Uniquement sur la Poutre. Longitude, en degrés au format WGS84, lorsqu'une position GPS est acquise et qu'elle a été modifiée depuis les derniers logs ; sinon, colonne vide.
hdop
Uniquement sur la Poutre. Dilution horizontale de la précision en mètres, lorsqu'une position GPS est acquise et qu'elle a été modifiée depuis les derniers logs ; sinon, colonne vide.
age
Uniquement sur la Poutre. Décalage en millisecondes entre le moment d'acquisition de la position GPS et celui de son affichage dans les logs, lorsqu'une position GPS est acquise et qu'elle a été modifiée depuis les derniers logs ; sinon, colonne vide.
ssid
ESSID du réseau, jusqu'à 32 caractères. Peut être vide, auquel cas c'est un réseau "caché".
channel
Canal Wi-Fi utilisé. Voyez Wikipédia pour la liste !
signal
RSSI, ou force du signal reçu, en dBm.
encryption

Sécurité du réseau. Peut prendre une des valeurs suivantes :

NONE
Réseau sans mot de passe ni chiffrement.
WEP
Réseau protégé par Wired Equivalent Privacy, dont on peut récupérer le mot de passe en quelques minutes si quelqu'un est connecté au réseau. Notons que WEP est le seul chiffrement compatible avec les Nintendo DS.
WPA1
Réseau protégé par Wi-Fi Protected Access, un protocole créé un peu dans l'urgence pour mettre à jour des cartes Wi-Fi existantes et qu'elles arrêtent d'utiliser WEP.
WPA2
Réseau protégé par Wi-Fi Protected Access 2, plus sûr, avec plus d'algorithmes de chiffrement. Récupérer un mot de passe peut prendre des heures ou des jours et nécessite des rainbow tables.
WPA1+2
Réseau protégé par Wi-Fi Protected Access, mais on peut choisir la version qu'on veut, pour que les cartes Wi-Fi anciennes continuent à fonctionner mais que les plus récentes puissent avoir plus de sécurité.
802.1X
Réseau protégé par WPA-Enterprise, qui nécessite un nom d'utilisateur en plus d'un mot de passe. Son usage le plus courant en France est sur le réseau FreeWifi_secure, où les utilisateurs Free peuvent se connecter de façon bien plus sécurisée qu'un hotspot ouvert.

La colonne peut aussi contenir des chiffres de 0 à 255, auquel cas c'est un mode de chiffrement qui a été renvoyé par la librairie de scan Wi-Fi mais qui n'était pas documenté…

bssid
Le BSSID, autre nom de l'adresse MAC de la carte réseau du routeur qui fournit ce réseau. C'est une information importante, puisque plusieurs routeurs peuvent avoir des réseaux Wi-Fi avec les même noms alors qu'ils sont à des endroits très différents et sont des réseaux distincts.

Avant d'en arriver à cette liste, il y a eu d'autres colonnes comme hidden qui indique explicitement un réseau caché, ou des colonnes manquantes, ou des noms de protocoles de sécurité Wi-Fi différents, ou des données encore plus étranges comme l'heure au format GPS (HHMMSS, sans séparateurs). Vous noterez que le format actuel n'inclut aucunement l'heure actuelle ; on laisse nos applications d'enregistrement de port série s'en charger, vu qu'elles ont une option pour cela, et c'est beaucoup plus simple comme ça.

Tout ce contexte est assez important pour comprendre quelques un des problèmes que j'ai rencontrés et qui m'ont invité à commettre encore plus de crimes informatiques, dont les fameuses expressions régulières que j'ai mentionné dans le dernier opus et que nous verrons la prochaine fois…


Vous pouvez maintenant consulter le résumé de nos aventures tel que vues par mon complice sur son blog.


Commentaires

fluffy, 2021-07-02

Merci d'utiliser la balise <abbr>, c'est quelque chose qui manque trop souvent ailleurs, et qui pourtant est fort utile.

Et sinon sur le fond : ça a l'air rigolo tout ça !