heitt 0.4.6 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/bin/heitt +88 -73
- data/lib/heitt/analyzer.rb +2 -5
- data/lib/heitt/decoder.rb +48 -0
- data/lib/heitt/formatter.rb +8 -2
- data/lib/heitt/grouper.rb +1 -3
- data/lib/heitt/scanner.rb +0 -3
- data/lib/heitt/version.rb +3 -2
- data/lib/heitt.rb +5 -3
- metadata +11 -7
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: ae7835969de375994bf7a0f9bf03c453f1ccd77d9086b4712a13e755084cb01c
|
|
4
|
+
data.tar.gz: 5754d899e34e5a9e8162c451fcef359939165221a0a758348e9ec608e9c0cc5a
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 1f2174d59e403b16385946ca733cdc428fb75f09c6c4275f42d6ecb6870725f8a4224d8389934d4d5a0106e6a01f65d9226eb1de30fc6997d98e2b4c81b09ade
|
|
7
|
+
data.tar.gz: 228b63e61c87e07b4f8f5c68afc8121fe95c6e9bffd644408cda410e05d7e6314684d730e14fa640793c14b8d21dc7664ba22ed84c27b5399fdf99141e249c2d
|
data/bin/heitt
CHANGED
|
@@ -8,14 +8,13 @@ require 'heitt'
|
|
|
8
8
|
|
|
9
9
|
module HEITT
|
|
10
10
|
class CLI
|
|
11
|
-
attr_accessor :inputs, :extended, :verbose, :
|
|
12
|
-
|
|
11
|
+
attr_accessor :inputs, :extended, :verbose, :tree, :database, :show_regex_match, :min_entropy, :peel_limit
|
|
13
12
|
def initialize
|
|
14
13
|
@inputs = []
|
|
15
14
|
@extended = false
|
|
16
15
|
@verbose = false
|
|
17
|
-
@
|
|
18
|
-
@
|
|
16
|
+
@tree = false
|
|
17
|
+
@peel_limit = 0
|
|
19
18
|
@database = ""
|
|
20
19
|
@show_regex_match = false
|
|
21
20
|
@min_entropy = 3.5
|
|
@@ -46,10 +45,13 @@ module HEITT
|
|
|
46
45
|
opts.separator ""
|
|
47
46
|
opts.separator "OUTPUT OPTIONS:"
|
|
48
47
|
opts.on("-V", "--verbose", "Show description and notes for each candidate") {@verbose = true}
|
|
49
|
-
opts.on("-
|
|
50
|
-
opts.on("-o", "--output FILEPATH", String, "File to write output to") {|v| @output = v}
|
|
48
|
+
opts.on("-t", "--tree", "Force tree format when output is redirected"){@tree = true}
|
|
51
49
|
opts.on("--debug", "Output in debug mode") {HEITT::Logger.enable_debug}
|
|
52
50
|
|
|
51
|
+
opts.separator ""
|
|
52
|
+
opts.separator "DECODE OPTIONS:"
|
|
53
|
+
opts.on("-L", "--peel-limit INTEGER", Integer, "Maximum decode layers to peel(supports base64 and hex)") {|v| @peel_limit = v}
|
|
54
|
+
|
|
53
55
|
opts.separator ""
|
|
54
56
|
opts.separator "FILTERING OPTIONS:"
|
|
55
57
|
opts.on("-e", "--extended", "Show extended candidates") {@extended = true}
|
|
@@ -64,7 +66,7 @@ module HEITT
|
|
|
64
66
|
opts.separator "EXAMPLES:"
|
|
65
67
|
opts.separator " heitt 634d398e96eb1550956b8128cfeb0747 -r"
|
|
66
68
|
opts.separator " heitt auth.log"
|
|
67
|
-
opts.separator " heitt auth.log
|
|
69
|
+
opts.separator " heitt auth.log | cat"
|
|
68
70
|
opts.separator " heitt auth.log --extended --regex-match"
|
|
69
71
|
opts.separator " heitt auth.log --min-entropy 4.0"
|
|
70
72
|
opts.separator " cat auth.log | heitt "
|
|
@@ -81,42 +83,13 @@ module HEITT
|
|
|
81
83
|
end.parse!
|
|
82
84
|
|
|
83
85
|
@inputs = if ARGV.empty?
|
|
86
|
+
|
|
84
87
|
if $stdin.tty?
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
puts header("=== HEITT INTERACTIVE MODE ====")
|
|
88
|
-
print "[debug:#{HEITT::Logger.debug_enabled? ? "on": "off"} || "
|
|
89
|
-
print "extended: #{@extended ? "on": "off"} || "
|
|
90
|
-
print "verbose: #{@verbose ? "on": "off"} || "
|
|
91
|
-
print "regex-match: #{@show_regex_match ? "on": "off"} || "
|
|
92
|
-
print "min-entropy: #{@min_entropy} || "
|
|
93
|
-
print "database: #{@database.empty? ? "default": database} || "
|
|
94
|
-
print "output-format: #{@json ? "json": "tree"}]\n"
|
|
95
|
-
puts ""
|
|
96
|
-
puts "Enter a hash or filepath. Press Ctrl+C or Enter to exit"
|
|
97
|
-
#puts "Extended: true" unless
|
|
98
|
-
# puts used flags here
|
|
99
|
-
|
|
100
|
-
loop do
|
|
101
|
-
print "heitt> "
|
|
102
|
-
input = $stdin.gets&.strip
|
|
103
|
-
break if input.nil? || input.empty?
|
|
104
|
-
results = HEITT::Scanner.scan(input, min_entropy: @min_entropy)
|
|
105
|
-
groups = HEITT::Grouper.group(results)
|
|
106
|
-
format = @json ? :json : :tree
|
|
107
|
-
output = case format
|
|
108
|
-
when :json
|
|
109
|
-
HEITT::Formatter.json(groups, extended: @extended, show_regex_match: @show_regex_match)
|
|
110
|
-
else
|
|
111
|
-
HEITT::Formatter.tree(groups, extended: @extended, show_regex_match: @show_regex_match)
|
|
112
|
-
end
|
|
113
|
-
puts output
|
|
114
|
-
puts ""
|
|
115
|
-
end
|
|
88
|
+
# instead of hanging, make it interactive
|
|
89
|
+
interactive_loop
|
|
116
90
|
else
|
|
117
91
|
[$stdin.read]
|
|
118
92
|
end
|
|
119
|
-
|
|
120
93
|
|
|
121
94
|
else
|
|
122
95
|
ARGV.dup
|
|
@@ -124,35 +97,81 @@ module HEITT
|
|
|
124
97
|
self
|
|
125
98
|
end
|
|
126
99
|
|
|
100
|
+
def interactive_loop
|
|
101
|
+
database = @database.empty? ? HEITT::DATABASE : load_custom_database(@database)
|
|
102
|
+
# Interactive mode
|
|
103
|
+
puts header("=== HEITT INTERACTIVE MODE ====")
|
|
104
|
+
#print "[debug:#{HEITT::Logger.debug_enabled? ? "on": "off"} || "
|
|
105
|
+
print "extended: #{@extended ? "on": "off"} || "
|
|
106
|
+
print "peel-limit: #{@peel_limit} || "
|
|
107
|
+
print "verbose: #{@verbose ? "on": "off"} || "
|
|
108
|
+
print "regex-match: #{@show_regex_match ? "on": "off"} || "
|
|
109
|
+
print "min-entropy: #{@min_entropy} || "
|
|
110
|
+
print "database: #{@database.empty? ? "default": database} || "
|
|
111
|
+
print "output-format: #{@json ? "json": "tree"}]\n"
|
|
112
|
+
puts ""
|
|
113
|
+
puts "Enter a hash or filepath. Press Ctrl+C or Enter to exit"
|
|
114
|
+
#puts "Extended: true" unless
|
|
115
|
+
# puts used flags here
|
|
116
|
+
|
|
117
|
+
loop do
|
|
118
|
+
print "heitt> "
|
|
119
|
+
input = $stdin.gets&.strip
|
|
120
|
+
break if input.nil? || input.empty?
|
|
121
|
+
results = HEITT::Scanner.scan(input, min_entropy: @min_entropy)
|
|
122
|
+
groups = HEITT::Grouper.group(results)
|
|
123
|
+
|
|
124
|
+
format = :tree
|
|
125
|
+
|
|
126
|
+
output = case format
|
|
127
|
+
when :tree
|
|
128
|
+
HEITT::Formatter.json(groups, extended: @extended, show_regex_match: @show_regex_match)
|
|
129
|
+
else
|
|
130
|
+
HEITT::Formatter.tree(groups, verbose: @verbose, extended: @extended, show_regex_match: @show_regex_match)
|
|
131
|
+
end
|
|
132
|
+
puts output
|
|
133
|
+
puts ""
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
|
|
127
138
|
def run
|
|
128
|
-
HEITT::Logger.debug("Loading database...")
|
|
129
139
|
database = @database.empty? ? HEITT::DATABASE : load_custom_database(@database)
|
|
130
|
-
HEITT::Logger.debug("Database (#{@database.empty? ? "default" : @database}) loaded")
|
|
131
140
|
|
|
132
|
-
format = @
|
|
141
|
+
format = if @tree
|
|
142
|
+
:tree
|
|
143
|
+
elsif !$stdout.tty?
|
|
144
|
+
:json
|
|
145
|
+
else
|
|
146
|
+
:tree
|
|
147
|
+
end
|
|
148
|
+
|
|
133
149
|
output = @inputs.map do |input|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
HEITT::
|
|
137
|
-
HEITT::Logger.debug("Grouping Results ...")
|
|
150
|
+
text = read_input(input)
|
|
151
|
+
text = HEITT::Decoder.peel(text, peel_limit: @peel_limit)[:final] if @peel_limit > 0
|
|
152
|
+
results = HEITT::Scanner.scan(text, database: database, min_entropy: @min_entropy)
|
|
138
153
|
groups = HEITT::Grouper.group(results)
|
|
139
154
|
|
|
140
155
|
case format
|
|
141
156
|
when :json
|
|
142
157
|
HEITT::Formatter.json(groups, extended: @extended, show_regex_match: @show_regex_match)
|
|
143
158
|
else
|
|
144
|
-
HEITT::Formatter.tree(groups, extended: @extended, show_regex_match: @show_regex_match)
|
|
159
|
+
HEITT::Formatter.tree(groups, verbose: @verbose, extended: @extended, show_regex_match: @show_regex_match)
|
|
145
160
|
end
|
|
146
161
|
end.join("\n")
|
|
147
162
|
|
|
148
|
-
unless @output.empty?
|
|
149
|
-
|
|
150
|
-
else
|
|
151
|
-
|
|
152
|
-
end
|
|
163
|
+
#unless @output.empty?
|
|
164
|
+
# File.write(@output, output)
|
|
165
|
+
#else
|
|
166
|
+
puts output
|
|
167
|
+
#end
|
|
153
168
|
end
|
|
154
169
|
|
|
155
170
|
private
|
|
171
|
+
def read_input(input)
|
|
172
|
+
File.exist?(File.expand_path(input)) ? File.read(File.expand_path(input)) : input
|
|
173
|
+
end
|
|
174
|
+
|
|
156
175
|
def header(text)
|
|
157
176
|
terminal_width = IO.console.winsize[1] rescue 70
|
|
158
177
|
text.center(terminal_width)
|
|
@@ -162,9 +181,9 @@ module HEITT
|
|
|
162
181
|
|
|
163
182
|
def load_custom_database(file_path)
|
|
164
183
|
filepath = File.expand_path(file_path)
|
|
165
|
-
HEITT::Logger.debug("
|
|
184
|
+
HEITT::Logger.debug("filepath: #{filepath}")
|
|
166
185
|
unless File.exist?(filepath)
|
|
167
|
-
HEITT::Logger.error("
|
|
186
|
+
HEITT::Logger.error("file #{filepath} does not exist")
|
|
168
187
|
exit(1)
|
|
169
188
|
end
|
|
170
189
|
begin
|
|
@@ -175,26 +194,22 @@ module HEITT
|
|
|
175
194
|
exit(1)
|
|
176
195
|
end
|
|
177
196
|
end
|
|
178
|
-
|
|
179
|
-
# def decode(text, decoders)
|
|
180
|
-
#Check if result is printable ascii after decoding
|
|
181
|
-
# decoders.each do |decoder|
|
|
182
|
-
# case decoder
|
|
183
|
-
# when "b64"
|
|
184
|
-
# text = text.gsub(/[A-Za-z0-9+\/]{4,}={0,2}/) do |match|
|
|
185
|
-
# current = match
|
|
186
|
-
# loop do
|
|
187
|
-
# #until word is non printable ascii continue decoding
|
|
188
|
-
# decoded = Base64.decode64(word) #rescue break
|
|
189
|
-
# current = decoded.strip.match?(/\A[[:print:]]+\z/) ? decoded.strip : break
|
|
190
|
-
#puts "IS PRINTABLE?: #{decoded.match?(/\A[[:print:]]+\z/)}"
|
|
191
|
-
#puts "RESULT: #{result}"
|
|
192
|
-
# end
|
|
193
|
-
# current
|
|
194
|
-
# end
|
|
195
|
-
# when "hex"
|
|
196
|
-
# text = tesxt.gsub(/)
|
|
197
197
|
end
|
|
198
198
|
end
|
|
199
199
|
|
|
200
200
|
cli = HEITT::CLI.new.parse!.run #if __FILE__ == $0
|
|
201
|
+
|
|
202
|
+
## Some flags will be removed.
|
|
203
|
+
# output flag will be replaced by tree flag. it existed because
|
|
204
|
+
# tree couldnt show when output was redirected.
|
|
205
|
+
# json flag will be removed, although it was created so its format will be seen
|
|
206
|
+
# it now looks redundant to the automatic version.
|
|
207
|
+
# -r flag wont be used for everything. it was made
|
|
208
|
+
# to filter out low confidence types from high confidence ones and show when asked for.
|
|
209
|
+
# in case of all being "regex-matched", -r shouldnt be necessary.
|
|
210
|
+
# this will make it convenient to check single hashes without always needing -r flag
|
|
211
|
+
#auto decoding hasn't being dropped, a library "codeberg.org/jobotow/lookslike" is in the making to help with encoded string identification.
|
|
212
|
+
# it will decode and check it it's a binary blob. if first decode shows binary blob, then it certainly isn't a hash hex or proper b64.
|
|
213
|
+
# else it should continue decoding till ut also meets binary blob before returning back to previous text before last decode"
|
|
214
|
+
# from the context that a text that's encoded once cant be decoded twice because the binary blob will show that the second text undergoing decoding was the actual answer.
|
|
215
|
+
# binary blob will be the eyes as it's uncertain the number of times a text has being encoded.
|
data/lib/heitt/analyzer.rb
CHANGED
|
@@ -1,12 +1,9 @@
|
|
|
1
|
-
require_relative 'utils'
|
|
2
1
|
require_relative 'profiles'
|
|
3
2
|
|
|
4
3
|
module HEITT
|
|
5
4
|
module Analyzer
|
|
6
5
|
def self.analyze(text, profiles: HEITT::PROFILES)#database: HEITT::DATABASE)
|
|
7
|
-
HEITT::Logger.debug("Counting keywords...")
|
|
8
6
|
keyword_counts = keyword_counts(text.downcase, profiles: profiles)
|
|
9
|
-
HEITT::Logger.debug("Counted keywords: #{keyword_counts}")
|
|
10
7
|
algorithm_scores(keyword_counts, profiles: profiles)
|
|
11
8
|
end
|
|
12
9
|
|
|
@@ -39,6 +36,7 @@ module HEITT
|
|
|
39
36
|
john: mode[:john],
|
|
40
37
|
extended: mode[:extended],
|
|
41
38
|
description: profile[:description],
|
|
39
|
+
notes: profile[:notes],
|
|
42
40
|
score: score
|
|
43
41
|
}
|
|
44
42
|
end
|
|
@@ -49,7 +47,6 @@ module HEITT
|
|
|
49
47
|
|
|
50
48
|
confidences = assign_confidence(scores_hash, prefix_matched_mode)
|
|
51
49
|
scored_candidates = matches.map{|m| m.merge(confidence: confidences[m[:name]])}.sort_by {|m| -m[:score]}
|
|
52
|
-
HEITT::Logger.debug("Scored Algorithm: #{scored_candidates.map{|s| s[:name] }} => Calculated Confidence: #{scored_candidates.map{|s| s[:confidence] }}")
|
|
53
50
|
scored_candidates
|
|
54
51
|
end
|
|
55
52
|
|
|
@@ -153,4 +150,4 @@ module HEITT
|
|
|
153
150
|
end
|
|
154
151
|
end
|
|
155
152
|
#private_constant :Analyzer
|
|
156
|
-
end
|
|
153
|
+
end
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
require 'base64'
|
|
2
|
+
module HEITT
|
|
3
|
+
module Decoder
|
|
4
|
+
ENCODED_B64 = '[A-Za-z0-9+\/]'
|
|
5
|
+
BASE_HEXBYTE = '[[:xdigit:]]'
|
|
6
|
+
|
|
7
|
+
def self.binary?(string)
|
|
8
|
+
return true if string.encoding == Encoding::ASCII_8BIT && !string.valid_encoding?
|
|
9
|
+
return true if string.include?("\x00")
|
|
10
|
+
sample = string.bytes.first(4096)
|
|
11
|
+
non_printable = sample.count { |b| b < 32 || b > 126}
|
|
12
|
+
(non_printable.to_f / sample.size) > 0.30
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def self.likely_base64?(string)
|
|
16
|
+
string.match(/\A(?:#{ENCODED_B64}{4})*(?:#{ENCODED_B64}{2}==|#{ENCODED_B64}{3}=)?\z/)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def self.likely_hex?(string)
|
|
20
|
+
string.match(/\A#{BASE_HEXBYTE}+\z/) && string.length.even?
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def self.decode_layer(string)
|
|
24
|
+
return [:base64, Base64.decode64(string)] if likely_base64?(string)
|
|
25
|
+
return [:hex, [string].pack("H*")] if likely_hex?(string)
|
|
26
|
+
nil
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def self.peel(string, peel_limit: 12)
|
|
31
|
+
steps = []
|
|
32
|
+
current = string.gsub(/\s+/, '')
|
|
33
|
+
|
|
34
|
+
peel_limit.times do
|
|
35
|
+
result = decode_layer(current)
|
|
36
|
+
break unless result
|
|
37
|
+
method, decoded = result
|
|
38
|
+
decoded = decoded.gsub(/\s+/, '')
|
|
39
|
+
break if binary?(decoded)
|
|
40
|
+
|
|
41
|
+
steps << { method: method, result: decoded }
|
|
42
|
+
current = decoded
|
|
43
|
+
end
|
|
44
|
+
{ final: current, steps: steps }
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
data/lib/heitt/formatter.rb
CHANGED
|
@@ -43,6 +43,10 @@ module HEITT
|
|
|
43
43
|
{text: "John Format: #{candidate[:john] || "--"}", children: []}
|
|
44
44
|
]
|
|
45
45
|
|
|
46
|
+
if extended
|
|
47
|
+
children << {text: "Extended: #{candidate[:extended]}", children: []}
|
|
48
|
+
end
|
|
49
|
+
|
|
46
50
|
if verbose
|
|
47
51
|
if candidate[:description] && !candidate[:description].empty?
|
|
48
52
|
children << {text: "Description: #{candidate[:description]}", children: []}
|
|
@@ -86,7 +90,9 @@ module HEITT
|
|
|
86
90
|
hashcat: candidate[:hashcat],
|
|
87
91
|
john: candidate[:john],
|
|
88
92
|
confidence: candidate[:confidence],
|
|
89
|
-
|
|
93
|
+
extended: candidate[:extended],
|
|
94
|
+
description: candidate[:description],
|
|
95
|
+
notes: candidate[:notes]
|
|
90
96
|
}
|
|
91
97
|
end
|
|
92
98
|
}
|
|
@@ -122,4 +128,4 @@ module HEITT
|
|
|
122
128
|
result
|
|
123
129
|
end
|
|
124
130
|
end
|
|
125
|
-
end
|
|
131
|
+
end
|
data/lib/heitt/grouper.rb
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
require_relative 'utils'
|
|
2
1
|
module HEITT
|
|
3
2
|
module Grouper
|
|
4
3
|
|
|
@@ -15,8 +14,7 @@ module HEITT
|
|
|
15
14
|
count: hashes.size
|
|
16
15
|
}
|
|
17
16
|
end
|
|
18
|
-
HEITT::Logger.debug("Hashes grouped successfully") unless groups.empty? || groups.nil?
|
|
19
17
|
groups
|
|
20
18
|
end
|
|
21
19
|
end
|
|
22
|
-
end
|
|
20
|
+
end
|
data/lib/heitt/scanner.rb
CHANGED
|
@@ -25,10 +25,7 @@ module HEITT
|
|
|
25
25
|
matched = scanner.matched
|
|
26
26
|
next unless matched.length < 8 || HEITT::Analyzer.high_entropy?(matched, min_entropy)
|
|
27
27
|
offset = scanner.pos - matched.length
|
|
28
|
-
HEITT::Logger.debug("Extracting prefix..")
|
|
29
28
|
delim_prefix = HEITT::Analyzer.extract_prefix(text, offset)
|
|
30
|
-
HEITT::Logger.debug("Extracted prefix: #{delim_prefix.length <= 1 ? "NULL" : delim_prefix}")
|
|
31
|
-
|
|
32
29
|
candidates = HEITT::Analyzer.score_candidates(modes, delim_prefix, context_scores)
|
|
33
30
|
#score = candidates.first[:score]
|
|
34
31
|
|
data/lib/heitt/version.rb
CHANGED
data/lib/heitt.rb
CHANGED
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
#require 'strscan'
|
|
4
4
|
#require 'logger'
|
|
5
5
|
#require 'colorize'
|
|
6
|
-
require_relative 'heitt/utils'
|
|
7
6
|
require_relative 'heitt/profiles'
|
|
7
|
+
require_relative 'heitt/decoder'
|
|
8
8
|
require_relative 'heitt/database'
|
|
9
9
|
require_relative 'heitt/analyzer'
|
|
10
10
|
require_relative 'heitt/scanner'
|
|
@@ -12,5 +12,7 @@ require_relative 'heitt/grouper'
|
|
|
12
12
|
require_relative 'heitt/formatter'
|
|
13
13
|
require_relative 'heitt/version'
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
# module HEITT
|
|
16
|
+
# something like heitt = HEITT.new(database: nil, profiles: nil)
|
|
17
|
+
# heitt.identify("hash_string")
|
|
18
|
+
|
metadata
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: heitt
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.5.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Jonathan Botchway Owusu
|
|
8
|
+
autorequire:
|
|
8
9
|
bindir: bin
|
|
9
10
|
cert_chain: []
|
|
10
|
-
date:
|
|
11
|
+
date: 2026-08-30 00:00:00.000000000 Z
|
|
11
12
|
dependencies:
|
|
12
13
|
- !ruby/object:Gem::Dependency
|
|
13
14
|
name: colorize
|
|
@@ -35,18 +36,20 @@ files:
|
|
|
35
36
|
- lib/heitt.rb
|
|
36
37
|
- lib/heitt/analyzer.rb
|
|
37
38
|
- lib/heitt/database.rb
|
|
39
|
+
- lib/heitt/decoder.rb
|
|
38
40
|
- lib/heitt/formatter.rb
|
|
39
41
|
- lib/heitt/grouper.rb
|
|
40
42
|
- lib/heitt/profiles.rb
|
|
41
43
|
- lib/heitt/scanner.rb
|
|
42
44
|
- lib/heitt/utils.rb
|
|
43
45
|
- lib/heitt/version.rb
|
|
44
|
-
homepage: https://
|
|
46
|
+
homepage: https://codeberg.org/jobotow/heitt
|
|
45
47
|
licenses: []
|
|
46
48
|
metadata:
|
|
47
|
-
homepage_uri: https://
|
|
48
|
-
source_code_uri: https://
|
|
49
|
-
changelog_uri: https://
|
|
49
|
+
homepage_uri: https://codeberg.org/jobotow/heitt
|
|
50
|
+
source_code_uri: https://codeberg.org/jobotow/heitt
|
|
51
|
+
changelog_uri: https://codeberg.org/jobotow/heitt/blob/main/CHANGELOG.md
|
|
52
|
+
post_install_message:
|
|
50
53
|
rdoc_options: []
|
|
51
54
|
require_paths:
|
|
52
55
|
- lib
|
|
@@ -61,7 +64,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
61
64
|
- !ruby/object:Gem::Version
|
|
62
65
|
version: '0'
|
|
63
66
|
requirements: []
|
|
64
|
-
rubygems_version: 3.
|
|
67
|
+
rubygems_version: 3.4.20
|
|
68
|
+
signing_key:
|
|
65
69
|
specification_version: 4
|
|
66
70
|
summary: Hash Extraction, Identification and Triage Tool.
|
|
67
71
|
test_files: []
|