Mathis Hammel Profile picture
Jul 24, 2021 31 tweets 10 min read Read on X
On ne le dira jamais assez : ARRÊTEZ DE PUBLIER DES CERTIFICATS DE VACCINATION SUR INTERNET !

Je vous propose un thread d'exemple avec cet article @France3tv, on va essayer de reconstituer le 2D-DOC "flouté" (et ce sera une excuse pour en apprendre beaucoup sur Datamatrix 😉) ⤵️ ImageImage
Saluons avant de commencer le courage de @Jefffrey68 qui a décidé de sacrifier son propre pass sanitaire pour la photo ;) Image
Le 2D-DOC (première version des certificats de vaccination) est encodé au format Datamatrix ECC-200, qui est comme la plupart des code-barres 2D résistant à des dégâts partiels des données, ici à l'aide de codes correcteurs Reed-Solomon.
Avec suffisamment de persévérance et un peu de lecture de documentation, il est complètement possible de décoder manuellement un Datamatrix.

Ici, on va essayer d'extraire le plus de données possibles (comme je n'ai trouvé aucun lecteur qui arrive à le lire, même partiellement)
On commence par l'emballage : un Datamatrix est forcément entouré d'une barre de pixels noirs sur deux côtés, et de pointillés sur les deux autres côtés. Si les dimensions sont trop grandes, on fait des subdivisions comme c'est le cas dans le 2D-DOC (2x2 régions). Image
Pour décoder, on va se baser sur ce pavage régulier de motifs en forme de L qui contiennent chacun 8 bits.

Ici, je mets un point rouge sur le bit de poids faible pour mettre en évidence la régularité du pavage. Image
Une fois ce découpage effectué, on peut commencer à décoder les octets bruts contenus dans le 2D-DOC. C'est tout simple, chaque motif en L se lit dans le sens de lecture en partant d'en haut à gauche. Dans cet exemple, on trouve 00101001 soit 41. Image
Tous les octets sont décodés dans un ordre de zigzag bien déterminé : Image
Une fois que tous les octets lisibles sont transcrits, il faut procéder à une dernière étape de décodage avant de pouvoir lire les données (tout du moins ce qu'on parvient à transcrire !) Image
Dans le screenshot du tweet précédent, on voit bien que les données brutes (avant décodage donc) ne correspondent pas du tout à ce qu'on trouve en scannant un certificat de vaccination avec un lecteur classique, cf.
Il y a plusieurs éléments à prendre en compte. Déjà, les caractères sont décalés de 1 dans la table ASCII. Ainsi, les lettres "ED" que l'on voit se décodent en "DC". Ce qui correspond déjà bien au "DC04FR03" que l'on retrouve dans les 2D-DOC de vaccination ! Image
Ensuite, les choses se compliquent un peu. Quand on essaie de regarder le caractère 0x85 dans la table ASCII, on se rend compte que c'est un caractère spécial (comme tous les caractères après 0x7F)...
En lisant la doc, on peut lire que les valeurs 130 à 229 encodent toutes les paires de chiffres entre 0 et 99. Il est donc possible d'encoder deux octets en un, pratique non ?
0x86 = 134, donc on décode les octets "04". Image
Le décodage se poursuit sans encombre, on arrive à récupérer le début du certificat "DC04FR03AV011E731E73L", mais ensuite tout s'effondre : le caractère 0xE6 (= 230) va venir nous poser quelques soucis. Il correspond au début d'un mode d'encodage nommé C40. ImageImage
Jusqu'ici, on était dans le plus simple encodage, l'encodage TEXT. Il est efficace pour stocker des nombres comme on peut encoder deux octets en un, mais le C40 offre une meilleure compression des lettres majuscules (qui constituent la majorité du reste du 2D-DOC).
Le C40 utilise une table de caractères réduite à 40 caractères, encodés en base 40.
Par exemple, la paire d'octets 22 EB se lit comme un nombre de 16 bits 0x22EB (= 8939). On soustrait 1, puis on décode en base 40 : 5 * 40² + 23 * 40 + 18 Image
Ces trois nombres en base 40 nous donnent les trois index des caractères dans le charset.

5 = "1"
23 = "J"
18 = "E"

On vient de trouver le début du champ L1 (prénom), ici "L1JEAN-FRANCOIS" 😉

Et une compression encore assez efficace car on encode 3 octets en seulement 16 bits. Image
Au bout d'une vingtaine d'octets décodés en C40, on rencontre la première des deux zones de floutage. 5 octets des données brutes sont fortement endommagés.

Comme les zones sont parcourues en diagonale, seuls 2 octets à la fois sont corrompus, ce qui facilite la reconstruction. Image
D'après la zone détruite, on se retrouve avec ce décodage partiel à la main :

FREY[DC]L1JEAN-FRANCOIS[DC]❓❓❓9031982

A noter que l'on a quitté le mode C40 pour repasser en texte afin d'encoder le byte [DC].
Les deux premiers octets sont faciles. Il s'agit de "L2", marqueur de début du champ date de naissance. Mais Jean-François est-il né le 9, le 19 ou le 29 mars 1982 ?

Comme on est repassés en mode texte, cette zone encode une paire de chiffres. Image
Le premier chiffre est le 2 du marqueur "L2", le second correspond au début de la date de naissance. 3 options donc : 20, 21 ou 22.

On rappelle que les paires de chiffres sont encodées par les valeurs 130 à 229, on devrait donc obtenir l'octet 150, 151 ou 152.
Dans la zone endommagée par le floutage, on peut lire 1001?11? avec les deux bits de droite manquants. Regardons nos options :

1001?11?
10010110 = 150 (paire "20")
10010111 = 151 (paire "21")
10011000 = 151 (paire "22")

Ce qui nous permet d'éliminer le 29 mars ! Image
Plus tard dans le décodage, le zigzag repasse par cette zone floutée. De nouveau, 2 octets corrompus mais ici ce sera beaucoup plus simple. En effet, on est en mode C40 et le décodage partiel est le suivant :
"1982L3COVID-19❓❓4J07BX03"
On est encore bien tombés, car les deux octets qui nous manquent sont pile sur le marqueur de champ L4 (on voit d'ailleurs le 4). Il manque "[DC]L" que l'on devra rajouter. En regardant ce qui suit, on peut comprendre que cette fois on reste en mode C40 pour encoder [DC] Image
Pour encoder le caractère spécial [DC] sans quitter le C40, on va utiliser les charsets Shift. La séquence "[DC]L" s'encode:

0 = Shift-1 pour passer au charset contenant [DC]
29 = index de [DC] dans Shift-1
25 = index de L en C40 standard (le shift ne dure que pour un caractère)
On peut donc continuer à décoder les bytes à la suite, et on se rend compte que les autres zones endommagées (le second flou, et là où se trouve le doigt) sont également faciles à reconstituer, sans même avoir à utiliser la redondance des codes correcteurs d'erreur !
Et une petite preuve que ma reconstitution fonctionne, parmi nos deux choix possibles c'était donc le 9 mars ;) Image
Tout ce thread était une grosse excuse pour apprendre comment fonctionne 2D-DOC et son support Datamatrix. J'espère quand même que vous retiendrez et partagerez que même flouté/gribouillé, il est dangereux de partager son pass sanitaire !
(Enfin bon, je pense que les gens qui lisent jusqu'au bout un thread sur les spécifications de Datamatrix et les gens qui postent leur QR sur internet sont deux populations strictement distinctes, bravo à vous qui lisez ceci)
Pour conclure, là je suis allé un peu loin à me croire comme McGee dans NCIS alors qu'un bon lecteur aurait sûrement marché. En réalité c'est HYPER facile de tomber sur des pass sanitaires valides et pas floutés, notamment dans la presse en ligne (en 10 minutes j'en ai trouvé 8)
Et pour celles et ceux qui se posent plein de questions pertinentes sur la sécurité des attestations vaccinales, j'ai essayé de vulgariser tout ça dans un autre thread, publié à l'instant :

• • •

Missing some Tweet in this thread? You can try to force a refresh
 

Keep Current with Mathis Hammel

Mathis Hammel Profile picture

Stay in touch and get notified when new unrolls are available from this author!

Read all threads

This Thread may be Removed Anytime!

PDF

Twitter may remove this content at anytime! Save it as PDF for later use!

Try unrolling a thread yourself!

how to unroll video
  1. Follow @ThreadReaderApp to mention us!

  2. From a Twitter thread mention us with a keyword "unroll"
@threadreaderapp unroll

Practice here first or read more on our help page!

More from @MathisHammel

Jun 20
J'en ai trop marre de voir des smicards pleurer pour qu'on augmente pas les impôts des millionnaires.

J'ai gagné un peu plus de 7000€/mois pendant plusieurs années, si tu te considères pas riche à ce niveau c'est du déni ou de la malhonnêteté. Thread ⤵️
J'aime pas trop parler d'argent ici parce que ça peut passer pour de l'orgueil, mais on voit tellement de conneries se propager en ce moment que je me suis senti obligé de partager mon expérience (je supprimerai probablement le thread d'ici quelques jours)
Commençons par "tu t'offres un ou deux resto par mois" : je mange au resto quasiment chaque midi en semaine.

Le soir j'aime bien cuisiner, jamais aucune hésitation avant de prendre des produits bio ou premium.
Read 10 tweets
Mar 29
THREAD - les manipulations illicites du classement lors de la compétition la plus chère d'Europe.

Cette semaine, l'équipe de l'European Cyber Cup a trafiqué arbitrairement son scoreboard pour favoriser certaines équipes qui lui faisaient pression. 1/14 Image
Je suis coach de 10 étudiant·es de @Guardia_School qui ont participé cette semaine aux épreuves de l'European Cyber Cup.

Cette compétition est organisée par le forum InCyber (anciennement FIC, qui a discrètement changé de nom à cause de quelques casseroles).
Le prix d'inscription n'est pas rendu public, mais en 2021 je me souviens que mon entreprise avait dû payer 10.000€ pour nous inscrire, sachant que le cash prize pour l'équipe gagnante est de 5.000€ 🙃 Image
Read 16 tweets
Feb 8
J'ai besoin de votre aide pour m'aider à entraîner l'équipe de France de cybersécurité !

Quelques détails ci-dessous, merci de partager au maximum 🙏
En janvier, j'ai eu l'honneur d'être nommé entraîneur des compétiteurs français en cybersécurité, pour la prestigieuse compétition WorldSkills qui opposera 65 pays cette année.
Contrairement aux excellentes compétitions FCSC/ECSC qui sont très orientées CTF, le challenge WorldSkills va plutôt demander des compétences métier, appliquées à des environnements réalistes.
Read 6 tweets
Nov 8, 2023
THREAD

Je me suis intéressé à la cybersécurité de Crush, l'appli de rencontres pour 10-21 ans qui fait beaucoup de bruit.

J'y ai découvert un réseau de sociétés fictives qui récolte activement les données de dizaines de milliers de mineur·es. Explications ⤵️ Capture de l'appli "Crush, trouve ton crush secret" sur le store iOS.
PARTIE 1. Le fonctionnement de l'appli

Crush est une appli dont le but est de découvrir ses admirateurs secrets au collège/lycée.

Elle a été renommée "Friendzy, sondages entre amis" depuis son bad buzz.
Le principe est simple : après avoir ajouté vos amis sur l'appli, vous répondez à des questions sur vos liens d'amitié.

Dans un autre onglet, vous pouvez savoir ce que les gens ont répondu sur vous, sans voir leur nom. Sondage "La discrétion est son superpouvoir" avec 4 choix parmi mes amis sur l'appli (j'ai masqué deux noms qui appartiennent potentiellement à des vraies personnes)
Read 24 tweets
Aug 1, 2023
Droite au Coeur est toujours en maintenance, mais j'ai réussi à contourner la fermeture de l'authentification donc j'ai toujours accès au site.

La vulnérabilité initiale a été corrigée, je peux donc légalement vous expliquer la pire faille de sécurité du monde. 🧵1/9
L'interface de Droite au Coeur, comme beaucoup de sites web depuis ~2010, est dynamique.

Cela signifie que votre navigateur va d'abord télécharger le code qui gère l'affichage de la page, mais sans télécharger le contenu.

Pendant qq secondes, la page ressemble en gros à ça : Image
C'est ce squelette de page qui va ensuite faire d'autres requêtes pour récupérer le contenu, ici les profils de dating.

Pour ça, l'interface va utiliser une API : c'est un programme hébergé côté serveur, qui va récupérer et formater les données qu'on lui demande. Image
Read 10 tweets
Jul 17, 2023
🧶THREAD - Un programme de 15 lignes de code Python arrive à rivaliser avec les meilleures intelligences artificielles !

Cette drôle de découverte vient d'être publiée par une équipe de chercheurs canadiens, et risque de bouleverser le monde du Machine Learning.

Explications ⤵️ "Qui gagne ?"  À gauche, un réseau de neurones ultra perfectionné avec 340 millions de paramètres  À droite, 15 lignes de Python
La classification de texte est l'un des domaines de recherche les plus actifs en intelligence artificielle : elle consiste à trier automatiquement des textes courts dans un ensemble de catégories pré-définies. Quelques phrases classées par catégorie :  Le briquet a été inventé 3 ans avant l'allumette (Histoire)  Les crocodiles ne peuvent pas tirer la langue (Nature)  Le miel ne périme jamais (Cuisine)  Les amandiers et les pêchers sont dans la même famille d'arbres (Nature)  (Instant culture inutile : toutes ces phrases sont vraies)
Pour évaluer la performance d'un modèle, on va travailler avec des datasets spécifiques.

L'un des plus connus est basé sur 1.4 millions de questions posées sur le site Yahoo Answers, réparties en 10 catégories : Plusieurs questions triées dans un tableau par catégorie. Voici par exemple les questions de la catégorie "Société" :  Comment ont été inventés les gros mots ? Comment devenir gothique ? SI DIEU NOUS A FAIT QUI A FAIT DIEU !? Est-ce que bisexuel est plus fun ? Croyez-vous en le nouvel an chinois ? Sens de la vie ?  (oui, ces questions existent vraiment dans le dataset)
Read 33 tweets

Did Thread Reader help you today?

Support us! We are indie developers!


This site is made by just two indie developers on a laptop doing marketing, support and development! Read more about the story.

Become a Premium Member ($3/month or $30/year) and get exclusive features!

Become Premium

Don't want to be a Premium member but still want to support us?

Make a small donation by buying us coffee ($5) or help with server cost ($10)

Donate via Paypal

Or Donate anonymously using crypto!

Ethereum

0xfe58350B80634f60Fa6Dc149a72b4DFbc17D341E copy

Bitcoin

3ATGMxNzCUFzxpMCHL5sWSt4DVtS8UqXpi copy

Thank you for your support!

Follow Us!

:(