JSON Web Tokens (JWT) can be a very attractive avenue of attack for penetration testers. Because it not only allows you to fake any user to obtain unlimited access, but also may further find more security vulnerabilities, such as information leakage, unauthorized access, SQLi, XSS, SSRF, RCE, LFI, etc.
First we need to recognize that the application is using JWT. The easiest way to do this is to search the broker tool’s history for JWT regular expressions:
[=]ey[A-zA-z0-9_ -]*\.[A-zA-z0-9._ -]* - Stable JWT version
[=] ey [A - Za - z0-9 _ \ / + -] * \ [A - Za - z0-9. _ \ / + - * - all JWT version (may be false positives)
Copy the code
Make sure the case sensitive and Regular Expression options are checked:
When you get a JSON Web token, how do you use them to bypass access control and hack into the system?
1. Leakage of sensitive information
Since the Header and Payload parts are encoded using the reversible Base64 method, anyone who can see the token can read the data.
To read the content, you just need to pass each part to the Base64 decoding function. Here are some examples:
Linux Base64 tool (with -d flag for decoding) :
$ echo eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9 | base64 -d
{"typ":"JWT","alg":"HS256"}
Copy the code
Browser JavaScript console:
>> atob("eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9")Copy the code
"{"typ":"JWT","alg":"HS256"}"Copy the code
Copy the code
Powershell:
PS C:\> [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String("eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9"))
{"typ":"JWT","alg":"HS256"}
Copy the code
Pyhton:
>>> import base64
>>> print(base64.b64decode('eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9'))
{"typ":"JWT","alg":"HS256"}
Copy the code
Once in a blog post, I accidentally announced the Token with the vulnerability pointing to the site, and the vulnerability site was found in minutes. Therefore, tokens cannot be freely published, and the data sent must not contain any sensitive data (such as passwords).
2. Change the algorithm to None
JWT supports setting the algorithm to “None”. If the “ALG” field is set to “None”, the signature is left blank so that any token is valid.
The original purpose of this feature was to facilitate debugging. However, if this feature is not turned off in a production environment, attackers can forge any token they want by setting the ALG field to “None,” and then use the forged token to impersonate any user to log on to the site.
Example:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjoiYWRtaW4iLCJhY3Rpb24iOiJ1cGxvYWQifQ.y2k9SJDRU81ybXm-anxpD2p1N-rKekDJtJGK GJlemjY
Copy the code
Set “ALG” : “None” without signature, generate Token:
eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0.eyJ1c2VyIjoiYWRtaW4iLCJhY3Rpb24iOiJ1cGxvYWQifQ.
Copy the code
Deconstruction:
{"typ":"JWT","alg":"none"}.
{"user":"admin","action":"upload"}.
[No signature!]
Copy the code
Does the page still return valid? If the page returns valid, there is a vulnerability.
How to defend against this attack? The JWT configuration should specify the desired signature algorithm, not “None”.
3. Key confusion attack
The two most commonly used algorithms for JWT are HMAC and RSA. HMAC (symmetric encryption algorithm) uses the same key to sign and authenticate the token. RSA (asymmetric encryption algorithm) requires two keys, encrypted with the private key to generate JWT, and then used its corresponding public key for decryption and authentication.
If the algorithm RS256 is changed to HS256 (asymmetric password algorithm => Symmetric password algorithm)?
Then, the back-end code uses the public key as the secret key, and then verifies the signature using the HS256 algorithm. Because the public key can sometimes be obtained by an attacker, the attacker can change the algorithm in the header to HS256 and then use the RSA public key to sign the data.
Example:
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJsb2dpbiI6InRpY2FycGkifQ.I3G9aRHfunXlZV2lyJvWkZO0I_A_OiaAAQakU_kjkJM
Copy the code
Deconstruction:
{"typ":"JWT","alg":"HS256"}.
{"login":"ticarpi"}.
Use HS256 signature and use RSA public key file as key authentication.
Copy the code
The back-end code uses RSA public key +HS256 algorithm for signature verification.
How to defend against this attack? JWT configurations should only allow HMAC or public key algorithms, and never both.
4. Invalid signature
When a client submits a request to an application, the server may not validate the token signature, allowing an attacker to simply bypass the security mechanism by providing an invalid signature.
Example:
A good example is the “Profile” page on the site, because we can only access this page if we are authorized to access it through a valid JWT, and we will replay the request and look for changes in the response to find problems.
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyIjoidGVzdCIsImFjdGlvbiI6InByb2ZpbGUifQ.FjnAvQxzRKcahlw2EPd9o7teqX-fQSt7MZhT 84hj7mU
Copy the code
Change the user field to admin to generate a new token:
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyIjoiYWRtaW4iLCJhY3Rpb24iOiJwcm9maWxlIn0._LRRXAfXtnagdyB1uRk-7CfkK1RESGwxqQC dwCNSPaI
Copy the code
Deconstruction:
{"typ": "JWT", "alg": "HS256"}.
{"user": "admin","action": "profile"}.
[New signature]
Copy the code
Send the regenerated Token to the server for verification. If the page can be accessed normally, the vulnerability exists.
5. Brute force cracking key
HMAC signing keys (such as HS256 / HS384 / HS512) use symmetric encryption, which means that the key that signs the token is also used to validate it. Because signature validation is a self-contained process, you can test the valid key of the token itself rather than having to send it back to the application for validation.
Therefore, HMAC JWT cracking is offline, with the JWT cracking tool, you can quickly check the list of known leaked passwords or the default passwords.
python jwt_tool.py eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyIjoiYWRtaW4iLCJhY3Rpb24iOiJ1cGxvYWQifQ.7ZbwdZXwfjm575fHGukkE09O8-eFY4bx-fEE BUK3XUE -C -d 1.txt
Copy the code
Obtain the key and forge any user’s Token:
If the HMAC key can be cracked, any content in the token can be forged. This vulnerability will have very serious consequences for the system.
6. Key leakage
Assuming that the attacker cannot brute force crack the key, he may obtain the password through other means, such as git information leakage, directory traversal, arbitrary file reading, XXE vulnerability, etc., thus forging any token signature.
Manipulate the KID
KID stands for Key ID. It is an optional field in the JWT header that a developer can use to identify a key for an authentication token. The correct use of the KID argument is as follows:
{Copy the code
"alg": "HS256",Copy the code
"typ": "JWT",Copy the code
"Kid ": "1" // Use key 1 to verify the tokenCopy the code
}Copy the code
Copy the code
Because this field is controlled by the user, an attacker could manipulate it with dangerous consequences.
Directory traversal
Because KID is commonly used to retrieve key files from a file system, if KID is not cleaned before use, the file system may be vulnerable to directory traversal attacks. In this way, an attacker can specify any file in the file system as the key for authentication.
"kid": ".. /.. // Use the public file main.css to verify the token
Copy the code
For example, an attacker could force an application to use a publicly available file as a key and sign an HMAC-encrypted token with that file.
SQL injection
KID can also be used to retrieve keys in a database. In this case, an attacker would most likely use SQL injection to bypass JWT security mechanisms.
If SQL injection can be made on the KID parameter, the attacker can use that injection to return arbitrary values.
"kid":"aaaaaaa' UNION SELECT 'key'; --" // Validate token with string "key"
Copy the code
The above injection causes the application to return the string “key” (because there is no key named “aaaaAAA” in the database). The token is then authenticated using the string “key” as the key.
The command injection
Sometimes, passing the KID argument directly to an insecure file read operation can cause commands to be injected into the code stream.
Some functions, such as Ruby Open (), allow this type of attack. An attacker can execute system commands by simply adding commands after the entered KID file name:
"key_file" | whoami;
Copy the code
This is just one example of many similar situations. In theory, this vulnerability can occur whenever an application passes an uncensored header file parameter to a function such as System (), exec ().
8. Manipulate header parameters
In addition to KID, the JWT standard lets developers specify keys through urls.
JKU header parameters
JKU, which stands for “JWKSet URL,” is an optional field in the header that specifies the URL to link to a set of cryptographic token keys. If this field is allowed without qualification, an attacker can host its own key file and specify an application with which to authenticate tokens.
Jku URL-> file containing the JWK set -> JWK used to validate the token
Copy the code
JWK header parameters
The optional header parameter JWK (JSON Web Key) enables an attacker to embed the authenticated Key directly into the token.
Manipulate X5U, X5C URLS
Similar to the JKU or JWK headers, the X5u and X5c header parameters allow an attacker to validate a Token’s public key certificate or certificate chain. X5u specifies information in the form of a URI, while X5c allows certificate values to be embedded in tokens.
Attack Token process obviously depends on how you test the JWT configuration and implementation, but in my test JWT, through to the target service Web request Token, which is used to read, tampered with, and the signature, you may encounter known attacks and potential security vulnerabilities and configuration errors, hope this article can help you find the security threat.
References:
https://github.com/ticarpi/jwt_tool/wiki
https://medium.com/swlh/hacking-json-web-tokens-jwts-9122efe91e4a