Skip to content

Get Started

andrea tedeschi edited this page Mar 11, 2021 · 16 revisions

If you cloned the repository

Run ./install.sh to install the script is not required in order to let the tool work, since you can just run python3 jwt-crack.py <token> [OPTIONS]. Anyway, writing this wiki, I assume that has been done, since normal installations (via rpm, dpkg or pip) has the syntax

  • jwtxpl <token> [OPTIONS]

Retrieve a Token

The first step, in order to use the tool, is to retrieve a token. Obviously the tool won't run if you does not provide any token.

Decoding a Token

In order to decode a token (its header an its payload) use the -d/--decode option:

jwtxpl <token> -d

This will return the header and the payload in json format.

Specify an Algorithm

Specify the algorithm using -a/--alg option. Valids algs are:

  • None, none
  • hs256, hs384, hs512
  • rs256, rs384, rs512
  • ps256, ps384, ps512
  • es256, es384, es512

Notes that alg is always required except when you are decoding the token. So, in other cases, even if you want to keep the original algorithm, you have to specify it via -a/--alg.

Algorithms are defined by the JSON Web Algortihms standard (JWA, RFC 7518), you can find more information about them in the JWA paragraph of this wiki.

Pass a Key

There are lot of key related options. By default, the tool accept a file containing the key. Using the -k/--key option you can pass the path to the key file.

Basic Payload Changes

After a token has been decoded, usually, the first thing you want to do is change payload claims. The option that does this is -p/--payload, that accepts as argument a key:value pair. The key is the key of the claim you want to change, while the value is the new value you want to privde to this claim. This option also offer access to subclaims, we will see this in Other Features. If the value you want to issue to a claim is a list of values, pass those values as comma separated ones. Even if the list has to contain only one value, append the comma to this value. Let's make some example:

  • Assuming we have this payload:

    • {'user': 'john', 'role': 'user'}
  • In order to change our role to admin we have to run:

    jwtxpl <token> -a hs256 -p role:admin -k /path/to/key
  • This will return a token, signed with the key contained in /path/to/key and HS256 algorithm, with the following payload:

    • {'user': 'john', 'role': 'admin'}
  • If we need to set a list of roles (admin and user):

    jwtxpl <token> -a hs256 -p role:admin,user -k /path/to/key
  • Will return a token with the payload:

    • {'user': 'john', 'role': ['admin', 'user']}
  • Or if we need to set a list of roles, containing only admin as value:

    jwtxpl <token> -a hs256 -p role:admin, -k /path/to/key
  • That return:

    • {'user': 'john', 'role': ['admin']}

N.B. You can call -p/--payload as many times as you need.

Handling Data Types in Payload Changes

By default, the tool, is always trying to convert values to integers. Obviously, it can't do it with normal strings such as 'admin' or 'hello', but when you pass a value like '1', it will be converted to an integer. Let's do an example:

  • With the following payload:

    • {'user': 'john', 'isadmin': '0'}
  • Running the command:

    jwtxpl <token> -a hs256 -p isadmin:1 -k /path/to/key
  • Will return a token with the payload:

    • {'user': 'john', 'isadmin': 1}

As you can see the 1 is converted to integer, but in this case, the generated token is invalid, since the original data type was a string. In order to avoid that we put a jolly character "%", in front of the numeric string we want to pass. For example, in the previous case, to get the rigth value for the 'isadmin' claim, the command should have been:

jwtxpl <token> -a hs256 -p isadmin:%1 -k /path/to/key

Doing that, the tool recognize you don't want to convert the numeric string to an integer. It does not changes when passing lists of values, for example, if we want to issue a list of values ('0' and '1') to the 'isadmin' claim, we just have to separate values with comma and, in order to not convert values in integers, put a "%" in front of every single value (as soon as we want to do that).

jwtxpl <token> -a hs256 -p isadmin:%0,%1 -k /path/to/key

Or if we want the '0' to be a string and the '1' to be an integer:

jwtxpl <token> -a hs256 -p isadmin:%0,1

I know that it may confuse, but this way we can avoid all conflict situations.

Quiet Output

  • (New in version 1.2.1)

By default, the output provides infos about tool version, data changed in the token, etc... It also provides proper warnings for common mistakes that may not generates errors, but can slow down the process. If you need a bare output (the final token only), you can specify it via the --quiet option. This is going to suppress information, warnings and colors, printing out only the crafted JWTs (yes, they could be more than one. Wait for next release), so that you can properly redirect stdout.

jwtxpl <token> -a hs384 -p isadmin:1 -k /path/to/key --quiet

None alg Attack

The most basic attack you can run on a JWT is the None alg attack. This consists in changing the algorithm to None or none. Since the alg will be None, you don't need to pass a key. Use -p/--payload, to change claims in the token payload.

jwtxpl <token> -a None -p <key>:<value>

This will return a token with no signature, if the server accepts the token, it means that you can consider it vulnerable.

Algorithm Confusion Attack

This attack consists in change the algorithm from an asymmetric one (like RS256), to a symmetric one (like HS256). Since RS256 uses a private key to sign the token, and a public key to verify it, the public key could be public avaiable. So, if the server its vulnerable, changing the alg to HS256 and use the server public key, will result in a valid token. So assuming we have this header:

  • {'alg': 'RS256', 'typ': 'jwt'}

And this payload:

  • {'user': 'john', 'role': 'user'}

And that we have stored the server public key under /home/user/tmpfiles/key.pem, the following command will elevates us to admin:

jwtxpl <token> -a hs256 -p role:admin -k /home/user/tmpfiles/key.pem