Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to learn more about Json Web Token

2025-01-19 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Network Security >

Share

Shulou(Shulou.com)05/31 Report--

This article shows you how to gain an in-depth understanding of Json Web Token, which is concise and easy to understand, which will definitely brighten your eyes. I hope you can gain something through the detailed introduction of this article.

Preface 0x00 environment preparation

I originally wanted to use python DRF's JWT to do it, but then I failed. I finally tried to use Php and found it very convenient.

PHP version PHP 7.2.4-1+b2 (cli), that is, the php that comes with kali linux. As for the installation method of composer and the use of each library, you can consult the official documentation if necessary.

Evaluation of php jwt Library

There are some php jwt libraries on jwt.io, so let's talk about how it feels to use it. Only the top three libraries were selected:

Firebase/php-jwt Star 3786

Support for PHP5/7

The operation is very simple, but it does not have many functions and is not highly recommended.

Lcobucci/jwt Star Star 2729

Support for PHP5/7

Do not have the method of JWE, easy to operate

Does not have multiple JWS,JWE methods and their corresponding serialization methods.

Spomky-labs/jose Star 351

Only PHP 7 is supported

Fully functional, with multiple JWE,JWS, and its corresponding serialization methods. Neither of the above is available.

0x01 JWT attack means

The attack methods of JWT include the following:

Reference website: https://auth0.com/blog/critical-vulnerabilities-in-json-web-token-libraries//.

1. Sensitive information disclosure

When the secret key of the server is disclosed, the forgery of JWT becomes very simple and easy. In this regard, the server should take good care of the private key so as not to be stolen by others.

two。 Change the encryption mode to 'none'

The following is the problem of Juice Shop JWT issue 1 in actual combat. I talked about nonsecure JWT before.

The signature algorithm ensures that malicious users will not modify JWT during transmission. However, the alg field in the title can be changed to none. Some JWT libraries support no algorithm, that is, no signature algorithm. When alg is none, the backend does not perform signature verification. After changing the alg to none, delete the signature data from the JWT (only the title +'.'+ payload +'.) and submit it to the server.

Countermeasures:

Methods that do not allow none

Turn on alg: none as an additional configuration option.

3. Modify the algorithm RS256 to HS256 (asymmetric cryptographic algorithm = > symmetric cryptographic algorithm)

HS256 uses a key to sign and verify each message. RS256 uses the private key to sign the message and the public key to authenticate the message.

If you change the algorithm from RS256 to HS256, the back-end code uses the public key as the key, and then uses the HS256 algorithm to verify the signature. Because the attacker can sometimes obtain the public key, the attacker can modify the algorithm in the header to HS256 and then sign the data with the RSA public key.

At this point, the backend code will use the RSA public key + HS256 algorithm for signature verification, thus allowing the verification to pass.

Countermeasures:

Symmetric encryption algorithms such as HS256 are not allowed to read the secret key. Jwtpy restricts this approach. An error should be thrown when a parameter such as "- xxx key -" is read

Match the secret key with the authentication algorithm.

4. HS256 (symmetric encryption) key cracking

If the HS256 key strength is weak, you can force it directly, and you can do this by exploding the HS256 key. The difficulty is relatively low. The solution is simple, using a complex secret key.

5. Incorrect stack encryption + signature verification hypothesis

Incorrect stacking encryption

This attack occurs in a single or nested JWE, and we imagine a JWE like this:

JWT RAW header:... Payload: "admin": false "uid": 123 "umail": 123@126.com... JWE Main protected / unprotected recipients: en_key: key1 en_key: key2 cipher: xxx

Ciphertext is modified without the attacker modifying the secret key. It often leads to the failure of decryption. However, even if it fails, many JWT decryptions will have output, especially in the absence of additional authentication data (ADD). Attackers modify the contents of the ciphertext so that other data cannot be decrypted, but as long as there is "admin": true in the final output payload. The goal has been achieved.

Countermeasures:

In the case of JWE, all data should be decrypted instead of extracting individual required data from the decrypted results. In addition, the use of additional authentication data ADD is also a very good choice.

Signature hypothesis verification

This attack occurs in a nested JWS. Let's imagine a nested JWS that consists of two layers of parts that are structured as follows:

JWT Main JWT Sub1 payload Signature2 Signature

Now, when the attacker can pass the verification of the outer layer in a certain way, the system should also check the signature data of the inner layer. If not, the attacker can tamper with the data of payload at will to achieve the goal of ultra vires.

Countermeasures:

Therefore, for nested JWS, it is sufficient to verify that the signatures at all levels are correct, not that the outermost signature is correct.

6. Invalid elliptic curve attack

Elliptic curve encryption is a very secure way, even more secure than RSA to some extent. The algorithm of elliptic curve will not be expanded here.

In elliptic curve cryptography, the public key is a point on the elliptic curve, while the private key is just a number in a special but very large range. If the input to these operations is not validated, the attacker can design to recover the private key.

Such attacks have been confirmed in the past. This kind of attack is called invalid curve attack. This kind of attack is more complex and designed to have a lot of mathematical knowledge. For more information, please refer to the document: critical-vulnerability-uncovered-in-json-encryption.

Countermeasures:

Checking the validity of all inputs passed to any public function is the key to resolving such attacks. The verification includes that the public key is a valid elliptic curve point of the selected curve and that the private key is within the range of valid values.

7. Replacement attack

In this attack, the attacker needs to obtain at least two different JWT, and then the attacker can use one or two of the tokens elsewhere.

In JWT, there are two ways to replace common Serge, which we call the same receiver attack (leapfrog JWT) and different receiver attack.

Attacks by different receivers

We can imagine a business logic as follows:

The Auth mechanism has its own private key and issues two public keys to App1 and App2 to verify the signature

Attacker logged in to App1 with his secret key.

At this point, the Auth institution sends a signed JWT to Attacker, and its payload content is as follows:

{'uname':'Attacker'' role': 'admin'}

At this point, if Attacker knows that the public keys of App1 and App2 are signed by the same Auth, he can use this JWT to log in to App2 and obtain Admin permissions.

Solution:

Bring the aud declaration in the jwt, such as aud: App1. To restrict that jwt can only be used for App1.

Same receiver attack / leapfrog JWT same recipient/Cross JWT

We can imagine a business logic as follows:

Under the same site, there are two applications, wordpress and phpmyadmin, which both use the same key pair and algorithm to verify the JWT signature

The site administrator is aware of the problem with Different Recipient, so he adds aud authentication to the wordpress application, but the number of phpmyadmin users is small, so there is no increase in aud authentication.

Attacker logged in to wordpress with his secret key.

At this point, the site sends a signed JWT to Attacker, whose payload content is as follows:

{'uname':'Attacker'' role': 'writer'' aud': 'shaobaobaoer.cn/wordpress'' iss': 'shaobaobaoer.cn'}

This JWT seems to be very secure, but this is only for wordpress applications. Thus Attacker can log in to phpmyadmin as writer.

Solution:

Add aud validation to all sub-applications

8. Other hypothetical methods of attack

JWT + SQL injection

Reference link: https://github.com/greunion/ctf-write-ups/tree/master/2018-nullcon/web/400-web6.

When there are many keys to decrypt JWT, it is often necessary to use kid to determine which key to use, and the keyid parameter is saved by b64 encryption and can be tampered with. When keyid is to be fetched through the database API, it is often associated with sql injection.

We can imagine the attack:

$keyID = $token- > getKeyID (); $keyContent = sqlAPI-> fromKeyidGetKeyContent ($keyID) # class sqlAPI (): function fromKeyidGetKeyContent ($keyID) {$result= Query ("select key_content from keyTable where key_id ='$keyID'"); return $result ['key_content']} # if ($token- > verify ($JWA,$keyContetn)) {echo $flag;}

In the following relatively simple code, by letting the database return the value as our custom key_content. The purpose of cracking JWT can be achieved.

By injecting:

'union select' easy' limit 1pm 1muri +

You can change the key to easy.

0x03 practical practice practice 1 sensitive information disclosure

I found a demo, online demo address: http://demo.sjoerdlangkemper.nl/jwtdemo/hs256.php.

The GitHub address is: https://github.com/Sjord/jwtdemo/.

The demo of php-jwt written using firebase/jwt. Can be used to complete the following questions.

In order to modify the jwt, I will change the data field to:

"data": {"hacker": "shaobaobaoer"}

The address of the topic is: http://demo.sjoerdlangkemper.nl/jwtdemo/rs256.

In the case of knowing the github project, we know the address of the public key and private key in disguise and visit directly:

Http://demo.sjoerdlangkemper.nl/jwtdemo/private.pemhttp://demo.sjoerdlangkemper.nl/jwtdemo/public.pem

You can get the contents of the public key and private key, and then encrypt it using our own jwt library.

The key code is as follows:

$keychain = new Keychain (); $sign = new Sha256 (); $token = "eyJ0eXAiO..."; $token = (new Parser ())-> parse ((string) $token) $hacktoken = (new Builder ())-> setIssuer ($token- > getClaim ('iss'))-> setIssuedAt ($token- > getClaim (' iat'))-> setExpiration ($token- > getClaim ('exp'))-> set ("data", ["hack" = > "shaobaobaoer"])-> sign ($sign,$keychain- > getPrivateKey (' file://key_box/private.pem'))-> getToken (); echo $hacktoken.PHP_EOL) Var_dump ($hacktoken- > verify ($sign,$keychain- > getPublicKey ('file://key_box/public.pem')));)

As you can see, we have made the change successfully.

Practical exercise 2 Juice Shop JWT issue 1

Juice shop is an OWASP vulnerable WEB project with node.js as the back-end language.

When I did it, I didn't even know what jwt was, and the title of two jwt was skipped. Now that I have mastered these concepts, I can take it out and have an aftertaste.

Most of the answers to juice shop questions can be found in the OWASP juice shop actual combat report.

Topic description

Forge an essentially unsigned JWT token that impersonates the (non-existing) user jwtn3d@juice-sh.op.

Actual combat process

First, log in with universal login and get the jwt as follows:

EyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdGF0dXMiOiJzdWNjZXNzIiwiZGF0YSI6eyJpZCI6MSwiZW1haWwiOiJhZG1pbkBqdWljZS1zaC5vcCIsInBhc3N3b3JkIjoiMDE5MjAyM2E3YmJkNzMyNTA1MTZmMDY5ZGYxOGI1MDAiLCJjcmVhdGVkQXQiOiIyMDE4LTA4LTEyIDA3OjUzOjM4LjA2NCArMDA6MDAiLCJ1cGRhdGVkQXQiOiIyMDE4LTA4LTEyIDA3OjUzOjM4LjA2NCArMDA6MDAifSwiaWF0IjoxNTM0MDYwNTM5LCJleHAiOjE1MzQwNzg1Mzl9.Jivk7Pil6wukFkShzCCaHNq7qmxegvcyD83FkbglT0uYYP0azTW2rM-FH4R8WYneTu1A5gQmUjB6VdFJh8APz5Qej_AA4RP3Q6nH-9qbytxQ5cebiEuuhRSridDxbXxuS0-oquQ0PkRtpenJ75mLJFzVROeaBWgKFNNcFIrV9hs

Put it into jwt.io to decrypt it. You can see that the data is structured as follows:

We have done experiments before that when alg chooses none, there is no need to sign JWT. Such jwt is also called insecure jwt.

The idea of this topic is to modify alg.

This approach can be utilized when the backend does not qualify the alg. Of course, jwt.io won't let you change alg to none. You need to manually change it yourself:

After a little manipulation on the header, the new token is as follows:

EyJhbGciOiJub25lIiwidHlwIjoiSldUIn0.eyJzdGF0dXMiOiJzdWNjZXNzIiwiZGF0YSI6eyJpZCI6MSwiZW1haWwiOiJqd3RuM2RAanVpY2Utc2gub3AiLCJwYXNzd29yZCI6IjAxOTIwMjNhN2JiZDczMjUwNTE2ZjA2OWRmMThiNTAwIiwiY3JlYXRlZEF0IjoiMjAxOC0wOC0xMiAwNzo1MzozOC4wNjQgKzAwOjAwIiwidXBkYXRlZEF0IjoiMjAxOC0wOC0xMiAwNzo1MzozOC4wNjQgKzAwOjAwIn0sImlhdCI6MTUzNDA2MDUzOSwiZXhwIjoxNTM0MDc4NTM5fQ

Sending a new jwt can solve this problem:

There is also a jwt issue 2, which I can't decompose the public key, nor can I start according to the official documentation. What is done can communicate with one or two.

Practical exercise 3 encryption method change

The back-end code of that website cannot demonstrate the attack method modified by encryption. There is something wrong with that blog. Here's an example.

The pseudo code at the back end should look like this:

# sometimes called "decode" verify (string token, string verificationKey) {# returns payload if valid token, else throws an error} string token = $inputstring verificationKey = file_get_content ('rsa_pub.key')

The back-end code should judge the encryption method of jwt, but this method is quite limited. First of all, for a good JWT library, RS256 and SH256 authentication will not be put together. In addition, HMAC should prohibit the public key as a secret.

For example, in pyjwt, this method is prohibited. Will throw a mistake.

Jwt.exceptions.InvalidKeyError: The specified key is an asymmetric key or x509 certificate and should not be used as an HMAC secret.

I probably wrote a small script that uses the public key to sign, as follows:

$secret = file_get_contents (". / key_box/public.pem"); / / var_dump ($secret); $sign = new Sha256 (); $token = "eyJ0eXAiO..."; $token = (new Parser ())-> parse ((string) $token) $hacktoken = (new Builder ())-> setIssuer ($token- > getClaim ('iss'))-> setIssuedAt ($token- > getClaim (' iat'))-> setExpiration ($token- > getClaim ('exp'))-> set ("data", ["hack" = > "shaobaobaoer"])-> sign ($sign,$secret)-> getToken (); echo $hacktoken.PHP_EOL;var_dump ($hacktoken- > verify ($sign,$secret)); practical exercise 4 HMAC key blasting

Reference link: https://delcoding.github.io/2018/03/jwt-bypass/.

In this question, you can return a string of jwt by visiting web:

EyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhZG1pbiI6ImZhbHNlIn0.oe4qhTxvJB8nNAsFWJc7_m3UylVZzO3FwhkYuESAyUM

Decrypting it, you can find that the algorithm is HS256,admin for flase.

{"alg": "HS256", "typ": "JWT"} {"admin": "false"}

Our goal is simple. We just need to convert admin to true. All that can be done now is to blow up the secret key. Of course you can write a small script to explode the key, and a tool c-jwt cracker is recommended here.

Through the gadget, we can quickly get out of the key, and my VPS probably used 2m to get out of the key 54l7y.

You can get flag by submitting JWT.

The above content is how to gain an in-depth understanding of Json Web Token. Have you learned any knowledge or skills? If you want to learn more skills or enrich your knowledge reserve, you are welcome to follow the industry information channel.

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Network Security

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report