Hello. It's no secret that every month OTUS launches several completely new and unique courses, this month the
Pentest. Penetration Testing Practice .
” According to an established tradition, on the eve of the start of the course, we are sharing with you the translation of useful material in this area.
During the last pentest, I came across an authorization scheme based on
JSON Web Token (or just JWT). JWT consists of three parts: header, payload, verification information. The first part of the header contains the name of the algorithm, which will be used later for the verification part of the JWT. This is dangerous, since an attacker can modify this information and thus (possibly) control which scheme the server will use for verification.
Two schemes are usually used: RS256 (
digital signature algorithm ) and HS256 (
MAC based algorithm ). A completely unsafe option would be a NULL scheme: do not include verification information at all - unfortunately the NULL scheme was not accepted by the target web server.
A small variation on the JWT
type confusion
attack, which might work if the server implementation uses a validation library that simply calls code like verify (token, key) and assumes that only digitally signed tokens will be used. In this case, the second parameter “key” will always be public and will be presented for verification (digital signatures use the private key to create a signature and the corresponding public key to verify the created signature).
Now the attacker can obtain the public key, create a new MAC-based token and use it to create part of the verification of this token. In a MAC-based scheme, only a secret key is needed to generate verification information, and thus the attacker uses a public key (digital signature) as a secret key for the MAC. If this token is now passed to the server for verification, the library identifies the scheme that will be used for the token (which was set by the attacker as HS256, pointing to the MAC scheme). The library will use the second parameter as input to create the MAC. Since this is a public key, the new MAC matches the MAC that was transmitted to the attackers, and since they match, the server will accept a fake token. What then should an application developer do? If the token is accepted by the server, the server should always check if the algorithm used matches the one that was originally planned by the developer.
Theoretically, this should be easy to verify, but I did not find a working tool. Therefore, I myself wrote a python script. To use it, in the source code you must use the following configurations:
-
jwks_url
: where can I get information about the public key. JWKS is used by many services to openly distribute key information. -
operation_url
: An HTTP GET request that uses a JWT token for authorization. -
token
: a valid JWT for a configured operation. -
audience
: The audience for which the token was configured.
The script does the following:
- Download the JWKS configuration file and retrieve the public key settings. This creates a pem representation.
- Ensures that the configured token can be verified using the extracted public key;
- Performs a configured operation with a valid token and displays the received HTTP status code and the resulting document (it is assumed that this will be JSON).
- Creates a new token based on the configured. In the new token, the type will be changed to HS256; A MAC (based on an open key) will be computed and used as verification information for the token.
- Perform the configured operation again with the modified token and display the HTTP status code, as well as the returned document.
Since the return status code (with a modified token) was 401 (authorization is prohibited), authorization checks on the side of the target server worked, and thus, it was not compromised by the signature-vs-mac attack. If this worked, identical status codes and similar resulting documents would be created with both HTTP calls (with the original as well as with the modified token).
I hope this article helps you in your pentest practice, use the python script with pleasure:
import jwt import requests from jwcrypto import jwk from cryptography.x509 import load_pem_x509_certificate from cryptography.hazmat.backends import default_backend
That's all. We are waiting for everyone who has read to the end at a free webinar on the topic:
"How to start sorting
out bugs on the Web .
"