Jagt på domæne-snyltere kan automatiseres med 113 linjers kode

En klassisk algoritme gør det muligt at finde nyregistrerede domæner, som kan forveksles med populære hjemmesider og misbruges til svindel.

Overskriften er lidt en tilsnigelse, for antallet af kodelinjer er kun for min hurtigt sammenbiksede primitive applikation. Pointen er, at det ikke kræver mere end nogle timers arbejde at stykke et program sammen, som kan automatisere jagten på potentielle svindeldomæner.

For hvad gør man, hvis man er ansvarlig for en stor hjemmeside, hvor det af den ene eller anden grund kan være lukrativt at eje et domænenavn, som ligger foruroligende tæt op af det rigtige navn?

Typosquatting (efter det engelske ord for trykfejl 'typo' og 'squatter', som kan oversættes til slumstormer) går i sin mest uskyldige form ud på at registrere et domæne, som en bruger af en populær hjemmeside kunne havne på ved at ramme den forkerte tast på tastaturet. På det næsten-korrekte domæne kan man placere bannerreklamer eller lede videre til en webshop.

Den mindre uskyldige form er der, hvor typosquatteren også kopierer varemærker og på flere måder udgiver sig for at være den ægte vare. Hvis det ægte domæne tilhører en tøjbutik, så kunne det være en netbutik, som sælger kopivarer. Eller det kunne være en side med falske nyheder, hvis domænet ligger tæt på et stort netmedie.

Den mest alvorlige form er der, hvor siden bruges til phishing for at lokke personlige oplysninger ud af brugeren eller få brugeren til at installere malware på sin pc.

Under alle omstændigheder kan det være interessant for en hjemmesideejer om ikke andet så at vide, hvilke domæner der eksisterer, som ligger tæt op af det rigtige.

Regex blev droppet

Det var dén opgave, vi på redaktionen talte om, at det måtte være muligt at automatisere, og det vakte min nysgerrighed.

Min første tanke var, at det måtte være muligt at konstruere et passende regulært udtryk (regular expression eller regex), som på en liste over registrerede domæner kunne finde dem, der lå tættest på et bestemt domæne. Det ville kræve nogle regler om eksempelvis udskiftning af visse tegn med andre.

Men et kig på reelle typosquatting-domæner fik idéen til at falde til jorden. For det var ikke blot at erstatte et 'o' med et '0' i versi0n2.dk. Det ville også kræve, at mit regex tog hensyn til forskellige plausible stave- og slåfejl såsom verson2.dk.

Det ville med andre ord blive en forholdsvis vanskelig øvelse at sammensætte ét eller flere regulære udtryk, som kunne finde varianter over et domænenavn, og den øvelse skulle gentages for hvert eneste domæne, der skulle overvåges.

Levenshtein til undsætning

Så jeg gik på jagt efter en algoritme, der kunne finde frem til, om en given tekststreng var en mutation af en anden tekststreng. Heldigvis er det ikke et ukendt problem i datalogien.

Levenshtein-afstand bruges til at måle det minimale antal operationer, der udgør forskellen mellem to tekststrenge. Det vil sige, hvor mange bogstaver skal udskiftes, indsættes eller fjernes for at få de to til at matche. Jo mindre denne værdi er, jo tættere ligger de to ord på hinanden. Ordene 'kylling' og 'killing' har en Levenshtein-afstand på 1, da blot y og i skal byttes ud.

Jeg brugte en implementering af Levenshtein-algoritmen fra DotNetPerls. Jeg var egentligt gået i gang med at skrive mit program i JavaScript, men skiftede til C#, fordi jeg gerne ville kunne specificere to filer med lister over domæner til programmet, så blev det C#, selvom jeg ligeså godt kunne have brugt Python.

Det skal siges, at Levenshtein-afstand kan være lidt beregningstung, fordi der arbejdes iterativt med matricer, så hvis man har mange tusinde domæner, som skal testes mod mange tusinde varemærker, så kan de forskellige implementeringer gøre en forskel.

I øvrigt bør jeg nok skifte til Damerau-Levenshtein-afstanden, fordi den også kan måle på ombytning af to tegn, der står ved siden af hinanden.

Første testkørsel på ægte domæner, inklusive en lidt sær fejl i min kode, som nu er rettet. Illustration: Privatfoto

Test på tvivlsomme domæner

Hele diskussionen udsprang af, at vi havde fået en liste over mistænkelige danske domænenavne tilsendt fra en læser. Med udgangspunkt i dén liste lavede jeg to filer: En med de tvivlsomme domænenavne og én med ægte domæner, som var hyppige mål for de tvivlsomme domæner.

Derefter fordrede jeg mit nycompilerede program med de to filer og gav det samtidig en tærskel for, hvor stort sammenfaldet mellem navnene skulle være i procent for at udløse en advarsel.

Umiddelbart virkede mit første udkast til programmet, som nu ligger på Github, sådan set udmærket, men min tilgang til løsningen viste nogle svagheder.

Et af de domæner, som blev misbrugt på den tvivlsomme liste, var Ikeas danske domæne. Men for korte navne er Levenshtein-afstanden ikke helt så anvendelig - i hvert fald ikke udtrykt som en procentdel, sådan som jeg havde implementeret min tærskel. Hvis man eksempelvis blot bytter om på to bogstaver, vil det give en Levenshtein-afstand på 2, men det udgør blot et sammenfald på 50 procent.

Omvendt vil det ikke være ideelt blot at sætte en ren numerisk tærskel for Levenshtein-afstanden, da det kunne give mange falske positiver for korte domænenavne eller lade ægte positiver slippe igennem maskerne for lange navne. Det er helt klart en del af mit program, der skal justeres ved at se, hvordan jeg bedst finder alle typer af variationer.

Data er den største forhindring

Imidlertid er det ikke justeringen af min algoritme, som viser sig at være den største udfordring. Det er derimod at skaffe de data, programmet skal fodres med.

Det er nemlig ikke bare sådan lige at downloade en liste over de senest registrerede domænenavne, og det bliver særlig kompliceret, hvis man også ønsker at dække sig ind over for domæner, der registreres under andre topdomæner.

Umiddelbart er den eneste løsning at købe sig til disse oplysninger. Prisen er overkommelig i forhold til, at det nok hovedsageligt er interessant, hvis man i forvejen er et større website, men hvis der skal betales for information fra flere udbydere for dække sig ind på flere nationale topdomæner, så bliver det både en større udgift, og det bliver en opgave at samle data.

Til gengæld kan jeg konkludere, at den overordnede idé om at kunne automatisere overvågning af domæner, som forsøger at snylte eller i hvert fald lukrere på et populært navn, er en overkommelig programmeringsmæssig opgave, som kan løses på 113 linjer.

En læser har gjort opmærksom på et andet projekt på Github dnstwist, som ud fra det domænenavn, du giver programmet, genererer en liste over potentielle typosquatting-domæner og laver DNS-opslag for at se, om de findes. En anden læser har gjort opmærksom på TRE, der også ligger på Github og er et Regex-library med forskellige muligheder for fuzzing.

Tips og korrekturforslag til denne historie sendes til tip@version2.dk
Følg forløbet
Kommentarer (7)
sortSortér kommentarer
  • Ældste først
  • Nyeste først
  • Bedste først
Povl H. Pedersen

Ellers må du løbe DNS igennem. Det tager lidt tid at suge alle mutationerne ned. Men det burde være muligt at sige længde +/- 1 karakter.

Tag rejseplanen. Hvis vi siger at det højst er 2 karakterer der må være i forskel, det mindsker også udfaldsrummet meget. Så er der 25*25 = 625 for hver 2 bogstavers afvigelse. Og det kan være 1,2..1,3..1,4..1,11 = 10 for første kombo. 2,3... for næste = 9..... Så ca. 54 muligheder * 625 = 33750. Det er overskueligt, selv for et langt navn. Ved ikke hvor mange DNS opslag man kan lave i sekunder ved parallel kørsel. Lad os sige 10, det er 600 i minuttet. Eller under 10 minutter. Man kan også bruge svartider til at se om det er cachet hvis man bruger eksempelvis google.

Så mangler man lige med 9 bogstaver (pil 1 bogstav ud skiftvis og kør igen). Og med 11 bogstaver. Så skal der prøves med alle bogstaver på hver mulig plads i ordet. Her begynder antallet at vokse.

  • 0
  • 0
David Konrad

Levenshtein er algoritmisk brugelig til formålet, men den tæller bare bogstaver - ikke semantik og udtale. Vi har et glimrende eksempel pt. i "wine-famly.com" der nasser på "wine-familiy.com", og i reklamerne udtales som "wine-familiy.com". Ikke mærkeligt hvis de får en del positiv crossover. Det er naturligvis dybt amoralsk men ikke ulovligt, altså med mindre man bruger et tocifret millionbeløb på en retssag, eller har varedeklareret navnet. I dk må man ikke nasse på domænenavne, men så duer Levenshtein ikke. Hvad med versjonto.dk? Den ville falde for Levenshtein ift version2x.dk. Øvelsen er mao ubrugelig, for der er intet formål med den.

Mit eget firmanavn er jeg flere gange er blevet advaret imod er titlen på en kendt sang, en spejderbevægelse og der er sågar eet af de største franske boligselskaber der hedder der samme (derfor får jeg tit uopfordrede ansøgninger på fransk, med CV og hele pivtøjet) men det er ikke mit problem. Jeg registrerede domænet først, for 10 år siden. Det er ligesom et telefonummer. Lev med det.

  • 1
  • 3
Michael Bisbjerg

Du ville ikke bruge en resolver til denne her øvelse. Du ville bruge de autoritative servere direkte. DK zonen har 6 hostnames (~2 ip'er hver), som er anycastede (vistnok).. Så det er bare at vælge den der svarer hurtigst (eller sprede sit load over flere).

I enkelte tilfælde har jeg kunnet presse flere tusinde opslag i sekundet igennem .. Så de er ikke langsomme :)

  • 0
  • 0
Log ind eller Opret konto for at kommentere