Rating: 2.0

Flag jokes, WEB 200 pti

Author: p4w

TL;DR

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

  • 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

  • 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

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

  • 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

  • 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
    {
        "keys": [
            {
                "e": "AQAB",
                "kid": "sqcE1a9gj9p08zNMR1MWbLLvuaPyUeJEsClBhy7Q4Jc",
                "kty": "RSA",
                "n": "wed4pVV95ZD+G5s+Ahlmb96zURRK70efNvduoOPIaaFmmPRBgSLSNCEF//VntFI2l72t8IOXQQ7sS/0JbnpzjHJ4Duo6KPyE9U/Ros1z6m46w/Ncw0xMcKkLTJjswxH3Ql4kIaueN988gppGbheEvWCazbQfgR8UD54zoGd6aqO71ni3Mp81ypoU1zjq7r4OfdX4iCv/ICxC4H9RFIFDX/4AnFa6CNmOCOhP2fKarFV3iWYEPtqOsoJx2tu6YP7ecv70DVfVzR9Zd4JbQuLkNtbo+ccCFTYQp2FYFkKveh+3LbfnWY2cIQdqPGG6i57B3qQkYF2FvvEzZaIFXjbiAQ=="
            }
        ]
    }
    
  • 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

  • Send the request to the challenge web application and get the flag

alt cert decoder

reference:

  • https://github.com/ticarpi/jwt_tool/wiki/Known-Exploits-and-Attacks
  • https://tools.ietf.org/id/draft-ietf-jose-json-web-signature-01.html#rfc.section.4
  • https://book.hacktricks.xyz/pentesting-web/hacking-jwt-json-web-tokens
  • https://jwt.io/
Original writeup (https://github.com/beerpwn/ctf/tree/master/2020/NahamCon_CTF/web/Flag_Jokes).