- En rétro-ingénierie pour intégrer à Home Assistant des guirlandes LED Bluetooth LE bon marché, le test de valeurs d’effets cachées sur une guirlande LED adressable de 10 m a rendu le contrôleur inutilisable
- Avec Bluetooth HCI snoop sur Android et Wireshark/tshark, les paquets BLE écrits par l’app sur les lumières ont été capturés, puis les octets de contrôle ont été suivis dans les requêtes d’écriture
btatt.opcode.method==0x12 - Les paquets de l’app iDeal LED ne ressemblaient pas à de simples valeurs on/off ; après décompilation de l’APK et consultation d’une analyse existante, ils ont été déchiffrés avec une clé AES fixe présente dans
libAES.so - Les paquets on/off déchiffrés se résumaient à un en-tête fixe et à une différence
1/0dans le 5e octet ; les motifs d’octets ont ensuite été relevés en exécutant à répétition les fonctions couleur, luminosité et effets - En envoyant pour le RGB des valeurs sur 8 bits au-delà de la plage 5 bits
0x1Futilisée par l’app, des couleurs plus lumineuses étaient possibles, mais l’envoi de l’effet numéro 12 a éteint la guirlande et fait disparaître la publicité Bluetooth
Point de départ : intégrer des lumières BLE bon marché à la domotique
- En partant du principe que les appareils communiquant en Bluetooth LE et disposant d’une app dédiée peuvent être intégrés à un système domotique, plusieurs rubans LED bon marché ont été rétro-ingéniérés
- Auparavant, un ruban LED 5 m non adressable contrôlé en Bluetooth LE à 2,38 £ avait été connecté à Home Assistant en quelques heures, et le code correspondant a été publié dans bj_led
- Un travail de rétro-ingénierie BLE du contrôleur LEDnetWF existe aussi dans lednetwf_ble
- La cible cette fois était une guirlande LED adressable de 10 m posée sur le bureau, contrôlée par l’app “iDeal LED”
- L’app propose beaucoup de fonctions et fonctionne relativement bien
- Les LED sont probablement des WS2812 ou un produit similaire
- Le produit est une guirlande achetée sur AliExpress
Capturer les octets BLE envoyés par l’app
- Pour contrôler l’appareil avec son propre logiciel, il faut d’abord identifier la suite d’octets envoyée à l’appareil par Bluetooth
- Un protocole d’éclairage typique peut être composé d’un en-tête, d’un octet de commande comme on/off ou changement de couleur, et d’un pied de paquet pouvant être une somme de contrôle
- Sur Android, la capture se fait dans l’ordre suivant
- Activer le mode développeur
- Installer l’app des lumières
- Activer
Bluetooth HCI snoopdans les options développeur - Effectuer des actions dans l’app, comme allumer et éteindre les lumières
- Copier le journal sur l’ordinateur avec
adb pull sdcard/btsnoop_hci.log .
- En ouvrant le journal dans Wireshark, on peut voir les octets transmis aux lumières
- Exemple de filtre :
bluetooth.dst == ff:ff:ff:ff:ff:ff && btatt.opcode.method==0x12 - L’adresse MAC doit être remplacée par celle des lumières réelles
btatt.opcode.method==0x12signifie qu’une opération d’écriture a eu lieu depuis l’appareil Android vers les lumières
- Exemple de filtre :
- Avec tshark, on peut extraire directement les valeurs des paquets dans le terminal
tshark -r <filename> -T fields -e btatt.valueaffiche la charge utile écrite sur le contrôleur LED
Le protocole iDeal LED ne se contentait pas d’un simple replay
- Certaines lumières présentent, pour les actions on/off, un motif quasiment lisible tel quel
- Par exemple,
69 96 02 01 01et69 96 02 01 00se répètent - Le dernier octet alterne entre
1et0pour indiquer l’allumage ou l’extinction
- Par exemple,
- Cette guirlande iDeal LED répétait des suites d’octets beaucoup plus longues ; les deux types de paquets correspondant à on/off étaient distinguables, mais les valeurs ressemblaient à du bruit
- S’il s’agit seulement d’allumer et d’éteindre, un replay consistant à retransmettre tel quel la suite d’octets capturée peut suffire
gatttoolpermet de se connecter à un appareil BLE et d’envoyer des octets- Le handle à utiliser doit être identifié dans Wireshark
- Pour obtenir davantage de contrôle, il fallait comprendre la structure des paquets ; l’étape suivante a donc été l’analyse de l’app Android elle-même
Décompiler l’APK et trouver la clé AES
- L’APK a été téléchargé puis ouvert avec jadx pour examiner le code de l’app
- Des références à AES apparaissant dans les sources, il devenait possible que le protocole soit chiffré
- Les hypothèses suivantes ont été posées à propos des données chiffrées
- Le texte chiffré d’une même action ne changeant pas à chaque fois, il pouvait exister une clé cohérente
- Comme le déchiffrement doit être rapide sur un MCU basse consommation, une clé courte est avantageuse
- La clé pouvait ne pas être propre à chaque appareil et être fixe
- L’app contenait une bibliothèque AES compilée nommée
libAES.so, impossible à analyser avecjadxseul - Une analyse d’une autre personne, qui avait décompilé la bibliothèque AES avec
ida freeet trouvé la clé intégrée, a été trouvée ; cette clé a été testée - Le déchiffrement en mode AES ECB avec
Crypto.Ciphera transformé les paquets on/off en une forme porteuse de sens- Les valeurs déchiffrées apparaissaient sous la forme
05 54 55 52 4E 01 ...et05 54 55 52 4E 00 ... - Après l’en-tête fixe, le 5e octet passe à
1ou0pour indiquer on/off - Le reste est rempli de zéros
- Les valeurs déchiffrées apparaissaient sous la forme
- À partir de cette étape, il est devenu possible de déchiffrer les paquets envoyés par l’app et de reproduire les mêmes commandes dans son propre code
Relever les motifs d’octets par fonctionnalité
- La portée du protocole a été élargie en exécutant une par une toutes les fonctions de l’app et en enregistrant les octets transmis
- Chaque action a été répétée plusieurs fois, et des séquences extinction/allumage ont été insérées pour délimiter les sections
- La couleur a été changée plusieurs fois dans l’ordre red, green, blue
- La luminosité a été modifiée selon 100 %, 50 %, 10 %, 50 %, 100 %
- Des off/on ont été ajoutés entre chaque groupe pour faciliter le repérage des limites dans les journaux de capture
- Cette méthode permet d’identifier quels octets changent selon l’action, puis de faire correspondre les actions enregistrées aux paquets capturés
L’effet numéro 12 qui a briqué le contrôleur
- En étudiant le changement de couleur, il a été constaté que l’app n’envoyait pas de valeurs supérieures à
0x1Fpour red, green et blue0x1Fcorrespond à une plage sur 5 bits- En envoyant directement des valeurs sur 8 bits, des couleurs plus lumineuses fonctionnaient
- Pour vérifier s’il existait des effets supplémentaires en plus des 10 effets utilisés par l’app, une boucle
range(20)a envoyé les numéros d’effet dans l’ordre- De 1 à 10, tout s’est déroulé normalement
- À 11, un comportement ressemblant à un mode caché est apparu
- Au passage à 12, les lumières se sont éteintes
- Ensuite, les lumières ne se sont plus rallumées
- Elles n’émettaient plus de publicité Bluetooth
- La connexion ne fonctionnait plus non plus
- Maintenir le bouton enfoncé à la mise sous tension ne les a pas restaurées
- Les laisser débranchées toute la nuit n’a rien changé
- L’hypothèse d’une corruption du firmware par dépassement de tampon a été envisagée, mais la cause n’a pas été confirmée
- Les LED elles-mêmes étant des LED adressables standard, la guirlande peut être réutilisée en la connectant à un autre microcontrôleur
Résultats restants et avertissement
- Malgré l’échec, la majeure partie du protocole a été documentée, et un projet GitHub incluant un composant personnalisé Home Assistant a été créé
- Le composant fonctionne, mais des expérimentations du même type peuvent endommager le contrôleur des lumières ; elles sont donc à mener à vos propres risques
1 commentaires
Commentaires de Hacker News
Plutôt qu’un « en-tête fixe » de FTA, cela ressemble à un octet de longueur (« la commande fait 5 octets »), avec la commande
TURN, l’argument 0/1, puis un remplissage par des zéros jusqu’à 16 octets54 55 52 4Esaute immédiatement aux yeux comme les lettres majusculesTURNQuand on sait que les chiffres commencent à
0x30, les majuscules à0x41et les minuscules à0x61, il devient facile de repérer des motifs alphanumériques dans un dump hexadécimalCe genre de connaissance est utile pour les chaînes courtes, mais quand on regarde des paquets ou des dumps mémoire, le format hexdump standard reste le meilleur choix
0x54 55 52 4Ecorrespond bien àT U R NuintCela pourrait être un problème d’alimentation. La famille WS281x peut s’allumer très fort, et quand on en regroupe beaucoup, elle consomme énormément de courant
Avec une alimentation 12 V 3 A pour un ruban de 100 LED, on peut à peine tout allumer en blanc à luminosité maximale, et c’est très éblouissant
Je regarderais donc d’abord du côté d’un fusible grillé. Le fait que le firmware n’utilise que 31 sur une luminosité maximale de 255 est aussi un indice
0x1f, j’ai aussi pensé à ça au début. Avec un peu de chance, l’alimentation a un fusible et seul celui-ci a sautéMême si ce n’est pas récupérable, une guirlande de LED WS281x standard peut être connectée à un Raspberry Pi, et mon contrôleur open source pour LED adressables peut aussi être utilisé :) https://github.com/mbevand/ledthemfight
Il propose des effets intégrés et a été conçu de façon très modulaire pour le DIY, si bien qu’avec deux lignes de Python on peut créer un module d’effet LED personnalisé simple. Démo ici : https://youtu.be/qpd2rILsnM4
12V, rouge, vert et bleuÇa ressemble à un ruban RGB analogique où tout le ruban s’allume de la même couleur, pas à des LED adressables individuellement
https://www.aliexpress.com/item/1005005485885067.html
Toute personne qui veut bricoler des éclairages LED devrait absolument regarder WLED. Il y a beaucoup d’effets intégrés, une interface web, ça utilise des ESP32 ou ESP8266 très bon marché comme contrôleurs, et ça peut aussi réagir au son. Je fais tourner WLED sur mes guirlandes de Noël d’intérieur en ce moment, et le rendu est excellent
C’est une façon élégante de limiter la consommation électrique
Bon article. Ça me rappelle la fois où j’ai essayé de rétroconcevoir mes éclairages et où j’ai découvert qu’ils étaient chiffrés
L’un était un amaran 60d et les autres quelques panneaux LED sur batterie SmallRig RM75 ; je voulais pouvoir tous les allumer et les éteindre avec un seul script, sans manipuler deux applis séparées
J’ai passé pas mal de temps à rétroconcevoir les applis et le protocole, et les deux lampes semblaient utiliser la même procédure de négociation, mais implémentée avec des bibliothèques différentes
J’ai essayé d’imiter l’échange de clés Diffie-Hellman effectué à la connexion, mais j’ai fini par abandonner. De mémoire, il y avait ensuite une ou deux étapes supplémentaires, et après l’envoi de la première clé, il envoyait encore un nombre qui ressemblait à de l’aléatoire (une autre clé ?), sans que je parvienne à comprendre ce qu’il attendait
En lisant cet article, je me dis que je devrais simplement essayer de mettre une clé codée en dur et voir si ça fonctionne
Une intégration open source pour Elgato Stream Deck ou Home Assistant serait un très beau cas d’usage. Pour les YouTubeurs qui tournent des vidéos face caméra à leur bureau, ce serait bien mieux que de contrôler les lumières avec une appli mobile
J’ai transformé des guirlandes de Noël connectées en BLE en déchet électronique en essayant de les automatiser. Vous aussi, vous pouvez le faire
Je ne sais pas pour l’iPhone, mais sur Android, en la laissant en arrière-plan, on peut capturer l’activité BLE dans une interface propre sur le téléphone. Je m’en sers tous les jours
Ça me rappelle ces MCU de clavier qui se retrouvaient briqués lorsqu’ils recevaient certaines commandes d’éclairage
OpenRGB a fini par devoir désactiver ce module sur le matériel concerné pour éviter qu’il ne s’exécute automatiquement. Parfois, le logiciel du constructeur déclenchait aussi le même bug
Malheureusement, il fallait généralement envoyer un rapport USB HID pour entrer en mode de programmation in-system, mais les appareils touchés ne s’énuméraient même plus
Reste à savoir s’il s’agissait réellement d’une corruption du firmware, ou si le matériel était endommagé à cause d’un autre comportement indéfini
« Envoyer du texte en clair par radio, ce n’est pas sécurisé »
« T’inquiète, on a ajouté du chiffrement AES »
C’est dû au mode d’appairage. L’appli diffuse des paquets à l’aveugle vers
255.255.255.255, et l’appareil cible (ampoule, prise, etc.) attend en mode promiscuousLe contenu des paquets est protégé par WPA2 ou équivalent, mais pas leur longueur ; l’appli envoie donc une énorme quantité de tout petits paquets dont la longueur est fixée à la valeur de l’octet ASCII du caractère suivant du handshake de configuration. Elle les envoie probablement plusieurs fois
C’est pourquoi l’appairage prend 2 minutes, puis s’arrête toujours soudainement avant que le compteur n’atteigne 0
C’est ce qui m’avait vraiment inquiété l’an dernier quand je faisais de la rétro-ingénierie sur le contrôleur BLE de ma cheminée
En particulier, la commande « Set password » accepte des octets bruts en entrée, alors que l’app OEM n’envoyait que des données numériques à longueur limitée
Heureusement, il semblait tout oublier dès qu’il y avait une brève coupure d’alimentation
Du coup, la plupart des contrôleurs BLE de la même marque semblent être restés avec le mot de passe par défaut
0000. À la moindre panne de courant, ils finissent par revenir à cet état. Si vous vous ennuyez vraiment, ça ferait un assez bon sujet de wardriving BLEJ’ai aussi transformé mes résultats de rétro-ingénierie en intégration Home Assistant (https://github.com/kaechele/napoleon-efire), et rédigé la documentation du système et du protocole (https://bonaparte.readthedocs.io/en/latest/index.html)
Je cherche des guirlandes lumineuses souples et robustes à installer sur la galerie de toit d’une voiture
Il faudrait qu’elles soient sur batterie et adaptées à l’extérieur/tous temps, et idéalement que le boîtier de batterie puisse se fixer facilement à une surface avec des colliers de serrage
Si possible, j’aimerais un format
T5« mini », avec du RGB programmable, pour pouvoir faire rouge/vert à Noël, violet/orange à Halloween, etc. selon les saisonsJe me demande si quelqu’un connaît un produit qui corresponde à ces critères. Les trois premiers se trouvent chez Walmart ou Home Depot, mais j’ai eu du mal à trouver quelque chose qui satisfasse le dernier
Les recherches ne renvoient qu’un tas de bruit
[1] https://cdn.christmaslightsetc.com/images/CategoryDetail/788...
Par exemple, on trouve facilement des rubans LED 12 V étanches IP67 (dans un tube en silicone) [0], et comme ils ont beaucoup plus de LED que des guirlandes de type éclairage de Noël, l’effet sera aussi plus marqué
En revanche, il faudra acheter et programmer un microcontrôleur du genre Arduino, ESP32 ou ESP8266, et trouver toi-même comment tirer l’alimentation depuis la batterie de la voiture [1]
Tu pourrais aussi mettre l’électronique dans la voiture et ne faire sortir que les fils par le coffre, en comptant sur le joint existant du coffre pour l’étanchéité
[0] https://www.aliexpress.com/item/1005004289391906.html
[1] https://www.aliexpress.com/item/1005005977505151.html
Il est aussi facile de les ressouder avec des rallonges ou de les chaîner
https://www.aliexpress.com/item/4000105913323.html
D’après ce que j’ai lu, ce type de produit, ou des éclairages 5 V similaires, semble être quasiment standard pour les spectacles de lumières de Noël en extérieur
#projectset#showcase. Il y a beaucoup de projets d’installation d’éclairage LED RGB sur des véhiculesAttention toutefois, on peut facilement se laisser aspirer par ce domaine
Lien d’invitation : https://discord.gg/eVhhh2Wh
Est-ce qu’on pourrait voir les guirlandes de Noël en panne démontées ?
Savoir quelle puce il y a à l’intérieur pourrait donner des indices sur la présence éventuelle de mémoire flash et sur la facilité à la dumper