jwtear 0.2.0 → 1.0.0.pre
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.gitignore +8 -1
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +0 -2
- data/Gemfile.lock +71 -0
- data/README.md +107 -27
- data/bin/jwtear +40 -115
- data/jwtear.gemspec +9 -3
- data/lib/jwtear.rb +15 -19
- data/lib/jwtear/errors.rb +11 -4
- data/lib/jwtear/helpers/extensions.rb +17 -0
- data/lib/jwtear/helpers/utils.rb +71 -0
- data/lib/jwtear/jwe.rb +102 -0
- data/lib/jwtear/jws.rb +80 -0
- data/lib/jwtear/token.rb +67 -0
- data/lib/jwtear/version.rb +1 -1
- data/plugins/bruteforce.rb +103 -0
- data/plugins/generate.rb +68 -0
- data/plugins/parse.rb +111 -0
- data/plugins/plugin-template.rb +32 -0
- data/plugins/wiki.rb +50 -0
- data/plugins/wiki/README.md +212 -0
- metadata +105 -16
- data/LICENSE.txt +0 -21
- data/lib/jwtear/algorithms.rb +0 -83
- data/lib/jwtear/extensions.rb +0 -41
- data/lib/jwtear/jwt.rb +0 -129
- data/lib/jwtear/utils.rb +0 -57
- data/modules/bruteforce.rb +0 -39
data/jwtear.gemspec
CHANGED
@@ -8,8 +8,8 @@ Gem::Specification.new do |spec|
|
|
8
8
|
spec.authors = ["KING SABRI"]
|
9
9
|
spec.email = ["king.sabri@gmail.com"]
|
10
10
|
|
11
|
-
spec.summary = %q{JWTear, command-line tool
|
12
|
-
spec.description = %q{JWTear, command-line tool
|
11
|
+
spec.summary = %q{JWTear, a modular command-line tool to parse, create and manipulate JWT tokens for security testing purposes.}
|
12
|
+
spec.description = %q{JWTear, a modular command-line tool to parse, create and manipulate JWT tokens for security testing purposes.}
|
13
13
|
spec.homepage = "https://github.com/KINGSABRI/jwtear"
|
14
14
|
spec.license = "MIT"
|
15
15
|
|
@@ -18,5 +18,11 @@ Gem::Specification.new do |spec|
|
|
18
18
|
spec.executables = ['jwtear']
|
19
19
|
spec.require_paths = ["lib"]
|
20
20
|
|
21
|
-
|
21
|
+
spec.add_dependency 'gli', '~> 2.19', '>= 2.19.0'
|
22
|
+
spec.add_dependency 'json-jwt', '~> 1.10', '>= 1.10.2'
|
23
|
+
spec.add_dependency 'jwe', "~> 0.4.0"
|
24
|
+
spec.add_dependency 'tty-markdown', "~> 0.6.0"
|
25
|
+
spec.add_dependency 'tty-pager', "~> 0.12.1"
|
26
|
+
|
27
|
+
# spec.add_development_dependency('rake', '~> 0.9.2.2')
|
22
28
|
end
|
data/lib/jwtear.rb
CHANGED
@@ -1,25 +1,21 @@
|
|
1
|
-
# Standard libraries
|
2
|
-
require 'base64'
|
3
|
-
require 'json'
|
4
|
-
require 'digest'
|
5
|
-
require 'openssl'
|
6
|
-
require 'open-uri'
|
7
|
-
|
8
1
|
# JWTear
|
9
2
|
require_relative 'jwtear/version'
|
10
3
|
require_relative 'jwtear/errors'
|
11
|
-
require_relative 'jwtear/
|
12
|
-
require_relative 'jwtear/
|
13
|
-
require_relative 'jwtear/
|
14
|
-
|
4
|
+
require_relative 'jwtear/helpers/utils'
|
5
|
+
require_relative 'jwtear/helpers/extensions'
|
6
|
+
require_relative 'jwtear/token'
|
15
7
|
|
16
|
-
|
17
|
-
|
8
|
+
# External gems
|
9
|
+
require 'json/jwt'
|
10
|
+
require 'tty-markdown'
|
11
|
+
require 'tty-pager'
|
12
|
+
require 'colorize'
|
18
13
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
#
|
23
|
-
#
|
24
|
-
# end
|
14
|
+
module JWTear
|
15
|
+
# extend JWTear::Helpers::Extensions::Print
|
16
|
+
# include JWTear::Helpers::Extensions::Print
|
17
|
+
# Kernel.include JWTear::Helpers::Extensions::Print
|
18
|
+
# autoload(:Print, 'jwtear/helpers/extensions')
|
25
19
|
end
|
20
|
+
|
21
|
+
|
data/lib/jwtear/errors.rb
CHANGED
@@ -1,9 +1,16 @@
|
|
1
1
|
module JWTear
|
2
2
|
|
3
3
|
# Token
|
4
|
-
class InvalidTokenError <
|
4
|
+
# class InvalidTokenError < JSON::JWT::InvalidFormat; end
|
5
5
|
|
6
6
|
# Algorithm Errors
|
7
|
-
class AlgorithmRequiresKeyError < TypeError; end
|
8
|
-
class AlgorithmUnknownError <
|
9
|
-
end
|
7
|
+
# class AlgorithmRequiresKeyError < JSON::JWT::TypeError; end
|
8
|
+
# class AlgorithmUnknownError < JSON::JWS::UnexpectedAlgorithm; end
|
9
|
+
# class InvalidFormat < JSON::JWT::InvalidFormat; end
|
10
|
+
# class Error < StandardError; end
|
11
|
+
|
12
|
+
# class MissingOption < CustomExit
|
13
|
+
#
|
14
|
+
# end
|
15
|
+
|
16
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module JWTear
|
2
|
+
module Helpers
|
3
|
+
module Extensions
|
4
|
+
# Add print styles
|
5
|
+
module Print
|
6
|
+
def print_status(msg); puts "[*] ".blue + "#{msg}"; end
|
7
|
+
def print_good(msg); puts "[+] ".green + "#{msg}"; end
|
8
|
+
def print_error(msg); puts "[x] ".red + "#{msg}"; end
|
9
|
+
def print_bad(msg); puts "[!] ".red + "#{msg}"; end
|
10
|
+
def print_warning(msg); puts "[!] ".yellow + "#{msg}"; end
|
11
|
+
def print_h1(msg); puts "-[" + "#{msg}".green.bold + "]----"; end
|
12
|
+
def print_h2(msg); puts "[+] ".green + "#{msg}:" ; end
|
13
|
+
def print_h3(*msg); print " - ".cyan.bold + "#{msg[0]}:" " #{msg[1..-1].join(' ')}\n" ; end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
module JWTear
|
2
|
+
module Helpers
|
3
|
+
module Utils
|
4
|
+
|
5
|
+
# Check latest version
|
6
|
+
def latest_version
|
7
|
+
begin
|
8
|
+
current_version = JWTear::VERSION
|
9
|
+
rubygem_api = JSON.parse open("https://rubygems.org/api/v1/versions/jwtear.json").read
|
10
|
+
remote_version = rubygem_api.first["number"]
|
11
|
+
latest = remote_version.eql?(current_version)? true : false
|
12
|
+
|
13
|
+
latest ? current_version : remote_version
|
14
|
+
rescue Exception => e
|
15
|
+
print_bad " Couldn't check the latest version, please check internet connectivity."
|
16
|
+
exit!
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
# read key as a string or from file(eg. pub_key.pem)
|
21
|
+
def read_key(key)
|
22
|
+
if key
|
23
|
+
File.file?(key)? File.read(key) : key
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
# check_dependencies
|
28
|
+
# check dependencies for plugins and throw a gentle error if not installed
|
29
|
+
# @param deps [Hash]
|
30
|
+
# The key is the library to be require, the key is the gem to be required
|
31
|
+
# @example
|
32
|
+
# deps = {'async-io' => 'async/ip'}
|
33
|
+
# check_dependencies(deps)
|
34
|
+
#
|
35
|
+
def check_dependencies(deps={})
|
36
|
+
return if deps.empty?
|
37
|
+
missing = []
|
38
|
+
|
39
|
+
deps.each do |gem, req|
|
40
|
+
begin
|
41
|
+
require req
|
42
|
+
rescue LoadError
|
43
|
+
missing << gem
|
44
|
+
end
|
45
|
+
end
|
46
|
+
ensure
|
47
|
+
unless missing.empty?
|
48
|
+
print_error "Missing dependencies!"
|
49
|
+
print_warning "Please install as follows:"
|
50
|
+
puts "gem install #{missing.join(' ')}"
|
51
|
+
exit!
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
# JWTear's logo
|
56
|
+
def banner
|
57
|
+
%Q{\n 888888 888 888 88888888888
|
58
|
+
"88b 888 o 888 888
|
59
|
+
888 888 d8b 888 888
|
60
|
+
888 888 d888b 888 888 .d88b. 8888b. 888d888
|
61
|
+
888 888d88888b888 888 d8P Y8b "88b 888P"
|
62
|
+
888 88888P Y88888 888 88888888 .d888888 888
|
63
|
+
88P 8888P Y8888 888 Y8b. 888 888 888
|
64
|
+
888 888P Y888 888 "Y8888 "Y888888 888
|
65
|
+
.d88P v#{JWTear::VERSION}
|
66
|
+
.d88P"
|
67
|
+
888P" }
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
data/lib/jwtear/jwe.rb
ADDED
@@ -0,0 +1,102 @@
|
|
1
|
+
require 'jwe'
|
2
|
+
|
3
|
+
module JWTear
|
4
|
+
# JWE
|
5
|
+
# Takes a parsed token from JSON::JWT#decode
|
6
|
+
#
|
7
|
+
class JWE
|
8
|
+
include JWTear::Helpers::Extensions::Print
|
9
|
+
|
10
|
+
attr_accessor :header, :encrypted_key, :iv, :cipher_text, :authentication_tag,
|
11
|
+
:kid, :auth_data, :plaintext, :alg, :enc, :zip, :cek,
|
12
|
+
:iss, :sub, :iat
|
13
|
+
|
14
|
+
# parse
|
15
|
+
# is a basic parser for JWE token
|
16
|
+
#
|
17
|
+
# @param token [String]
|
18
|
+
# parsed token string
|
19
|
+
#
|
20
|
+
# @return [Self]
|
21
|
+
#
|
22
|
+
def parse(token)
|
23
|
+
jwt = JSON::JWT.decode(token, :skip_decryption, :skip_verification)
|
24
|
+
@header = jwt.header
|
25
|
+
@encrypted_key = jwt.send(:jwe_encrypted_key)
|
26
|
+
@iv = jwt.iv
|
27
|
+
@cipher_text = jwt.cipher_text
|
28
|
+
@authentication_tag = jwt.send(:authentication_tag)
|
29
|
+
@algorithm = jwt.algorithm
|
30
|
+
@auth_data = jwt.auth_data
|
31
|
+
@plaintext = jwt.send(:plain_text)
|
32
|
+
@kid = jwt.kid
|
33
|
+
@alg = @header["alg"]
|
34
|
+
@typ = @header["typ"]
|
35
|
+
@cty = @header["cty"]
|
36
|
+
@enc = @header["enc"]
|
37
|
+
@zip = @header["zip"]
|
38
|
+
@iat = @encrypted_key["iat"]
|
39
|
+
@iss = @encrypted_key["iss"]
|
40
|
+
@cek = @encrypted_key
|
41
|
+
self
|
42
|
+
rescue JSON::JWS::UnexpectedAlgorithm => e
|
43
|
+
puts e.full_message
|
44
|
+
rescue JSON::JWT::InvalidFormat => e
|
45
|
+
print_error e.message
|
46
|
+
puts token
|
47
|
+
exit!
|
48
|
+
end
|
49
|
+
|
50
|
+
def to_json_presentation
|
51
|
+
header = @header
|
52
|
+
if is_encrypted?(@encrypted_key)
|
53
|
+
encrypted_key = Base64.urlsafe_encode64(@encrypted_key, padding: false)
|
54
|
+
else
|
55
|
+
encrypted_key = @encrypted_key.to_json
|
56
|
+
end
|
57
|
+
iv = Base64.urlsafe_encode64(@iv)
|
58
|
+
cipher_text = Base64.urlsafe_encode64(@cipher_text, padding: false)
|
59
|
+
authentication_tag = Base64.urlsafe_encode64(@authentication_tag, padding: false)
|
60
|
+
|
61
|
+
"#{header.to_json}" + "●" +
|
62
|
+
"#{encrypted_key}" + "●" +
|
63
|
+
"#{iv}" + "●" +
|
64
|
+
"#{cipher_text}" + "●" +
|
65
|
+
"#{authentication_tag}"
|
66
|
+
end
|
67
|
+
|
68
|
+
# generate_jwe
|
69
|
+
# generate JWE token
|
70
|
+
#
|
71
|
+
# @param header [JSON]
|
72
|
+
# @param payload [JSON]
|
73
|
+
# @param key [String]
|
74
|
+
#
|
75
|
+
# @return [String] the generated token
|
76
|
+
#
|
77
|
+
def generate_jwe(header:, payload:, key:)
|
78
|
+
key = OpenSSL::PKey::RSA.new(key)
|
79
|
+
jwt = JSON::JWT.new(JSON.parse(payload, symbolize_names: true))
|
80
|
+
jwt.header = JSON.parse(header, symbolize_names: true)
|
81
|
+
::JWE.encrypt(payload, key, enc: jwt.header[:enc]) # I had to use this gem as json-jwt does not support A192GCM AFAIK
|
82
|
+
rescue TypeError => e
|
83
|
+
print_bad "Invalid data type."
|
84
|
+
print_warning "Make sure your public/private key file exists."
|
85
|
+
rescue ArgumentError => e
|
86
|
+
print_error e.message
|
87
|
+
print_warning "Make sure that you have a proper header."
|
88
|
+
puts jwt.header
|
89
|
+
rescue OpenSSL::PKey::RSAError => e
|
90
|
+
print_error "#{e.message} '#{key}'"
|
91
|
+
print_warning "Make sure your public/private key file exists."
|
92
|
+
exit!
|
93
|
+
end
|
94
|
+
|
95
|
+
def is_encrypted?(item)
|
96
|
+
JSON.parse item
|
97
|
+
false
|
98
|
+
rescue JSON::ParserError
|
99
|
+
true
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
data/lib/jwtear/jws.rb
ADDED
@@ -0,0 +1,80 @@
|
|
1
|
+
module JWTear
|
2
|
+
# JWS
|
3
|
+
# Takes a parsed token from JSON::JWT#decode
|
4
|
+
#
|
5
|
+
class JWS
|
6
|
+
include JWTear::Helpers::Extensions::Print
|
7
|
+
|
8
|
+
attr_accessor :header, :payload, :signature,
|
9
|
+
:typ, :cty, :alg, :kid, :jku,
|
10
|
+
:iss, :sub, :iat, :exp, :aud, :hd,
|
11
|
+
:azp, :email, :at_hash, :email_verified
|
12
|
+
|
13
|
+
# parse
|
14
|
+
# is a basic parser for JWS token
|
15
|
+
#
|
16
|
+
# @param token [String]
|
17
|
+
# parsed token string
|
18
|
+
#
|
19
|
+
# @return [Self]
|
20
|
+
#
|
21
|
+
def parse(token)
|
22
|
+
jwt = JSON::JWT.decode(token, :skip_verification)
|
23
|
+
@header = jwt.header
|
24
|
+
@payload = jwt.to_h
|
25
|
+
@signature = jwt.signature
|
26
|
+
@alg = @header["alg"]
|
27
|
+
@typ = @header["typ"]
|
28
|
+
@cty = @header["cty"]
|
29
|
+
@kid = @header["kid"]
|
30
|
+
@jku = @header["jku"]
|
31
|
+
@iat = @payload["iat"]
|
32
|
+
self
|
33
|
+
rescue JSON::JWT::InvalidFormat => e
|
34
|
+
print_error e.message
|
35
|
+
puts token
|
36
|
+
exit!
|
37
|
+
rescue Exception => e
|
38
|
+
puts e.full_message
|
39
|
+
end
|
40
|
+
|
41
|
+
def to_json_presentation
|
42
|
+
"#{@header.to_json}" + "●" + "#{@payload.to_json}" + "●" + "#{Base64.urlsafe_encode64(@signature, padding: false)}"
|
43
|
+
end
|
44
|
+
|
45
|
+
# generate_jws
|
46
|
+
# generate JWS token
|
47
|
+
#
|
48
|
+
# @param header [JSON]
|
49
|
+
# @param payload [JSON]
|
50
|
+
# @param key [String]
|
51
|
+
#
|
52
|
+
# @return [String] the generated token
|
53
|
+
#
|
54
|
+
def generate_jws(header:, payload:, key:)
|
55
|
+
jwt = JSON::JWT.new(JSON.parse(payload, symbolize_names: true))
|
56
|
+
jwt.header = JSON.parse(header, symbolize_names: true)
|
57
|
+
handle_signing(jwt, key)
|
58
|
+
rescue JSON::JWS::UnexpectedAlgorithm => e
|
59
|
+
puts "Unexpected algorithm '#{jwt.header[:alg]}'."
|
60
|
+
puts e.message
|
61
|
+
exit!
|
62
|
+
end
|
63
|
+
|
64
|
+
private
|
65
|
+
|
66
|
+
# handle_signing
|
67
|
+
# Handles the algorithm 'none'.
|
68
|
+
# @param jwt [JSON]
|
69
|
+
# @param key [String]
|
70
|
+
#
|
71
|
+
def handle_signing(jwt, key=nil)
|
72
|
+
if jwt.alg =~ /none/i
|
73
|
+
jwt.to_s
|
74
|
+
else
|
75
|
+
raise JSON::JWS::UnexpectedAlgorithm.new("Encryption algorithm '#{jwt.alg}' requires key.") if key.nil?
|
76
|
+
jwt.sign(key).to_s
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
data/lib/jwtear/token.rb
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
require_relative 'jws'
|
2
|
+
require_relative 'jwe'
|
3
|
+
|
4
|
+
module JWTear
|
5
|
+
class Token
|
6
|
+
include JWTear::Helpers::Extensions::Print
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
@jws = JWS.new
|
10
|
+
@jwe = JWE.new
|
11
|
+
end
|
12
|
+
|
13
|
+
# parse
|
14
|
+
# An interface for JWS and JWE parse operation.
|
15
|
+
# @param token [String]
|
16
|
+
#
|
17
|
+
# @return [JWS|JWE]
|
18
|
+
def parse(token)
|
19
|
+
token_segments = token.split('.').size
|
20
|
+
if token_segments <= 3 # JWS
|
21
|
+
@jws.parse(token)
|
22
|
+
else # JWE
|
23
|
+
@jwe.parse(token)
|
24
|
+
end
|
25
|
+
rescue Exception => e
|
26
|
+
print_error "Unknown Exception: #{method(__method__).owner}"
|
27
|
+
print_warning 'Please report the issue to: https://github.com/KINGSABRI/jwtear/issues'.underline
|
28
|
+
puts e
|
29
|
+
puts e.backtrace
|
30
|
+
exit!
|
31
|
+
end
|
32
|
+
|
33
|
+
# generate
|
34
|
+
# An interface for JWS and JWE token generation operation.
|
35
|
+
# @param type [Symbol]
|
36
|
+
# @param header [JSON]
|
37
|
+
# @param payload [JSON]
|
38
|
+
# @param key [String]
|
39
|
+
#
|
40
|
+
# @example
|
41
|
+
# token = JWTear::Token.new
|
42
|
+
# token.generate(:jws, header: '{"alg":"HS256","typ":"JWT"}', payload: '{"user":"admin"}', key: "P@ssw0rd123")
|
43
|
+
#
|
44
|
+
# @return [JWS | JWE]
|
45
|
+
def generate(type, header:, payload:, key:)
|
46
|
+
case type
|
47
|
+
when :jws
|
48
|
+
@jws.generate_jws(header:header , payload:payload , key:key)
|
49
|
+
when :jwe
|
50
|
+
@jwe.generate_jwe(header:header , payload:payload , key:key)
|
51
|
+
else
|
52
|
+
print_error "Unknown type: #{type}"
|
53
|
+
raise
|
54
|
+
end
|
55
|
+
rescue JSON::ParserError => e
|
56
|
+
print_error "Unexpected Token."
|
57
|
+
puts e.message
|
58
|
+
rescue Exception => e
|
59
|
+
method = method(__method__)
|
60
|
+
print_error "Unknown Exception: #{method.owner}##{method.name}"
|
61
|
+
print_warning 'Please report the issue to: https://github.com/KINGSABRI/jwtear/issues'.underline
|
62
|
+
puts e.full_message
|
63
|
+
exit!
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
data/lib/jwtear/version.rb
CHANGED
@@ -0,0 +1,103 @@
|
|
1
|
+
module JWTear
|
2
|
+
module CLI
|
3
|
+
extend GLI::App
|
4
|
+
extend JWTear::Helpers::Extensions::Print
|
5
|
+
|
6
|
+
desc %Q{plugin to offline bruteforce and crack token's signature.}
|
7
|
+
command [:bruteforce, :bfs] do |c|
|
8
|
+
c.desc 'Token to crack its key.'
|
9
|
+
c.arg_name 'JWT_TOKEN'
|
10
|
+
c.flag [:t, :token], required: true
|
11
|
+
|
12
|
+
c.desc 'Password or password list to bruteforce the signature'
|
13
|
+
c.arg_name 'PASS_LIST'
|
14
|
+
c.flag [:l, :p, :list, :password], required: true
|
15
|
+
|
16
|
+
c.desc "Run verbosely."
|
17
|
+
c.switch [:v, :verbose], negatable: false
|
18
|
+
|
19
|
+
c.example %Q{jwtear bruteforce -t TOKEN -l rockyou.list -v}
|
20
|
+
c.example %Q{jwtear bruteforce -t TOKEN -l P@ssw0rd123}
|
21
|
+
|
22
|
+
c.action do |_, options, _|
|
23
|
+
begin
|
24
|
+
bf = Bruteforce.new(options[:token], options[:list])
|
25
|
+
bf.run(options[:verbose])
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
class Bruteforce
|
33
|
+
include JWTear::Helpers::Extensions::Print
|
34
|
+
include JWTear::Helpers::Utils
|
35
|
+
|
36
|
+
def initialize(token, list)
|
37
|
+
deps = {'async-io' => 'async/io'}
|
38
|
+
check_dependencies(deps)
|
39
|
+
@token = Token.new
|
40
|
+
@jws = @token.parse(token)
|
41
|
+
@list = list
|
42
|
+
end
|
43
|
+
|
44
|
+
def run(verbose=false)
|
45
|
+
keys = handle_key
|
46
|
+
case
|
47
|
+
when keys.kind_of?(Enumerator::Lazy)
|
48
|
+
keys.each do |key|
|
49
|
+
print_status "Trying password: #{key}" if verbose
|
50
|
+
|
51
|
+
gen_token = @token.generate(:jws, header: @jws.header.to_json, payload:@jws.payload.to_json , key: key)
|
52
|
+
sig = gen_token.split('.').last
|
53
|
+
if sig == Base64.urlsafe_encode64(@jws.signature, padding: false)
|
54
|
+
print_good "Password found: #{key}"
|
55
|
+
puts gen_token
|
56
|
+
exit!
|
57
|
+
else
|
58
|
+
print_bad "Invalid key: #{key}" if verbose
|
59
|
+
# puts gen_token if verbose
|
60
|
+
end
|
61
|
+
end
|
62
|
+
when keys.kind_of?(String)
|
63
|
+
gen_token = @token.generate(:jws, header: @jws.header.to_json, payload:@jws.payload.to_json , key: keys)
|
64
|
+
sig = gen_token.split('.').last
|
65
|
+
if sig == Base64.urlsafe_encode64(@jws.signature, padding: false)
|
66
|
+
print_good "Password found: #{keys}"
|
67
|
+
puts gen_token
|
68
|
+
else
|
69
|
+
print_bad "Invalid key: #{keys}"
|
70
|
+
end
|
71
|
+
|
72
|
+
else
|
73
|
+
print_error "Unknown key type"
|
74
|
+
raise
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
|
79
|
+
def handle_key
|
80
|
+
if File.file?(@list)
|
81
|
+
read_wordlist(@list)
|
82
|
+
else
|
83
|
+
@list
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def read_wordlist(file)
|
88
|
+
if File.file?(file)
|
89
|
+
print_status "Found '#{file}' file."
|
90
|
+
File.readlines(file, chomp: true)
|
91
|
+
.lazy
|
92
|
+
.map(&:strip)
|
93
|
+
.reject(&:empty?)
|
94
|
+
.reject(&:nil?)
|
95
|
+
else
|
96
|
+
print_bad "File not found. #{file}"
|
97
|
+
exit!
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|