Internet Güvenliği 2: Hashing Nedir, Nasıl Hayat Kurtarır
Şu senaryoyu hayal edin: Facebook'ta yüksek rütbeli bir mühendissiniz. Pembe panjurlu bir eviniz, size tapan bir eşiniz ve pırlanta gibi üç çocuğunuz var. Tam bir klişesiniz yani. Bir gün işten eve döndüğünüzde yemek masasının üstünde bir not görüyorsunuz:
"Ailen elimizde. Tüm kullanıcı şifrelerini veritabanından çekip bize vermezsen, onlara bütün gün asansör müziği dinleteceğiz. Yetmezse İsmail YK. Herkesin bir kırılma noktası var. Kocanı da en sona bırakacağız ki çocuklarının çektiği acıyı görsün."
(Evet, ana karakter kadın. Sütyen de giymiyor. Bu yazı femen tarafından sponsor edilmektedir.)
Niye böyle şeyler olmuyor? Birini kaçırmaya dahi gerek yok, telefonla tehdit etmek yahut social engineering (türlü türlü psikolojik manipülasyon) gayet kolay. Ve işin ucunda belki de milyar dolarlık bir veri hazinesi var. Niye Facebook mühendisleri korumayla dolaşmıyorlar?
***
Açık Şifre Depolamak
Bunu anlamak için, bir web sitesine girmeye çalıştığınızda olanları bir gözünüzde canlandırın. Muhtemelen çoğunuzun aklındaki olay akışı şöyledir:
- Yazdığım şifre bir şekilde sitenin sunucularına iletiliyor
- Bunu kendi depolarındaki şifre kayıtlarıyla karşılaştırıyorlar
- Aynı şifreyse, bana giriş izni veriyorlar
(imajları büyütmek için üstlerine tıklayın)
Eğer gerçekte durum bu olsaydı, hassas bilgileriniz her adımda saldırıya açık olurdu. Açıkçası, süper dandik sitelerde olan da bu:
- Aradaki konuşmayı koruyan HTTPS yok
- Giriş deneme sayısının kısıtlanması ve hesap kilitleme yok
- Two factor authentication yok (telefona mesajla kod yollama yani)
- Ve şifrelerin saklandığı veritabanının ayrıyeten şifrelenmesi de yok
İyi bir sistemde ise her adımda korumalar var:
Bir sürü bileşeni eklemedim, zira bizim için önemli olan şey, sondaki hashing. Mühendisleri tehdit etmeyi manasız kılan asıl detay bu.
Anahtarsız Kilit
Hashing: Hassas kullanıcı bilgilerinin tek yönlü sifrelenmesi.
Normalde bir şeyi şifrelemenin (encryption) zayıf noktası, bunun bir anahtarı olmasıdır. Kilidiniz ne kadar komplike olursa olsun, anahtarı varsa eninde sonunda çalınacaktır. Fakat "tek yönlü" şifrelemelerde bir anahtar yok. Bilgiler bir kere şifrelendi mi, şirketin CTO'su elindeki bir uber-şifre ile bu tabloları tekrar açıp, müşterilerin gerçek parolalarını göremiyor:
Basit bir hash fonksiyonu örneği: 1-100 arası iki sayı seçin. Bunlar sizin kullanıcı adınızı ve şifrenizi temsil etsinler. Bu sayıları kaydetmek yerine, ikisini topluyorum ve çıkan sonucun son iki rakamını kaydediyorum. Orijinal sayılar hiçbir yere kaydedilmiyor. Ve hash'inize bakan birinin orjinal sayılarınızı tahmin etmesi imkansız.
(Bu çok kötü bir fonksiyon tabii, çünkü bir sürü farklı şifrenin hash'i aynı olacak. İyi bir hash fonksiyonunda bu tip çakışmalar çok nadir olmalı.)
Peki sistem sizin asıl şifrenizi depolamıyorsa, giriş yaparken kimliğinizi nasıl doğruluyor? Girdiğiniz bilgileri her seferinde aynı hash fonksiyonuna sokup, deposundaki hash ile karşılaştırarak:
LinkedIn Rezaleti
Elbette bu mimari de %100 güvenli değil. 2012'de, koskoca LinkedIn (o zamanlarda da "koskoca LinkedIn" idi) hash tablolarını Rus hackerlara çaldırmıştı. Hemen ertesi gün, 6.5 milyon kullanıcı şifresi açık halde yayınlandı. Şifreleme tek yönlü oluyorsa, bunu nasıl becerdiler?
İki basit kavramı kullanarak:
- Brute Force
- Rainbow Table
Bir sitenin web arayüzünden tek tek her olası şifreyi denemek zordur. IP'niz bloklanır, erişmeye çalıştığınız hesaplar dondurulur, vs. Ama bir şekilde hem hash tablolarını (milletin şifrelenmiş bilgileri), hem de kullanılan hash fonksiyonunu çalmışsanız, aynı ortamı kendi bilgisayarınızda yaratabilirsiniz.
Tek yapacağınız iş, tüm olası şifreleri teker teker bu fonksiyona yedirmek, çıkan sonuçları çaldığınız tablodaki hash'lerle karşılaştırmak. Tutan olursa, o kullanıcının asıl şifresi, sizin o saniye fonksiyona yedirmiş olduğunuz rastgele şifredir. Bunu otomatikman yapan programlar var. Tek gereken şey zaman.
Ama LinkedIn olayında zamana dahi gerek yoktu. Zira endüstride yaygın olarak kullanılan hash fonksiyonları belli. Ve her biri için, sık kullanılan şifrelerin hash'lerini önceden hesaplamak mümkün. Bunun için bir siteyi hacklemeyi beklemeye gerek yok.
Rainbow Table denen bu tablolar, referans belgeleri gibi halihazırda mevcutlar. Bir siteden hashleri çaldığınız anda tek yapacağınız iş, o listeler ile referans tablolarını karşılaştırmak. Herhangi bir PC için birkaç saatlik iş.
(Bazı sitelerde herhangi bir şifrenin hashlenmiş halini anında görebilirsiniz. Aman ha değerli bir şifrenizi oralarda denemeyin, depoluyor olabilirler. 123456 filan deneyin.)
Çare Sarıgül
Belki tablodaki her kullanıcının şifresini bulmanız milyarlarca yıl sürer ama hepsini kırmanıza gerek yok zaten, en kolay kısmını kırsanız yine de milyonlarca şifre demek bu. LinkedIn rezaletinde açığa çıkan şifrelerin üçte biri aşırı zayıftı. Yani halihazırda bilinen "sık kullanılanlar" listelerinde mevcuttular, o yüzden de rainbow table'lar ile anında kırıldılar.
Daha sonraki analizlerde, bir diğer üçte birlik kısmının da, o kadar zayıf olmamakla birlikte, standart brute-force programlarıyla kolayca kırılabilecek cinsten oldukları görüldü.
Diyelim LinkedIn bu güvenlik ihlalini duyurdu ve emailini her gün kontrol eden biri olarak, korunmak için anında şifrenizi yenilediniz. Peki bunu her hesap için yapacak zamanınız var mı? Ne de olsa çoğu insan aynı şifreyi veya çok basit varyasyonlarını tekrar tekrar kullanıyor. Eğer kırılan şifre 123Linked ise, bunu 123Google ile otomatik olarak değiştirip, Google'ın web arayüzünden deneyen programlar var.
Öyle görülüyor ki anahtarsız kilidimizi balyozla kırdılar, bize de parçalarını toplamak düştü. Peki bu brute force + rainbow table kombinasyonuna karşı bir çare var mı?
Salt
LinkedIn'in iki büyük günahı vardı: Hem "salt" kullanmamış, hem de zayıf bir fonksiyon olan MD5 kullanmıştı. Bugün düzgün siteler bu iki hatayı da yapmıyorlar.
Salting: Hassas bilgilerinizi hash fonksiyonuna sokmadan önce, rastgele bazı karakterlerle veya kullanıcı adınızla birleştirmek, yani yemeğinize biraz tuz eklemek.
Bu taktik, rainbow table'ları etkisiz bırakıyor. "123456" gibi bir şifrenin MD5 hash'ini önceden hesaplamış olabilirsiniz ama "123456imtolstoyevksi"nin hashini hesapladınız mı? Her kullanıcı adı, her yaygın hash fonksiyonu ve her olası şifre kombinasyonunun önceden denenmesi imkansız. Hele hele salt olarak "kullanıcı adı + rastgele karakterler" kullanan bir siteye saldırıyorsanız geçmiş olsun, zayıf şifreleri bile kırmak trilyonlarca yıl sürebilir.
(Salt kullanmanın diğer bir yararı da, aynı şifreyi kullanan kullanıcılar için farklı hash yaratabilmesi. İkimizin de şifresi "yapmahayrettin" olabilir ama sistemin ikimiz için de yarattığı rastgele "tuz" aynı olmayacağı için, depolanan hashler farklı. Bu da güvenliği arttırıyor.)
Öte yandan, salt kullanımı brute force'u engellemiyor. Çünkü salt'ları da çalmak mümkün. Daha doğrusu, hash'leri çalan biri, otomatikman salt'ları da çalmıştır. Neden?
Örneğin Facebook'a her girişimde kimliğimin doğrulanması için, sistem, denediğim şifreye orijinal salt'ımı ekleyip fonksiyona yedirecek, ve çıkan sonuç veritabanındaki hash ile karşılaştırılacak, değil mi? Yani o salt'ın her kullanıcı için bir yerde saklanması gerekiyor. Yoksa her login oluşunuzda ayrı ve rastgele bir salt üretilse, hashler hep farklı olacağı için sizin kimliğinizi doğrulayamaz sistem.
***
Tabloları çalmış bir Mr Robot klonunun yapacağı iş, ilk satırdaki salt'a bakmak (yukardaki tabloda salt zaten kullanıcı adının kendisi, yani "user1@example.com"), sonra elindeki "en sık kullanılan 10,000 şifre" listesine teker teker bu saltı eklemek ve her biri için hash hesaplayıp, o ilk satırdaki çalıntı hash ile karşılaştırmak. Daha sonra ikinci satıra geçip bunu tekrarlamak.
Böyle bir saldırıda, arama kümesi (search space) 10 bin şifre, yani tablodaki kullanıcı sayısı x 10 bin tane hesap yapılması gerekiyor. Bu çok değil, dolayısıyla dictionary attack ile kırılacak kadar dandik bir şifreniz varsa yine tehlikedesiniz.
Ama asıl fark, saldırgan ikinci adımda gerçek brute force'a geçtiğinde ortaya çıkıyor: Her karakter kombinasyonunu denemeye başlayınca, arama kümesi belki 100 milyara çıkacak. Ve sırf salt kullanıldığı için, liste genelinde tek bir kez 100 milyar hash hesabı yapmak yerine, listedeki her kullanıcı için bunu yapmak zorunda saldırganımız. LinkedIn'den çalınan 6.5 milyon kullanıcı bilgisini düşünün. 650 katrilyon hesap az değil...
Rehash
...Ama imkansız da değil. Saniyede 40 milyar MD5 hash hesabı yapan sistemden geçen bölümde bahsetmiştim. Bu tip saldırıların işini iyice zorlaştıran şey, MD5 yerine daha sağlam algoritmalar kullanmak ve defalarca hash'in de hash'ini almak.
Rehash: Şifrenizi rastgele bir sayıda tekrar tekrar hashleyip, sadece en sonda çıkan sonucu depolamak.
Rehash, arama kümesini büyütmüyor ama her deneme için gereken süreyi arttırıyor. Bunu iki türlü yapıyor:
- Belki 10 kere rehash ediyorum, belki 1000 kere. Brute force deneyen biri bu sayıyı bilmiyorsa, her deneme için bir de bu değişkeni hesaba katmalı.
- O rakamı biliyorsa dahi, en azından her hesaplama için harcayacağı süre x misli artacak.
Bir noktada, bu işe harcayacağınız elektrik faturası, kıracağınız şifreleri satarak kazanacağız paradan fazla oluyor, tıpkı cryptomining'de olduğu gibi. Tabii pratikte çok fazla rehash kullanmanın da maliyeti var, çünkü sistem her kullanıcı girişinde aynı hesapları yapmak zorunda ve kullanıcıyı 5 dakika boyunca kimlik doğrulaması için bekletmenin manası yok.
***
Hashing'i Niye Anlattım
Hashing, sistem güvenliğinin bir alt kümesi sadece. Dışardan gelen saldırılara karşı korunmak veya içerden yapılan izinsiz erişimleri loglamak gibi başka parçarlar da var. Ve sistem güvenliği kümesinin tümü de, Internet güvenliğinin bir alt kümesi. Hayatımızdaki bir çok rahatlığı borçlu olduğumuz HTTPS mesela apayrı bir konu.
Fakat, ayrıntılarını bilmesek de, birçok bileşen için kafamızda bir kavramsal şablon mevcut. Mesela VPN nedir biliyoruz, tünel gibi bir şey. Hashing içinse çoğumuzun kafasında canlanan bir resim yok.
Aksi gibi, asıl bilmemiz gereken kavram da bu, çünkü yaygın şifre pratiklerine göbekten bağlı. Ve o pratikler, ilk bölümde bahsettiğim gibi, kaş yapacağım derken göz çıkarıyorlar.
Bana kalsa şifre güvenliği konusunu resimli bir şekilde ilkokuldaki bebelere anlatırdım. Sonuçta o çocukların bile email hesabı, Facebook hesabı varsa, niye bu işin güvenliğini anlatmak için ta üniversitedeki kriptografi dersine kadar bekliyoruz? Sadece bu konu üstüne uzmanlaşacak %0.1'lik kesimi mi ilgilendiriyor Internet güvenliği? Hem de hataların maliyeti bu kadar büyükken?
Neyse, şimdi sakinleşelim, üstümüze rahat bir şeyler giyip üçüncü ve son bölüme geçelim: Göz çıkarmadan kaş yapabilen 10 güvenlik kuralı...