Solution de Abyss-W4tcher pour Objets connectés

hardware radio

1 décembre 2023

Rappel de l’énoncé

Dans votre nouveau laboratoire, vous trouvez un micro-onde appelé Louis et une cafetière nommée Rachèle qui vous semblent être tout à fait sympathiques. Selon les employés du labo, ils sont capables d’émettre quand ils ont fini. En les regardant de plus près, vous remarquez que des capteurs de température leur sont accolés. Les étiquettes de ces capteurs contiennent des termes que vous ne comprenez pas dont une mention liée à une fréquence, LoRa : 433.242 MHz. Vous sortez vos outils de capture de signal que vous avez sous la main. Vous extrayez un fichier en prenant une fréquence de capture de 1 MHz.
Les capteurs n’ont pas l’air d’être neufs et leur aspect vous fait penser que certaines données ont été corrompues mais le vieux briscard du labo vous assure que la correction se fait toute seule et que le message est tout à fait compréhensible.

Un fichier au format IQ nous est fourni par la suite.

Premières analyses (Inspectrum)

Nous commencons par analyser le fichier via le logiciel inspectrum (n’hésitez pas à zoomer):

1d96182f716878f698c126f98aa7a03eda9357add6522ffff56d16d7f8f3ce72

Nous retrouvons ici plusieurs suites de signaux, à un offset (positif et négatif) d’environ 270kHz à partir de 0. N’ayant jamais vu ce type de données auparavant, nous entamons la lecture de documentation sur LoRa, la technologie mentionnée dans l’énoncé.
Voilà plusieurs sources très intéressantes, qui ont permis une mise à niveau et une meilleure compréhension :

https://revspace.nl/DecodingLora
https://www.youtube.com/watch?v=-YNMRZC6v1s, https://www.youtube.com/watch?v=NoquBA7IMNc (présentations de Matt Knight sur le protocole ainsi qu’un projet gnuradio)

Nous n’allons pas détailler le fonctionnement du protocole, le premier lien cité plus haut résume parfaitement ce qu’il y a à comprendre et nous vous invitons à le consulter. Le formatage n’est pas compliqué à assimiler, mais le décodage à la main avec inspectrum risque d’être impossible, long et imprécis.

Le logiciel gnuradio est alors tout indiqué, car il dispose de toutes les fonctionnalités d’analyse du signal nécessaires. N’ayant pas spécialement envie d’implémenter toute la chaîne à la main, nous nous mettons à la recherche d’un projet GitHub.

Tentatives de décodage via gr-lora_sdr

gr-lora de rpp0 est un OOT (Out Of Tree modules) implémentant des blocs gnuradio spécifiques au décodage de LoRa. Nous l’installons donc avec la dernière version de gnuradio (3.10.2.0 ), et tentons de décoder le fichier IQ, en modifiant certains paramètres :

24ec08c12b381929b8658a1cd8284cbe9eee5059fd56ad994b7d89df228fa9fb

Ici, nous choisissons un sample rate de 1MHz, qui est la valeur par défaut et n’a pas besoin d’être modifiée, un centrage en fréquence de 0 (nous n’utilisons pas d’antenne), une “Bandwidth” de 250kHz et un “Spreading Factor” (nombre de bits par symbole) de 7. Pourquoi ces deux dernières valeurs ? En voilà l’explication :

52a5ba3601f6e3b41c557afab4b1a680f4b1da98adc039d471e6ca9150814091 source : dautrylimoges.scenari-community.org

Nous avons pu voir dans inspectrum une largeur de bande d’environ 250 kHz, ce qui implique alors un SF de 7. Néanmoins, nous allons voir que cette implication n’était pas forcément vraie.

Le bloc de décodage ne trouve rien du tout, et la présence d’erreurs (indiqué dans l’énoncé) me fait penser qu’il va falloir être en possession de toute la chaîne de décodage. Il est l’heure de chercher un autre projet GitHub.

Décodage d’un morceau du flag via gr-lora_sdr

gr-lora_sdr de tapparelj implémente toute la chaîne de blocs permettant le décodage de LoRa. C’est donc le candidat parfait pour essayer de modifier spécifiquement certaines valeurs et rentrer dans les détails. Nous décidons de l’installer.

Nous omettons volontairement la partie où il a été nécessaire de créer une seconde VM pour installer gnuradio 3.8, car cet OOT ne semblait pas vouloir fonctionner avec la dernière version de gnuradio :)

Le repo GitHub contient un exemple de schéma de décodage, que nous nous empressons de reproduire à l’identique :

41efc50b15f8e59e8240d7e217262487cc3d68bf32fb5a85eb4d9baa97bfccec

Afin de gagner du temps nous déclarons quelques variables pour les tests à venir, puis nous exécutons en modifiant simplement BW et SF :

1114e7df7a346ec8195d995d64b5838ad2880e418d9fd006cac7287805605295

Miracle ! Le flag Une partie du flag s’affiche sous nos yeux ! Nous remarquons instantanément la double répétition du message suivie d’une indication d’en-tête. Cela correspond aux trois bandes à l’offset positif visibles sur la capture inspectrum. Il ne nous reste plus qu’à comprendre pourquoi la bande en négatif n’est pas détectée.

Correction d’erreur et seconde partie du flag

Nous retournons sur inspectrum et tentons de situer l’erreur :

df9f4769eb4d22072af4896837665d5a74054e875c1d6135a2603d852ec83f17

En repensant à un certain passage lue dans la documentation plus haut, cela nous apparaît comme une évidence :

[…]On the air I have seen the following waveforms:
a series of up-chirps at the start of a message (preamble), the number of up-chirps corresponds to the PreambleLength registers[…]

Ce signal LoRa est en effet inversé, si vous regardez la première capture inspectrum, vous pouvez voir que les trois blocs du hauts commencent par des chirps (sauts en fréquence) positifs. Le schéma est donc le même, mais tous les chirps sont inversés.

Après une dizaine de minute à imaginer des plans bien trop complexes pour inverser ces chirps, nous nous rappelons que nous avons affaire à un fichier IQ, et que l’inversion de ces deux composants devrait suffire !

Le bloc “swap iq” de gnuradio n’est apparu qu’en version 3.9, il a fallu retourner sur le premier schéma gr-lora_sdr pour réaliser cette opération

2c1014a6bd7a373b7f6904898d4accf008c5df5f1e6f43796e59958695261cda

Voyons le résultat dans inspectrum :

d6bafd5728981ea728d17dbc950251853fa432a78baa1ed2026cd7f1a3c437ec

Hourra ! Les deux bandes ont changé de place, et les chirps sont désormais dans le bon sens (ou le mauvais pour les trois bandes désormais en offset négatif).

Nous changeons de fichier source sur le schéma gnuradio, et décodons … rien du tout. En effet, nous pouvons voir que le nombre de chirps par seconde (l’axe X de inspectrum représente le temps) est beaucoup plus élevé pour les signaux de la première partie du flag que dans la seconde.
Néanmoins, la largeur de bande est de 250kHz, ce qui implique forcément un SF de 7 ? Et bien, visiblement, Louis le micro-onde ou Rachèle la cafetière nous a induit en erreur et a décidé d’ignorer le tableau de correspondance plus haut.

La bonne réponse était … bruteforcer le SF :

5f1ca633998aa36fb68775353988ffac9d183b604a463ec682111aebb5dc6c2b

f3ded0a226b27acd2b26b04185108a6a15742a53ca00e27535db6ebfa4bdea95

Cela fait sens au niveau de la durée des chirps, mais pas de la largeur de bande. Soit nous avons manqué quelque chose (bien que tous les tableaux sur le web confirmaient qu’une BW de 250kHz associait forcément un SF de 7), soit cela faisait partie de l’épreuve (la seconde option est à privilégier :) )

Conclusion

Challenge particulièrement intéressant et difficile lorsque l’on ne connaît pas LoRa, qui nous a permis de nous confronter à de la télécom’ assez sympa et peu ordinaire en CTF.

Flag : FCSC{0083fa85206b09970d550b9e8ba8a705be62027e6e769d6ed5e87b8e93dd5759}