XOR à un octet : décoder l'hexadécimal et inverser une clé d'un octet
Le défi
Un petit binaire de CTF stocke son flag sous forme de chaîne hexadécimale et le XOR avec un octet fixe au démarrage. Vous avez extrait l'hexadécimal ci-dessous et l'octet 0x2a (le caractère « * »). Décodez l'hexadécimal, refaites le XOR, et soumettez le flag (HDNA{...}).
Ce que tu vas apprendre
- Reconnaître une chaîne entièrement hexadécimale comme une couche de transport hexadécimale
- Décoder l'hexadécimal en octets bruts avant d'appliquer une opération au niveau des octets
- Inverser un XOR à un octet avec un octet de clé connu
- Comprendre que le XOR est sa propre inverse
- Expliquer pourquoi un XOR à un octet n'a que 256 clés possibles et ne protège rien
Compétences testées
Prérequis
- À l'aise avec la lecture de l'hexadécimal
- Comprendre que le XOR est sa propre inverse
Comment ça marche
C'est le décodage en couches le plus simple qui soit : un flag stocké sous forme de chaîne hexadécimale et XORé avec un seul octet. L'hexadécimal n'est qu'une façon textuelle d'écrire des octets, deux caractères hexadécimaux par octet, donc la première étape consiste à reconvertir l'hexadécimal imprimable en octets bruts qu'il représente. Ces octets restent illisibles car ils ont été brouillés par XOR avec un octet fixe.
Le XOR est symétrique : appliquer le même octet aux données une seconde fois annule le premier, car A XOR B XOR B = A. Il suffit donc de XORer chaque octet avec la clé pour retrouver le texte en clair. Ici, la clé est 0x2a, le caractère ASCII *. Un XOR à un octet n'a que 256 clés possibles, ce qui explique qu'il n'offre aucune sécurité : un analyste peut toutes les essayer instantanément et garder le résultat qui se lit comme du texte.
Dans le workbench, ajoutez From Hex, puis XOR avec la clé 0x2a (ou le caractère *), et le flag apparaît en direct dans la sortie. Les autres opérations (base64, ROT, atbash, reverse, Vigenere, URL-decode) sont des leurres : base64 est le piège le plus proche, mais l'entrée n'est pas du base64 valide, donc elle ne peut pas s'appliquer.
Erreurs fréquentes
- Essayer le base64 au lieu de l'hexadécimal. L'entrée est entièrement composée de caractères hexadécimaux sans padding : décodez-la en hex, pas en base64.
- XORer directement le texte hexadécimal. Décodez d'abord l'hexadécimal en octets, puis XORez ces octets.
- Se tromper sur la clé. 0x2a est le caractère '*' : saisissez l'octet attendu par le workbench.
- Supposer une clé plus longue. Il s'agit d'un seul octet ; une clé multi-caractères ne le décodera pas.
Comment s'en protéger
Pour les défenseurs et les reverse engineers, la leçon est que le XOR à un octet sur de l'hexadécimal est le degré minimal d'obfuscation : c'est la première chose à essayer lors du triage d'un petit binaire, et cela ne doit jamais protéger quoi que ce soit d'important. Si votre propre code « protège » une valeur de cette façon, traitez-la comme du texte en clair.
- Effectuez un brute force sur les 256 clés XOR à un octet contre les blobs hexadécimaux ou binaires courts lors du triage.
- Décodez automatiquement les enveloppes hexadécimales et base64 avant d'analyser les octets sous-jacents.
- Ne stockez jamais de vrais secrets sous forme d'hexadécimal plus un octet XOR statique : utilisez un chiffrement authentifié avec une clé gérée.
- Gardez les flags et secrets hors du binaire lorsque le modèle de menace l'exige.