Qu'est-ce qu'un homoglyphe
Un homoglyphe est un caractère qui ressemble visuellement à un autre mais possède un code point Unicode différent. Unicode contient des milliers de scripts — latin, cyrillique, grec, arménien — dont beaucoup partagent des glyphes visuellement indiscernables.
Cette ambiguïté est exploitée en stéganographie : on substitue certaines lettres latines par leurs équivalents cyrilliques ou grecs. Le texte affiché est visuellement identique — seule une inspection du code source ou du fichier hexadécimal révèle la différence.
| Char visible | Unicode latin | Unicode alternatif | Script |
|---|---|---|---|
| a | U+0061 | U+0430 (а) | Cyrillique |
| e | U+0065 | U+0435 (е) | Cyrillique |
| o | U+006F | U+043E (о) | Cyrillique |
| p | U+0070 | U+0440 (р) | Cyrillique |
| c | U+0063 | U+0441 (с) | Cyrillique |
| x | U+0078 | U+0445 (х) | Cyrillique |
| H | U+0048 | U+0397 (Η) | Grec |
| A | U+0041 | U+0391 (Α) | Grec |
Texte affiché : "café" (identique visuellement)
Vrai contenu : c(U+0063) a(U+0430) f(U+0066) é(U+00E9)
↑
'а' cyrillique (U+0430)
pas 'a' latin (U+0061)
Dans un éditeur de code :
"café" en UTF-8 : 63 61 66 C3A9 (tout latin)
"café" stégo : 63 D0B0 66 C3A9 (a cyrillique en 2 bytes!)Le dictionnaire des confusables Unicode
Unicode maintient officiellement une liste de confusables dans le rapport technique Unicode TR39. Ce document liste tous les caractères visuellement similaires à travers les différents scripts.
Pour la stéganographie, on associe à chaque lettre substituable une paire :
Confusables cyrilliques
~30 substitutionsLe script cyrillique offre les meilleures substitutions avec le latin. Les lettres а, е, о, р, с, х sont visuellement indiscernables de leurs homologues latins dans la plupart des polices.
Confusables grecs
~12 substitutionsL'alphabet grec partage plusieurs glyphes avec le latin : Α (alpha), Β (bêta), Η (êta), Ι (iota), Κ (kappa), Μ (mu), Ν (nu), Ο (omicron), Τ (tau), Υ (upsilon), Χ (khi), Ζ (dzêta).
Encodage binaire par substitution
Pour encoder un message, on parcourt le texte de couverture à la recherche de lettres substituables. Pour chaque bit du message :
- bit = 0Garder la lettre originale (latin standard)
- bit = 1Remplacer par l'homoglyphe correspondant (cyrillique ou grec)
Si le texte ne contient pas assez de lettres substituables, le message est trop long pour ce texte de couverture. La capacité est directement liée au nombre de caractères confusables présents dans le texte porteur.
TEXTE DE COUVERTURE : "La securite est primordiale" MESSAGE : "Hi" = 01001000 01101001 Substitutions disponibles : e(×4), a(×2), o, i(×2), c, ... Bit 0 → 'e' reste 'e' (U+0065) Bit 1 → 'a' devient 'а' (U+0430 cyrillique) Bit 0 → 's' reste 's' (pas de substitution disponible → skip) Bit 0 → 'e' reste 'e' Bit 1 → 'c' devient 'с' (U+0441 cyrillique) ... Texte stégo affiché : "La securite est primordiale" (identique!) Texte stégo réel : "Lа sеcurite est primordiale" (2 chars changés)
Détection
Un éditeur hexadécimal ou un analyseur Unicode révèle immédiatement les substitutions : un 'a' cyrillique (2 octets UTF-8 : D0 B0) est distinguable d'un 'a' latin (1 octet : 61). Certains navigateurs et éditeurs de code soulignent les caractères mixtes par sécurité.
Les homoglyphes sont également exploités dans des contextes malveillants : l'IDN homograph attack consiste à enregistrer des noms de domaine avec des homoglyphes (ex: gооgle.com avec о cyrillique) pour tromper les utilisateurs. Les navigateurs modernes affichent ces domaines en Punycode (xn--) pour les démasquer.
// Détecter homoglyphes JavaScript
function detectHomoglyphs(text) {
const suspicious = []
for (const char of text) {
const cp = char.codePointAt(0)
// Détecter chars cyrilliques dans texte latin
if (cp >= 0x0400 && cp <= 0x04FF) suspicious.push({ char, cp: cp.toString(16) })
// Détecter chars grecs
if (cp >= 0x0370 && cp <= 0x03FF) suspicious.push({ char, cp: cp.toString(16) })
}
return suspicious
}⚠ Les moteurs de recherche et les filtres anti-spam modernes détectent les mélanges de scripts Unicode. Un texte contenant des homoglyphes cyrilliques dans un contexte latin peut déclencher des alertes de sécurité.
Homoglyphes vs Zero-Width
Les homoglyphes et les caractères zero-width sont les deux principales approches de stéganographie textuelle Unicode. Elles diffèrent fondamentalement dans leur méthode : substitution visible pour les uns, insertion invisible pour les autres. Chaque approche a des avantages selon le contexte de transmission.
| Critère | Homoglyphes | Zero-Width |
|---|---|---|
| Détection visuelle | Impossible | Impossible |
| Détection technique | Analyse Unicode (facile) | Recherche ZWC (facile) |
| Capacité | Limitée (chars substituables) | Plus élevée (insertion libre) |
| Transmission email/web | ~ Risque filtres anti-spam | ✓ Généralement préservé |
| Complexité encodage | Modérée (dict. confusables) | Simple (insertion directe) |
Questions fréquentes
Qu'est-ce qu'un homoglyphe et pourquoi c'est invisible ?
Un homoglyphe est un caractère d'un autre alphabet (cyrillique, grec) qui a exactement la même forme visuelle qu'une lettre latine. Par exemple, le 'а' cyrillique (U+0430) et le 'a' latin (U+0061) sont identiques à l'écran dans quasiment toutes les polices. Seul un éditeur hexadécimal ou l'inspection des codes Unicode révèle la différence.
Les homoglyphes sont-ils utilisés pour autre chose que la stéganographie ?
Oui — et c'est là leur côté sombre. L'attaque IDN homograph consiste à enregistrer des noms de domaine avec des homoglyphes : `gооgle.com` avec un 'о' cyrillique au lieu du latin. Les navigateurs modernes affichent ces domaines en Punycode (xn--) pour les démasquer. Les filtres anti-spam les détectent aussi comme signal de phishing.
Peut-on facilement encoder automatiquement un message en homoglyphes ?
Oui. Le dictionnaire de confusables Unicode (TR39) est public et facile à implémenter. En Python, une table de substitution `{'a': 'а', 'e': 'е', 'o': 'о', ...}` permet d'encoder automatiquement. La contrainte est la capacité : le texte de couverture doit contenir suffisamment de lettres substituables pour encoder tous les bits du message.
Comment détecter des homoglyphes dans un texte suspect en CTF ?
Coller le texte dans un analyseur Unicode (unicode.org character inspector) ou utiliser Python : `[hex(ord(c)) for c in text]` révèle les codes points réels. Un 'a' cyrillique retourne 0x430, un 'a' latin retourne 0x61. En JavaScript : `text.split('').map(c => c.codePointAt(0).toString(16))` fait la même chose.
La technique des homoglyphes est-elle sécurisée pour communiquer ?
Non, pas sans chiffrement. Les homoglyphes assurent l'invisibilité visuelle, pas la confidentialité. Si quelqu'un analyse le texte avec les bons outils, il peut décoder le message facilement avec le dictionnaire de confusables. Combinez toujours avec AES-256 : chiffrez d'abord le message, puis encodez le résultat en homoglyphes.
Outil homoglyphes en développement
L'outil homoglyphes est en cours de développement. En attendant, utilisez l'outil Zero-Width qui repose sur un principe similaire de stéganographie textuelle.