Collision Based Hashing Algoritma İfşası

Sven Morgenroth - 25 Eylül 2017 -

Bu makalede, Collision Based Hashing Algoritma İfşası yönteminden yararlanarak, hedef web sitesinin kullanıcılara ait parolaları hash'lerken SHA-1 algoritmasını kullanıp kullanmadığını tespit etmenin yollarını anlattık.

Collision Based Hashing Algoritma İfşası

Şubat 2017'de Google Mühendisleri tarafından ilk SHA-1 collision oluşturuldu. Bu hashing algoritmasının 2011'de NIST tarafından artık kullanılmadığı ifade edilse de hala yaygın olarak kullanılmaktaydı.

Collision Based Hashing Algoritma İfşası-1

Hash Collision Nedir?

Bir hash collision, iki farklı cleartext değeri aynı hash değerini ürettiğinde gerçekleşir. Bu collision’lar çeşitli problemlere sebep olabilirler fakat biz bu makalede onlara değinmeyeceğiz.

Bunun yerine, bu yazıda collision’ların bir başka yan etkisine göz atacağız: bir web sitesinin zayıf hash fonksiyonlarını kullanıp kullanmadığını tespit etmeyi sağlayan bir yönteme değineceğiz. Bu, kaynak koda erişmeden de yapılabilir.

Hatırlamayı kolaylaştırmak için Collision Based Hashing Algoritma İfşası yönteminden bahsedeceğiz.

Hash Collision’a Bir Örnek

Google mühendislerinin bulduğu collision, herkesin farklı içerik ve aynı hash ile iki PDF dosyası oluşturmasına olanak tanır. Google'ın kullandığı cleartext değerlerine bir göz atalım:

255044462D312E330A25E2E3CFD30A0A0A312030206F626A0A3C3C2F57696474682032203020522F4865696768742033203020522F547970652034203020522F537562747970652035203020522F46696C7465722036203020522F436F6C6F7253706163652037203020522F4C656E6774682038203020522F42697473506572436F6D706F6E656E7420383E3E0A73747265616D0AFFD8FFFE00245348412D3120697320646561642121212121852FEC092339759C39B1A1C63C4C97E1FFFE017346DC9166B67E118F029AB621B2560FF9CA67CCA8C7F85BA84C79030C2B3DE218F86DB3A90901D5DF45C14F26FEDFB3DC38E96AC22FE7BD728F0E45BCE046D23C570FEB141398BB552EF5A0A82BE331FEA48037B8B5D71F0E332EDF93AC3500EB4DDC0DECC1A864790C782C76215660DD309791D06BD0AF3F98CDA4BC4629B1

255044462D312E330A25E2E3CFD30A0A0A312030206F626A0A3C3C2F57696474682032203020522F4865696768742033203020522F547970652034203020522F537562747970652035203020522F46696C7465722036203020522F436F6C6F7253706163652037203020522F4C656E6774682038203020522F42697473506572436F6D706F6E656E7420383E3E0A73747265616D0AFFD8FFFE00245348412D3120697320646561642121212121852FEC092339759C39B1A1C63C4C97E1FFFE017F46DC93A6B67E013B029AAA1DB2560B45CA67D688C7F84B8C4C791FE02B3DF614F86DB1690901C56B45C1530AFEDFB76038E972722FE7AD728F0E4904E046C230570FE9D41398ABE12EF5BC942BE33542A4802D98B5D70F2A332EC37FAC3514E74DDC0F2CC1A874CD0C78305A21566461309789606BD0BF3F98CDA8044629A1

Bu iki string onaltılık encode halde ve bunları decode ettikten sonra ikisi de aynı SHA-1 sum’ını bir kez hashlenmiş hale getirecektir:

f92d74e3874587aaf443d1db961d4e26dde13e9c

Collision Based Hashing Algoritma İfşasına Giriş

Web Uygulamalarında Hashing Algoritmaları

Bir çevrimiçi servise kayıt olduğunuzda, web sitelerinin çoğu parolanızı hash hale getirir ve bu hash değerini veri tabanında tutar. Web uygulamasının parolanızı potansiyel bir saldırganın cleartext olarak görüntülemesine izin vermeyen bir biçimde saklamasına olanak tanıdığı için bu, iyi bir yöntemdir. Bununla birlikte, etkili olması için güçlü bir hashing algoritması kullanılmalıdır. Bu da, SHA-1 ve MD5 gibi algoritmaların bu tür bir uygulama için uygun olmadığı anlamına gelir. Yine de bu algoritmalar, günümüzde geliştiriciler tarafından parolaları hashlemek için sıklıkla kullanılmaktadırlar.

Web sitesine login olmaya çalışırken, veritabanındaki parola hash’i ile giriş formuna gönderdiğiniz parolanın hash’i karşılaştırılır. Bu nedenle hedef web uygulaması SHA-1 hashing algoritması kullanıyorsa ve biz kendi collision dizelerimizi gönderiyorsak; hash aynı olacaktır. Bu aynı zamanda iki farklı string ve parola kullanarak giriş yapabileceğimiz anlamına gelir.

Aynı tekniği black box biçiminde kullanarak; bir web uygulamasının aşağıda açıklandığı gibi savunmasız bir hashing algoritması kullanıp kullanmadığını belirleyebiliriz.

Collision Based Hashing Algoritma İfşası Nasıl Çalışır?

Saldırı Arkasındaki Teori

Teoride saldırı çok kolaydır. Web uygulamasında test etmek istediğiniz bir hesap oluşturun. Parola olarak, aynı hash’i farklı bir string olarak üreten bir string kullanın. Hesap kaydedildikten sonra tekrar giriş yapmayı deneyin. Bu sefer, parola olarak aynı hash’i üreten diğer farklı string’i gönderin. Giriş yapabildiyseniz bu; hedef web uygulamasının SHA-1 algoritmasını kullandığı anlamına gelir.

Collision Based Hashing Algoritma İfşası Örneği

Bir web uygulamasına yeni bir kullanıcı kaydettiğinizi varsayalım. Uygulama, parola olarak verdiğiniz cleartext1 dizesini kullanır ve onu hashler. Aşağıda görüldüğü gibi, hashlenmiş parola, abcd hash’ini ortaya çıkarar. Artık veri tabanında şu şekilde saklanır:

hash(cleartext1) == 'abcd'

Web uygulaması, hashlenen parolayı veri tabanında saklanan hash ile kıyasladığında eşleşir ve oturumu açarsınız.

hash(password) == dbhash

Bununla birlikte, bu yöntemin birkaç sınırlaması vardır ve aşağıdaki durumlarda çalışmaz:

  • Kayıt ve giriş formlarında, 20 karakterlik bir parola sınırında olduğu gibi, sunucu taraflı sıkı parola kısıtlamaları kullanılırsa,
  • İzin verilen karakterlerden oluşan bir beyaz liste varsa,
  • Önüne (sonuna değil) eklenen bir salt varsa.

Bir Web Uygulamasının SHA-1 Hashing Algoritmasını Kullanıp Kullanmadığını Kontrol Etme

Aşağıda, bir web uygulamasının SHA-1 hashing algoritmasını kullanıp kullanmadığını nasıl kontrol edebileceğiniz adım adım açıklamıştır.

  1. Netsparker Desktop’taki gibi bir interception proxy'si kurun ve web tarayıcısından geçen istekleri proxy üzerinden yapılandırın.
  2. Web uygulamasında bir hesap açın ve bilinen bir şifre kullanın örneğin: !! PASS !! Böylelikle HTTP isteğini aradığınızda bulmak kolay olur.
  3. Proxy'deki kayıt talebini !! PASS !! 'in tüm tekrarlarını yukarıdaki örnekte bulunan ilk collision string’i (URL encoding’e dönüştürülen) ile değiştirerek düzenleyin.

Collision Based Hashing Algoritma İfşası-2

NOT: Collision stringlerini URL encode etmek için her kodlanmış baytın önüne % karakteri yerleştirmeniz gerekir. Bunu yapmak için aşağıdaki PHP kodunu kullanabilirsiniz:

implode(array_map(function($byte){ return '%' . $byte;},str_split($collisionstring,2)));

  1. İsteği web uygulamasına gönderdikten sonra bir hash oluşturulur ve bu hash veri tabanında saklanır. Eğer web uygulaması SHA-1 algoritmasını kullanıyorsa hash; f92d74e3874587aaf443d1db961d4e26dde13e9c olur.
  2. Şimdi !! PASS !! dizesini tekrar parola olarak kullanarak web uygulamasına giriş yapmayı deneyin.
  3. Login HTTP isteğini durdurun ve tüm !! PASS !! tekrarlarını ikinci string’in URL encode hali ile değiştirin.
  4. Web uygulaması, sağlanan şifrenizi hash hale getirir ve veri tabanındaki kayıtlı değerle kıyaslar. Hash değeri bir kez daha f92d74e3874587aaf443d1db961d4e26dde13e9c olmalıdır.

Web uygulaması SHA-1 algoritmasını kullanıyorsa, farklı bir değer verseniz de giriş yapabileceksiniz.

Sonuçlar ve Beklentiler

Parolaların uyuşmaması nedeniyle login olmayı başaramazsanız; o zaman web uygulaması SHA-1'den farklı bir hashing algoritması kullanıyor demektir. Fakat, web uygulamasına giriş yapmayı başarırsanız, parola hash’i için SHA-1 hashing algoritması kullanıldığı anlamına gelir.

Bu Collision Based Hashing Algoritma İfşası yalnızca SHA-1 Algoritmasında mı Çalışır?

Bu yöntem, bilinen collision’ları olan diğer hashing algoritmalarıyla da çalışır. Örneğin; MD5. Ön koşullar fazla farklılık göstermez. Bununla birlikte, uzunluk kısıtlaması daha az endişe vericidir, çünkü bilinen md5 collision’ları uzun değildir (sadece 64 byte). Bu yine de bazı sunucu taraflı filtrelemeler için çok uzun olabilir.

Test için kullanabileceğimiz bilinen bir MD5 collision:

4dc968ff0ee35c209572d4777b721587d36fa7b21bdc56b74a3dc0783e7b9518afbfa200a8284bf36e8e4b55b35f427593d849676da0d1555d8360fb5f07fea2

4dc968ff0ee35c209572d4777b721587d36fa7b21bdc56b74a3dc0783e7b9518afbfa202a8284bf36e8e4b55b35f427593d849676da0d1d55d8360fb5f07fea2

Her iki dizi de aşağıdaki hash değerini verir:

008ee33a9d58b51cfeb425b0959121c9

Collision Based Hashing Algoritma İfşası Kimler Tarafından Bilinmelidir?

Bir web sitesinin geliştiricisi olarak hangi hashing algoritmasını kullandığınızı zaten biliyorsunuz ve algoritmanızın güvenli olup olmadığını görmek için bu teste ihtiyacınız yok. Hangi hash algoritmasının kullanıldığını bilmek de saldırı sırasında bir saldırgana yardım etmez.

Yine de bunun, özellikle yararlı olduğu iki senaryo vardır: kaynak koda ulaşmanın mümkün olmadığı black box sızma testlerinde ve bir veri tabanı dökümünün (dump) doğrulamasını (authenticity) kontrol ederken bu yöntemi kullanmak fayda sağlayabilir.

Sızdırılmış bir veri tabanı salt’lanmamış bir SHA-1 hashi kullanıyorsa ve bu yöntem web sitesinin SHA-1 hashing algoritmasını kullandığını doğruluyorsa bu, dump’ın güvenilir olduğuna dair çok küçük bir gösterge olabilir.

URL Encoded Haldeki String’ler

Yukarıdaki karşılaştırmanın URL encoded dizileri şu şekilde olacaktır:

SHA-1

String 1

%25%50%44%46%2D%31%2E%33%0A%25%E2%E3%CF%D3%0A%0A%0A%31%20%30%20%6F%62%6A%0A%3C%3C%2F%57%69%64%74%68%20%32%20%30%20%52%2F%48%65%69%67%68%74%20%33%20%30%20%52%2F%54%79%70%65%20%34%20%30%20%52%2F%53%75%62%74%79%70%65%20%35%20%30%20%52%2F%46%69%6C%74%65%72%20%36%20%30%20%52%2F%43%6F%6C%6F%72%53%70%61%63%65%20%37%20%30%20%52%2F%4C%65%6E%67%74%68%20%38%20%30%20%52%2F%42%69%74%73%50%65%72%43%6F%6D%70%6F%6E%65%6E%74%20%38%3E%3E%0A%73%74%72%65%61%6D%0A%FF%D8%FF%FE%00%24%53%48%41%2D%31%20%69%73%20%64%65%61%64%21%21%21%21%21%85%2F%EC%09%23%39%75%9C%39%B1%A1%C6%3C%4C%97%E1%FF%FE%01%73%46%DC%91%66%B6%7E%11%8F%02%9A%B6%21%B2%56%0F%F9%CA%67%CC%A8%C7%F8%5B%A8%4C%79%03%0C%2B%3D%E2%18%F8%6D%B3%A9%09%01%D5%DF%45%C1%4F%26%FE%DF%B3%DC%38%E9%6A%C2%2F%E7%BD%72%8F%0E%45%BC%E0%46%D2%3C%57%0F%EB%14%13%98%BB%55%2E%F5%A0%A8%2B%E3%31%FE%A4%80%37%B8%B5%D7%1F%0E%33%2E%DF%93%AC%35%00%EB%4D%DC%0D%EC%C1%A8%64%79%0C%78%2C%76%21%56%60%DD%30%97%91%D0%6B%D0%AF%3F%98%CD%A4%BC%46%29%B1

String 2

%25%50%44%46%2D%31%2E%33%0A%25%E2%E3%CF%D3%0A%0A%0A%31%20%30%20%6F%62%6A%0A%3C%3C%2F%57%69%64%74%68%20%32%20%30%20%52%2F%48%65%69%67%68%74%20%33%20%30%20%52%2F%54%79%70%65%20%34%20%30%20%52%2F%53%75%62%74%79%70%65%20%35%20%30%20%52%2F%46%69%6C%74%65%72%20%36%20%30%20%52%2F%43%6F%6C%6F%72%53%70%61%63%65%20%37%20%30%20%52%2F%4C%65%6E%67%74%68%20%38%20%30%20%52%2F%42%69%74%73%50%65%72%43%6F%6D%70%6F%6E%65%6E%74%20%38%3E%3E%0A%73%74%72%65%61%6D%0A%FF%D8%FF%FE%00%24%53%48%41%2D%31%20%69%73%20%64%65%61%64%21%21%21%21%21%85%2F%EC%09%23%39%75%9C%39%B1%A1%C6%3C%4C%97%E1%FF%FE%01%7F%46%DC%93%A6%B6%7E%01%3B%02%9A%AA%1D%B2%56%0B%45%CA%67%D6%88%C7%F8%4B%8C%4C%79%1F%E0%2B%3D%F6%14%F8%6D%B1%69%09%01%C5%6B%45%C1%53%0A%FE%DF%B7%60%38%E9%72%72%2F%E7%AD%72%8F%0E%49%04%E0%46%C2%30%57%0F%E9%D4%13%98%AB%E1%2E%F5%BC%94%2B%E3%35%42%A4%80%2D%98%B5%D7%0F%2A%33%2E%C3%7F%AC%35%14%E7%4D%DC%0F%2C%C1%A8%74%CD%0C%78%30%5A%21%56%64%61%30%97%89%60%6B%D0%BF%3F%98%CD%A8%04%46%29%A1

MD5

String 1

%4d%c9%68%ff%0e%e3%5c%20%95%72%d4%77%7b%72%15%87%d3%6f%a7%b2%1b%dc%56%b7%4a%3d%c0%78%3e%7b%95%18%af%bf%a2%00%a8%28%4b%f3%6e%8e%4b%55%b3%5f%42%75%93%d8%49%67%6d%a0%d1%55%5d%83%60%fb%5f%07%fe%a2

String 2

%4d%c9%68%ff%0e%e3%5c%20%95%72%d4%77%7b%72%15%87%d3%6f%a7%b2%1b%dc%56%b7%4a%3d%c0%78%3e%7b%95%18%af%bf%a2%02%a8%28%4b%f3%6e%8e%4b%55%b3%5f%42%75%93%d8%49%67%6d%a0%d1%d5%5d%83%60%fb%5f%07%fe%a2