## Flag jokes, WEB 200 pti
#### Author: p4w
In this challenge we have to exploit a __JWKS Spoofing__ vulnerability. This vulnerability exists if the application __trust an arbitrary url__ to retrieve the __public key__ to verify the cookie signature. An attacker can host his own public key on his malicious server in order to modify and sign the cookie with his key-pair.
### Token analysis
* The challenge let us login with any username we want, except from __admin__, and the goal is to become __admin__.
* The login phase is simple we send the username we want and the application respond with a signed jwt.
* Analysis of the jwt-cookie:
![alt cert decoder](./screen/login.png)
* Token analysis
* As we can notice we have 3 elements into the json part of the jwt-header and you can find the details at this link https://tools.ietf.org/id/draft-ietf-jose-json-web-signature-01.html#rfc.section.4
![alt cert decoder](./screen/jws_spec.png)
* To summarize, the `alg` header parameter specify the algorithm used by the web-application to sign the cookie. The `kid` header parameter is used to identify a specific key in a list of keys. The `jku` header parameter is used to point to an URL which contains a set of __json encoded public keys__.
* Let's see if we can retrieve the remote `jwks.json` file pointed by the token we have
![alt cert decoder](./screen/retrive_jwks_file.png)
### Exploiting the vuln
* The general idea should be to tamper the `jkw` to point to our server hosting our `jwks.json` file with our lists of keys.
* Generate RSA key-pair with `openssl`:
* with this command we can generate the RSA private key:
$ openssl genpkey -algorithm RSA -out private_key.pem -pkeyopt rsa_keygen_bits:2048
* with this command we can extract the public certificate associated to the RSA private key previously created:
$ openssl rsa -pubout -in private_key.pem -out public_key.pem
* Now we should have both __PUBLIC__ and __PRIVATE__ certificate in our current folder and we need to extract the `n` value. To do that I used an online service:
![alt cert decoder](./screen/extract_public_key_values.png)
* Since the values for the public key contained in the `jwks.json` shold be in base64, then we need to convert the n from `hex` to `base64(raw-hex-bytes)`. To do that we can use burp-proxy:
![alt n decode](./screen/encode_n_in_b64.png)
* Create our `jwks.json` file. To do that we can just use the original one and replace the value of __n__ with the value associated with our RSA-key:
$ cat jwks.json
* Now we need to modify the __jku__ value of the jwt-header to point to our server where we hosted the `jwks.json` file, and modify the payload data to become `admin`. After we can sign the cookie with our hosted RSA key-pair and to do that I used the https://jwt.io service:
![alt cert decoder](./screen/sign_jwt.png)
* Send the request to the challenge web application and get the __flag__
![alt cert decoder](./screen/get_flag.png)