05
févr.
'21

Interphones sans-fil, comment que ça n'avance pas

Publié le 05 février 2021

L'année 2021 démarre plutôt bien, et j'ai profité des premiers lives Twitch de l'année pour continuer la bidouille de minitels mais aussi pour tenter de convertir deux anciens téléphones à cadrans rotatifs en interphones sans-fil. Tandis que la modification des minitels suit son cours (je viens tout juste de souder le connecteur du clavier du Minitel), la conversion des vieux téléphones en interphones sans-fil se révèle plus problématique que prévu. Petit point rapide dans ce billet des soucis rencontrés, des solutions testées, et de l'avenir de ce projet.

Des interphones sans-fil ?

Revenons deux minutes à l'origine de ce projet. On trainait en famille dans un vide-grenier (oui, à l'époque où c'était encore possible) et je suis tombé sur un de ces vieux téléphones à cadran rotatif, ce même type de téléphone que j'utilisais tout petit pour appeler mes grands-parents. Il faut avouer que composer le numéro à 8 chiffres -- dans cet ancien temps la numérotation n'était pas encore à 10 chiffres -- était vraiment amusant: on plaçait le doigt dans le numéro souhaité, puis on faisait tourner le cadran jusqu'en butée, et ce dernier revenait en position initiale en faisant un petit bruit de crécelle. Tout nostalgique que j'étais, j'en ai acheté deux exemplaires pour moins de 10€, avec en tête l'idée de les réhabiliter à la maison.

Dans un premier temps, on souhaitait s'en servir comme second téléphone fixe, mais il s'est avéré que la méthode de génération du numéro composé n'est plus supportée par les réseaux téléphoniques d'aujourd'hui. Le système de numérotation par impulsion de l'ancien temps ne peut donc fonctionner, et il est donc impossible de passer des appels avec ce type de téléphone. Du coup, pourquoi ne pas les transformer en interphones sans-fil ? Tant qu'à faire, autant intégrer de la modernitude dans ces vieilleries ! Et c'est d'un pratique pour appeler les enfants qui jouent dans la mezzanine pour leur demander de mettre le couvert, pardi 😇.

Exemple d'usage

Premiers essais, premiers échecs

Tout excité à l'idée de réaliser ce projet (on était en 2020 à ce moment là), je teste dans un premier temps si les micros et les hauts-parleurs des téléphones fonctionnent, ce qui est le cas. Puis je connecte un micro à une entrée analogique d'un arduino Nano, et je code un petit programme qui échantillonne le signal en provenance du micro (amplifié avec un module lm386, histoire d'avoir un niveau de signal suffisant) et le retransmet sur le haut-parleur, lui aussi couplé à un module d'amplification similaire. Et miracle, ça fonctionne ! Bon d'accord, le son est pourri, mais ça fonctionne !

La voix humaine varie entre 40 et 1500 Hertz (d'après Musimem), et l'arduino Nano que j'utilisais, cadencé à 16 MHz, ne peut pas échantillonner plus vite que 615 384 échantillons à la seconde, ou plus simplement 615 kHz. C'est plutôt pas mal, mais la résolution sonore est limitée car le convertisseur analogique/numérique (ou ADC) ne produit des valeurs que sur 8 bits au vu de la vitesse d'échantillonnage requise. Ceci dit, le résultat n'était pas trop mal !

Le souci avec un système de communication bi-directionnelle comme un interphone, c'est qu'il faut gérer en même temps la conversion du signal audio en provenance du micro en échantillons numériques, l'envoi de ces échantillons, mais aussi la conversion des échantillons numériques reçus en signal analogique à destination du haut-parleur. Ca veut donc dire faire plein d'autres choses que de l'échantillonnage de la voix, ce qui réduit la vitesse d'échantillonnage effective.

Avec ce premier test réussi, j'ai tenté l'implémentation d'un projet existant (Long Range Arduino Based Walkie Talkie using nRF24L01 [EN]) visant à transmettre de la voix sur du 2.4 GHz, mais sans succès. Comme je m'y attendais, l'arduino voit sa vitesse d'échantillonnage réduite et la piètre résolution du convertisseur analogique/numérique n'arrange pas la qualité sonore. En cherchant un peu plus, je me rends alors compte que je ne suis pas le seul qui s'est cassé la tête sur ce type d'usage, comme le démontre le retour d'expérience de GreatScott!! sur Hacakday [EN].

Il va falloir tester autre chose.

ESP32 à la rescousse (ou pas)

Vu que pas mal de mes connaissances m'ont parlé en bien des systèmes produits par Espressif et notamment la plateforme ESP32, je me suis demandé s'il était possible que ces derniers fassent l'affaire. J'ai pu expérimenter le développement sur ESP32 avec mon projet de smartwatch programmable (la vénérable T-Watch 2020 v1 de Lilygo), et je dois avouer que ça m'a bien bluffé. Je décidais donc de donner sa chance à l'ESP32, et commandais un ESP32 NodeMCU sur Amazon pour prototyper tout ça.

Prototypage des interphones lors du live Twitch

C'est à ce moment là (donc début 2021, si vous suivez) que j'ai commencé à prototyper sur ESP32 lors de lives sur Twitch, et les premiers résultats ont été assez satisfaisants. J'ai réussi à échantillonner le son du micro et à l'envoyer sur le haut-parleur, mais la qualité était juste horrible. Ceci dit, c'était encore acceptable. C'est quand j'ai commencé à interfacer l'ESP32 à un service accessible en WiFi que les choses se sont gâtées. L'envoi du son sur le service distant fonctionnait, mais d'une part la qualité n'était pas merveilleuse du tout, mais de la donnée était perdue et il y avait un décalage énorme (entre 5 à 10 secondes) entre l'échantillonnage par l'ESP32 et la transmission via WiFi.

Alors oui, l'ESP32 ça fonctionne bien, mais il a beaucoup de mal à réaliser en même temps la conversion du signal audio en échantillons numériques et la transmission de ces derniers. Et encore, c'était sans intégrer la convesion numérique/analogique pour la restitution du son sur le haut-parleur. Bref, ça devenait mal engagé. Certes l'ESP32 NodeMCU ne coûte pas bien cher, mais il souffre de plusieurs défauts.

Le premier défaut concerne la conversion numérique/analogique (DAC): la résolution du DAC interne de l'ESP32 est de 8 bits, on ne peut donc coder que des valeurs de 0 à 256, qui constitueront autant de "paliers" dans la tension de sortie et donc une imprécision dans le signal audio restitué. Surtout que la conversion analogique/numérique (ADC) ne souffre pas de cette limitation, la résolution étant de 12 bits. La réduction de 12 bits à 8 bits altère le son de manière significative, et impacte de fait la qualité de la communication. Le second défaut concerne l'électronique du NodeMCU: l'entrée analogique est parasitée par une alimentation du circuit un peu mal fichue, et par l'absence de quelques composants permettant de filtrer l'audio entrant. C'est aussi ce qui ressort des tests qu'a effectué atomic14 dans sa vidéo youtube [EN]: le son est parasité, la qualité sonore très dégradée, et sans prendre en compte la transmission via le réseau !

Encore un fail, mais bon ça m'aura permis de bien prendre en main le dev sur ESP32.

Alors, comment faire ?

Une des solutions possibles consiste à externaliser la conversion numérique/analogique et analogique/numérique, idéalement en employant des composants permettant d'échantillonner avec une bonne résolution (12 bits dans les deux cas), et fournissant un débit suffisant pour avoir une bonne qualité audio. On pourrait aussi envisager l'emploi d'un microphone I2S (qui fournit directement des échantillons numériques), mais je n'ai pas envie de perdre le grain du microphone du téléphone original.

La solution idéale pour le prototypage consiste à utiliser une carte adaptée, en l'occurence une esp32-lyrat-mini, compatible avec le framework esp-adf d'Espressif. Ce framework est dédié au traitement audio, et cette carte compatible intègre tout ce qu'il faut pour faire la conversion analogique/numérique et numérique/analogique via des composants externes. Elle intègre aussi des filtres adaptés, histoire d'avoir une meilleure qualité sonore. En bref, c'est vraiment une board faite pour cet usage. Comme un crétin, je ne pensais pas devoir en arriver là pour réaliser ce projet, mais je pense que je ne vais pas avoir d'autre choix. J'ai passé commande, on verra dans quelques semaines ce que ça donne 😀.

ESP32-Lyrat-Mini
03
janv.
'21

Wrap-up 2020 & welcome 2021 !

Publié le 03 janvier 2021

L'année 2020 est désormais terminée, l'occasion de faire le bilan de cette année qui fut, je pense que tout le monde en conviendra, bien pourrie. Entre épidémie de COVID-19, l'école à la maison, le télétravail à plein temps, les WTFs politiques, l'annulation de (presque) tous les events sécu ou leur report en 2021, et surtout la plongée dans l'incertitude causée par le virus et la gestion de ce dernier, cela a été éprouvant. Je profite donc du passage à la nouvelle année pour faire le point sur ce qu'a été pour moi 2020, et comment j'envisage cette nouvelle année.

Confinement

2020 m'a appris dès le mois de mars plusieurs choses importantes. La première et pas des moindres, c'est que les professeurs des écoles ont bien du courage. J'ai eu mes deux affreux comme élèves chaque matinée pendant le confinement (enfin presque, ma moitié a pris le relais certaines semaines), et ce n'était pas de la tarte. J'ai du réorganiser mes journées durant les premières semaines afin de concilier école à la maison et boulot à distance, ce qui me faisait des journées bien chargées (9h - 3h). J'ai tenu le rythme pendant deux semaines, youpi.

La seconde, c'est l'importance d'avoir une pièce à part pour le télétravail. C'est priceless. Lorsque j'ai emmenagé dans ma maison actuelle, j'avais prévu une pièce dédiée pour mon bureau car j'étais déjà à cette période régulièrement en télétravail. Du coup quand on s'est retrouvé confinés, je pouvais bosser dans une pièce à part avec tout le matériel requis (écran externe, clavier, souris, connexion FTTH, fauteuil confortable), ce qui était très appréciable. J'ai de nombreux collègues et amis qui ont pété des câbles à force de bosser dans leur salon ou leur cuisine, encore plus lorsqu'ils habitent sur Paris.

La troisième et dernière, c'est qu'il est important de prendre du temps pour soi. Avec toute la famille à la maison, je n'avais plus d'instants de solitude tels ceux que j'avais régulièrement dans les transports en commun, et c'est vite devenu pesant. Difficile de trouver un moment calme pour prendre du temps pour moi, que ce soit pour des hobbies ou plus simplement être tranquille. J'ai pris l'habitude de me réserver deux ou trois heures la nuit, entre 23h et 1h ou 2h du matin, afin de vaquer à des occupations diverses et souffler. Et ça m'a permis de mieux tenir, je crois.

This is fine.

Rentrée 2020

Après un été complètement déconnecté, la reprise en septembre s'est passée relativement bien. Et chargée, aussi. Toujours en télétravail. La différence avec mars, c'est que la plupart des gens avec qui j'étais en contact pour le boulot se sont habitués aux réunions à distance, et l'activité a ainsi pu reprendre son cours. A ce moment précis, le moral n'était pas au top mais tenait le coup.

C'est à ce moment que je me suis rendu compte des dégâts du confinement. Je pensais m'en être assez bien sorti, car bon le télétravail cela fait quelques années que je pratique et j'estimais avoir un moral solide. Au final, je pense avoir fait une mini-dépression (comme pas mal de monde d'après les statistiques), et je ne m'en suis pas rendu compte de suite. Pour ne rien arranger, la structure chargée de la garde à domicile de mes loulous nous a clairement fait comprendre qu'ils n'avaient plus personne (à cause du COVID), et il a donc fallu gérer cela en parallèle.

Je me suis ainsi retrouvé plusieurs soirs devant mon ordinateur, à vouloir bosser sur des projets persos et au final terminer sur youtube à regarder des vidéos inintéressantes pendant des heures. Jusqu'à me rendre compte que je n'ai rien fait, et désespérer de ne rien avancer (alors que ce n'était pas les projets qui manquaient).

Débuts sur Twitch

Fort de ce constat, je me suis demandé si Twitch ne pourrait pas être une solution. Je connaissais Twitch de par le confinement et pour y avoir streamé une fois dans le cadre de PlopSec, et plus j'y pensais et plus cela semblait intéressant. Twitch offre une proximité, une interaction, qui me rappellaient les évènements sécu qui commençaient à me manquer. Peut-être que ce que je fais habituellement dans le cadre de mes projets persos pouvait intéresser du monde ? En ce qui me concerne, je pensais qu'avoir du monde qui me regarde avancer mes projets allait me donner un coup de pied au derrière et m'éviter de tomber dans les méandres de youtube. Aussi, avant de me lancer, j'ai sondé Twitter:

Le retour a été très positif, et c'est comme cela qu'ont débuté en septembre mes premiers lives sur Twitch, l'occasion d'avancer réellement les projets qui étaient dans les cartons. Comme les deux super-minitels qu'il me restait à terminer suite au financement participatif de OpenIt, et que je devais réaliser depuis des années, et qui sont encore attendus par deux des backers. Ce projet demandait pas mal de boulot, car il fallait refaire la carte électronique dans son intégralité pour l'adapter aux dernières évolutions des Raspberry Pi (la première version étant conçu pour un Raspberry Pi 1). Ou encore le reverse de mon Ninja Badge de la DEFCON 18 (2010), que je m'étais promis de faire depuis que je l'ai eu.

Au final, le coup de pied au derrière a été bénéfique et je suis encore étonné du nombre de personnes qui suivent mes lives techniques, et qui parfois avouent ne pas trop comprendre mais trouvent ça cool ! J'ai ainsi pu bien avancer mes projets et découvrir des streamers francophones qui font aussi des trucs super cools (coucou CabriDIY, Neodyme et iooner, Barbatronic et Yorzian a.k.a. Yves Rougy), tout en étant soutenu par de plus en plus de personnes durant les lives. C'est un peu stressant au début, mais je crois que je me suis pris au jeu et ce qui devait être à l'origine occasionnel est désormais plutôt régulier. Encore un grand merci à toutes les personnes qui sont passés durant les lives, qui suivent plus ou moins de près mes projets et celles qui ont été là dès le début. C'est ultra-motivant, et sincèrement je pense que cela a rendu la fin d'année plus agréable et suportable malgré les circonstances actuelles !

Un grand merci aussi aux potos de YesWeHack qui ont tenu à me fournir un PC digne de ce nom pour que je puisse streamer en toute quiétude et avec une qualité décente, ça me change des fins de live à 10 fps avec un CPU à 90% ! J'ai un peu investi afin d'améliorer l'image durant les lives, en particulier pour tout ce qui concerne l'électronique et le DIY en général. On verra si ça fonctionne assez rapidement, je pense.

Quoi de neuf pour 2021 ?

Maintenant que 2020 est désormais derrière nous, il est temps de se concentrer sur 2021 et les projets sur lesquels je compte avancer (faudra quand même prioriser avant):

  • Les deux super-minitels à terminer ;
  • La hackwatch, a.k.a la transformation d'une smartwatch en outil de hack portable pour WiFi et Bluetooth Low Energy ;
  • Un hack de vieux téléphones à cadrans rotatifs pour en faire des interphones sans-fil pour la maison ;
  • Mon avion RC conçu maison et imprimé en 3D ;
  • Un panneau "ON AIR" automatisé pour la porte du bureau, histoire de pas être dérangé durant des calls ;
  • Un challenge hardware maison à destination de ceux qui veulent débuter en reverse hardware et software ;
  • Un ou plusieurs gadgets interactifs pour égayer les lives Twitch.

Voilà les différentes idées que j'ai eu pour cette nouvelle année, et c'est sans parler des mini-projets de reverse hardware qui seront faits en live, des replays de talks précédents ou encore d'autres idées qui pourraient survenir durant l'année. D'ailleurs, si vous en avez n'hésitez pas à m'en faire part sur Twitter ou lors d'un live Twitch ! Mon objectif principal consiste à boucler au plus vite les super-minitels pour les envoyer à leurs destinataires, histoire de combler la dette que j'ai auprès des backers du financement participatif, et ensuite de m'éclater à faire ces projets en live avec les wins et les fails habituels !

Enfin, j'aimerais pouvoir refaire des talks lors de conférences mais pour l'instant je n'ai aucune visibilité sur l'organisation de ces dernières. Les conférences en ligne c'est bien, mais il manque sincèrement l'interaction avec le public, ce qui fait que c'est beaucoup moins drôle à faire. On verra en fonction des idées de talks et de l'évolution de la situation globale. Mais je n'attends qu'une seule chose, pouvoir remonter sur une scène lors d'une conférence et partager mes hacks/tools/whatever avec plein de gens (et partager/échanger autour d'une bière ou d'un coca lors d'un event). Et j'espère que cela pourra se faire en 2021.

Pour finir

Bonne année à tous, j'espère qu'elle sera bien mieux que l'année 2020 ! Hackez plein de trucs, bidouillez dans la joie et la bonne humeur 😄. Pensez à prendre le temps de prendre soin de vous, de chérir les personnes qui vous sont proches, de profiter de la vie. Si 2020 nous a enseigné au moins une chose, c'est bien cela.

09
déc.
'20

Attaquer du ZigBee pour moins de 10€ ? Yes we can !

Publié le 09 décembre 2020

to (Killer)bee or not to (Killer)bee

Je me suis récemment attaqué à la rétro-ingénierie du Ninja Badge de la DEFCON 18, et il se trouve que ce badge communique avec d'autres badges similaires via la couche MAC du protocole ZigBee (IEEE 802.15.4). Disposant d'un HackRF One, j'ai réussi à décoder les messages envoyés à l'aide de Gnuradio Companion, mais il m'était très difficile de coder un outil permettant de faire de l'envoi et de la réception en simultané, le HackRF One n'étant pas full-duplex. Il m'a donc fallu trouver un plan B.

Quand il s'agit de recevoir et de transmettre des paquets ZigBee, le framework Killerbee sauve pas mal la vie. Ce framework écrit en Python s'interface avec des équipements adaptés, et est en mesure de sniffer et injecter des paquets ZigBee. Enfin, quand on l'utilise avec des équipements qui le permettent. En effet, le seul device abordable qui était compatible avec ce framework est le RZ Raven d'ATMEL, dont la production a été arrêtée et qui est actuellement introuvable. Les équipements restants sont plus coûteux, comme l'ApiMote d'Attify (150$), le TelosB Mote, ou encore des cartes Silicon Labs compatibles (~300€). Par ailleurs, il existe bien un second équipement pas cher, une clé USB à base de TI CC2531, mais cette dernière ne supporte que le sniffing, ce qui ne me suffisait pas.

Une clé TI CC2531

J'ai donc commandé une de ces clés USB à base de TI CC2531, et j'ai réussi à capturer des paquets ZigBee et à débuter l'analyse du protocole de communication du badge. Cependant, impossible d'envoyer de manière fiable des paquets, et donc d'interagir avec ce dernier. Je commençais sérieusement à douter du framework, et songeais à trouver une solution alternative. Il était clair à ce moment que personne n'avait implémenté le support de l'injection de paquet pour cette clé USB, malgré plusieurs demandes faites via des issues sur leur repository Github. La réponse apportée ? "Do it yourself", si je résume le propos. Eh bien faisons ça alors.

Création d'un firmware pour le TI CC2531

Ayant déjà développé sur des puces gérant des communications radio dans le cadre de mes recherches sur le protocole Bluetooth Low Energy, développer un firmware spécifique pour la puce TI CC2531 ne me faisait pas tellement peur. Par contre, si je pouvais éviter d'y passer trois semaines, ça m'arrangerait passablement. J'ai donc commencé à scruter le web à la recherche de kits de développement permettant de développer pour cette puce, avec potentiellement le support de la couche radio déjà disponible. Je suis assez rapidement tombé sur le code de Contiki, un micro-système d'exploitation qui supporte notamment la puce en question. Et pour lequel la couche radio est déjà implémentée, yippie !

Je me suis donc lancé dans le développement de ce firmware, en ajoutant une couche de communication par port série (exposé via la connectique USB) afin de piloter la puce à partir d'un ordinateur qui communique avec le code gérant la radio. La structure de Contiki, qui propose un semblant de processus, permet d'implémenter cela de manière très simple. Le premier test a pu être rapidement effectué, et s'est montré très concluant: j'arrivais à sniffer et transmettre des paquets ZigBee, autrement dit j'avais une bonne base de travail. J'ai bouclé le développement du firmware en moins d'une semaine, et mis le code à disposition (ainsi qu'une release pré-compilée) sur mon repository Github associé.

Ajout d'un driver à Killerbee

Développer un firmware c'est bien, mais faire en sorte que Killerbee puisse communiquer avec est encore mieux. En parallèle, j'ai donc implémenté un driver spécifique dans le framework Killerbee, capable de communiquer avec le firmware en question et qui supporte ainsi le sniffing et l'injection de paquets. Ce développement a été effectué sur la branche py3 du projet, qui n'est pas encore la version 3.0 officielle de Killerbee mais qui devrait l'être une fois que le portage sur Python 3.0 sera terminé, grâce à la réactivité de RiverLoopSec qui a poussé des modifications en attente quand je les ai sollicité sur Twitter (encore merci à eux !).

Ce driver est ainsi capable de sniffer des paquets ZigBee, avec pour seule limitation que ces paquets doivent avoir un FCS (une somme de contrôle) valide (il est possible d'ajouter le support des paquets invalides, mais je ne l'ai pas encore fait). Il est par ailleurs capable d'envoyer des paquets, là encore sans possibilité de contrôler le FCS. Mais c'est bien suffisant pour ce que j'ai à faire sur ce matériel. Il a d'ailleurs fallu trouver un petit nom à ce firmware, et celui proposé par tartofraise lors d'un live Twitch a été retenu: Bumblebee.

Le code du driver est intégré dans mon fork de Killerbee, disponible en suivant ce lien.

Comment installer et utiliser Bumblebee ?

Le code source et une version pré-compilée du firmware ont été rendus publics sur mon dépôt Github associé, qui détaille par ailleurs plusieurs méthodes permettant d'installer ce dernier sur une clé TI CC2531. Basiquement, il vous faudra un programmateur CC-Debugger, ou un Raspberry Pi voire un Arduino. Une fois le firmware installé sur la clé, cette dernière est prête à l'emploi.

Sur l'ordinateur, installer killerbee à l'aide de l'outillage Python:

$ git clone --branch py3 https://github.com/virtualabs/killerbee.git
$ cd killerbee
$ python3 setup.py sdist
$ sudo pip3 install dist/killerbee-2.7.1.tgz

Killerbee est installé et prêt à l'emploi, y compris le support de Bumblebee. Vous pouvez désormais utiliser tous les outils classiques de Killerbee avec cette clé USB !

Si vous trouvez des bugs, ou souhaitez des améliorations, n'hésitez pas à soumettre des issues ou des feature requests, et pourquoi pas des pull requests !



Les contenus disponibles sur ce blog sont publiés sous licence Creative Commons BY-NC-SA.
Vous pouvez réutiliser tout ou partie de ces contenus à condition de citer l'auteur et l'origine, vous ne pouvez en faire une utilisation commerciale, et enfin vous devez partager tout travail ou œuvre dérivée sous les mêmes conditions — c'est-à-dire avec la même licence d'utilisation Creative Commons.