P27 Réseau LoRaWAN

De Wiki de Projets IMA
Révision datée du 24 février 2018 à 15:39 par Flefevre (discussion | contributions) (Planning)
(diff) ← Version précédente | Voir la version actuelle (diff) | Version suivante → (diff)

Présentation générale du projet

Contexte

Les réseaux bas débits, faible consommation et longue portée sont en plein essor pour des applications variées allant du suivi de troupeaux jusqu'aux villes intelligentes. Il est commun que certaines de ces applications manipulent des données sensibles. Il devient donc essentiel de penser à la sécurité des données échangées.

Description et objectifs

Le protocole LORA est un des protocole disponible actuellement qui permet le développement de réseaux de ce type. Dans ce projet, nous proposons alors de réaliser un réseau LoRaWAN, protocole réseau se basant sur la technologie LoRa. Au sein de cette architecture, nous retrouvons un concentrateur LoRa, qui sera déployé via une Raspberry Pi pour créer une station de base, ainsi que divers capteurs embarquant une radio LoRa qui échangeront avec la station de base. Une fois que ce réseau sera mis en place, nous évaluerons dans un second temps les possibilités d'attaque sur un tel réseau, aussi bien logicielle que radio, pour pouvoir proposer par la suite des contre-mesures à appliquer.


Noeud LoRa SX1276
Montage de la station de base
Raspberry Pi + station de base LoRa ic880A-SPI (SX1301)


Planning

Répartition des tâches
Phase Tâche Sem 1 Sem 2 Sem 3 Sem 4 Sem 5 Sem 6 Sem 7
Appropriation et mise en place des outils de développement Recherche de matériel complémentaire x
Création et implémentation du shield x
Découverte des différents protocoles et implémentations x x x
Déploiement du réseau Test du matériel et vérification du bon fonctionnement x x x
Mise en place d'une implémentation LoRaWAN x x
Administration du réseau et ajout de noeuds x x x x
Évaluation des attaques possibles Etat de l'art et lecture de la certification officielle LoRaWAN x
Attaque par rejeu x x x x
Rendu des travaux finaux Rédaction du rapport x
Préparation à la soutenance x

Tableau de bord

Semaine 1 // 08/01/18 - 12/01/18

Jour 1

  • Recherche d'un shield réalisant l'interface entre la Raspberry Pi et le module récepteur LoRa permettant de créer une station de base. Cela permettra d'éviter la conception d'un PCB pour réaliser cet interfaçage. Voici quelques liens où l'on retrouve ce type de composant :

https://www.tindie.com/products/gnz/imst-ic880a-lorawan-backplane-kit/

https://pcbs.io/share/zvoQ4

https://shop.coredump.ch/product/ic880a-lorawan-gateway-backplane/

  • Nous nous sommes rendus compte que réaliser une commande sur n'importe lequel de ces sites prendrait un temps conséquent puisque les stocks sont épuisés sur chacun de ces sites. Sur l'un d'eux, il était possible de récupérer le schematic de ce shield. J'ai donc été rencontré Thierry Flamen pour savoir si la conception du shield était possible en réutilisant ce schematic. Nous allons donc demander au service EEI de Polytech pour concevoir ce shield.
  • Recherche d'une implémentation du protocole LoRaWAN pour pouvoir la flasher sur les différents nœuds du réseau. On veillera à trouver une solution qui ne se base pas sur l'IoT The Things Network puisqu'on ne sait pour le moment pas vraiment quelle est la politique d'utilisation de ce réseau et on souhaite éviter que toutes les informations transitant sur notre réseau LoRaWAN soient accessibles par d'autres utilisateurs ou bien que certaines personnes avec de mauvaises intentions aient accès au réseau.

Jour 2

  • Installation de Raspbian et des outils nécessaires sur la Raspberry. Il faut que l'interface SPI soit activée pour que la Raspberry puisse communiquer avec notre station de base. Nous avons également écrit un script sur la Raspberry qui permet de reset notre station de base. Ce script sera appelé à chaque fois que l'on démarre notre Raspberry, pour activer la pin de reset.
  • Documentation sur le fonctionnement de l'implémentation LoRaWAN et recherche de différents programmes permettant d'implémenter ce protocole pour pouvoir les tester et déployer notre réseau.

Tutoriel pour la configuration de notre Raspberry pour le bon fonctionnement avec la station de base :

https://wireless-solutions.de/images/stories/downloads/Radio%20Modules/iC880A/iC880A-SPI_QuickStartGuide.pdf

Exemple d'une implémentation LoRaWAN pour notre station de base LoRa :

https://github.com/Lora-net/lora_gateway

Exemple d'une implémentation LoRaWAN pour nos noeuds LoRa :

https://os.mbed.com/teams/Semtech/code/LoRaWAN-demo-76/

Documentation sur l'implémentation LoRaMAC pour faire du LoRaWAN et comprendre le fonctionnement du protocole :

http://stackforce.github.io/LoRaMac-doc/index.html

http://www.ioi-labs.com/technologies/comprendre-reseau-lorawan

https://www.frugalprototype.com/technologie-lora-reseau-lorawan/

Tutoriel pour connaître le mappage des pins entre la Raspberry Pi et notre station de base et pouvoir initialiser notre module récepteur :

https://doc.info.fundp.ac.be/mediawiki/index.php/Setup_IC880A-SPI_(LoRaWAN_concentrator)_on_Raspberry_Pi_3

  • En utilisant le dépôt GIT lora_gateway donné précédemment et le programme (util_pkt_logger) permettant de récupérer les paquets reçus sur notre station, il est possible de faire fonctionner la station de base et de récupérer les paquets transitant vers cette station en stockant toutes les informations associées aux paquets dans des logs sur notre Raspberry.

Jour 3

  • On retrouve un exemple de déploiement d'un réseau LoRaWAN avec les liens suivants :

https://www.miscmag.com/lorawan-deploiement-dune-infrastructure-de-test-partie-1-2/

https://connect.ed-diamond.com/MISC/MISCHS-015/LORAWAN-deploiement-d-une-infrastructure-de-test

  • Nous voulons maintenant faire fonctionner nos noeuds pour qu'ils puissent communiquer avec la station de base. On flashera nos STM32 avec le programme trouvé sur mbed.com (LoRaWAN-demo-76) en passant par le compilateur en ligne. On récupère ainsi un fichier bin que l'on copie sur notre microcontrôleur et celui-ci peut alors faire tourner notre programme.
  • L'envoi des trames par les nodes devraient fonctionner correctement, formatées selon la spécification LoRaWAN. Cependant, du côté de la gateway, les trames reçues n'ont pas vraiment l'air d'être parsées selon cette spécification. Nous recherchons donc un autre moyen d'implémenter notre station de base. Nous avons trouvé quelques exemples qui utilisent un système de "packet forwarding" qui redirige les paquets reçus vers un serveur d'application qui traitera ces paquets, sans passer par le réseau TTN (The Things Network) :

https://blog.trifork.com/2016/05/20/collecting-data-from-a-private-lorawan-sensor-network-into-elastic/

https://github.com/Lora-net/packet_forwarder

https://github.com/gotthardp/lorawan-server

  • Les deux premiers liens nous proposent de réaliser ce procédé en redirigeant les paquets vers un serveur personnel via une API appelée Logstash plutôt que de passer par TTN. Le dernier décrit un serveur LoRaWAN qui prend entièrement en charge la redirection de paquets ainsi que le traitement de ceux-ci, ce qui nous permettrait de pouvoir traiter toutes nos données sur la Raspberry. Nous testerons cet exemple en premier lieu.

Jour 4

  • Récupération du PCB au service EEI qui est le shield permettant d'interfacer la Raspberry avec notre station de base.
  • Soudures des broches sur le PCB pour pouvoir connecter directement les pins du module LoRa à la Raspberry Pi.
  • Le shield n'alimente pas correctement notre station de base. Après plusieurs essais, nous nous sommes rendus compte que la broche d'alimentation pouvait être court-circuité ou bien pas suffisamment soudée.

Jour 5

  • Nous cherchons à faire fonctionner notre shield. Après avoir discuté avec quelques professeurs, nous avons pu comprendre que tous les vias de notre PCB n'étaient pas effectifs. En effet, les PCBs réalisés au service EEI ne sont pas métallisés, ce qui empêche les vias de pouvoir conduire le courant entre les deux faces de notre PCB, qui est bien évidemment double face. Il a donc fallu dessouder tous les connecteurs pour pouvoir faire passer de fin fils à travers les trous qui doivent faire communiquer les deux faces pour les souder directement sur les pistes. Une fois cette chose faite, nous avons pu souder à nouveau les connecteurs comme il se doit.
  • Après toutes ces manipulations concernant notre shield, celui-ci est donc fonctionnel. Nous pouvons à présent nous concentrer sur la partie logicielle du projet, à savoir déployer notre réseau LoRaWAN.


Couche supérieure du shield
Montage final avec shield
Couche inférieure du shield


Semaine 2 // 15/01/18 - 19/01/18

Jour 6

  • Nous sommes repartis sur nos recherches pour pouvoir déployer un réseau LoRaWAN. Ne comprenant pas pourquoi notre station de base ne recevait presque aucun paquet, nous sommes partis de la base pour comprendre le problème. Nous avons voulu nous assurer que les nodes LoRa fonctionnaient correctement et pour cela nous avons testé un simple programme de ping pong entre deux nodes. Cela s'est révélé être un succès :


Ping Pong entre deux émetteurs LoRa


  • Nous voulons maintenant tester si notre station de base arrive à bien recevoir des paquets. Nous savons déjà qu'elle arrive à en émettre en utilisant un programme de test du projet "lora_gateway" récupéré sur le github officiel Lora-net. Nous avons aussi ajouté une antenne à notre station de base ce qui facilitera grandement les communications radios, ce qui était sûrement la raison d'une réception partielle de paquets. Cependant cette modification ne semble pas apporter de gros changements.


Montage final du concentrateur radio sur Raspberry + antenne


  • Après des recherches complémentaires, nous avons trouvé un autre moyen de déployer un réseau LoRaWAN à notre manière sans passer par le réseau TTN (les liens se retrouvent au jour 3), en utilisant un serveur open-source que l'on configure soi-même du début à la fin :

https://www.loraserver.io/

Jour 7

  • Nous n'arrivons toujours pas à une réception convenable des paquets sur la station de base. Nous avons modifié la configuration du module pour qu'il ne réceptionne pas que des paquets LoRa avec une en-tête MAC. C'était possible que cela soit une source d'erreur cependant cela ne change pas grand chose. En regardant les retours sur le github de notre programme, nous avons pu remarqué que, comme dans notre cas, des personnes arrivent à émettre avec la station de base mais pas à recevoir. Dans la majorité des cas cela était dû à une alimentation qui ne fournissait pas une tension suffisante. Nous avons alors vérifier que nous avions du 5V aux bornes de notre station, ce qui était bien le cas.

Jour 8

  • Après avoir modifié le code du ping pong pour un node en ne faisant qu'envoyer une trame toutes les secondes qui est "COUCOU", on réceptionne bien les paquets sur notre station de base, à quelques détails près.
  • En effet, dans notre fichier de logs, on remarque que la taille de la payload est bien de taille 7, ce qui correspond à notre chaîne de caractères. On retrouve bien les mêmes paramètres de communication radio à savoir un Spread Factor de 7 et une bande passante de 250 kHz. Cependant on remarque que notre chaîne de caractères est altéré lors de la communication puisqu'on ne retrouve pas exactement la même chaîne de caractères sur la station de base. Après avoir décodé la payload via la table ASCII, on retrouve certains lettres qui sont correctes, d'autres non.
  • De plus, on remarque également sur les timestamps que l'on ne reçoit pas réellement de paquets chaque seconde. Il peut passer un certain temps sans que l'on ne reçoit de trames. La station doit sûrement rejeter certains paquets pour une raison particulière.


Réception de paquets LoRa sur la station de base
Détails des paquets reçus dans un fichier .csv



Jour 9

  • Après avoir été dans l'incompréhension durant toute une journée, nous avons enfin compris le mode de fonctionnement du concentrateur LoRa. En effet, en réutilisant le programme de ping pong basique et juste en jouant avec les paramètres du signal, nous avons réussi à récupérer correctement les trames envoyées par l'émetteur.
  • Pour cela, il était indispensable de régler les paramètres de l'émetteur pour qu'ils correspondent à l'une des channels de notre station de base, ce qui signifie une certaine fréquence radio, bande passante et un certain spread factor parfois. On a alors nos trames qui sont réceptionnées au bon moment et avec la bonne payload, à savoir le message "PING" suivi d'octets de padding. De plus, il était nécessaire de permettre au concentrateur de récupérer toutes les trames LoRa qui transitent et pas seulement celles respectant la certification LoRaWAN. Pour cela, on règle le paramètre correspondant dans la configuration du programme.
  • En réalisant ces tests, nous avons pu noter également que la modification du spread factor des signaux envoyés entraînait une modification de la puissance d'émission. En effet, au plus le spread factor est grand, au plus les trames envoyées seront facilement "captées" par le concentrateur, c'est-à-dire à une puissance plus élevée.


Envoi de trames "PING" par le noeud
Détails des paquets reçus dans un fichier .csv
















  • Maintenant que nous avons testé le bon fonctionnement de notre matériel, nous pouvons passer à l'implantation du serveur LoRaWAN sur la Raspberry Pi
  • Pour cela, nous allons utiliser un ensemble d'outils appelé ELK Stack, qui nous permet finalement de réaliser de l'analyse de logs. Plus précisément, ces outils nous permettront de récupérer les logs ou les payloads des trames reçues pour les envoyer vers un serveur applicatif et ainsi pouvoir traiter ces données. Pour cela, nous allons utiliser un de nos précédents liens (blog trifork) qui propose de découvrir ces outils et de faire une implémentation d'un serveur LoRaWAN sans passer par le réseau TTN, mais aussi le lien suivant qui est un tutoriel pour déployer l'ELK stack sur la Raspberry :

https://logz.io/blog/elk-stack-raspberry-pi/

Jour 10

  • Nous continuons sur l'implémentation de notre ELK Stack, qui pose quelques difficultés étant donné que l'on souhaite la réaliser sur une Raspberry. La manière standard de procéder ne s'applique pas vraiment aux architectures ARM comme celle de notre Raspberry. Voici d'autres liens qui nous permettent de mieux comprendre comment procéder sous Raspbian :

http://www.intranetofstuff.com/the_tools/elk-stack.html

https://thesecuritystoic.com/2017/08/home-security-iii-elk-on-a-raspberry-pi/


Semaine 3 // 22/01/18 - 26/01/18

Jour 11

  • Après avoir réglé tous les différents problèmes que nous avons pu avoir pour implanter notre ELK stack, celui-ci est désormais opérationnel. Pour rappel, cet procédé nous permet de récupérer, indexer, traiter et analyser nos logs d'une manière conviviale via une interface web, qui permet la réalisation de dashboards et d'analyser les critères que l'on souhaite pour les différentes données reçues. En plus de ce stack, nous utilisons également le service Nginx qui nous permet d'accéder à notre application web Kibana sur le navigateur directement, depuis n'importe quel autre ordinateur si l'on connaît l'adresse IP de notre Raspberry Pi. A la base, nos logs sont fournis par une implémentation TTN pour un gateway LoRaWAN, qui va récupérer les paquets LoRa reçus pour les transformer en logs, plus faciles à lire. Cependant, au lieu de passer par le réseau TTN pour faire transiter nos logs, nous passons par Logstash, un des services du ELK stack, qui permet de récupérer des logs bruts et de faire en sorte que notre stack puisse les comprendre et les interpréter (via ElasticSearch).
  • En général, ce genre d'application est utilisé pour faire du cloud sur un serveur à distance, mais nous l'utilisons ici pour faire de la récupération de données sur notre Raspberry localement. De plus, nous allons gérer une quantité limitée de données, à savoir juste les paquets reçus sur notre petit réseau LoRaWAN. Les ressources de la Pi sont donc amplement suffisantes pour notre cas de figure. Ce n'aurait pas pu être possible si nous voulions faire du traitement de données à grande échelle.
  • Nous sommes donc maintenant capable de récupérer tous les paquets LoRa transitant vers notre station de base, et d'analyser ces trames directement sur Kibana. Cependant, nous n'arrivons pour le moment pas encore à récupérer les paquets certifiés LoRaWAN. De plus, il sera nécessaire d'ajouter un plugin sur notre ELK stack pour pouvoir décrypter les trames reçues par la station de base. En effet, selon la certification LoRaWAN, les paquets sont cryptés à deux reprises avec deux clés différentes. Pour pouvoir récupérer la payload d'un paquet, il sera nécessaire de décrypter le contenu de ce paquet.


Interface web Kibana pour la visualisation des paquets LoRa reçus


  • On récupère bien notre payload envoyé par l'émetteur. Celle-ci est seulement encodée en base64 par notre implémentation de gateway TTN. Après décodage, on récupère bien le bon message.


Jour 12

  • Nous arrivons maintenant à récupérer nos paquets LoRaWAN sur notre interface web. Le souci est que l'on n'arrive pas à échanger des données dans nos paquets.
  • En effet, en utilisant un décodeur de paquets LoRaWAN pour analyser le contenu d'un paquet ( https://lorawan-packet-decoder-0ta6puiniaut.runkit.sh/ ), on remarque que tous les paquets reçus sont en fait des "join request" exclusivement. Cela signifie que notre node demande à notre station de base une confirmation pour pouvoir échanger, cependant il ne semble pas recevoir de "join accept".


Réception des paquets LoRaWAN sur Kibana


Contenu du paquet reçu décrypté sur le décodeur


  • Après quelques recherches dans les logs système liés au service de "packet forwarder" installé sur la gateway, on remarque que pour tous les paquets envoyés vers notre interface web, on ne reçoit aucun ACK ou acknowledgment via notre service lorsque l'on fait un "PUSH DATA", autrement dit lorsque notre gateway envoie des logs au service Logstash, qui fait la liaison entre la gateway et notre interface web Kibana. Le service semblerait alors ne fournir aucune confirmation au node de ce fait, c'est-à-dire de lui envoyer un "join accept" pour que les deux entités puissent enfin échanger des données.
  • Par conséquent, on peut en déduire qu'il est alors normal que notre gateway ne reçoit aucun paquet sur le downstream de la part de Logstash. La gateway ne renverra donc aucun paquet vers notre noeud.


Statistiques de notre packet forwarder sur la gateway

Jour 13

  • Après quelques discussions avec les encadrants, nous nous sommes rendus compte que l'implémentation de notre serveur LoRaWAN n'était pas viable et cela ne pouvait correspondre aux attentes du projet.
  • Effectivement, cette implémentation ne permet que de transmettre tous les paquets reçus sur la gateway vers notre ELK stack, sans réaliser aucun traitement sur nos paquets, à savoir être capable d'évaluer un join request pour répondre par un join accept par exemple. Nous avions suivi des exemples d'implémentations qui permettaient d'utiliser l'implémentation du serveur LoRaWAN du réseau TTN, mais sans passer par ce réseau et en redirigeant tous les paquets en local.
  • Cette configuration était alors fonctionnelle mais il semblerait que le serveur LoRaWAN en tant que tel se retrouve sur le réseau TTN. C'est ce fournisseur d'accès qui s'occupe du traitement des paquets, de les décrypter ...
  • Nous nous tournons donc vers une autre implémentation de serveur LoRaWAN en retournant sur nos pas et en utilisant un précédent lien que nous avions trouvé, qui devrait cette fois-ci gérer également le protocole LoRaWAN en plus de jouer le rôle du "packet forwarder" :

https://www.loraserver.io/

Jour 14

  • Mise en place de l'implémentation du serveur LoRaWAN avec la référence donnée hier.
  • L'interface web est fonctionnelle et accessible en local. On utilise VNC pour pouvoir accéder à cette interface. Les paquets sont bien reçus par notre "packet-forwarder", même service que dans l'ancienne implémentation pour faire l'interface hardware/software sur notre gateway.
  • En utilisant le service Mosquitto, on peut également voir le trafic des paquets sur ce MQTT Broker, qui nous permet de récupérer les paquets envoyés par UDP par le "packet-forwarder" et de les transmettre via le protocole MQTT à notre serveur réseau.
  • Il faut maintenant administrer nos différents nœuds sur cette interface web pour que des trames de données puissent être échangées entre la gateway et ces nœuds.


Jour 15

  • Après avoir compris le fonctionnement de notre implémentation, nous avons pu attribuer un de nos noeuds à notre gateway et nous sommes capables d'échanger des données entre la gateway et un noeud.
  • Pour pouvoir analyser le contenu de la payload d'un paquet, puisque celle-ci est encryptée, on utilise le décodeur en ligne utilisée précédemment pour pouvoir l'obtenir en clair en fournissant le paquet complet ainsi que nos deux clés de session (network key et application key). On retrouve bien la chaîne de caractères que nous souhaitions envoyer du noeud vers le concentrateur.


Nouvelle interface web pour l'administration de notre réseau



Ajout de notre noeud SX1276 sur l'interface web



On peut analyser tous les paquets reçus et émis par la gateway


Analyse du paquet LoRaWAN décrypté : on retrouve bien le message "COUCOU" codé en héxadécimal

Semaine 4 // 29/01/18 - 02/02/18

Jour 16

  • Maintenant que notre réseau est opérationnel, le travail restant à accomplir consiste à ajouter des noeuds sur ce réseau. Pour cela, nous avons d'autres noeuds basés sur un STM32 également mais cependant avec des shields LoRa différents de ce que nous devions utiliser au départ. Nous n'avons finalement qu'un seul noeud qui utilisera un shield SX1276. Les deux restants sont des shields de chez ST également, qui sont fournis déjà avec un firmware LoRaWAN.
  • Le problème concernant ces nouveaux shields est que le firmware fourni ne correspond pas réellement à nos attentes concernant son fonctionnement, à savoir se comporter comme un noeud LoRaWAN. Nous avons donc trouvé un exemple qui fait exactement ce que l'on souhaite, cependant il va falloir le compiler nous-même, sans pouvoir passer par le compilateur Mbed en ligne, ni en utilisant le firmware fourni sur le dépôt Github du constructeur du shield.


Un des nouveaux shields I-NUCLEO-LRWAN1 fournis

Jour 17

  • Nous nous sommes rendus compte que nous n'avions pas bien saisi l'utilité et le fonctionnement du firmware LoRaWAN fourni pour le shield I-NUCLEO-LRWAN1 de chez ST. En effet, celui-ci nous permettra en fait de faire tout ce que l'on souhaite pour un noeud de notre réseau. Il fonctionne par commandes AT, c'est-à-dire que sa configuration s'effectue par liaison série. On envoie les commandes que l'on souhaite sur le port série pour que notre noeud ait le comportement voulu, par exemple envoie tel message avec tels paramètres radios toutes les 5 secondes.
  • Nous avons donc reflashé les STM32 avec le firmware et tenté de configurer les shields par cette méthode. Cependant, nous n'arrivons pas pour le moment à configurer convenablement ces noeuds.


Jour 18

  • En attendant d'en savoir plus sur la manière de configurer par commandes AT, nous avons commencé à nous intéresser aux attaques possibles sur notre réseau LoRaWAN, qui est le coeur de ce projet. Nous commençons par réaliser un état de l'art et à nous documenter sur le sujet pour en apprendre plus. Après avoir discuté avec les professeurs, on se concentrera tout d'abord sur les possibles attaques par rejeu sur ce genre de réseau. Voici une thèse sur l'analyse des vulnérabilités de LoRaWAN qui nous guident pour cette analyse :

Fichier:Thesis Xueying P27.pdf

  • Après quelques discussions, nous avons pu nous rendre compte que la configuration AT n'était pas fonctionnelle sûrement dû au fait que le port série entre la STM et le shield n'était pas forcément relié, ou alors qu'une certaine configuration du microcontrôleur empêchait d'accéder directement au shield par port série via la STM. Nous avons donc pris un câble USB série (celui de la Raspberry) pour se connecter directement sur les pins du shield, et nous l'avons alimenté via la STM.
  • En procédant de cette manière, nous avons désormais accès au terminal AT pour configurer les shields et nous arrivons à communiquer avec succès avec notre gateway. Notre réseau comporte donc maintenant une gateway ainsi que trois différents noeuds. Nous pouvons maintenant passer à la partie "analyse des attaques" sur notre réseau.
  • On notera également qu'avec le firmware LoRaWAN implanté sur nos deux derniers shields, celui-ci n'arrive pas à prendre en compte si une session entre le noeud et la gateway a déjà été initiée. En d'autres termes, si l'on reset un des noeuds I-NUCLEO-LRWAN1, il devra procéder à nouveau à un join request pour initier une session alors que du côté de la gateway, on aura une session qui est toujours en cours avec le noeud déconnecté. Le noeud enverra donc des join requests en continu sans que la gateway ne les prenne en compte. Cette réaction est plutôt normale puisque dans une architecture LoRaWAN, les équipements ne sont pas censés être hors tension ou presque pas. Pour remédier à ce problème dans les procédures de test, il est nécessaire de reset la gateway lorsqu'on reset un des noeuds ou inversement. Pour reset la gateway, il faudra supprimer puis recréer le device sur l'interface web pour pouvoir réaliser une nouvelle activation du noeud.
  • On cherche également à réaliser un programme à flasher sur les STM32 qui possèdent un shield I-NUCLEO-LRWAN1 pour pouvoir envoyer des commandes AT de manière automatique sur le port série et ainsi pouvoir envoyer des messages en continu, sans devoir taper une commande "send" à chaque fois que l'on souhaite envoyer un message.


Jour 19

  • Lecture de la documentation officielle sur la certification LoRaWAN pour pouvoir faire des recherches pertinentes sur les vulnérabilités du protocole par la suite. Suite à cette lecture, nous avons pu déjà faire une petite liste de caractéristiques du protocole qui peuvent potentiellement présenter une vulnérabilité.


Jour 20

  • Après avoir vu en détails toutes les composantes du protocole LoRaWAN, nous pouvons maintenant nous préoccuper des différentes attaques possibles sur notre réseau LoRaWAN. Nous faisons alors un état de l'art des différentes attaques connues, en particulier en matière d'attaques par rejeu comme souhaité précédemment. Nous avons donc trouvé d'autres sources en plus de la thèse (différentes attaques possibles dont attaque par rejeu) trouvée précédemment sur le sujet :

https://labs.mwrinfosecurity.com/assets/BlogFiles/mwri-LoRa-security-guide-1.2-2016-03-22.pdf

https://lirias.kuleuven.be/bitstream/123456789/587540/1/camera_ready.pdf

  • En analysant ces documents, il en ressort qu'une attaque par rejeu est possible dans différents cas de figure sur le protocole LoRaWAN. La principale faille réside dans l'utilisation des "frame counters", qui comptent le nombre de trames échangées durant une session. Dans le cas d'une activation ABP, moins sécurisée que l'OTAA mais souvent utilisée dans des phases de développement, les clés de session sont fixes et stockées directement sur le noeud et le serveur réseau. Or, lorsqu'on effectue un reset d'un noeud, c'est-à-dire qu'une nouvelle session entre un noeud et la gateway est créée, les "frame counters" sont réinitialisés à zéro et les clés restent quant à elles identiques. Il devient alors possible pour un attaquant ayant capturé une trame avec une valeur de compteur quelconque de rejouer cette trame après le reset du noeud. Cette trame sera alors acceptée par le serveur et les futures envois venant du noeud victime seront rejetés par ce serveur, en accord avec la certification LoRaWAN qui dit qu'un paquet avec un "frame counter" inférieur ou égal à celui du paquet précédemment reçu doit être rejeté. Cela remet en cause la disponibilité des données puisque tous les paquets envoyés seront rejetés tant que le "frame counter" ne passera pas au-dessus du paquet initialement émis par l'attaquant.
  • Ce genre d'attaque est également possible quand les sessions s'activent par OTAA cependant cela est plus complexe. En effet, les clés de session sont de nouveau générées à chaque nouvelle session créée, ce qui rend impossible le rejeu après le reset d'un noeud. Cependant, la valeur des "frame counters" est limitée puisqu'elle doit être codée sur 16 bits (passage à 32 bits pour la nouvelle certification 1.1.0). Selon la certification LoRaWAN, il revient au développeur de gérer l'implémentation de ces compteurs et devoir générer de nouvelles sessions quand la valeur du compteur approche de sa limite, cependant rien ne l'oblige à le faire. Il est donc possible qu'après un certain temps d'activation d'une session, la valeur du compteur atteint sa valeur maximale et se reset à zéro. Un attaquant pourrait alors attendre ce moment pour effectuer un rejeu et ainsi réaliser la même attaque qu'énoncée juste au-dessus. Cette attaque est aussi possible pour une activation ABP d'une session.
  • Nous essayerons alors vérifier si cette attaque est possible par la pratique pour la suite du projet. On notera qu'aucune implémentation de la dernière version de la certification LoRaWAN n'est sortie pour le moment. Nous avons pour le moment une implémentation de la version 1.0.2. Nous démarcherons alors pour la suite du projet en suivant cette version. Depuis la dernière certification (1.1.0), on notera que l'attaque décrite est beaucoup plus complexe à réaliser, des contre-mesures ayant été adoptées.
  • Pour ce qui est de la réalisation des programmes pour automatiser l'envoi de commandes AT sur les shields I-NUCLEO-LRWAN1, cela se révèle compliqué étant donné que les broches RX et TX qu'utilise le shield pour communiquer ne peuvent pas être utilisées par la STM32 aisément. En effet, pour pouvoir utiliser le port série sur la STM32 correspondant aux broches correspondantes du shield, il est apparemment nécessaire d'ajouter un "solder bridge" sur la STM32 et d'en retirer un autre, selon la datasheet du Nucleo F401RE. Il pourrait alors être plus simple de créer un script qui tournera sur un PC et qui enverra automatiquement des commandes au shield directement par son port série.

Semaine 5 // 05/02/18 - 09/02/18

Jour 21

  • Nous allons donc tester le scénario d'attaque décrit fin de semaine dernière, l'attaque par rejeu basée sur la faille du frame counter. Nous nous inspirerons de la démonstration réalisée par M. Yang dans sa thèse. Voici un schéma qui représente tous les éléments impliqués lors de cette attaque, où l'attaquant serait muni d'une gateway LoRaWAN :


Dispositif dans le cas d'une attaque par rejeu


  • On notera que pour réaliser ce type d'attaque, il est grandement préférable que l'attaquant ait en sa possession une gateway "pirate", qui lui permettra de récupérer tous les paquets qui transitent sur le réseau LoRaWAN. En effet, l'utilisation d'un node, bien que possible, pour la réception des paquets limite de manière conséquente les possibilités d'attaques. Les émetteurs de type LoRa peuvent effectuer de la réception sur une channel unique, avec des paramètres radios prédéfinis comme une fréquence fixe, un spread factor fixe, etc...
  • On aurait donc des chances minces de réceptionner tous les paquets souhaités, comparé à une gateway qui possède plusieurs channels fonctionnant à différentes fréquences et différents SF. Nous allons donc demander à nos encadrants s'il est possible de récupérer un second concentrateur LoRa ainsi qu'une Raspberry pour simuler une gateway "pirate" et ainsi réaliser un scénario qui se rapproche le plus possible de la réalité.
  • Nous avons également intégré de nouveau le ELK stack que nous utilisions précédemment à notre serveur LoRaWAN. L'implémentation que nous avons choisie nous permet d'envoyer tous les logs reçus sur le serveur applicatif par requêtes HTTP, ce qui permet de récupérer ces logs sur l'application web que l'on souhaite. Nous redirigeons donc nos paquets sur Logstash pour que ceux-ci soient acheminés sur Kibana et que nous puissions visualiser d'une manière plus ergonomique les payloads de nos paquets, en réalisant notamment des dashboards par exemple. Cela est beaucoup plus agréable que de les visualiser sur l'interface web du serveur LoRaWAN, que l'on réservera plutôt à l'administration du réseau. Le côté traitement des données se fera sur Kibana :


Retrouvailles avec notre ELK stack pour la visualisation des datas


  • On retrouve bien les payloads envoyées depuis un des noeuds, qui envoie la chaîne de caractères "COUCOU". Le seul souci résidant dans cette application est le fait que le "COUCOU" est encodé en base64. Nous travaillons sur le fait de pouvoir décoder le base64 et afficher les informations directement en clair. Après quelques recherches dans l'interface web Kibana, nous avons réussi à modifier la manière dont l'API affichait le champ "data" pour que celui-ci soit décodé du format base64.
  • Nous avons également réalisé un diagramme représentant l'architecture de notre réseau ainsi que les différents services utilisés au sein des différentes entités. Cela permet une compréhension globale du travail effectué et facilite l'élaboration des différents scénarios d'attaque possibles, en voyant directement les endroits du réseau par lesquels une infiltration est possible.


Représentation de notre architecture réseau et logicielle


Jour 22

  • Nous cherchons à pouvoir réaliser des graphiques ou autres représentations des données envoyées par nos noeuds sur Kibana. Pour le moment nous rencontrons des problèmes pour cela étant donné que dans les JSON envoyés par le serveur LoRaWAN, le champ "data" est de type String et non pas Int, ce qui nous empêche de pouvoir l'utiliser pour réaliser des graphiques représentant la moyenne de la valeur par exemple. Nous travaillons sur ce point.
  • Élaboration d'un programme dédié à la STM32 pour pouvoir envoyer des commandes AT directement au shield sans passer par le port série, ce qui serait plus approprié dans une application grandeur nature. Nous le testerons prochainement.

Jour 23

  • Récupération du matériel nécessaire pour le développement d'une seconde gateway LoRaWAN qui jouera le rôle de la gateway pirate. Nous avons donc une seconde Raspberry avec un concentrateur LoRa. Nous allons implanter le même serveur LoRaWAN que celui sur la gateway de notre réseau.

Jour 24

  • Nous pouvons maintenant utiliser notre gateway pirate pour sniffer les paquets radios dans son périmètre. L'attaquant sera représenté par cette gateway ainsi que le noeud SX1276 que nous retirerons du réseau pour que l'attaquant ait de quoi émettre des paquets, nécessaire pour effectuer une attaque par rejeu.
  • Nous avons testé avec succès le programme pour que les STM32 envoient des commandes AT de manière automatique aux shields I-NUCLEO-LRWAN1. Pour une raison obscure, un des deux shields n'arrive pas à se connecter au serveur LoRaWAN. Le noeud est bien enregistré du côté serveur mais le noeud considère quant à lui qu'il n'a pas rejoint le réseau et envoie des "join request" en boucle. Ceci est d'autant plus étonnant puisque nous utilisons le même matériel et le même programme pour l'autre shield. Il faudra voir pour quoi ceci ne fonctionne plus.
  • Nous pourrons au moins tester une attaque par rejeu avec un noeud, en le configurant en activation ABP pour que les clés restent fixent lors d'un reset. Nous testerons ensuite l'envoi d'une trame avec un frame counter quelconque et nous verrons si la théorie se valide, à savoir que le serveur n'acceptera par la suite aucune des trames reçues par le noeud "honnête", jusqu'à temps que le frame counter dépasse la valeur de celui contenu dans le paquet envoyé par le noeud pirate juste au moment du reset.


Jour 25

  • Nous passons au test de l'attaque par rejeu liée au frame counter. Pour ce qui est de la démarche, voici comment nous allons procéder :
  - Nous allons écouter en continu les paquets émis au sein de notre réseau LoRaWAN sur notre gateway pirate. 
  - A un instant t, nous allons manuellement provoquer le reset d'un noeud, qui initialisera du coup une nouvelle session avec un frame counter de retour à zéro.
  - En s'aidant du décodeur de paquets LoRaWAN en ligne, nous allons retrouver le paquet ayant le frame counter le plus élevé, à savoir celui précédant la nouvelle requête de "join request". Nous utiliserons alors notre noeud SX1276 pour réémettre tel quel le paquet en question le plus rapidement possible après le reset.
  - La gateway de notre réseau devrait alors normalement accepter ce paquet. A partir de ce moment, tous les paquets émis par le noeud "piraté" devraient être rejetés par la gateway jusqu'à temps que son frame counter dépasse celui du paquet rejoué par le pirate.
  • Après quelques tentatives de reset manuel, nous nous sommes aperçus d'un problème dans la gestion des frame counters. En effet, lors d'un reset du noeud, le compteur du côté du noeud est bien remis à zéro. Cependant, ce n'est pas le cas du côté du network server qui garde en mémoire la dernière valeur du compteur enregistrée. Cette réaction est tout à fait normale si l'on suit la dernière certification du protocole, qui dit la chose suivante :
 ABP devices have their Frame Counters initialized to 0 at fabrication. In ABP devices the
 frame counters MUST NEVER be reset during the device’s life time. If the end-device is
 susceptible of losing power during its life time (battery replacement for example), the frame
 counters SHALL persist during such event.
  • Notre serveur respecte donc cette condition et garde en mémoire la valeur du compteur. Du côté du noeud, nous n'avons pas une implémentation respectant la toute dernière spécification, ce qui rend la sauvegarde du compteur impossible. En effet, dans les versions précédant la 1.1.0, un reset d'un noeud configuré par ABP doit remettre à zéro les deux compteurs, du côté serveur et du côté noeud.
  • Notre attaque est donc rendu obsolète par le fait que le compteur ne se réinitialise pas du côté serveur.
  • Modifications apportées avec la dernière version 1.1.0 de la spécification LoRaWAN qui empêche les attaques par rejeu :
FCnt changes : 
 - All counters are 32bits wide , 16bits not supported any more
 - Separation of FCntDown into AFCntDown and NFCntDown
 - Remove state synchronization requirement from NS/AS
 - Remove requirement to discard frames if FCnt gap is greater than MAX_FCNT_GAP
 - Unnecessary with 32bit counters
 - End-device Frame counters are reset upon the successful processing of a Join-Accept
 - ABP device must never reset frame counters
  • Voici d'autres méthodes pour réaliser des attaques par rejeu, si la certification sur laquelle nous travaillons est antérieure à la 1.1.0 :

https://medium.com/@brocaar/notes-on-lorawan-security-7e741a8ee4fa

Semaine 6 // 12/01/18 - 16/01/18

Jour 26

  • Nous discutons actuellement avec le créateur de l'implémentation du serveur LoRaWAN pour comprendre la manière dont le serveur gère le reset d'un noeud par activation ABP. Il s'avère que le serveur s'apparente plus à une implémentation de la version 1.1.0 du protocole étant donné que le créateur du serveur a considéré que le compteur ne se réinitialise jamais pour un noeud en mode ABP, justement pour éviter les attaques par rejeu. De ce fait, le serveur considère que lors d'un reset, le noeud gardera en mémoire la valeur de son compteur pour pouvoir la réutiliser par la suite, ce qui est clairement décrit dans la version 1.1.0 (citation donnée ci-dessus).
  • Nous pensions que cette attaque était possible puisque le serveur se base sur la version 1.0.2 du protocole, cependant le créateur a corrigé les quelques vulnérabilités de cette version notamment celles sur les frame counters pour le mode ABP. Il est vrai que dans la certification, la manière de gérer le reset d'un noeud reste un peu obscure et n'est pas clairement décrite, ce qui laisse le choix quant à l'implémentation du protocole. Pour pouvoir gérer correctement le reset d'un noeud avec l'implémentation que nous avons choisie, il est donc nécessaire de flasher la mémoire du noeud constamment pour conserver la valeur du compteur.
  • Ce choix concernant la gestion du compteur paraît paradoxale puisque le serveur utilise une des caractéristiques de la version 1.1.0 du protocole alors que celui-ci est censé implémenter la version 1.0.2. Cela nous empêche de nous servir des vulnérabilités de la version du protocole qui est censée être implémentée. On pourrait donc dire que l'implémentation du serveur n'est vraiment correcte puisqu'elle corrige les vulnérabilités d'une ancienne version par la nouvelle tout en prétendant implémenter cette dernière version.
  • Puisque ce type d'attaque semble compromis, nous commençons à nous intéresser à d'autres attaques qui s'apparentent à du rejeu, mais qui nécessitent cependant le contrôle de la gateway du réseau. Une des attaques possibles est celle qu'on appelle ACK spoofing, qui consiste à capturer un paquet quelconque que la gateway envoie pour faire un "acknowledgment" d'un paquet reçu d'un noeud. En plus de capturer ce paquet, on doit empêcher la gateway d'émettre des paquets pendant un certain moment, ce qui nous oblige d'avoir le contrôle sur la gateway pour cette attaque. Suite à cela, on pourra durant un certain moment valider tous les paquets émis par un noeud en retransmettant les ACKs capturés lors de la désactivation de la communication de la gateway avec le noeud.


Jour 27

  • Suite à l'impossibilité d'effectuer des attaques par rejeu sur notre réseau, nous avons cherché d'autres possibilités d'attaques diverses et variées. La plupart nécessite d'avoir un contrôle physique ou d'accéder à distance aux entités du réseau, ce qui complexifie la chose.
  • Même si toutes les attaques paraissent impossibles, il reste tout de même la possibilité d'une attaque par rejeu en utilisant la taille "limitée" du frame counter. Celui-ci est est d'une taille de 16 bits, ce qui signifie qu'un overflow du compteur peut se produire de manière occasionnelle, à savoir toutes les semaines si l'on envoie des trames toutes les 10 secondes. Cependant, si l'on respecte la certification LoRaWAN, un émetteur doit respecter un duty cycle de 1%, ce qui donne généralement une émission toutes les minutes ou les deux minutes, en fonction du nombre de données envoyées. Cela augmente donc la fréquence d'overflow du frame counter mais cela reste tout de même envisageable.
  • Après discussion, nous allons plutôt utiliser notre gateway pirate pour faire un sniffer de paquets LoRa et que celui-ci renvoie tous les paquets qu'il reçoit, pour ainsi analyser le comportement du réseau face au rejeu et à la redondance. Cela nous permettra peut-être de découvrir de nouvelles vulnérabilités.
  • S'il reste du temps, nous pourrons toujours effectuer une attaque par rejeu en utilisant l'overflow du frame counter.

Jour 28

  • Étant donné que nous n'arrivons toujours pas à réaliser des graphiques avec nos données sur Kibana, le problème étant normalement résolu avec la toute dernière version du service non disponible sur Raspbian, nous avons choisi de déporter le ELK stack sur un PC. Cela permettra également d'alléger notre Raspberry puisqu'il était difficile de faire tourner le ELK stack avec une interface graphique en même temps.
  • On notera que, concernant l'implémentation LoRaWAN du serveur, nous n'avons pas essayé la deuxième possibilité non-officielle trouvée au début du projet, qui est la suivante :

https://github.com/gotthardp/lorawan-server

  • Il peut être judicieux d'évaluer comme précédemment les possibilités d'attaque, mais sur cette implémentation. Celle-ci respectera peut-être plus la spécification 1.0.2 et n'a peut-être pas corrigé les vulnérabilités de cette version comme celle que nous utilisons. Vu le temps restant pour le projet, nous n'aborderons pas cette implémentation.

Jour 29

  • Nos shields I-NUCLEO-LRWAN1 fonctionnent correctement tous les deux. C'était une petite erreur dans le programme tournant sur la STM32 qui empêchait l'un des deux de fonctionner normalement. Ces shields sont activés par ABP, ce qui nous permettra de tenter une attaque par rejeu au moment de l'overflow du frame counter si nous devions la réaliser.
  • L'ELK stack ne fonctionne pas encore sur notre PC. Le problème semblerait venir de la liaison entre l'intégration HTTP que l'on utilise sur l'interface web du serveur LoRaWAN et notre service Logstash. En effet, du côté de l'application web, on voit dans les logs que la connexion avec le PC a été refusée et donc les requêtes HTTP ne peuvent pas être échangées. Notre service Logstash ne reçoit donc aucune requête et il n'est pas capable de se connecter à la Raspberry non plus.

Jour 30

  • Nous avons testé d'implanter l'ELK stack sur un PC de l'école, le problème venant peut-être de la configuration du PC personnel. Cependant, cela n'a rien apporté et nous n'arrivons toujours pas à visualiser Kibana.
  • Concernant le sniffer LoRaWAN et la réémission de chaque paquet reçu, nous allons partir sur un script Python qui fera la lecture des fichiers CSV qu'enregistre un programme fourni par Semtech, contenant tous les caractéristiques des paquets reçus. Celui-ci enverra par la suite par liaison série à notre shield SX1276 relié à la gateway tous les paramètres radios et la payload de chaque paquet pour qu'ils puissent les retransmettre.
  • Après réflexion, réaliser un script ne nous permettra pas d'avoir une synchronisation parfaite entre la réception de paquets l'envoi de ceux-ci directement après réception. Cela nous oblige à modifier le code du programme fourni par Semtech qui permet de stocker ces paquets dans des logs. Pour chaque paquet enregistré, nous réaliserons l'envoi de celui-ci.


Semaine 7 // 19/02/18 - 23/02/18

Jour 31

  • Rédaction du rapport
  • Nous avons tout de même voulu avoir une attaque de présentable pour la fin du PFE. Nous avons donc laisser tourner tout le weekend un émetteur qui envoie des trames le plus rapidement possible pour tester les failles du protocole concernant l'overflow du frame counter.
  • Notre noeud envoie des trames toutes les 200 ms, cependant le serveur possède un temps de traitement conséquent pour la réception de paquets, qui est de 1,5s. Nous ne pouvons donc pas faire mieux que de recevoir une trame toutes les 3s environ en comptant tous les temps de latence possibles. Vu que le frame counter est de taille 16 bits (selon la certification 1.0.2), il devrait se réinitialiser après 2^16 = 65 536 itérations. Le reset du frame counter devrait alors survenir après 65 536 * 3 = 196 608s, ce qui fait deux jours et quelques heures. Nous attendons donc ce reset pour voir si la faille sur le frame counter est vérifiée et s'il sera possible d'effectuer un rejeu.
  • La méthodologie employée pour cette attaque est identique à celle que l'on aurait utilisée pour l'attaque par rejeu en provoquant manuellement le reset.

Jour 32

  • Nous continuons la rédaction du rapport
  • Après nous être rendus compte qu'une fois de plus notre serveur LoRaWAN non-officiel ne respecte réellement la version 1.0.2 de la certification, l'attaque ne pouvait être envisagée. En effet, une fois arrivé à la valeur 2^16 qui est censé être son maximum, le frame counter continue de s'incrémenter au lieu de se réinitialiser. Celui-ci est donc sûrement de taille 32 bits, ce qui également une nouveauté venue avec la version 1.1.0 de LoRaWAN.
  • Pour tenter d'obtenir un scénario d'attaque présentable, nous avons tout de même tenter de réaliser une attaque par rejeu en supposant que le compteur côté serveur se réinitialise en atteignant la valeur de 2^16. Nous avons donc généré manuellement une nouvelle session entre le noeud "victime" et le serveur pour que les compteurs soient remis à zéro de part et d'autre.
  • En procédant de cette manière, nous avons finalement réussi à effectuer un rejeu en faisant du "spoofing" sur la gateway via notre noeud pirate, c'est-à-dire en lui envoyant un message malicieux que le serveur considère comme authentique car envoyé précédemment par le noeud "victime". Ce message a été judicieusement choisi parmi tous les messages enregistrés sur la gateway pirate. Ainsi, nous avons provoqué un déni de service sur le noeud "victime" car plus aucun de ses messages ne seront acceptés tant que leur frame counter ne dépasse pas la valeur de celui contenu dans le paquet malicieux.
  • L'attaque ayant été réalisé aujourd'hui, on ne pourra vérifier le temps total de déni de service puisque celui-ci risque de durer au-delà de la soutenance de PFE. On retiendra donc grâce aux captures suivantes que le serveur ne reçoit plus de données de la part du noeud depuis que celui-ci a été "spoofé":


Etat du frame counter après envoi du message malicieux
Après réception du paquet malicieux, plus aucun message n'est reçu
Paquets reçus par le serveur







Jour 33

  • Finition du rapport de projet

Jour 34

  • Préparation à la soutenance

Jour 35

  • Soutenance du projet

Bilan et évolution possible pour le projet

  • Il pourrait être intéressant de tenter à nouveau des attaques par rejeu de manière plus poussée car nous n’avons pas vraiment eu le temps de réaliser des tests approfondis
  • Au cours de ce projet, nous nous sommes intéressés au cas des attaques par rejeu. Cependant, il reste tout de même d’autres types d’attaques qui peuvent être testés, comme le « ACK spoofing »
  • Tester la seconde implémentation non officielle trouvée au départ
  • Design des équipements
  • A la fin du projet, nous avions comme possible mission de réaliser un sniffer de paquets LoRaWAN qui doit réémettre chaque trame reçue pour évaluer la manière dont un serveur gère la redondance ou le rejeu. La réalisation d’un sniffer plus intelligent pourrait être envisagée, dont le but serait de détecter automatiquement le reset d’un nœud du réseau et d’émettre une trame avec une grande valeur de « frame counter » parmi celles qu’il enregistre pour attaquer automatiquement

Conclusion

  • Nous pouvons considérer que le cahier des charges initial a été rempli avec plus ou moins satisfaction.
  • Préférable de réaliser plus de scénarios d'attaque après déploiement du réseau. Nous avons passé un temps trop conséquent sur l'implantation de ce réseau.
  • Bonne initiation à la recherche et expérience dans la sécurité informatique
  • Thématique du sujet en plein essor, c'est une opportunité de pouvoir travailler sur ce genre de technologie

Rendus