L’analyse de la prise a révélé trois vulnérabilités : un accès sans authentification en lecture et écriture aux données via le réseau, un accès à ces mêmes informations via un port de debug (UART) accessible et un protocole d’échange de clef faillible qui envoie la clef en clair à toutes les personnes à portée et hors du réseau wifi.
Contexte
Lors de courses au magasin de bricolage du coin avec le président de l’entreprise pour acheter de nouveaux cadenas à crocheter, nous sommes tombés par hasard sur un bac de « prises intelligentes wifi cyber-digitales 3.0 ».
Bien évidemment, les promesses du produit donnent envie de s’y intéresser sérieusement : « Technologie smart******* », « Cryptage de haut niveau », aucune mention de méthodes de configuration en dehors de la phrase « Lancez l’application smartphone, appairez la prise et ça marche. »
Nous avons donc acheté une paire de ces jolies boîtes à LED dans le but d’en analyser le contenu une fois rentré au bureau, et en particulier percer le mystère de ce fameux « smart-appairage magique ».
Analyse du protocole d’appairage
L’appairage de la prise avec un point d’accès wifi est réalisé via une application Android disponible sur le Google Play Store.
Pour l’utiliser, il faut commencer par brancher la prise, lancer l’application depuis un téléphone présent sur le réseau wifi à associer et renseigner la clef partagée utilisée.
La prise ne mentionne aucune technologie tierce (bluetooth, wps, etc.) pour obtenir les informations de connexion du téléphone. La première étape consiste donc à identifier le canal utilisé pour faire communiquer le téléphone connecté en wifi et un appareil hors réseau, ne pouvant pas déchiffrer les communications.
L’écoute passive (déchiffrée avec la clef de session récupérée lors de la négociation « 4 way handshake ») des communications entre le téléphone et le point d’accès wifi révèle l’envoi de nombreux paquets sur le réseau lors de la demande d’appairage.
Les trames réseau sont alors de deux types :
- Des paquets constitués exclusivement de répétitions de l’octet 0x05, envoyés en broadcast ;
- Des paquets constitués exclusivement du caractère « 0 », envoyés sur des adresses IP aléatoires.
Ce point de vue ne reflète pas celui de la prise. En effet, l’appareil ne peut pas lire le contenu des paquets car ceux-ci sont chiffrés par une clef à laquelle la prise n’a pas accès.
On peut alors en déduire que les paquets chiffrés sont suffisants pour transmettre les informations nécessaires à l’établissement d’une connexion entre le point d’accès et l’appareil.
Les deux informations disponibles d’un point de vue externe sont donc :
- La taille des paquets chiffrés ;
- Si le paquet est en broadcast.
Les messages envoyés vers des adresses IP aléatoires sont toujours identiques, contrairement aux messages en broadcast qui suivent un schéma précis :
- Une série de paquets de 120 octets ;
- Une série de paquets de tailles variables ;
- Une série de paquets de 133 octets.
La totalité de cette séquence est répétée cinq fois de suite.
Par observation et tests successifs, il a été observé que la seconde étape, constituée de messages de taille variable, ne change que lors de l’appairage avec une clef partagée différente.
A cette étape, on peut donc en déduire que la clef est encodée sur cette partie du message.
L’observation des changements de taille permet d’observer un décalage identique à celui des valeurs ASCII des caractères de la clef utilisée.
En regroupant ces valeurs, on observe que la taille des paquets est calculée avec la formule suivante :
Taille du paquet chiffré = valeur ASCII du caractère + 120
La constante de 120 utilisée correspond à la taille des paquets initiaux, envoyés en préambule avant la charge utile. Cette valeur correspond donc à une clef de décalage.
Le protocole de transmission de clef est donc basé sur une transmission en clair des données, avec un décalage de 120 et du bruit aléatoire via l’envoi de paquets unicast.
Connaissant ce fonctionnement, une preuve de concept a pu être développée (Python/Scapy).
Cet outil met en écoute l’interface wifi et détecte un appairage. Si celui-ci est bien présent, la clef transmise est écoutée, puis décodée :
Encore une preuve que le chiffrement de César est une bonne idée.
Découverte et analyse d’un accès dérobé
L’ouverture de la prise permet d’identifier rapidement le chipset wifi utilisé :
Cette puce permet la communication sur un réseau wifi, de monter un point d’accès et d’héberger un serveur HTTP de configuration (désactivé sur ce produit).
La documentation et les outils de configuration fournis par le constructeur mentionnent l’utilisation du port UDP 48899 pour des actions de configuration.
Les premiers tests de communication sur ce canal n’ont pas abouti et le périphérique n’a pas envoyé de réponse aux sollicitations.
Parmi les outils proposés par le constructeur, une application Android de débug permet de communiquer directement via des commandes AT vers un appareil situé sur le même réseau que le téléphone.
La décompilation de l’application via les outils apktools et dex2jar a alors révélé l’utilisation d’un paquet « magique » ouvrant le mode debug (constante CMD_SCAN_MODULES).
Cette valeur est définie dans les constantes de l’application avec une valeur en dur :
L’envoi de cette commande, suivie des commandes d’ouverture de session « +++a » et de la commande AT pour afficher l’aide (informations issues de la documentation technique du chipset) a permis de lister l’ensemble des commandes accessibles.
Une personne présente sur le réseau via un accès limité peut donc réaliser sans authentification tout un ensemble de commandes dont :
- Afficher/Modifier la clef partagée du réseau wifi ;
- Afficher/Modifier l’identifiant et le mot de passe de l’interface d’administration ;
- Lancer une mise à jour du firmware depuis une adresse arbitrairement choisie ;
- Passer la prise en mode point d’accès wifi ;
- Activer l’association via WPS et lancer un appairage (fonction non utilisée par la prise).
Pourquoi s’embêter avec une authentification ?
Identification de la fuite d’information via UART
La documentation mentionnant la présence de ports de debug UART sur la puce, il est possible pour un attaquant ayant récupéré l’appareil d’obtenir les informations concernant le dernier point d’accès utilisé.
Ces données sont enregistrées dans la mémoire de la puce sans contrôle d’accès et aucune option ne permet à un utilisateur légitime de l’effacer.
Proposition de correctif
Une fois ces 3 faiblesses identifiées, il a semblé amusant de proposer un correctif pour au moins l’une d’elles.
L’étape précédente ayant révélé la présence de commandes liées au mécanisme WPS, il est possible de s’affranchir du protocole de transfert de clef. Le choix s’est donc porté sur la création d’un petit boîtier muni d’un bouton poussoir pour déclencher un appairage.
Schéma de la solution (dans les grandes lignes).
Dans un premier temps, un connecteur a été ajouté en façade de la prise. Le correctif se contente d’envoyer une série de commandes UART sans tenir compte des retours. Une simple broche 4 pins suffit donc pour transporter les données (Rx, Tx, Vcc, GND).
Ajout d’un connecteur, bigrement bien intégré à l’existant !
La seconde étape a été de développer un petit programme Arduino envoyant la bonne séquence de commandes :
- +++ // Initialise la communication ;
- a // Passe en mode commandes ;
- AT+WPSBTNEN=on // Active le WPS (off par défaut) ;
- AT+WPS // Lance une demande d’appairage WPS.
Le code final (commenté) ressemble donc à :
Dispositif de patch :
Le test d’appairage WPS a été réalisé avec un routeur classique TP-LINK :
Le module externe permet bien d’ajouter une prise wifi via le WPS, la fuite d’informations via le broadcast de la PSK est corrigée !
Conclusion
L’analyse de la prise a révélé au final trois faiblesses de conception :
- Un protocole d’échange de clef, mis en avant par une communication commerciale comme étant « sécurisé et pratique pour l’utilisateur final ». Malheureusement, celui-ci repose sur un simple décalage de clef (valeur ascii + 120) broadcasté hors du réseau ;
- Un accès sans authentification reposant sur un backdoor chaine magique permettant l’accès en lecture et en écriture à l’ensemble des informations du périphérique ;
- Un port UART accessible permettant de récupérer l’ensemble des données de la puce. Ce point est problématique dans le scénario où un utilisateur se débarrasse de la prise et que celle-ci est récupérée par une personne aux intentions peu louables.
Ces travaux portent principalement sur le chipset wifi, qui concentre à lui seul les trois vulnérabilités identifiées. Ce composant, ici déployé dans une solution de domotique simple, est malheureusement aussi présent d’après le fabricant dans de nombreux produits médicaux et industriels.
L’entreprise n’ayant répondu à aucune sollicitation, le nom du produit et de l’entreprise ne peut être révélé.
Ces problématiques sont d’autant plus regrettables que les commandes permettant la correction de certains éléments sont présentes par défaut dans le matériel utilisé.