Skip to content

Commit ecfdec9

Browse files
authored
Fix issue #20396
1 parent d484191 commit ecfdec9

File tree

1 file changed

+39
-10
lines changed

1 file changed

+39
-10
lines changed

modules/auxiliary/analyze/crack_windows.rb

Lines changed: 39 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,9 @@ def initialize
3030
'Actions' => [
3131
['john', { 'Description' => 'Use John the Ripper' }],
3232
['hashcat', { 'Description' => 'Use Hashcat' }],
33+
['auto', { 'Description' => 'Use either John the Ripper or Hashcat, if both are present, use Hashcat' }]
3334
],
34-
'DefaultAction' => 'john',
35+
'DefaultAction' => 'auto',
3536
'Notes' => {
3637
'Stability' => [CRASH_SAFE],
3738
'SideEffects' => [],
@@ -62,9 +63,11 @@ def half_lm_regex
6263
def show_command(cracker_instance)
6364
return unless datastore['ShowCommand']
6465

65-
if action.name == 'john'
66+
newaction = getaction()
67+
68+
if newaction == 'john'
6669
cmd = cracker_instance.john_crack_command
67-
elsif action.name == 'hashcat'
70+
elsif newaction == 'hashcat'
6871
cmd = cracker_instance.hashcat_crack_command
6972
end
7073
print_status(" Cracking Command: #{cmd.join(' ')}")
@@ -96,13 +99,16 @@ def process_cracker_results(results, cred)
9699
end
97100

98101
def check_results(passwords, results, hash_type, method)
102+
103+
newaction = getaction()
104+
99105
passwords.each do |password_line|
100106
password_line.chomp!
101107
next if password_line.blank?
102108

103109
fields = password_line.split(':')
104110
cred = { 'hash_type' => hash_type, 'method' => method }
105-
if action.name == 'john'
111+
if newaction == 'john'
106112
# If we don't have an expected minimum number of fields, this is probably not a hash line
107113
next unless fields.count > 2
108114

@@ -136,7 +142,7 @@ def check_results(passwords, results, hash_type, method)
136142
cred['password'] = john_lm_upper_to_ntlm(password, nt_hash)
137143
end
138144
next if cred['password'].nil?
139-
elsif action.name == 'hashcat'
145+
elsif newaction == 'hashcat'
140146
next unless fields.count >= 2
141147

142148
cred['core_id'] = fields.shift
@@ -163,6 +169,9 @@ def check_results(passwords, results, hash_type, method)
163169
end
164170

165171
def run
172+
173+
newaction = getaction()
174+
166175
tbl = cracker_results_table
167176

168177
# array of hashes in jtr_format in the db, converted to an OR combined regex
@@ -178,7 +187,7 @@ def run
178187

179188
# build our job list
180189
hash_types_to_crack.each do |hash_type|
181-
job = hash_job(hash_type, action.name)
190+
job = hash_job(hash_type, newaction)
182191
if job.nil?
183192
print_status("No #{hash_type} found to crack")
184193
else
@@ -196,7 +205,7 @@ def run
196205
# Inner array format: db_id, hash_type, username, password, method_of_crack
197206
results = []
198207

199-
cracker = new_password_cracker(action.name)
208+
cracker = new_password_cracker(newaction)
200209

201210
# generate our wordlist and close the file handle.
202211
wordlist = wordlist_file
@@ -220,7 +229,7 @@ def run
220229
# dupe our original cracker so we can safely change options between each run
221230
cracker_instance = cracker.dup
222231
cracker_instance.format = format
223-
if action.name == 'john'
232+
if newaction == 'john'
224233
cracker_instance.fork = datastore['FORK']
225234
end
226235

@@ -231,7 +240,7 @@ def run
231240
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
232241
next if job['cred_ids_left_to_crack'].empty?
233242

234-
if action.name == 'john'
243+
if newaction == 'john'
235244
print_status "Cracking #{format} hashes in single mode..."
236245
cracker_instance.mode_single(wordlist.path)
237246
show_command cracker_instance
@@ -274,7 +283,7 @@ def run
274283
print_status "Cracking #{format} hashes in wordlist mode..."
275284
cracker_instance.mode_wordlist(wordlist.path)
276285
# Turn on KoreLogic rules if the user asked for it
277-
if action.name == 'john' && datastore['KORELOGIC']
286+
if newaction == 'john' && datastore['KORELOGIC']
278287
cracker_instance.rules = 'KoreLogicRules'
279288
print_status 'Applying KoreLogic ruleset...'
280289
end
@@ -299,4 +308,24 @@ def run
299308
end
300309
end
301310
end
311+
312+
def getaction
313+
newaction = action.name
314+
if action.name == 'auto'
315+
path = Rex::FileUtils.find_full_path('hashcat') ||
316+
Rex::FileUtils.find_full_path('hashcat.exe')
317+
if path
318+
newaction = 'hashcat'
319+
else
320+
path = Rex::FileUtils.find_full_path('john') ||
321+
Rex::FileUtils.find_full_path('john.exe')
322+
if path
323+
newaction = 'john'
324+
else
325+
raise PasswordCrackerNotFoundError, 'No suitable john/hashcat binary was found on the system'
326+
end
327+
end
328+
end
329+
return newaction
330+
end
302331
end

0 commit comments

Comments
 (0)