Dans la précedente partie, nous avons vu le fonctionnement du protocole LoRaWAN, le format des paquets et les mécanismes de sécurité.
Les versions 1.0.3 et antérieur du LoRaWAN présentent plusieurs vulnérabilités allant du déni de service au déchiffrement des données en passant par l’usurpation. Ces failles reposent principalement sur la gestion de persistance des sessions et un manque de contextualisation des paquets entre eux.

Débordement et réinitialisation des compteurs

Les compteurs de paquets FCntUp et FCntDwn doivent êtres sur 16 bits au minimum (spécifications 1.0.3 ligne 523) :

The LoRaWAN allows the use of either 16-bits or 32-bits frame counters. […] If a 16-bits frame counter is used, the FCnt field can be used directly as the counter value, possibly extended by leading zero octets if required.

Lorsque FCnt arrive à son maximum, la prochaine valeur débordera et le compteur recommencera de 0. Ce débordement provoque la réutilisation de FCnt précédents. Dans le cas des appareils utilisant un compteur sur 16 bits, il faut tout de même 2^16 communications avant d’arriver à un débordement, ce qui peut prendre un certain temps vu l’intervalle d’émission mais est théoriquement faisable (10 ans de durée de vie sur les appareils LoRaWAN d’après Semtech).
Pour les plus pressés, un appareil ABP redémarré remet ses compteurs FCntUp et FCntDwn à 0 si la persistance de session n’est pas effective entre redémarrages, comme décrit dans les spécifications 1.0.3 ligne 512 :
After a JoinReq – JoinAccept message exchange or a reset for a personalized end device, the frame counters on the end device and the frame counters on the network server for that end device are reset to 0.

Lors d’une réinitialisation des compteurs, il est possible pour un attaquant de rejouer les paquets de la session OTAA actuelle ou de n’importe quelle session ABP précédente (car les clés de session ne changent jamais) avec un FCnt supérieur à celui de la session actuelle.
En rejouant un paquet uplink, l’attaquant bloque également toutes les communications suivantes de l’appareil qui ont un FCnt inférieur ou égal au paquet rejoué. Ce déni de service abuse de l’écart de désynchronisation autorisé par le protocole pour palier la fiabilité des transmissions: tout paquet avec un FCnt compris dans l’intervalle FCntUp + MAX_FCNT_GAP est accepté.

Déni de service par retransmission

Réétablissement de session OTAA

Lors de l’appairage, les JoinRequest et JoinAccept ne sont pas liées entre elles, un appareil n’est pas en mesure de savoir si un JoinAccept correspond à son JoinRequest. Ainsi, il est possible d’établir des sessions en rejouant un JoinRequest ou en répondant à un JoinRequest par un précédent JoinAccept.
Si une session est établie avec l’appareil à la place du serveur, alors celui-ci ne partage plus les mêmes matériaux cryptographiques que le serveur et ses communications ne sont pas traitées.

Si l’appareil conserve les nonces reçus alors les JoinAccept capturés ne seront pas acceptés car les AppNonce déjà utilisés. Dans la pratique, les spécifications indiquent devoir garder “un certain nombre” de nonces utilisés (spécifications 1.0.3 ligne 974) :
DevNonce is a random value. For each end-device, the network server keeps track of a certain number of DevNonce values used by the end-device in the past, and ignores join requests with any of these DevNonce values from that end-device.

L’attaque cible plutôt l’appareil que le serveur car celui-ci dispose de ressource limitées. Il est plus probable qu’il garde moins de AppNonce utilisés en mémoire que le serveur ne garde de DevNonce. En rejouant un JoinAccept plus rapidement que le serveur en réponse au JoinRequest, on peut s’appairer à l’appareil en place du serveur, donnant lieu à un déni de service.

Collision du DevNonce

Le DevNonce est un nombre aléatoire sur 16 bits contenu dans la JoinRequest et utilisé avec AppNonce pour dériver les clés de session. Un attaquant peut générer des DevNonce à volonté en redémarrant l’appareil, forçant un nouvel appairage OTAA donc l’envoi de JoinRequest et JoinAccept, pour épuiser les 2^16 possibilités du DevNonce. Ainsi une répétition peut apparaitre au bout de ~2^15 JoinRequest si le générateur d’aléas utilisé est fiable, auparavant sinon en se basant sur le paradoxe des anniversaires.
Comme pour le réétablissement de session OTAA, l’attaque cible l’appareil car ses contraintes inhérentes aux systèmes embarqués rendent plus probable un mauvais générateur d’aléas, le problème de source d’aléas cryptographiquement sûre dans les systèmes embarqués est d’ailleurs évoqué dans les spécifications 1.0.3 note 1 page 35 :
The DevNonce can be extracted by issuing a sequence of RSSI measurements under the assumption that the quality of randomness fulfills the criteria of true randomness

La réutilisation d’un DevNonce couplé au réétablissement d’une session OTAA en rejouant un JoinAccept permet à un attaquant de réétablir une session précédente. Puisque ce sont les mêmes clés de session qui sont dérivées, tous les paquets de cette précédente session sont valides et peuvent être rejouées (en considérant un FCnt incrémental).
De plus, ces mêmes clés de session sont utilisées pour chiffrer le FRMPayload de la session actuelle. Cela permet de tenter le déchiffrement des paquets puisque la sécurité d’AES CTR n’est pas garantie lors de la réutilisation des paramètres de chiffrement.

Déni sélectif de paquet

L’accusé de réception est un paquet standard (uplink ou downlink) avec le champ ACK à 1. Il n’indique pas quel message il confirme et son MIC n’intègre pas de valeurs supplémentaires que les autres paquets.
En interceptant un accusé de réception downlink (champ ACK à 1) et impêchant sa transmission à l’appareil émetteur du uplink confirmed jusqu’à ce qu’il considère le paquet perdu, un attaquant se retrouve en possession d’un downlink avec accusé de réception valide mais inconnu de l’appareil. Il peut l’utiliser pour accuser réception n’importe quel uplink confirmed en place du serveur pour dénier le service.
L’attaque est plus simple à mettre en place lorsqu’en position de Man In The Middle entre la passerelle et le serveur, sinon possibilité de brouillage sélectif du LoRa au niveau de la passerelle.


Les messages ACK peuvent être réutilisés pour accuser réception de paquets autres que celles destinées originellement

Brute force des clés cryptographiques

Certains constructeurs livrent leurs capteurs LoRaWAN avec des clés par défaut, comme on retrouve des mots de passe par défaut sur nombre d’appareils. On parle ici de la clé racine AppKey pour les appareils OTAA et les clés de sessions inchangeables AppSKey et NwkSKey en ABP. Ces clés ne sont pas toujours changées par les clients du produit, ce qui entraîne une perte d’authenticité, intégrité, confidentialité et disponibilité du produit si celle-ci est retrouvée.
Même lorsque changées, ces clés ne sont pas toujours générées aléatoirement mais dérivées depuis des éléments uniques non secrets: l’identifiant unique de l’appareil (DevEUI pour OTAA ou DevAddr en ABP), son adresse MAC si carte réseau ou encore un numéro de série peuvent être utilisés comme base pour dériver une clé, certes unique par appareil, mais non totalement aléatoire.

Pour chaque paquet intercepté, il est possible de recalculer le MIC avec une clé choisie et regarder si les résultats correspondent afin de trouver la clé utilisée: toutes les valeurs utilisées pour calculer le MIC sont soient connues (dans les spécifications), soient présentes dans le paquet.
Les MIC de JoinRequest et JoinAccept permettent de retrouver AppKey en mode OTAA alors que n’importe quel paquet en mode ABP est signé par NwkSKey.

Confidentialité de AppSKey

Lors de l’établissement d’une session OTAA, c’est le serveur réseau qui dérive les clés de session depuis AppKey et transmet AppSKey au serveur applicatif. Hors le serveur réseau peut être gérer par un opérateur et non le constructeur des appareils LoRaWAN. L’opérateur a donc accès à tous les matériaux cryptographiques, notamment la clé de chiffrement des données transmises dans le FRMPayload. Il peut potentiellement espionner et même modifier les communications puisqu’en position de Man In The Middle et possession des 2 clés cryptographiques qui garantissent les propriétés de confidentialité, intégrité et authenticité.

Conclusion

Dans la version 1.0.3 et antérieur, les spécifications laissent des choix d’implémentation qui impactent directement la sécurité (taille des compteurs, persistance des sessions).
Même si FCnt empêche le rejeu arbitraire, un manque de contextualisation permet de réutiliser des paquets considérés perdus donc inconnus de l’appareil ou du serveur.

LoRaWAN continu d’évoluer et prend en considération les vulnérabilités découvertes au fil des versions. LoRa Alliance intègre des remédiations dans leurs nouvelles versions 1.1 et 1.0.4 qui seront passées en revue dans la troisième partie de cette série d’article sur le LoRaWAN.

À lire également