Skip to content

Commit bd3ce5f

Browse files
authored
Fix issue #20396
1 parent 56f138c commit bd3ce5f

File tree

1 file changed

+41
-11
lines changed

1 file changed

+41
-11
lines changed

modules/auxiliary/analyze/crack_databases.rb

Lines changed: 41 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,9 @@ def initialize
3434
'Actions' => [
3535
['john', { 'Description' => 'Use John the Ripper' }],
3636
['hashcat', { 'Description' => 'Use Hashcat' }],
37+
['auto', { 'Description' => 'Use either John the Ripper or Hashcat, if both are present, use Hashcat' }]
3738
],
38-
'DefaultAction' => 'john',
39+
'DefaultAction' => 'auto',
3940
'Notes' => {
4041
'Stability' => [CRASH_SAFE],
4142
'SideEffects' => [],
@@ -58,29 +59,34 @@ def initialize
5859
def show_command(cracker_instance)
5960
return unless datastore['ShowCommand']
6061

61-
if action.name == 'john'
62+
newaction = getaction()
63+
64+
if newaction == 'john'
6265
cmd = cracker_instance.john_crack_command
63-
elsif action.name == 'hashcat'
66+
elsif newaction == 'hashcat'
6467
cmd = cracker_instance.hashcat_crack_command
6568
end
6669
print_status(" Cracking Command: #{cmd.join(' ')}")
6770
end
6871

6972
def check_results(passwords, results, hash_type, method)
73+
74+
newaction = getaction()
75+
7076
passwords.each do |password_line|
7177
password_line.chomp!
7278
next if password_line.blank?
7379

7480
fields = password_line.split(':')
7581
cred = { 'hash_type' => hash_type, 'method' => method }
7682

77-
if action.name == 'john'
83+
if newaction == 'john'
7884
next unless fields.count >= 3
7985

8086
cred['username'] = fields.shift
8187
cred['core_id'] = fields.pop
8288
cred['password'] = fields.join(':') # Anything left must be the password. This accounts for passwords with semi-colons in it
83-
elsif action.name == 'hashcat'
89+
elsif newaction == 'hashcat'
8490
next unless fields.count >= 2
8591

8692
cred['core_id'] = fields.shift
@@ -109,6 +115,9 @@ def check_results(passwords, results, hash_type, method)
109115
end
110116

111117
def run
118+
119+
newaction = getaction()
120+
112121
tbl = tbl = cracker_results_table
113122

114123
# array of hashes in jtr_format in the db, converted to an OR combined regex
@@ -128,7 +137,7 @@ def run
128137

129138
# hashcat requires a format we dont have all the data for
130139
# in the current dumper, so this is disabled in module and lib
131-
if action.name == 'john'
140+
if newaction == 'john'
132141
hash_types_to_crack << 'oracle'
133142
hash_types_to_crack << 'dynamic_1506'
134143
end
@@ -143,7 +152,7 @@ def run
143152

144153
# build our job list
145154
hash_types_to_crack.each do |hash_type|
146-
job = hash_job(hash_type, action.name)
155+
job = hash_job(hash_type, newaction)
147156
if job.nil?
148157
print_status("No #{hash_type} found to crack")
149158
else
@@ -161,7 +170,7 @@ def run
161170
# Inner array format: db_id, hash_type, username, password, method_of_crack
162171
results = []
163172

164-
cracker = new_password_cracker(action.name)
173+
cracker = new_password_cracker(newaction)
165174

166175
# generate our wordlist and close the file handle.
167176
wordlist = wordlist_file
@@ -187,7 +196,7 @@ def run
187196
cracker_instance = cracker.dup
188197
cracker_instance.format = format
189198

190-
if action.name == 'john'
199+
if newaction == 'john'
191200
cracker_instance.fork = datastore['FORK']
192201
end
193202

@@ -198,7 +207,7 @@ def run
198207
job['cred_ids_left_to_crack'] = job['cred_ids_left_to_crack'] - results.map { |i| i[0].to_i } # remove cracked hashes from the hash list
199208
next if job['cred_ids_left_to_crack'].empty?
200209

201-
if action.name == 'john'
210+
if newaction == 'john'
202211
print_status "Cracking #{format} hashes in single mode..."
203212
cracker_instance.mode_single(wordlist.path)
204213
show_command cracker_instance
@@ -239,7 +248,7 @@ def run
239248
print_status "Cracking #{format} hashes in wordlist mode..."
240249
cracker_instance.mode_wordlist(wordlist.path)
241250
# Turn on KoreLogic rules if the user asked for it
242-
if action.name == 'john' && datastore['KORELOGIC']
251+
if newaction == 'john' && datastore['KORELOGIC']
243252
cracker_instance.rules = 'KoreLogicRules'
244253
print_status 'Applying KoreLogic ruleset...'
245254
end
@@ -263,4 +272,25 @@ def run
263272
end
264273
end
265274
end
275+
276+
def getaction
277+
newaction = action.name
278+
if action.name == 'auto'
279+
path = Rex::FileUtils.find_full_path('hashcat') ||
280+
Rex::FileUtils.find_full_path('hashcat.exe')
281+
if path
282+
newaction = 'hashcat'
283+
else
284+
path = Rex::FileUtils.find_full_path('john') ||
285+
Rex::FileUtils.find_full_path('john.exe')
286+
if path
287+
newaction = 'john'
288+
else
289+
raise PasswordCrackerNotFoundError, 'No suitable john/hashcat binary was found on the system'
290+
end
291+
end
292+
end
293+
return newaction
294+
end
295+
266296
end

0 commit comments

Comments
 (0)