forked from RajChowdhury240/JWT-Cracker
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathJWT-Cracker.py
200 lines (159 loc) · 4.69 KB
/
JWT-Cracker.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
#!/usr/bin/env python
import jwt
import base64
from colorama import Fore, Style
from pyfiglet import Figlet
import argparse
import json
wordlists = []
def banner():
print(Fore.RED)
print('\033[1m' + Figlet().renderText('JWT-Cracker') + '\033[0m')
print(Style.RESET_ALL)
def usage():
parser = argparse.ArgumentParser(description = """Title: JWT-Cracker - JWT Encoder, Decoder & Brute-forcer
\nAuthor: RootRaj
\nDescription: A command line tool for encoding, decoding and brute-forcing JSON Web Token(JWT).""", formatter_class = argparse.RawTextHelpFormatter, usage = 'use "%(prog)s --help" for more information')
parser.add_argument('-d', '--decode', nargs = 1, help = 'Decode a JWT Token')
parser.add_argument('--brute', action = 'store_true', help = 'Enable brute-force mode')
parser.add_argument('-w', '--wordlist', type = argparse.FileType('r'), help = 'Specify a wordlist for brute-forcing')
parser.add_argument('--version', action = 'version', version = '%(prog)s v1.0 (Beta)', help = 'Shows the version information and exit')
args = parser.parse_args()
return args
#Encoding a JWT Token
def encode(payload, secret, algo, header):
payload = json.loads(payload)
encoded_jwt = ''
if(header != ''):
try:
header = json.loads(header)
encoded_jwt = jwt.encode(payload, secret, algorithm=algo, headers=header).decode('utf-8')
except:
print('Wrong algorithm provided.')
else:
try:
encoded_jwt = jwt.encode(payload, secret, algorithm=algo).decode('utf-8')
except:
print('Wrong algorithm provided.')
return encoded_jwt
#Decoding a JWT Token
def decode(token):
jwt_parts = token.split('.')
jwt_parts.pop()
jwt_data = []
for base in jwt_parts:
try:
jwt_data.append(base64.b64decode(base).decode("utf-8"))
except:
try:
base = base + '='
jwt_data.append(base64.b64decode(base).decode("utf-8"))
except:
base = base + '=='
jwt_data.append(base64.b64decode(base).decode("utf-8"))
return jwt_data
#Brute-forcing a JWT Token to know about secret key
def brute_force():
jwt_token = input('Enter the JWT Token: ')
jwt_data = decode(jwt_token)
algorithm = json.loads(jwt_data[0])['alg']
flag = False
for word in wordlists:
encoded_jwt = encode(jwt_data[1], word, algorithm, jwt_data[0])
if(encoded_jwt != ''):
if(encoded_jwt == jwt_token):
print(Fore.RED)
print('\033[1m' + 'Found Secret: ' + '\033[0m', end = '')
print(Style.RESET_ALL, end = '')
print(Fore.CYAN, end = '')
print(word)
print(Style.RESET_ALL)
flag = False
break
else:
flag = True
if(flag == True):
print('No key matches.')
#Display
def display(jwt_data):
header = json.loads(jwt_data[0])
payload = json.loads(jwt_data[1])
print('Header:')
print(json.dumps(header, indent = 4))
print('\nPayload:')
print(json.dumps(payload, indent = 4))
#Menu-driven program
def menu():
global wordlists
print('1. Encode JWT')
print('2. Decode JWT')
print('3. Brute-force the secret')
print('4. Exit')
try:
choice = int(input('\nEnter your choice: '))
if(choice == 1):
algorithm = input('Algorithm: ').upper()
payload = input('Payload {"key": "value"}: ')
secret = input('Secret Key: ')
print('Do you want to add headers (Yes/No): ', end = '')
option = input()
if(option.lower()[0] == 'y'):
header = input('Header {"key": "value"}: ')
token = encode(payload, secret, algorithm, header)
if(token != ''):
print('\nJWT Token: ' + token)
elif(option.lower()[0] == 'n'):
token = encode(payload, secret, algorithm, '')
if(token != ''):
print('\nJWT Token: ' + token)
else:
print('Enter yes or no only.')
elif(choice == 2):
jwt_token = input('\nEnter the JWT Token: ')
display(decode(jwt_token))
elif(choice == 3):
wordlist_path = input('Enter the location of wordlist (absolute/relative path): ')
f = open(wordlist_path, 'r')
keys = f.read()
f.close()
keys = keys.split('\n')
keys.pop()
wordlists = keys
brute_force()
elif(choice == 4):
print('\nExiting...\nGood Day')
else:
print('\nEnter right option.')
except ValueError:
print('\nEnter an integer value')
except KeyboardInterrupt:
print('\nForced Exit\nGood Day')
#Main function
def main():
global wordlists
args = usage()
if(args.decode):
display(decode(args.decode[0]))
return
elif(args.brute):
if(args.wordlist):
for word in args.wordlist:
wordlists.append(word.strip('\n'))
brute_force()
return
else:
print('Insufficient wordlist.')
return
elif(args.wordlist):
for word in args.wordlist:
wordlists.append(word.strip('\n'))
if(args.brute):
brute_force()
return
else:
print('Missing --brute option.')
return
banner()
menu()
if __name__ == '__main__':
main()