Brute Force saldırısı, kilitli kapıyı tekmeleyerek kırmaya çalışmaya benzer. Herhangi bir zeka barındırmadan, karakter setindeki bütün karakterlerin kombinasyonlarını deneyerek login işlemlerini aşmayı hedefler. Kullanılan şifrelerin karakter sayısı ve karmaşıklığına göre, şifrenin kırılma ihtimali artar veya azalır. Örnek olarak, 29 harften oluşan, kullandığımız alfabedeki harflerden oluşan ve 4 haneli olan bir şifrenin kırılma ihtimali 29x29x29x29 = 707.281 ‘de birdir. Şifrenin karakter sayısı ve karakter farklılığını artırdığınızda kırılması daha zor hale gelmektedir. Brute Force ile nasıl şifre kırıldığını test etmek için öncelikle basit bir ASP.NET uygulaması geliştirelim. Sayfada User Name ve Password girmek için iki TextBox ve giriş yapmak için bir Button olsun. Butona tıklandığında veritabanından, giriş yapılan kullanıcıyı doğruluyor. Kullanıcı doğrulaması başarılı ise bir label’a “Giriş başarılı”, hatalı ise “Hatalı giriş.” yazıyor. Şimdi Brute Force kodlarımıza geçelim. Test için windows application uygulaması yazacağız. WinApp projesi oluşturup aşağıdaki formu tasarlayın:

URL’i girilen login sayfasına Brute Force saldırısı başlatacağız. ListView’de login için denenen değerler listelenecektir. Şifre ile eşleşen değer renklendirilecektir. Hadi başlayalım!

Öncelikle, aldığı karakter setinin belirtilen uzunluktaki text kombinasyonlarını üretecek bir fonksiyona ihtiyacımız var. Örnek olarak, “a,b,c” karakter setinden oluşan 3 haneli bir şifrenin 3x3x3 = 27 ihtimali vardır. Fonksiyon, bu karakter setini alıp, 3 haneli olacak şekilde “aaa, aab, aac, aba, abb, abc ….” gibi farklı kombinasyonlarını üretecektir. Aşağıda bu kombinasyonları üretecek fonksiyonumuz görünmektedir:

GetAllMatches metodu, parametre olarak aldığı karakter setinin, ikinci parametrede belirtilen uzunluktaki text kombinasyonlarını üretir. Son karakterden başlayarak, bir kaydırma yöntemi ile bütün kombinasyonları üretir. Butonun click olayında öncelikle, kullanılacak karakter setini ve şifrenin kaç haneli olarak üretileceğini belirterek, bütün kombinasyonları elde ediyoruz. Benim uygulamamda User Name = test2 ve Password = test3 olan login bilgisi için deniyorum.

Normalde charset, a-z, A-Z, 0-9 ve şifre textlerinde kullanılmasına izin verilen karakterlerden oluşur. Bu durumda şifre için telafuz edemeyeceğim büyüklükte ihtimal söz konusu 🙂 Test amaçlı olduğu için kapsamı sınırlı tuttum. Şifre, belirtilen 7 karakter setindeki karakterlerden oluşan, 5 haneli bir şifre. GetAllMatches metoduna karakter setini ve şifrenin kaç haneli olduğu bilgisini yolluyoruz ve bütün 5 haneli kombinasyonları elde ediyoruz. Kullanıcı adı ve şifreyi, hedef web sayfasında nasıl deneyeceğiz?

Bir web formun kaynağına baktığınızda, hidden olarak ViewState ve EventValidation değerlerini görürsünüz. ViewState, formdaki kontrollerin durumu için ve EventValidation, formun kaynak server tarafından oluşturulduğunu doğrulamak için kullanılır. Bir web servera talepte bulunduğunuzda, web server size gönderdiği sayfaya, ürettiği bir validation key değerini ekler. Sayfayı server’a post ettiğinizde, server encryption key ile validation key’i doğrular. Böylece post edilen sayfanın, server tarafından üretildiği doğrulanmış olur. Dolaysı ile öncelikle sayfanın ViewState ve EventValidation değerlerini elde etmemiz gerekiyor. Sayfanın source’una baktığımızda ViewState ve EventValidation değerleri aşağıdaki gibidir:

Sayfayı okuduktan sonra aşağıdaki fonksiyonla, basitçe ID değerini kullanarak ViewState ve EventValidation keylerini elde ediyoruz.

Web formda, login için User Name ve Password değerlerini de girerek aşağıdaki şekilde formu post ediyoruz:

Belirtilen karakter setindeki karakterlerin, 5 haneli bütün kombinasyonlarını elde etmiştik. Bir döngü içerisinde, üretilen bu değerleri tek tek şifre olarak deniyoruz. Öncelikle header’ına ContentType ve UserAgent bilgisini eklediğimiz bir client ile sayfayı okuyoruz. Sayfanın HTML içeriği artık elimizde. Yukarıdaki fonksiyon ile HTML içerik içerisinden ViewState ve EventValidation değerlerini elde ediyoruz. EventTarget, post işlemini gerçekleştirecek kontrolü işaret ediyor. Login butonunun ID’sini set ediyoruz. Böylece post işleminde, login butonunun click olayı çalışacaktır. Formdaki kontrollerin ID’lerini ve yazmak istediğimiz değerleri set ediyoruz. Böylece sanki, “browserdan formu doldurup, login butonuna tıklayarak login oluyormuş” davranışını sağlıyoruz. Şifre denemesi için ürettiğimiz değeri, şifre değerinin girildiği TextBox2’ye set ediyoruz. Sayfayı post ettiğimizde, server’ın bize gönderdiği cevabı okuyoruz. Giriş denemesinin başarılı olup olmadığını burada yakalayacağız. Yukarıda, ASP.NET uygulaması oluştururken, giriş başarısız olduğunda bir label’a “Hatalı giriş.” yazdığımızı belirtmiştik. Eğer giriş denememiz başarısız ise bize dönen sayfanın içeriğinde “Hatalı giriş.” yazması lazım. Bu texti, response içerisinde yakalayarak, giriş denemesinin başarılı olup olmadığını tespit ediyoruz. Eğer giriş başarılı olmuş ise şifreyi bulduk demektir. Tabii burada, hedef sitenin hatalı giriş denemelerinde nasıl davrandığını manuel test edip, ona göre giriş denemesinin başarılı olup olmadığını tespit edecek bir yöntem uygulamak lazım. Uygulamamızı çalıştırıp, test edelim:

7 karakter  ve 5 haneli şifre, 7x7x7x7x7 = 16.807 ihtimal denenmiştir ve şifre ile eşleşen text tespit edilmiştir. Facebook, twitter gibi uygulamaları düşünelim. Kullanıcı adlarını zaten biliyoruz. Brute Force ile eninde sonunda şifre mutlaka kırılır. Tabi, tedbiri olmasaydı 🙂 Brute Force saldırılarını engellemek için kullanılan en yaygın yöntem captcha kullanımıdır. Login ekranı kullanan uygulamalarda, ya ilk girişte yada belirli bir sayıda hatalı giriş denemesi sonrasında captcha ile, giriş yapmaya çalışanın gerçek kullanıcı olduğu doğrulanır. Bu da, kod ile otomatik giriş denemelerini engeller. Brute Force saldırıları, ikinci bir mantıkla wordlist’ler kullanılarak gerçekleştirilmektedir. İnsanların, şifre olarak kullanabilecekleri mantıklı kombinasyonlar bir text dosyasında kaydedilir. Wordlist’ten okunan değerler ile brute force saldırısı gerçekleştirilir. Aşağıda, yaygın kullanılan wordlist’ler yer almaktadır:

https://wiki.skullsecurity.org/Passwords

Aşağıdaki linkte de, şifre olarak kullanılmış, tüm zamanların en basit textlerinin Top 500 listesi yer almaktadır:

http://www.whatsmypass.com/the-top-500-worst-passwords-of-all-time

Brute Force saldırısını sadece web login için düşünmemek lazım. Windows/Linux işletim sistemleri için de brute force saldırısı uygulanabilir. Örnek olarak, Windows’ta ./Administrator veya Linux’ta root kullanıcıları brute force ile kırılabilir.

İkinci konumuz, Data Flood saldırıları. Captcha, ikinci olarak Data Flood saldırılarını engellemek için kullanılır. Neticede birçok sitenin, iletişim formu sayfası bulunmaktadır. Buraya girilen veriler, veritabanında kaydedilmektedir. İletişim formunu okuyup, yukarıdaki gibi değerleri set ederek, sınırsız bir döngüde formu post edersek, veritabanını gereksiz şişirip, siteyi devre dışı bırakabiliriz. Bu şekilde data flood yapılmasını engellemek için veri girişi olan formlarda da captcha kullanılmaktadır. Hedef sitemiz üzerinden örnekleyelim 🙂

Aşağıda linkini verdiğim, iletişim formu data flood saldırılarına açıktır:

http://www.yeniakit.com.tr/iletisim.html

Sayfayı açıp, kaynak koduna baktığımızda data flood yapmak için gerekli olan bütün bilgileri bize sunmaktadır:

Brute Force, saldırısında yazdığımız kodları, bir konsol uygulamada aşağıdaki gibi değiştirelim:

Uygulamayı çalıştırdığımızda, set ettiğimiz değerler ile form post edilecektir. Bu kodun while(true) bloku içerisinde sabaha kadar çalıştığını düşünün! Veritabanı gereksiz şişecek ve bir süre sonra down olacaktır. Aşağıda, Fiddler’de görüldüğü gibi form başarıyla post ediliyor:

Özetle, captcha hayat kurtarır 🙂 Sonraki yazıda görüşmek üzere.

Reklamlar