Ukládáš hesla do databáze jen tak, v čitelné podobě? Nebo používáš MD5? Nebo snad SHA-1? Vsadím se, že nevíš, co je to salt. Taky tajně doufám, že neposíláš hesla e-mailem. Jednoho krásného dne se někde na webu objeví obsah databáze tvojí webové aplikace a její uživatelé nebudou mít radost. Nevystavuj je zbytečnému nebezpečí a raději si rezervuj místo v první řadě a já ti ukážu, jak se se svým webem nedostat do hlavního zpravodajství TV Nova.
Zajímá vás správné ukládání hesel? Přijďte si o tom popovídat na školení Bezpečnost PHP aplikací: http://www.michalspacek.cz/skoleni/bezpecnost-php-aplikaci
2. Michal Špaček www.michalspacek.cz
323 loginů
+
SHA-1 hashů hesel
crackstation.net
Proč je vůbec ukládání hesel tak důležité? Ukážeme si příklad z naší kotliny – na jednom malém
e-shopu, který jsem zmiňoval na WebTop100 2012, se dal volně stáhnout soubor se zálohou
databáze, ve které bylo přes 300 uživatelských jmen a hesel zahashovaných pomocí SHA-1.
3. Michal Špaček www.michalspacek.cz
crackstation.net
111 cracknutých hesel
Řeknete si, lidský faktor, taková věc nemá být volně ke stažení. Ne, nemá, ale byla. Hashovaná
hesla jsem předhodil online nástroji, který ve svém obrovském slovníku našel 111 shod, během
chvíle jsem tak získal 111 uživatelských účtů i s hesly. Útok hrubou silou by počet jistě zvýšil.
4. Michal Špaček www.michalspacek.cz
exoddus
Tbvfs1
9plams
P1ll3d
Neznašov
Zde jsou některá zajímavá hesla, která CrackStation dokázal najít ve svém slovníku. Kromě
typicky českých slov jsou to i hesla, která splní podmínky pro tvorbu hesel velké části služeb
a aplikací. Všimněte si hesla P1ll3d: obsahuje více než 6 znaků, malá i velká písmena a čísla.
5. Michal Špaček www.michalspacek.cz
111 cracknutých hesel
52 k loginu
…@seznam.cz
Z těch 111 cracknutých a tedy čitelných hesel jich 52 patřilo k účtům, které měly e-mailovou
schránku na doméně seznam.cz. Celkem takových uživatelů daného e-shopu s e-mailem na
seznam.cz bylo 165, ale jen k 52 takovým účtům jsem znal heslo. Ale to mi stačilo.
6. Michal Špaček www.michalspacek.cz
52 loginů …@seznam.cz
Kolik stejných hesel jako
na Seznam?
Chtěl jsem zjistit, jestli vůbec a jak moc se recyklují hesla. Je třeba vzít v potaz, že vzorek dat byl
malý, byl půl roku starý a také to, že firmě provozující daný e-shop jsem doporučil informovat
zákazníky a doporučit jim změnu hesla. Výsledné číslo tedy ve skutečnosti může být vyšší.
7. I přesto je výsledek zarážející. Z 52 hesel, která jsem měl k dispozici, jich 9 fungovalo pro
přihlášení k e-mailové schránce na seznam.cz. 9 uživatelů tedy mělo a má stejné heslo pro
přístup ke své e-mailové schránce, jako heslo pro příhlášení k onomu e-shopíku. Přístup ke
schránce je průser, už třeba jenom proto, že v ní lze nalézt registrační údaje k dalším službám
(které si nikdo nikdy nezmění, pokud mu je vygenerujete a při registraci pošlete) a také třeba
proto, že weby běžně e-mailem posílají zapomenutá hesla a instrukce k nastavení nového hesla.
Masaaki Miyara https://www.flickr.com/photos/argyle-street/5721058729/
8. Michal Špaček www.michalspacek.cz
…@email.cz 2 z 8
…@centrum.cz 3 z 9
…@gmail.com 1 z 15
Přístup k 9 schránkám na seznam.cz není všechno. Z celkem 8 účtů s adresou na email.cz
používalo stejné heslo jen pár uživatelů. Získat přístup k tomu jednomu účtu na Gmailu byl trochu
oříšek, Gmail totiž detekoval, že se hlásím z divného umístění (přes anonymizér) a tak chtěl po
mě potvrdit, že jsem to opravdu já, kdo se k účtu snaží přihlásit. No, kdo jiný než já by to asi tak
byl, že. Chtěl po mě tedy telefonní číslo toho uživatele Gmailu, ale to nebylo problém najít, jak
jinak než zadáním té e-mailové adresy do … wait for it … do Google. To je ochrana k ničemu.
9. Domnívám se, že důvodem, proč uživatelé recyklují hesla může být částečně i to, že je k tomu
webové aplikace navádějí. Pokud v jednom políčku uživatel zadává svůj e-mail, tak je možné, že
do druhého políčka prostě napíše heslo k té schránce, aniž by nad tím nějak přemýšlel. Podívejte
se na tento formulář ještě jednou. Trochu to dává smysl, ne? Zkuste tedy políčko pro zadání hesla
doplnit například textem „nezadávejte heslo k vaší e-mailové schránce“. Třeba to uživateli dojde.
10. Vidíte, že pokud se hesla rozhodnete ukládat špatně, tak ohrožujete svoje uživatele. Útočník tak
nepřímo může získat přístup ke službám, ke kterým by jinak jména a hesla získával dost těžko.
Můj skromný odhad je, že hesla špatně ukládá půlka z vás. Vy samozřejmě ne, jen Vaše druhé já.
11. Michal Špaček www.michalspacek.cz
v čitelné podobě
(v plaintextu)
Co to vlastně znamená, to „ukládat hesla špatně“? Nejjednodušším špatným způsobem uložení
hesla je ho uložit tak, jak do aplikace přišlo z prohlížeče, nedělat s ním žádné cviky, žádné
hashování, to je sprosté slovo. Naše aplikace je přece zabezpečená, ne?
12. Pokud hesla uživatelů ukládáte do databáze jen tak, tak vaši aplikaci brzy navštíví tady ten pán na
obrázku. Nikdy neukládejte hesla do databáze jen tak, v čitelné podobě! Pokud se někdo
nějak dostane k databázi nebo k zálohám databáze, data vašich uživatelů jsou v ohrožení.
13. Michal Špaček www.michalspacek.cz
MD5(heslo)
SHA-1(heslo)
CRC32(heslo)
Možná jste slyšeli, že hesla se mají ukládat zahashovaná. Tedy že se mají nejdříve prohnat
nějakou hashovací funkcí. To je správně, ale není to úplně správně. Jsou hashe lepší a horší.
A i ty dobré se dají použít špatně. Uvedené hashe nejsou nejlepší a navíc jsou špatně použité.
14. Funkce MD5, SHA-1 a CRC32 jsou dobré na kontrolu integrity dat, ale ne na hashování hesel
uvedeným způsobem. V příkladu na začátku jste viděli, že hesla byla hashována pomocí SHA-1,
ale ničemu to nepomohlo, původní hesla nebyl problém získat. Takhle tedy také ne.
15. Existují totiž databáze předpočítaných MD5 a SHA-1 hashů pro různé možné i nemožné řetězce.
Pokud do výpočtu hashe nepřidáte salt, viz dále, tak velkou část hesel lze v těchto databázích
najít. Umí v nich hledat i Google, nalezení původního hesla je často otázka jednoho dotazu.
16. Pokud databáze předpočítaných hashů nestačí, tak třeba pomůže grafická karta a software, který
na ní umí lámat hashe. Jeremi Gosney postavil cluster s celkem 25 GPU, který umí vytvořit třeba
180 miliard MD5 hashů za vteřinu. Hrubá síla FTW. A ano, to nahoře je počítač.
17. Jak jde čas, tak si Jeremi kupuje pořád nějaké nové nejvýkonnější grafické karty. Žádná z nich
sice nikdy nezobrazí ani jeden pixel, ale crackování hesel na nich sviští od rána… do rána. Tohle
je fotka z roku 2013, nějakou dobu před vánoci.
18. Jeremi GosneyJeremi Gosney
Sagitta HPCSagitta HPC
V roce 2015 Jeremi Gosney staví cluster s 96 GPU a do konce 2016 v něm chce mít 192 GPU.
Pokud hesla ukládáte jako MD5 nebo SHA-1, tak je to stejné, jako kdyby byla v plaintextu. Jeremi
takové stroje prodává, server s 8 GPU stojí $18499, ale na StarCraft si kupte něco levnějšího.
20. Počet opakování musí být celkem vysoký (v tisících), navíc velmi záleží na použitém algoritmu, při
vícenásobném hashování pomocí MD5 vzniká větší počet kolizních součtů napadnutelných
útokem vedeným nějakým tunelem. Nebo tak něco. Tudy raději tedy ne, tunelů máme už tak dost.
21. Z doposud uvedeného tedy plyne, že potřebujeme nějakou pomalou hashovací funkci.
Relativně pomalou, tedy takovou, aby výpočet jednoho hashe nebyl tak moc časově náročný, ale
aby útok hrubou silou byl prakticky nemožný, protože by trval věčnost. Nebo dvě věčnosti.
Robert Thomson, https://www.flickr.com/photos/14degrees/440515255/
22. Michal Špaček www.michalspacek.cz
MD5(heslo + salt)
SHA-1(heslo + salt)
Určitě jste slyšeli nebo četli o jakémsi saltu (sůl) a i já jsem ten pojem již zmínil. Používat salt při
hashování hesel je nutné. Náhodně generovaný salt může být uložen v čitelné podobě v databázi
a jeho úkolem je zabránit vyhledávání v předpočítaných tabulkách a také znemožnit nalezení
uživatelů se stejným heslem (tzv. Birthday Attack). Stejné heslo by bez saltu mělo totiž stejný
hash a to by v databázi šlo velice jednoduše poznat. Stejně jako v kuchyni tak i u hashování hesel
záleží na tom, jak se sůl použije. Uvedený příklad je často k vidění, nicméně není ideální.
23. Nástroje pro crackování hesel, jako například oclHashcat, počítají s touto variantou solení hesel
(tedy připojení saltu před, nebo za heslo) a rovnou ji uvádějí v seznamu algoritmů, které umí
louskat. Útočník má tedy hash i salt a může zaútočit hrubou silou, jako kdyby žádný salt použit
nebyl. To samé platí pro slovníkové útoky. Nicméně, řekli jsme si, že hlavní úlohou saltu je bránit
narozeninovým útokům a hledání v předpočítaných tabulkách, takže to moc nevadí. Jen trochu.
24. Michal Špaček www.michalspacek.cz
HMAC(heslo, salt)
hash_hmac(sha512, heslo, salt)
O trochu zajímavější způsob solení je implementován v algoritmu HMAC (Hash-based message
authentication code). Se saltem se provede XOR, připojí se k heslu, zahashuje a poté ještě
jednou to samé v bledě modré. Pokud použijete pomalou hashovací funkci, dá se to i používat.
25. Pomalá hashovací funkce je důležitá, ale i taková SHA-512 je jen 10× pomalejší, než SHA-256,
30× pomalejší, než SHA-1 a 80× pomalejší, než MD5. To není moc. HMAC tedy také není nejlepší
volba. Pro ukládání hesel přece musí existovat vhodnější algoritmus a funkce.
26. Michal Špaček www.michalspacek.cz
bcrypt!
Blowfish hashing
Však určitě. Takovým algoritmem je třeba bcrypt, někdy též nazýván jako Blowfish hashing.
Algoritmus je relativně pomalý, sám o sobě podporuje salt i vícenásobné hashování (má parametr
cost, který říká kolikrát se má hashovat a určuje tak, jak dlouho má hashování hesla trvat).
27. Michal Špaček www.michalspacek.cz
crypt() salt=$2y$…
password_hash()
password_verify()
V PHP podporuje bcrypt funkce crypt(), pokud se jí předá salt, který začíná $2y$, to funguje až
od PHP 5.3.7, dřívější verze a salty začínající na $2a$ a $2x$ nepoužívejte. V PHP 5.5 jsou
dostupné hezké a jednoduché funkce, pro starší PHP jsou tyto ke stažení jako uživatelské funkce.
28. Michal Špaček www.michalspacek.cz
scrypt
PBKDF2
Podobně dobré jsou i algoritmy scrypt a PBKDF2 (Password-Based Key Derivation Function).
scrypt znemožňuje útoky hrubou silou tím, že potřebuje hodně paměti, ale v PHP je funkce
dostupná jen jako extension. Od PHP 5.5 existuje hash_pbkdf2(), ale použít bcrypt je jistější.
29. Michal Špaček www.michalspacek.cz
Argon2
Password Hashing Competition
Ale každá z těch uvedených funkcí má nějaký drobný problém. V létě 2015 se vyhlásily výsledky
soutěže PHC a vybral se vítěz, Argon2, což bude absolutně nejlepší hashovací funkce na hesla.
Zatím ještě není úplně dokončená, ale pak snad brzo bude i v PHP a bude se dát používat.
(Aktualizace: v listopadu 2015 byl Argon2 dokončen, ale počkejte, až ho budou podporovat PHP
funkce password_hash() a password_verify() a zatím je používejte v klidu dál.)
30. I při použití správného hashování můžete leccos zkazit. Kontroverzní seznamka Ashley Madison
měla hesla hashovaná bcryptem, ale kromě toho v jiném sloupci v databázi jen pomocí MD5. V
létě 2015 byla hacknuta a data unikla na web. Útočníci samozřejmě útočili na slabší funkci MD5.
31. Pár dobrých rad na závěr. Hesla z prohlížeče nepřenášejte jen přes HTTP, použijte HTTPS se
správným certifikátem, znemožníte tak jejich odposlech. Rovněž samotný přihlašovací formulář
přenášejte přes HTTPS, jinak by ho po cestě mohl někdo upravit, třeba změnit atribut action.
Nikos Providakis, https://www.flickr.com/photos/nikosprovidakis/5701097734/
32. Nikdy neposílejte hesla e-mailem. Nikdy, ani po registraci. Uživatelé si je nikdy nezmění, nechají
si to původní zaslané a e-mailová schránka je z dlouhodobého hlediska nezabezpečené
úložiště, stačí ztratit chytrý telefon nebo laptop a máte problém. Taky vůbec netušíte, kudy všude
daný e-mail prochází a spojení mezi poštovnímy servery jsou spíše nešifrovaná, disky v nich také.
Schub@, https://www.flickr.com/photos/schubi74/5439723004/
33. Pokud máte na webu funkci pro připomenutí zapomenutého hesla, tak to heslo nikdy neposílejte
e-mailem v čitelné podobě. To vlastně ani nemůžete, protože ho v databázi máte zahashované
bcryptem, že? Posílejte pouze za hodinu expirující jednorázový odkaz s náhodným tokenem,
jiným pro každý takový pokus o reset hesla. Ten odkaz povede na stránku, kde si uživatel může
nové heslo nastavit. Pokud uživatel zadá nesprávný e-mail, neříkejte mu to, vypište hlášku, jako
kdyby zadal správnou adresu. Útočník by jinak mohl zjistit, jaké e-maily se v databázi nacházejí.
Juan J. Martínez, https://www.flickr.com/photos/reidrac/4696900602/
34. a76c8ba54d7be5d57daf858987c168a458009312
Michal Špaček
www.michalspacek.cz
@spazef0rze
Přijďte na školení
http://www.michalspacek.cz/skoleni/bezpecnost-php-aplikaci
Tak a to je vše, přátelé. Sledujte mě na Twitteru https://twitter.com/spazef0rze, pokud se chcete
dozvědět, co se děje v mém světě PHP, bezpečnosti a výkonnosti. Pokud vás zajímá bezpečné
ukládání hesel a vůbec webová bezpečnost, tak přijďte na školení, které vedu. Díky a zas někdy!
No jenže jak jde čas, tak si Jeremi kupuje pořád nové a nové GPU a víc a víc. Tohle je fotka z roku 2013.
Rychlosti hashovacích funkcí viz oclHashcat benchmarking:
http://thepasswordproject.com/oclhashcat_benchmarking
CRYPT_BLOWFISH security fix details:
http://www.php.net/security/crypt_blowfish.php
password_* funkce pro PHP 5.3.7 a novější:
https://github.com/ircmaxell/password_compat