Til hovedinnhold

Så enkelt er det å knekke en passorddatabase

Vi forklarer mekanismene bak hvordan passord sikres.

Hashing og angrep på hasher

Et par-tre ganger i året skjer det like punktlig som naturkatastrofer: En stor nettjeneste har blitt hacket og passord har kommet på avveie. Det har skjedd med Playstation Network, Xbox Live, Adobe og nylig datingnettstedet Ashley Madison, for å nevne noen. Brukernavn og tilhørende passord lagres i databaser på serverne til nettjenestene, og hvis hackere kommer seg inn i systemene kan de stikke av med verdifull informasjon som kan selges videre på det svarte markedet, publiseres for offentligheten eller utnyttes for å tjene penger.

De som har ansvaret for sikkerheten på slike nettsteder er naturligvis klar over denne faren – det er tross alt jobben deres – og derfor lagres ikke passord som leselig tekst i databasene. Først blir passordene hashet, men, som vi kommer til å vise i denne artikkelen, er det langt i fra tilstrekkelig.

Fra klartekst til røre

En hashfunksjon er et program som konverterer en melding, som for eksempel et passord, til uleselig tekst som ikke har noen likhet med den opprinnelige meldingen. Hasher vi for eksempel «tek.no» med den populære hashfunksjonen MD5 får vi ut «64acf9a61e4be21e6aa642abf01462c8» som resultat. Samme melding gir alltid samme resultat. En hash – i motsetning til en kryptert melding – kan ikke reverseres, noe som vil si at det i praksis er umulig å generere «tek.no» ut i fra hashen over. Når du logger inn på et nettsted genereres hashen på nytt fra passordet du har skrevet inn, og denne blir deretter sammenlignet med hashen som ligger i databasen. Hvis den er identisk, vet systemet at du har skrevet inn riktig passord.

En hashfunksjon må oppfylle flere viktige egenskaper. For det første må selv små endringer i meldingen som blir hashet føre til store endringer i den produserte hashen. Det vil i praksis si at «Tek.no» gir en helt ulik hash enn «tek.no».

Det andre viktige punktet handler om kollisjoner. En kollisjon betyr at to ulike meldinger genererer samme hash. Hvis for eksempel «passord1234» og «mittpassord» gir samme hash, har det skjedd en kollisjon. Dette er et problem fordi et passordsystem ikke sjekker om et gitt passord stemmer overrens med det som er lagret i databasen, men om hashen til et gitt passord stemmer overrens med hashen lagret i databasen. I overnevnte eksempel vil det bety at det er mulig logge inn med «mittpassord» selv om brukeren laget en konto med passordet «passord1234».

En hashfunksjon genererer alltid hasher av samme lengde. Hasher du bokstaven «t» eller hele bibelen vil hashen uansett bli like lang – 32 tall fra 0 til 9 og bokstaver A-F for MD5. Siden hashen har forhåndsbestemt lengde er det begrenset med hvor mange ulike hasher det er mulig å lage, og av den grunn er det umulig å unngå kollisjoner.

De som følger litt med i sikkerhetsverden har sikkert fått med seg snakket om at det har blitt funnet sårbarheter i MD5, og nå nylig SHA-1. Dette dreier seg om at forskere har funnet effektive metoder for å produsere to og to meldinger som gir samme hash – og er dermed en bekymring med tanke på eksempelvis SSL-sertifikater, men ikke sikring av passord. Svakhetene kan kun utnyttes hvis man kan bestemme beggemeldingene, og det er dermed ikke lettere å finne en kollisjon for en gitt hash enn det var før – men det betyr slettes ikke at disse to hashfunksjonene er sikre for å lagre passord. La oss gå videre for å se hvorfor.

Ut av syne – ut av sinn?

Som tidligere nevnt er hashing enveis, noe som gjør det er umulig å generere et passord ut i fra en hash. Dette betyr dog ikke at passordene ligger trygt lagret så lenge de er hashet – tvert i mot kan det gi en falsk trygghet. For å knekke en hash eller en database med hasher kan vi bruke samme fremgangsmetode som for å sjekke om et passord er gyldig: Først genererer vi en hash ut i fra et passord, og så sjekker vi om hashen stemmer overens.

Ettersom vi ikke vet det korrekte passordet å generere en hash ut i fra, må vi prøve og feile. Vi kan gjøre det systematisk, ved å generere hasher for "a", "b", "c" og så videre helt til vi finner en identisk hash. Dette kalles brute forcing, av den grunn av vi prøver alle mulige tall- og bokstavkombinasjoner til vi finner et passord som produserer korrekt hash.

Dictionary attacks og lookup tables

En mer effektiv metode er å bruke en liste med mulig passord, som for eksempel en ordliste, for å så generere hasher fra disse passordene og deretter sjekke hashene opp mot databasen. Dictionary attacks er som regel en langt mer effektiv metode enn brute forcing, da det er mulig å lage en god passordliste som gjør at vi slipper å kalkulere hasher for usannsynlige passord. «l!verp00l» er et mer sannsynlig passord enn «b?KA8_x2Y»; og en omfattende passordliste vil inneholde svært mange permutasjoner og allikevel være en liten brøkdel av størrelsen til en liste med alle mulige passordkombinasjoner.

Siden vi kan generere hasher uten å ta hensyn til hashene vi prøver å knekke, er det mulig å lage store tabeller med passord og hasher på forhånd som i ettertid kan testes mot en passorddatabase. Disse forhåndskalkulerte tabellene kalles lookup tables og er ofte benevnt som rainbow tables, dog sistnevnte egentlig er noe annet. Hvis vi skal teste en million passord mot en passorddatabase er det kalkulering av hasher som tar tid – hashfunksjonen krever prosessorkraft. Dette er helt neglisjerbart hvis vi skal kalkulere én hash fra ett passord, altså det serveren må gjøre når du logger inn med korrekt passord, men hvis vi skal kalkulere millioner av hasher er det bare å smøre seg med tålmodighet. Det er av den grunn at lookup tables er nyttige: du kan ta vare på eller laste ned en liste med ferdig kalkulerte hasher som samsvarer med en liste med passord.

Sikker passordlagring

Beskyttelse mot dictionary attacks

For å forhindre at angripere kan nytte seg av forhåndsgenererte tabeller med passord og hasher, kan vi modifisere passordet før det hashes og lagres i databasen. Hvis du bruker passordet «l!verp00l», kan vi legge til ekstra tekst på passordet. Legger vi til eksempelvis "2Kd40dZs" på slutten, er vi i tryggere hender. En god passordliste inneholder muligens «l!verp00l», men sannsynligheten er liten for at den inneholder "l!verp00l2Kd40dZs". Denne teksten vi legger til på slutten kalles en salt, og salting er en svært effektivt og mye brukt metode for å øke motstanddyktigheten til en hash. Det er to viktige punkter å føye til her: For det første må saltet være unikt for hver bruker, ellers kan en angriper bare modifisere sin passordliste og legge til saltet på slutten av hvert passord. For det andre må vi ta vare på saltet selv, for dette må vi bruke for å sjekke om en bruker har oppgitt riktig passord når hun prøver å logge inn. Saltet er som regel lagret i klartekst, og hvis det er tilfeldig generert er det ikke farlig om en angriper vet hva saltet til en gitt hash er.

Salting er også brukt i WPA- og WPA2-kryptering for trådløse nettverk. Her er det nettverksnavnet, som eksempelvis «dlink», som er saltet. Det vil si at to ulike nettverk med samme salt og passord vil ha samme krypteringsnøkkel, og for å forhindre dictionary attacks mot trådløse nettverk bør man derfor bytte til et unikt nettverksnavn.

Fra steinaldersverd til helautomatisk skytevåpen

Som du nå har lært, er det få snarveier for å knekke en passorddatabase. Det som gjelder er å teste med en god passordliste, men selv med en svært god passordliste – som både er omfattende og sortert i rekkefølge slik at mer sannsynlige passord blir testet først – må en angriper prøve mange passord før en nevneverdig andel av passordene i databasen blir funnet. Svært mange. De mest omfattende passordlistene som tas i bruk av hobbycrackere er på størrelsesorden rundt én milliard, men det finnes dog svært effektive lister på en brøkdel av størrelsen.

I løpet av de siste 10 årene har det skjedd en revolusjon innenfor passordcracking. OpenCL og CUDA fra henholdsvis AMD og Nvidia har gjort det mulig å bruke skjermkort til å løse andre oppgaver enn å tegne grafikk – som for eksempel å regne ut hasher. Det har vist seg at skjermkort er spesielt effektive til å kalkulere hasher, noe som betyr at passorcrackere kan teste ordlister mot passorddatabaser med mye høyere hastighet enn tidligere. Som eksempel, vil en moderne firekjerne-prosessor fra Intel klare å kalkulere rundt 100 millioner MD5-hasher per sekund, mens et Nvidia GTX 980 klarer rundt én milliard per sekund. Differansen er mye større på andre hashfunksjoner, som for eksempel WPA(2), som er rundt 50 ganger raskere.

Styrken til en hashfunksjon

Motstandsdyktigheten til en passorddatabase, gitt samme passord og hasher, bestemmes av hvilken hashfunksjon som er brukt. Styrken til en hashfunksjon, med tanke på passordlagring, bestemmes av hvor lang tid det tar å generere en hash ut i fra et passord. Hvis en hashfunksjon bruker ett sekund på å regne ut en hash, mens en annen bruker ett minutt, vil sistnevnte være tryggere ettersom angriperen må bruke seksti ganger mer tid for å teste den samme listen med passord.

Kraftige grafikkort kalkulerer hasher mye raskere enn vanlige PC-prosessorer. Foto: Kristoffer Møllervik, Tek.no

En hashfunksjon er laget for å være rask i bruk. Dette strider mot prinsippene som gjør en passorddatabase sikker, men hashfunksjoner brukes til mye mer enn å lagre passord. For å løse dette problemet, kan vi med vilje gjøre hashfunksjonen tregere. Ved å først hashe passordet og saltet, for å så hashe passordet, saltet og den forrige hashen om og om igjen kan vi selv velge hvor mye prosesseringskraft som trengs for å generere en endelig hash ut i fra et passord.

Det er dette prinsippet Key Derivation Functions (KDF) – hashfunksjoner spesielt laget for å lagre passord – er bygget på. Et eksempel på en KDF er bcrypt. Ved å bruke et skjermkort er det mulig å generere én milliard MD5-hasher per sekund, men med bcrypt klarer samme skjermkort rundt ti tusen hasher per sekund. I praksis betyr dette at enkle hashfunksjoner som MD5 ikke gir noen sikkerhet i det hele tatt. Det er ikke engang nødvendig med en god passordliste; en cracker trenger bare et relativt kraftig skjermkort for å knekke alle passord med normal lengde. Med bcrypt, eller andre KDF-er, er samme oppgave umulig.

I tillegg er KDF-er ofte designet for å være ineffektive å løse ved hjelp av skjermkort. Mens MD5 er rundt 10 ganger raskere og WPA 50 ganger raskere, er bcrypt bare dobbelt så raskt på et entusiast-skjermkort som på en moderne prosessor.

Du kan ikke anta at dine passord ligger trygt lagret

Så, hva kan vi lære av alt dette? Kryptografi, hashing og sikkerhet er svært tekniske og vanskelige emner, og undertegnede er langt i fra noen ekspert. Men det viser seg, gang på gang, at nettjenester heller ikke tar passordsikring seriøst. Ashley Madison-siden, som nylig ble hacket, hadde passordene kryptert med bcrypt. Selv om hashene ble lekket på nett, var det antatt at passordene var trygge. Men, av ukjente årsaker var rundt halvparten av passordene lagret separat og kryptert med MD5. Å knekke passorddatabasen hadde tatt flere tiår med bcrypt, men oppgaven var unnavgjort på et par korte arbeidsdager med MD5.

Trygg passordlagring har kompleks teori, men det er enkelt i praksis. Det krever bare at de som er ansvarlige for å oppbevare passordene dine nytter en god hashfunksjon og tilfeldige salter.

annonse