Jag börjar med möjliga konsekvenser av att bli av med sitt lösenord: om allt det leder till är att någon kan logga in på ens forumkonto och skriva "Nvidia är bäst lol" så är det inte hela världen, och det kommer troligen snabbt upptäckas.
Om en användare dock exempelvis använt samma lösenord på fler ställen, typiskt ett e-postkonto (men även andra platser kan vara problematiska), så kan en attackerare möjligen komma åt detta konto, och därifrån går det att göra rätt mycket. Identitetsstöld, sökande efter känslig information (företagshemligheter, personliga kontakter) i utpressningssyfte, … — med fantasi kan man komma på en hel del saker.
Har du bytt ditt lösenord på alla sidor så kan en attackerare ju dock inte komma åt dessa konton längre, vilket är anledningen till att seriösa sidor alltid är snabba och tydliga med uppmaningar om att byta sina lösenord överallt efter liknande intrång. I praktiken är detta något användare borde göra periodiskt ändå, då inte alla sidor säger till när de blivit utsatta för intrång, och ibland inte ens har en möjlighet att veta att ett intrång skett.
En annan möjlighet är att din e-postadress numera finns i klartext på vift på nätet, vilket skulle kunna göra den till ett mål för spam. I mina ögon är detta inte speciellt mycket att oroa sig för, då detta är en risk man tar varje gång man skickar ett e-post till någon i hela vida världen, och man inte bör se på en e-postadress som en "hemlighet" i sig. Även om man vidtar alla åtgärder man kan tänka sig så har man troligen någon gång skickat ett e-post till en vän, som i sin tur blivit hackad, och vips är ens egen e-postadress likväl känd. Det tål att nämnas som en konsekvens av liknande "hack", men det är inte värre än att ens spamfilter möjligen får arbeta lite mer.
Jag fortsätter med en längre utläggning om de termer som nämns i artikeln och i diskussionen ovan, för de som känner sig borttrollade när det pratas om "hash", "salt", etc.
——
En dödssynd som vissa sidor begår är att de lagrar användares lösenord i klartext (*host host*). Det betyder att om Christina med e-postadress christina@hotmail.com
använder lösenordet "mammasmurf", så lagrar sidan "mammasmurf" i databasen med användaruppgifter på deras server.
Om en sådan sida skulle bli av med sina användardata på något sätt så kan den som kommer över denna information direkt mappa varje användarnamn och e-postadress till ett visst lösenord. Det första en attackerare då gör är att gå till Hotmail och testa att logga in på christina@hotmail.com
med lösenord "mammasmurf". Lyckas detta så har attackeraren tillgång till Christinas e-postkonto, vilket i praktiken innebär tillgång till alla Christinas online-konton genom lösenordsåterställningsfunktioner och liknande. Christina skulle även kunna ha känslig information liggandes direkt i sitt e-postarkiv.
I ovanstående hypotetiska fall så var det (minst) två aktörer som felade:
Bättre är de fall då en sida enbart lagrar ett hash av ett lösenord. Utförligare förklaring följer.
En hashfunktion kan liknas vid en svart låda som kan ta ett in-värde (av godtycklig längd), och därefter spottar ut ett motsvarande ut-värde (av en viss konstant längd). Ett visst in-värde ger alltid samma ut-värde. En kryptografiskt användbar hashfunktion har även egenskapen att det, utifrån ett givet ut-värde, är näst intill omöjligt att lista ut vilket in-värde som gavs (en envägsfunktion). Ett exempel är hashfunktionen SHA-1, som skulle ge:
"mammasmurf" → [SHA-1] → "d99abf2e4bcd8b6a2634ee06df444c6179c7dda5"
SHA-1 är en känd funktion, och vem som helst med tillgång till en dator kan enkelt kontrollera att "mammasmurf" ger exakt detta utvärde. Däremot, så om man bara känner till att det var SHA-1 som användes och man har utvärdet tillgängligt så är det väldigt svårt att gå "baklänges" och lista ut att det var just "mammasmurf" som skickades in.
När Christina skriver in "mammasmurf" under registreringen på en vettigare sida så tar servern och applicerar en hashfunktion på strängen, och lagrar sedan bara resultatet. Nästa gång Christina vill logga in så skriver hon likväl "mammasmurf", servern applicerar samma hashfunktion på vad än Christina skriver in och jämför det med det lagrade resultatet. Om detta ut-värde stämmer med det som lagrades vid registrering så kan man anta att användaren skrivit in samma lösenord, och Christina loggas in. Notera dock att servern inte någon gång behöver lagra strängen "mammasmurf" för att ändå kunna identifiera Christina.
Om en attackerare får tag i denna hashade användardatabas så är det inte lika öppen gata som i klartextfallet. Attackeraren får ju nu inte lösenordet serverat, utan bara ut-värdet efter att hashfunktionen applicerats. Även om Christina hade använt "mammasmurf" på sitt Hotmail-konto så går det inte att skriva in "d99abf2e4bcd8b6a2634ee06df444c6179c7dda5" hos Hotmail och loggas in. Christina har fortfarande slarvat genom att återanvända lösenord, men det är inte lika kritiskt, då den som skötte fjärrservern hade kammat sig och använt en bättre metod än klartext.
Men: en ihärdig attackerare skulle kunna sitta och skapa en egen tabell över vilka in-värden som motsvarar vissa ut-värden för en viss hashfunktion. Om attackeraren helt enkelt tar en lista på de 10 000 vanligaste lösenorden (som de kanske fått tag i genom att tidigare hacka en sida som använt klartextslösenord) och kör dessa genom SHA-1 så kommer de ha en tabell i stil med
Min lista över vanliga SHA-1-utvärden
-------------------------------------
"lösenord" → "699c2ff778df74c7ed6fb3ec095c01c366c6cbb1"
"password" → "5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8"
"passw0rd" → "7c6a61c68ef8b9b6b061b28c348bc1ed7921cb53"
"12345" → "8cb2237d0679ca88db6464eac60da96345513964"
"hunter2" → "f3bbbd66a63d4bf1747940578ec3d0103530e21d"
"banankontakt" → "8a8ab52073c34d5cc9b456c050a9b946175951a2"
…
"mammasmurf" → "d99abf2e4bcd8b6a2634ee06df444c6179c7dda5"
…
Hjälp! Nu kan attackeraren ta ett hashvärde från den stulna databasen och jämföra värdet i högerkolumnen, vilket ger att originallösenordet var "mammasmurf", använda detta för att logga in på Christinas Hotmail-konto, osv.
Problemet för användaren här kan ha varit att lösenordet som användes var för enkelt: antingen var det ett av de vanligare lösenorden, eller så var det bara lätt att lista ut för en dator som började med "a", "b", "c", …, "aa", "ab", …, "abh7fdsah", "abh7fdsai", …, osv, och testade alla dessa kombinationer för att bygga en ordentlig "översättningstabell" (en så kallad regnbågstabell).
Adobe hade en stor databasläcka för ett tag sedan, och tittade man på de lösenord som användes så såg man:
# Antal användare Hash Lösenord
--------------------------------------------------------
1. 1911938 EQ7fIpT7i/Q= 123456
2. 446162 j9p+HwtWWT86aMjgZFLzYg== 123456789
3. 345834 L8qbAD3jl3jioxG6CatHBw== password
4. 211659 BB4e6X+b2xLioxG6CatHBw== adobe123
5. 201580 j9p+HwtWWT/ioxG6CatHBw== 12345678
6. 130832 5djv7ZCI2ws= qwerty
7. 124253 dQi0asWPYvQ= 1234567
8. 113884 7LqYzKVeq8I= 111111
9. 83411 PMDTbP0LZxu03SwrFUvYGA== photoshop
10. 82694 e6MPXQ5G6a8= 123123
11. 76910 j9p+HwtWWT8/HeZN+3oiCQ== 1234567890
12. 76186 diQ+ie23vAA= 000000
13. 70791 kCcUSCmonEA= abc123
14. 61453 ukxzEcXU6Pw= 1234
15. 56744 5wEAInH22i4= adobe1
16. 54651 WqflwJFYW3+PszVFZo1Ggg== macromedia
17. 48850 hjAYsdUA4+k= azerty
18. 47142 rpkvF+oZzQvioxG6CatHBw== iloveyou
19. 44281 xz6PIeGzr6g= aaaaaa
20. 43670 Ypsmk6AXQTk= 654321
21. 43497 4V+mGczxDEA= 12345
22. 37407 yp2KLbBiQXs= 666666
23. 35325 2dJY5hIJ4FHioxG6CatHBw== sunshine
24. 34963 1McuJ/7v9nE= 123321
25. 33452 yxzNxPIsFno= letmein
26. 32549 dCgB24yq9Bw= monkey
27. 31554 dA8D8OYD55E= asdfgh
28. 28349 L8qbAD3jl3jSPm/keox4fA== password1
29. 28303 zk8NJgAOqc4= shadow
30. 28132 Ttgs5+ZAZM7ioxG6CatHBw== princess
31. 27853 pTkQrKZ/JYM= dragon
32. 27840 2aZl4Ouarwm52NYYI936YQ== adobeadobe
33. 27720 NpVKrCM6pKw= daniel
34. 27699 Dts8klglTQDioxG6CatHBw== computer
35. 27415 4aiR1wv9z2Q= michael
36. 27387 XpDlpOQzTSE= 121212
37. 26502 ldvmctKdeN8= charlie
38. 25341 5nRuxOG9/Ho= master
39. 24499 y7F6CyUyVM/ioxG6CatHBw== superman
40. 24372 R3jcdque71gE+R+mSnMKEA== qwertyuiop
41. 23417 TduxwnCuA1U= 112233
42. 23157 2hD1nmJUmh3ioxG6CatHBw== asdfasdf
43. 22719 MyFBO2YW+Bw= jessica
44. 22672 cSZM/nlchzzioxG6CatHBw== 1q2w3e4r
45. 22204 Vqit1GVLLek= welcome
46. 22180 e+4n2zDarnvioxG6CatHBw== 1qaz2wsx
47. 22143 ZHgi8hFCTvrSPm/keox4fA== 987654321
48. 22103 OrzNCxMfwrw= fdsa
49. 21795 4chDWZgI7v0= 753951
50. 21449 vp6d18mfGL+5n2auThm2+Q== chocolate
51. 21383 4I4DOfx+UUg= fuckyou
52. 21208 Z07sabFOg5Y= soccer
53. 21100 pBqRSZNU8XU= tigger
54. 20961 WlMTLimQ5b4= asdasd
55. 20581 r/OONiXT+Ko= thomas
56. 20578 XWL3FNwnp+czgMjd+wJwNw== asdfghjkl
57. 20571 ueE89xIj8RTioxG6CatHBw== internet
58. 20331 ietF94QrMIbioxG6CatHBw== michelle
59. 20268 ecW6IyEemknioxG6CatHBw== football
60. 20022 ziypr2hyamc= 123qwe
61. 19907 7MLKr9CfrNg= zxcvbnm
62. 19825 7Z6uMyq9bpxe1EB7HijrBQ== dreamweaver
63. 19818 ZDxAirVSzvs= 7777777
64. 19237 zkXlvHcZYOg= maggie
65. 19129 GymA1zhi51k= qazwsx
66. 19113 lVwka/Mn8TPioxG6CatHBw== baseball
67. 18969 ghrvkwCcX4bioxG6CatHBw== jennifer
68. 18879 FTeB5SkrOZM= jordan
69. 18470 eOsrbcW/PeTioxG6CatHBw== abcd1234
70. 18177 Nz4/TI6o5RrioxG6CatHBw== trustno1
71. 18108 wQKWOaXi5eA= buster
72. 18049 b5LJqTmQmvQ= 555555
73. 18008 tnWjMXDBaIkzgMjd+wJwNw== liverpool
74. 17986 NtCzq/i0Ffc= abc
75. 17933 iMhaearHXjPioxG6CatHBw== whatever
76. 17717 OPQxDLW2L+DioxG6CatHBw== 11111111
77. 17706 jAZbtIgk1cg= 102030
78. 17581 g5pZihfzGve6cdBSCql/UQ== 123123123
79. 17454 MEXwK6GOWHk= andrea
80. 17442 JXko2WSrc6s= pepper
81. 17296 VATj787A2Ho= nicole
82. 17174 oa/GBGqIApo= killer
83. 17077 7eu5/SYuhng= abcdef
84. 16963 ORpiFlGkd0g= hannah
85. 16898 L3uQHNDF6Mw= test
86. 16616 kAtMKrzaD6jxHUX3hQObgQ== alexander
87. 16535 HWMCJDWy2MI= andrew
88. 16526 u5YtgXT+JKk= 222222
89. 16468 +XW6eYb0HTg= joshua
90. 16456 WVVYjePjnX4= freedom
91. 16374 QSay9kzQVz8= samsung
92. 16177 F9nqBYx2LhA= asdfghj
93. 16091 6KJbvp1JGKY= purple
94. 16073 FcX+iulysVg= ginger
95. 15962 v0cefPH2OLI= 123654
96. 15910 e21tszGBy4k= matrix
97. 15803 fbO2Wx232qY= secret
98. 15788 kOAk8W94ZX4= summer
99. 15752 pCVd59qFewU= 1q2w3e
100. 15637 agRGj5rtLD8= snoopy1
Lösenordsfrekvens i Adobe-dump
dvs runt sex miljoner användare hade "åkt dit" bara för att de använde något av de 100 vanligaste lösenorden. Hashningen hjälpte, men problem kvarstod.
Hur skyddar man sig från en attackerare som testar alla möjliga lösenordskombinationer för att bygga upp en bank med alla möjliga lösenord? Tja, vi kan börja med att konstatera att det finns n⁸⁰ möjliga lösenord om en användare slumpmässigt väljer n tecken ur mängden:
För 10 tecken blir antalet kombinationer en etta följd av 80 nollor. Det är ungefär lika många atomer som det finns i det observerbara universum, vilket är många lösenord, även för en dator. I praktiken så kommer en attackerare fokusera på varianter av ord som finns i ordböcker, kombinerade med siffror och specialtecken på olika mer eller mindre enkla sätt när listan byggs upp.
Det kan ta lång tid att bygga upp en sådan lista, men när den väl är klar så går det otroligt snabbt att göra en uppslagning och matcha ett hashvärde. Hur kan man någonsin klara sig?
Salt kan man lägga på maten, men man kan även addera det till ett lösenord. Nu tänker vi oss en server som när Christina registrerar sig genererar en slumpmässig sträng på låt säga 10 tecken: "@. Ay-`}+Z". Denna sträng blir Christinas "salt", och lagras i databasen (typiskt i klartext). När Christina sedan skriver in "mammasmurf" så tar servern detta lösenord, lägger till saltet och skickar sedan detta till hashfunktionen:
"mammasmurf@. Ay-`}+Z" → [SHA-1] → "fb0d7637262b5d59f9b0742ee04db078b1e7413b"
och lagrar detta ut-värde. Nästa gång Christina loggar in så tar servern återigen det Christina skriver, lägger till saltet, kör funktionen, och jämför resultatet.
En attackerare ser ju saltet i den databasdump som kommits åt och kan lägga till detta själv, så hur hjälper detta? Jo, låt säga att även Åke använde "mammasmurf" som lösenord — eftersom de har olika salt (det slumpades ju fram vid registreringen) så kommer en enda översättningstabell inte kunna komma åt båda dessa lösenord! En attackerare måste nu i praktiken skapa en ny översättningstabell för varje salt, vilket i praktiken är för varje enskild användare. Var det 50 000 användare i databasen så blev saker helt plötsligt 50 000 gånger jobbigare. Det betyder inte att det är "omöjligt", men det är en enkel åtgärd som gör det bra mycket svårare för en attackerare innan de kan komma åt Christinas Hotmail-konto. Inte minst så betyder det att en attackerare inte bara kan ta en sedan länge färdig SHA-1-tabell och köra på från sekund 1 när väl dumpen blivit tillgänglig.
Då datortid kostar pengar, och det sällan finns brist på dumpade användardatabaser här i världen, så kanske en attackerare helt enkelt väljer att fokusera på en annan databasdump. Även om attackeraren känner att det är värt att jobba på denna saltade dump så kommer det ta längre tid vilket dels enligt ovan kostar pengar, och dels gör att användare har längre tid på sig att hinna byta sina lösenord.
——
PS: Ren SHA-1 är inte att rekommendera som kryptografiskt säker hashfunktion för detta ändamål med dagens tillgängliga datorkraft (se hellre exempelvis implementationen av PBKDF2), saltlängden och hur det appliceras bör tänkas över mer än ovanstående exempel, använd inte "mammasmurf" som lösenord, etc. Generellt bör en enskild programmerare undvika att "tänka för mycket själv" och hellre använda färdiga och vältestade lösningar för säkerhet, men detta var inte tänkt som en implementationsguide, utan bara som en konceptuell text kring några begrepp som använts i tråden.