Skip to content

Commit d88c4bd

Browse files
authored
Fix issue #20396
1 parent 5aee8d5 commit d88c4bd

File tree

1 file changed

+39
-10
lines changed

1 file changed

+39
-10
lines changed

modules/auxiliary/analyze/crack_osx.rb

Lines changed: 39 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,9 @@ def initialize
2424
'Actions' => [
2525
['john', { 'Description' => 'Use John the Ripper' }],
2626
['hashcat', { 'Description' => 'Use Hashcat' }],
27+
['auto', { 'Description' => 'Use either John the Ripper or Hashcat, if both are present, use Hashcat' }]
2728
],
28-
'DefaultAction' => 'john',
29+
'DefaultAction' => 'auto',
2930
'Notes' => {
3031
'Stability' => [CRASH_SAFE],
3132
'SideEffects' => [],
@@ -47,23 +48,28 @@ def initialize
4748
def show_command(cracker_instance)
4849
return unless datastore['ShowCommand']
4950

50-
if action.name == 'john'
51+
newaction = getaction()
52+
53+
if newaction == 'john'
5154
cmd = cracker_instance.john_crack_command
52-
elsif action.name == 'hashcat'
55+
elsif newaction == 'hashcat'
5356
cmd = cracker_instance.hashcat_crack_command
5457
end
5558
print_status(" Cracking Command: #{cmd.join(' ')}")
5659
end
5760

5861
def check_results(passwords, results, hash_type, method)
62+
63+
newaction = getaction()
64+
5965
passwords.each do |password_line|
6066
password_line.chomp!
6167
next if password_line.blank?
6268

6369
fields = password_line.split(':')
6470
cred = { 'hash_type' => hash_type, 'method' => method }
6571
# If we don't have an expected minimum number of fields, this is probably not a hash line
66-
if action.name == 'john'
72+
if newaction == 'john'
6773
next unless fields.count >= 3
6874

6975
cred['username'] = fields.shift
@@ -72,7 +78,7 @@ def check_results(passwords, results, hash_type, method)
7278
4.times { fields.pop } # Get rid of extra :
7379
end
7480
cred['password'] = fields.join(':') # Anything left must be the password. This accounts for passwords with semi-colons in it
75-
elsif action.name == 'hashcat'
81+
elsif newaction == 'hashcat'
7682
next unless fields.count >= 3
7783

7884
cred['core_id'] = fields.shift
@@ -91,6 +97,9 @@ def check_results(passwords, results, hash_type, method)
9197
end
9298

9399
def run
100+
101+
newaction = getaction()
102+
94103
tbl = tbl = cracker_results_table
95104

96105
# array of hashes in jtr_format in the db, converted to an OR combined regex
@@ -102,7 +111,7 @@ def run
102111

103112
# build our job list
104113
hash_types_to_crack.each do |hash_type|
105-
job = hash_job(hash_type, action.name)
114+
job = hash_job(hash_type, newaction)
106115
if job.nil?
107116
print_status("No #{hash_type} found to crack")
108117
else
@@ -120,7 +129,7 @@ def run
120129
# Inner array format: db_id, hash_type, username, password, method_of_crack
121130
results = []
122131

123-
cracker = new_password_cracker(action.name)
132+
cracker = new_password_cracker(newaction)
124133

125134
# generate our wordlist and close the file handle.
126135
wordlist = wordlist_file
@@ -144,7 +153,7 @@ def run
144153
# dupe our original cracker so we can safely change options between each run
145154
cracker_instance = cracker.dup
146155
cracker_instance.format = format
147-
if action.name == 'john'
156+
if newaction == 'john'
148157
cracker_instance.fork = datastore['FORK']
149158
end
150159

@@ -153,7 +162,7 @@ def run
153162
results = check_results(cracker_instance.each_cracked_password, results, format, 'Already Cracked/POT')
154163
vprint_good(append_results(tbl, results)) unless results.empty?
155164

156-
if action.name == 'john'
165+
if newaction == 'john'
157166
print_status "Cracking #{format} hashes in single mode..."
158167
cracker_instance.mode_single(wordlist.path)
159168
show_command cracker_instance
@@ -194,7 +203,7 @@ def run
194203
print_status "Cracking #{format} hashes in wordlist mode..."
195204
cracker_instance.mode_wordlist(wordlist.path)
196205
# Turn on KoreLogic rules if the user asked for it
197-
if action.name == 'john' && datastore['KORELOGIC']
206+
if newaction == 'john' && datastore['KORELOGIC']
198207
cracker_instance.rules = 'KoreLogicRules'
199208
print_status 'Applying KoreLogic ruleset...'
200209
end
@@ -218,4 +227,24 @@ def run
218227
end
219228
end
220229
end
230+
231+
def getaction
232+
newaction = action.name
233+
if action.name == 'auto'
234+
path = Rex::FileUtils.find_full_path('hashcat') ||
235+
Rex::FileUtils.find_full_path('hashcat.exe')
236+
if path
237+
newaction = 'hashcat'
238+
else
239+
path = Rex::FileUtils.find_full_path('john') ||
240+
Rex::FileUtils.find_full_path('john.exe')
241+
if path
242+
newaction = 'john'
243+
else
244+
raise PasswordCrackerNotFoundError, 'No suitable john/hashcat binary was found on the system'
245+
end
246+
end
247+
end
248+
return newaction
249+
end
221250
end

0 commit comments

Comments
 (0)