Détection de domaines look-alike : algorithmes et méthodes
Guide technique : détectez les domaines similaires via la distance de Damerau-Levenshtein, les homoglyphes et l'analyse structurelle. Avec exemples de code.
Un domaine look-alike est un nom de domaine conçu pour ressembler visuellement ou phonétiquement à un domaine légitime. La détection systématique de ces domaines repose sur trois familles de techniques : la distance d'édition, la substitution d'homoglyphes, et l'analyse de patterns structurels. Pour un domaine comme "acme.com", un scan complet peut générer plusieurs centaines de variantes candidates avant filtrage. Cet article couvre chacune de ces méthodes avec des exemples concrets et du code, puis explique comment Domain Sentinel les combine dans un pipeline de surveillance continue.
Distance d'édition : Levenshtein et Damerau-Levenshtein
La distance de Levenshtein entre deux chaînes est le nombre minimum d'insertions, suppressions et substitutions de caractères uniques nécessaires pour transformer l'une en l'autre. La variante Damerau-Levenshtein ajoute les transpositions de caractères adjacents, ce qui couvre les erreurs de frappe les plus fréquentes en conditions réelles.
Exemples concrets pour la chaîne "acme" :
- "acme" vs "acmee" : distance 1 (insertion d'un caractère)
- "acme" vs "acne" : distance 1 (substitution de "m" par "n")
- "acme" vs "amce" : distance Damerau 1 (transposition), distance Levenshtein 2
Pour la surveillance de marque, un seuil de distance de 1 ou 2 est généralement utilisé selon la longueur du nom. Les noms courts (4-5 caractères) nécessitent un seuil de 1 pour éviter les faux positifs ; les noms plus longs peuvent tolérer 2.
Implémentation Python
def damerau_levenshtein(s1, s2):
d = {}
len1, len2 = len(s1), len(s2)
for i in range(-1, len1 + 1):
d[(i, -1)] = i + 1
for j in range(-1, len2 + 1):
d[(-1, j)] = j + 1
for i in range(len1):
for j in range(len2):
cost = 0 if s1[i] == s2[j] else 1
d[(i, j)] = min(
d[(i - 1, j)] + 1,
d[(i, j - 1)] + 1,
d[(i - 1, j - 1)] + cost
)
if i > 0 and j > 0 and s1[i] == s2[j-1] and s1[i-1] == s2[j]:
d[(i, j)] = min(d[(i, j)], d[(i-2, j-2)] + cost)
return d[(len1 - 1, len2 - 1)]
def generate_variants_distance_1(name):
alphabet = 'abcdefghijklmnopqrstuvwxyz0123456789-'
variants = set()
for i in range(len(name)):
variants.add(name[:i] + name[i+1:])
for c in alphabet:
variants.add(name[:i] + c + name[i+1:])
variants.add(name[:i] + c + name[i:])
if i < len(name) - 1:
variants.add(name[:i] + name[i+1] + name[i] + name[i+2:])
return variants - {name}
Génération de variantes à distance 1
Les quatre catégories de modifications et le volume qu'elles produisent pour un nom de longueur n :
- Suppressions : n variantes
- Substitutions : n × 36 variantes (26 lettres + 10 chiffres + tiret)
- Insertions : (n+1) × 36 variantes
- Transpositions : (n-1) variantes
Pour un nom de 5 lettres, cela produit environ 380 à 420 variantes brutes avant filtrage des chaînes invalides en DNS et déduplication.
Homoglyphes : l'attaque par substitution de caractères Unicode
Un homoglyphe est un caractère Unicode qui ressemble visuellement à un autre. Les attaques par homoglyphes exploitent les noms de domaine internationalisés (IDN), qui permettent des caractères non-ASCII encodés en Punycode. Le "а" cyrillique (U+0430) est visuellement identique au "a" latin (U+0061) dans quasiment toutes les polices. Un attaquant peut enregistrer "аpple.com" avec un "а" cyrillique et ce domaine s'affiche comme "apple.com" dans de nombreux contextes.
Substitutions homoglyphes les plus fréquentes :
| Original | Substituts courants |
|---|---|
| a | а (U+0430 cyrillique), ɑ (U+0251), α (U+03B1 grec) |
| o | о (U+043E cyrillique), 0 (zéro), ο (U+03BF grec) |
| e | е (U+0435 cyrillique), ё (U+0451) |
| c | с (U+0441 cyrillique) |
| p | р (U+0440 cyrillique) |
| l | 1 (un), I (i majuscule), |
| n | п (U+043F cyrillique) |
| i | í (U+00ED), ï (U+00EF), 1 (un) |
Détection programmatique des homoglyphes
Le Consortium Unicode maintient un jeu de données public "confusables" qui associe chaque caractère à ses équivalents visuels. Une approche Python pratique :
HOMOGLYPHES = {
'a': ['а', 'ɑ', 'α'],
'o': ['о', '0', 'ο'],
'e': ['е', 'ё'],
'c': ['с'],
'l': ['1', 'I'],
'p': ['р'],
}
def generate_variantes_homoglyphes(domaine):
nom, tld = domaine.rsplit('.', 1)
variantes = set()
def recursion(index, courant):
if index == len(nom):
if courant != nom:
variantes.add(f"{courant}.{tld}")
return
char = nom[index]
recursion(index + 1, courant + char)
for substitut in HOMOGLYPHES.get(char, []):
recursion(index + 1, courant + substitut)
recursion(0, '')
return variantes
Attention à l'explosion combinatoire : un nom de 6 lettres où chaque lettre possède 3 homoglyphes possibles génère jusqu'à 3^6 = 729 variantes par homoglyphes seuls. En pratique, on applique une profondeur de substitution maximale (typiquement 2 substitutions par domaine) pour garder l'ensemble gérable.
Comment les navigateurs modernes gèrent les IDN
Chrome et Firefox affichent la représentation Punycode (commençant par xn--) plutôt que le domaine Unicode quand un domaine mélange des scripts différents (par exemple latin et cyrillique dans le même label). Ainsi, "аpple.com" avec un "а" cyrillique apparaît dans la barre d'adresse comme xn--pple-43d.com. En revanche, les domaines cyrilliques monoscript peuvent encore s'afficher en Unicode, ce qui rend la détection d'homoglyphes toujours pertinente. Le Punycode pour аcme.com (а cyrillique) est xn--cme-9cd.com.
Analyse structurelle : variantes de TLD et patterns préfixes/suffixes
La troisième famille ne manipule pas les caractères individuels, mais la structure du domaine lui-même.
TLD swapping
Remplacer le TLD est la variante la plus simple à générer et souvent la plus pertinente commercialement. Pour "acme.com", cela produit acme.net, acme.io, acme.co, acme.app, acme.shop. Les TLDs les plus fréquemment utilisés pour les abus :
- .co (très courant : visuellement proche de .com et ccTLD légitime)
- .net (historique, largement reconnu)
- .io (standard secteur tech, confusion croissante avec .com)
- .app (mobile et SaaS)
- .shop, .store (e-commerce)
- .xyz, .top, .tk, .ml, .ga (souvent gratuits ou quasi-gratuits, utilisés massivement pour le phishing)
Patterns préfixe/suffixe courants
Ces patterns sont souvent plus dangereux que les simples fautes de frappe car ils peuvent tromper des utilisateurs avertis :
get{marque}.com try{marque}.com essai{marque}.com
{marque}app.com {marque}hq.com {marque}online.com
{marque}-login.com {marque}-secure.com {marque}-account.com
{marque}officiel.com {marque}support.com {marque}-aide.com
mon{marque}.com {marque}pro.com {marque}plus.com
{marque}portail.com {marque}-verification.com
Les mots "login", "secure", "compte" et "verification" dans un nom de domaine sont des signaux d'alarme, pas des signaux de confiance. Les services légitimes incluent rarement ces termes dans leur nom de domaine principal.
Séparateurs et variantes composées
Si votre marque est composée ("Domain Sentinel"), surveillez : domainsentinel.com, domain-sentinel.com, sentineldomain.com, sentinel-domain.com. Si votre marque utilise un tiret, surveillez la version sans tiret et vice-versa.
Combiner les méthodes : le pipeline complet de détection
Domain Sentinel combine ces trois familles dans un pipeline séquentiel :
- Génération des candidats via les variantes Damerau-Levenshtein (distance 1-2), les substitutions homoglyphes (jusqu'à 2 substitutions), les permutations de TLD sur une liste de TLDs sélectionnée, et les variantes structurelles (préfixes/suffixes).
- Déduplication et filtrage pour éliminer les chaînes invalides en DNS (labels supérieurs à 63 caractères, combinaisons de caractères invalides) et réduire l'ensemble des candidats.
- Vérification RDAP en batch pour chaque candidat : enregistré, disponible, ou en attente/réservé.
- Classification des résultats : les nouveaux enregistrements déclenchent des alertes ; les domaines disponibles peuvent être signalés pour un éventuel enregistrement préventif.
- Priorisation des alertes par risque : les domaines combinant plusieurs signaux de similarité (faute de frappe + mot-clé sensible + enregistrement récent) sont classés plus haut que les simples permutations de TLD avec un long historique d'enregistrement.
Le problème du "bruit" est réel : la génération exhaustive peut produire des milliers de candidats. La priorisation par distance d'édition, niveau de risque du TLD, et présence de mots-clés à haut risque (login, secure, officiel, verification, support) maintient la file d'alertes exploitable.
Outils open source et APIs disponibles
Pour les équipes qui souhaitent construire leur propre pipeline ou valider des résultats :
dnstwist(Python, open source) est l'outil de référence pour la génération de variantes de domaines look-alike. Il implémente la plupart des méthodes décrites ici et inclut des lookups RDAP/WHOIS.urlcrazyest similaire, axé sur la génération de variantes de typosquatting.- Le service RDAP de l'ICANN sur
rdap.orggère les lookups RDAP individuels gratuitement et sans authentification. - Domain Sentinel automatise l'ensemble du pipeline en continu, envoie des alertes quand de nouveaux enregistrements sont détectés, et gère la complexité des requêtes RDAP et des limites de débit.
La limite principale des outils open source : ils génèrent des variantes mais ne surveillent pas en continu. Exécuter dnstwist une fois vous dit ce qui est enregistré aujourd'hui. Il faut le réexécuter demain, puis le surlendemain, et construire son propre système de notification par-dessus. C'est l'écart que Domain Sentinel comble.
En pratique, commencer par les permutations de TLD et les patterns structurels donne le signal le plus rapide avec le moins de bruit. Ajouter les variantes Damerau-Levenshtein pour une couverture exhaustive des fautes de frappe, puis intégrer la détection d'homoglyphes pour une couverture complète. Le scan complet d'un nom de marque de 6 caractères sur 20 TLDs et un ensemble de 30 patterns préfixe/suffixe produit environ 2 000 à 3 000 domaines candidats à vérifier via RDAP. Lancez une analyse de votre domaine sur Domain Sentinel pour voir lesquels sont déjà enregistrés.
Commencez par un domaine qui vous importe
Recherchez-le gratuitement. Pour recevoir des alertes sur les changements de statut ou l'expiration, créez un compte. Ça prend 30 secondes.